Daffodil_Tryon - Version 1.0.0.1

Version Notes

First Release

Download this release

Release Info

Developer Daffodil Software
Extension Daffodil_Tryon
Version 1.0.0.1
Comparing to
See all releases


Version 1.0.0.1

Files changed (116) hide show
  1. app/code/local/Ajax/Face/controllers/Face.php +31 -0
  2. app/code/local/Ajax/Face/controllers/IndexController.php +29 -0
  3. app/code/local/Ajax/Face/controllers/IndexController.php.bak +12 -0
  4. app/code/local/Ajax/Face/controllers/SimpleImage.php +105 -0
  5. app/code/local/Ajax/Face/controllers/mashape/MashapeClient.php +30 -0
  6. app/code/local/Ajax/Face/controllers/mashape/authentication/Authentication.php +7 -0
  7. app/code/local/Ajax/Face/controllers/mashape/authentication/AuthenticationUtil.php +40 -0
  8. app/code/local/Ajax/Face/controllers/mashape/authentication/BasicAuthentication.php +21 -0
  9. app/code/local/Ajax/Face/controllers/mashape/authentication/CustomHeaderAuthentication.php +20 -0
  10. app/code/local/Ajax/Face/controllers/mashape/authentication/HeaderAuthentication.php +9 -0
  11. app/code/local/Ajax/Face/controllers/mashape/authentication/MashapeAuthentication.php +17 -0
  12. app/code/local/Ajax/Face/controllers/mashape/authentication/OAuth10aAuthentication.php +24 -0
  13. app/code/local/Ajax/Face/controllers/mashape/authentication/OAuth2Authentication.php +20 -0
  14. app/code/local/Ajax/Face/controllers/mashape/authentication/OAuthAuthentication.php +40 -0
  15. app/code/local/Ajax/Face/controllers/mashape/authentication/QueryAuthentication.php +20 -0
  16. app/code/local/Ajax/Face/controllers/mashape/exceptions/ExceptionConstants.php +70 -0
  17. app/code/local/Ajax/Face/controllers/mashape/exceptions/MashapeClientException.php +37 -0
  18. app/code/local/Ajax/Face/controllers/mashape/http/Chunked.php +46 -0
  19. app/code/local/Ajax/Face/controllers/mashape/http/ContentType.php +34 -0
  20. app/code/local/Ajax/Face/controllers/mashape/http/HttpClient.php +134 -0
  21. app/code/local/Ajax/Face/controllers/mashape/http/HttpMethod.php +36 -0
  22. app/code/local/Ajax/Face/controllers/mashape/http/HttpUtils.php +92 -0
  23. app/code/local/Ajax/Face/controllers/mashape/http/MashapeResponse.php +61 -0
  24. app/code/local/Ajax/Face/controllers/mashape/http/UrlUtils.php +39 -0
  25. app/code/local/Ajax/Face/controllers/mashape/json/Json.php +40 -0
  26. app/code/local/Ajax/Face/controllers/mashape/json/Services_JSON.php +806 -0
  27. app/code/local/Ajax/Face/etc/config.xml +26 -0
  28. app/code/local/Daffodil/Tryon/Block/Product/list.php +9 -0
  29. app/code/local/Daffodil/Tryon/Block/Product/list.php~ +9 -0
  30. app/code/local/Daffodil/Tryon/Helper/Data.php +10 -0
  31. app/code/local/Daffodil/Tryon/Helper/Data.php~ +10 -0
  32. app/code/local/Daffodil/Tryon/Helper/data.php.bak +6 -0
  33. app/code/local/Daffodil/Tryon/Model/Avatar.php +10 -0
  34. app/code/local/Daffodil/Tryon/Model/Avatar.php~ +10 -0
  35. app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar.php +9 -0
  36. app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar.php.bak +9 -0
  37. app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar.php~ +9 -0
  38. app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar/collection.php +11 -0
  39. app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar/collection.php.bak +10 -0
  40. app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar/collection.php~ +11 -0
  41. app/code/local/Daffodil/Tryon/Model/System/Config/Source/Position.php +27 -0
  42. app/code/local/Daffodil/Tryon/Model/System/Config/Source/Position.php~ +27 -0
  43. app/code/local/Daffodil/Tryon/controllers/Face.php +36 -0
  44. app/code/local/Daffodil/Tryon/controllers/Face.php~ +36 -0
  45. app/code/local/Daffodil/Tryon/controllers/IndexController.php +46 -0
  46. app/code/local/Daffodil/Tryon/controllers/IndexController.php~ +46 -0
  47. app/code/local/Daffodil/Tryon/controllers/SimpleImage.php +90 -0
  48. app/code/local/Daffodil/Tryon/controllers/SimpleImage.php~ +90 -0
  49. app/code/local/Daffodil/Tryon/controllers/mashape/MashapeClient.php +30 -0
  50. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/Authentication.php +11 -0
  51. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/Authentication.php~ +11 -0
  52. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/AuthenticationUtil.php +20 -0
  53. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/AuthenticationUtil.php~ +20 -0
  54. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/BasicAuthentication.php +21 -0
  55. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/CustomHeaderAuthentication.php +20 -0
  56. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/HeaderAuthentication.php +9 -0
  57. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/MashapeAuthentication.php +17 -0
  58. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/OAuth10aAuthentication.php +24 -0
  59. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/OAuth2Authentication.php +20 -0
  60. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/OAuthAuthentication.php +40 -0
  61. app/code/local/Daffodil/Tryon/controllers/mashape/authentication/QueryAuthentication.php +20 -0
  62. app/code/local/Daffodil/Tryon/controllers/mashape/exceptions/ExceptionConstants.php +50 -0
  63. app/code/local/Daffodil/Tryon/controllers/mashape/exceptions/ExceptionConstants.php~ +50 -0
  64. app/code/local/Daffodil/Tryon/controllers/mashape/exceptions/MashapeClientException.php +37 -0
  65. app/code/local/Daffodil/Tryon/controllers/mashape/http/Chunked.php +46 -0
  66. app/code/local/Daffodil/Tryon/controllers/mashape/http/ContentType.php +34 -0
  67. app/code/local/Daffodil/Tryon/controllers/mashape/http/HttpClient.php +134 -0
  68. app/code/local/Daffodil/Tryon/controllers/mashape/http/HttpMethod.php +36 -0
  69. app/code/local/Daffodil/Tryon/controllers/mashape/http/HttpUtils.php +72 -0
  70. app/code/local/Daffodil/Tryon/controllers/mashape/http/HttpUtils.php~ +72 -0
  71. app/code/local/Daffodil/Tryon/controllers/mashape/http/MashapeResponse.php +61 -0
  72. app/code/local/Daffodil/Tryon/controllers/mashape/http/UrlUtils.php +39 -0
  73. app/code/local/Daffodil/Tryon/controllers/mashape/json/Json.php +40 -0
  74. app/code/local/Daffodil/Tryon/controllers/mashape/json/Services_JSON.php +806 -0
  75. app/code/local/Daffodil/Tryon/etc/config.xml +61 -0
  76. app/code/local/Daffodil/Tryon/etc/config.xml~ +61 -0
  77. app/code/local/Daffodil/Tryon/etc/system.xml +41 -0
  78. app/code/local/Daffodil/Tryon/etc/system.xml~ +41 -0
  79. app/code/local/Daffodil/Tryon/sql/avatar_setup/mysql4-install-0.1.0.php +22 -0
  80. app/code/local/Daffodil/Tryon/sql/avatar_setup/mysql4-install-0.1.0.php~ +22 -0
  81. app/design/frontend/default/default/layout/tryon.xml +42 -0
  82. app/design/frontend/default/default/template/tryon/list.phtml +109 -0
  83. app/design/frontend/default/default/template/tryon/list.phtml~ +109 -0
  84. app/design/frontend/default/default/template/tryon/rightsection.phtml +236 -0
  85. app/design/frontend/default/default/template/tryon/rightsection.phtml~ +236 -0
  86. app/design/frontend/default/default/template/tryon/view.phtml +142 -0
  87. app/design/frontend/default/default/template/tryon/view.phtml~ +142 -0
  88. app/etc/modules/Ajax_Face.xml +9 -0
  89. app/etc/modules/Daffodil_Tryon.xml +9 -0
  90. js/tryon/ajaxupload.3.5.js +546 -0
  91. js/tryon/jquery-1.8.2.js +9441 -0
  92. js/tryon/jquery-ui.min.js +5 -0
  93. js/tryon/jquery.hoverscroll.js +449 -0
  94. js/tryon/jquery.stickyfloat.js +179 -0
  95. js/tryon/jquery.ui.button.js +170 -0
  96. js/tryon/jquery.ui.core.js +334 -0
  97. js/tryon/jquery.ui.dialog.js +820 -0
  98. js/tryon/jquery.ui.draggable.js +832 -0
  99. js/tryon/jquery.ui.mouse.js +167 -0
  100. js/tryon/jquery.ui.widget.js +272 -0
  101. media/modelphotos/face.jpg +0 -0
  102. media/modelphotos/model1.jpg +0 -0
  103. media/modelphotos/model2.jpg +0 -0
  104. media/modelphotos/model3.jpg +0 -0
  105. media/modelphotos/model4.jpg +0 -0
  106. media/modelphotos/model5.jpg +0 -0
  107. media/modelphotos/model6.jpg +0 -0
  108. media/modelphotos/model7.jpg +0 -0
  109. media/modelphotos/model8.jpg +0 -0
  110. media/uploads/1337296847_2.jpg +0 -0
  111. package.xml +18 -0
  112. skin/frontend/default/default/images/ajax-loader.gif +0 -0
  113. skin/frontend/default/default/images/cross.png +0 -0
  114. skin/frontend/default/default/images/images.jpeg +0 -0
  115. skin/frontend/default/default/images/model2.jpg +0 -0
  116. skin/frontend/default/default/tryon/tryon.css +105 -0
app/code/local/Ajax/Face/controllers/Face.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once("mashape/MashapeClient.php");
3
+
4
+
5
+ class Face {
6
+ const PUBLIC_DNS = "lambda-face-detection-and-recognition.p.mashape.com";
7
+ private $authHandlers;
8
+
9
+ function __construct($publicKey, $privateKey) {
10
+ $this->authHandlers = array();
11
+ $this->authHandlers[] = new MashapeAuthentication($publicKey, $privateKey);
12
+
13
+ }
14
+ public function detect($images) {
15
+ $parameters = array(
16
+ "images" => $images);
17
+
18
+ $response = HttpClient::doRequest(
19
+ HttpMethod::GET,
20
+ "https://" . self::PUBLIC_DNS . "/detect",
21
+ $parameters,
22
+ $this->authHandlers,
23
+ ContentType::FORM,
24
+ true);
25
+ return $response;
26
+ }
27
+
28
+
29
+
30
+ }
31
+ ?>
app/code/local/Ajax/Face/controllers/IndexController.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Ajax_Face_IndexController extends Mage_Core_Controller_Front_Action
3
+ {
4
+ public function indexAction()
5
+ {
6
+
7
+ $data = $_POST['dataString'];
8
+ echo $data;
9
+
10
+
11
+
12
+
13
+ require_once("Face.php");
14
+
15
+
16
+ // basic instantiation. TODO Put your authentication keys here.
17
+
18
+ $obj = new Face("6z1mstluneooiy1ulntokkfs08cd7w", "nirjdkl9hmqsh1cri0r3qeoklxrub9");
19
+
20
+ $response = $obj->detect($data);
21
+
22
+
23
+ $top = $response->body->photos[0]->tags[0]->eye_left->y;
24
+ $left = $response->body->photos[0]->tags[0]->eye_left->x;
25
+ echo ",".$top.",";
26
+ echo $left.",";
27
+ }
28
+ }
29
+
app/code/local/Ajax/Face/controllers/IndexController.php.bak ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Photo_Avatar_IndexController extends Mage_Core_Controller_Front_Action
4
+ {
5
+ public function indexAction()
6
+ {
7
+
8
+ echo "Hello World";
9
+ // $this->loadLayout();
10
+ // $this->renderLayout();
11
+ }
12
+ }
app/code/local/Ajax/Face/controllers/SimpleImage.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * File: SimpleImage.php
5
+ * Author: Simon Jarvis
6
+ * Copyright: 2006 Simon Jarvis
7
+ * Date: 08/11/06
8
+ * Link: http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php
9
+ *
10
+ * This program is free software; you can redistribute it and/or
11
+ * modify it under the terms of the GNU General Public License
12
+ * as published by the Free Software Foundation; either version 2
13
+ * of the License, or (at your option) any later version.
14
+ *
15
+ * This program is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ * GNU General Public License for more details:
19
+ * http://www.gnu.org/licenses/gpl.html
20
+ *
21
+ */
22
+
23
+ class SimpleImage {
24
+
25
+ var $image;
26
+ var $image_type;
27
+
28
+ function load($filename) {
29
+
30
+ $image_info = getimagesize($filename);
31
+ $this->image_type = $image_info[2];
32
+ if( $this->image_type == IMAGETYPE_JPEG ) {
33
+
34
+ $this->image = imagecreatefromjpeg($filename);
35
+ } elseif( $this->image_type == IMAGETYPE_GIF ) {
36
+
37
+ $this->image = imagecreatefromgif($filename);
38
+ } elseif( $this->image_type == IMAGETYPE_PNG ) {
39
+
40
+ $this->image = imagecreatefrompng($filename);
41
+ }
42
+ }
43
+ function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
44
+
45
+ if( $image_type == IMAGETYPE_JPEG ) {
46
+ imagejpeg($this->image,$filename,$compression);
47
+ } elseif( $image_type == IMAGETYPE_GIF ) {
48
+
49
+ imagegif($this->image,$filename);
50
+ } elseif( $image_type == IMAGETYPE_PNG ) {
51
+
52
+ imagepng($this->image,$filename);
53
+ }
54
+ if( $permissions != null) {
55
+
56
+ chmod($filename,$permissions);
57
+ }
58
+ }
59
+ function output($image_type=IMAGETYPE_JPEG) {
60
+
61
+ if( $image_type == IMAGETYPE_JPEG ) {
62
+ imagejpeg($this->image);
63
+ } elseif( $image_type == IMAGETYPE_GIF ) {
64
+
65
+ imagegif($this->image);
66
+ } elseif( $image_type == IMAGETYPE_PNG ) {
67
+
68
+ imagepng($this->image);
69
+ }
70
+ }
71
+ function getWidth() {
72
+
73
+ return imagesx($this->image);
74
+ }
75
+ function getHeight() {
76
+
77
+ return imagesy($this->image);
78
+ }
79
+ function resizeToHeight($height) {
80
+
81
+ $ratio = $height / $this->getHeight();
82
+ $width = $this->getWidth() * $ratio;
83
+ $this->resize($width,$height);
84
+ }
85
+
86
+ function resizeToWidth($width) {
87
+ $ratio = $width / $this->getWidth();
88
+ $height = $this->getheight() * $ratio;
89
+ $this->resize($width,$height);
90
+ }
91
+
92
+ function scale($scale) {
93
+ $width = $this->getWidth() * $scale/100;
94
+ $height = $this->getheight() * $scale/100;
95
+ $this->resize($width,$height);
96
+ }
97
+
98
+ function resize($width,$height) {
99
+ $new_image = imagecreatetruecolor($width, $height);
100
+ imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
101
+ $this->image = $new_image;
102
+ }
103
+
104
+ }
105
+ ?>
app/code/local/Ajax/Face/controllers/mashape/MashapeClient.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ require_once(dirname(__FILE__) . "/http/HttpClient.php");
28
+ require_once(dirname(__FILE__) . "/http/MashapeResponse.php");
29
+
30
+ ?>
app/code/local/Ajax/Face/controllers/mashape/authentication/Authentication.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ interface Authentication {
3
+ public function handleHeaders();
4
+
5
+ public function handleParams();
6
+ }
7
+ ?>
app/code/local/Ajax/Face/controllers/mashape/authentication/AuthenticationUtil.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ class AuthenticationUtil {
28
+
29
+ public static function generateAuthenticationHeader($publicKey, $privateKey) {
30
+ $header = "";
31
+ if (!($publicKey == null || $privateKey == null)) {
32
+ $hash = hash_hmac("sha1", $publicKey, $privateKey);
33
+ $header = "X-Mashape-Authorization: " . base64_encode($publicKey . ":" . $hash);
34
+ }
35
+ return $header;
36
+ }
37
+
38
+ }
39
+
40
+ ?>
app/code/local/Ajax/Face/controllers/mashape/authentication/BasicAuthentication.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/HeaderAuthentication.php");
3
+
4
+ class BasicAuthentication extends HeaderAuthentication {
5
+
6
+ private $headers;
7
+
8
+ function __construct($username, $password) {
9
+ $headerValue = $username . ":" . $password;
10
+ $this->headers = array("Authorization: Basic " . base64_encode($headerValue));
11
+ }
12
+
13
+ public function handleHeaders() {
14
+ return $this->headers;
15
+ }
16
+
17
+ public function handleParams() {
18
+ return null;
19
+ }
20
+ }
21
+ ?>
app/code/local/Ajax/Face/controllers/mashape/authentication/CustomHeaderAuthentication.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/HeaderAuthentication.php");
3
+
4
+ class CustomHeaderAuthentication extends HeaderAuthentication {
5
+
6
+ private $headers;
7
+
8
+ function __construct($headerName, $headerValue) {
9
+ $this->headers = array($headerName . ": " . $headerValue);
10
+ }
11
+
12
+ public function handleHeaders() {
13
+ return $this->headers;
14
+ }
15
+
16
+ public function handleParams() {
17
+ return null;
18
+ }
19
+ }
20
+ ?>
app/code/local/Ajax/Face/controllers/mashape/authentication/HeaderAuthentication.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/Authentication.php");
3
+
4
+ abstract class HeaderAuthentication implements Authentication {
5
+ public function handleParams() {
6
+ return null;
7
+ }
8
+ }
9
+ ?>
app/code/local/Ajax/Face/controllers/mashape/authentication/MashapeAuthentication.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/AuthenticationUtil.php");
3
+ require_once(dirname(__FILE__) . "/HeaderAuthentication.php");
4
+
5
+ class MashapeAuthentication extends HeaderAuthentication {
6
+
7
+ private $headers;
8
+
9
+ function __construct($publicKey, $privateKey) {
10
+ $this->headers = array(AuthenticationUtil::generateAuthenticationHeader($publicKey, $privateKey));
11
+ }
12
+
13
+ public function handleHeaders() {
14
+ return $this->headers;
15
+ }
16
+ }
17
+ ?>
app/code/local/Ajax/Face/controllers/mashape/authentication/OAuth10aAuthentication.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/OAuthAuthentication.php");
3
+
4
+ class OAuth10aAuthentication extends OAuthAuthentication {
5
+
6
+ function __construct($consumerKey, $consumerSecret, $callbackUrl) {
7
+ parent::__construct($consumerKey, $consumerSecret, $callbackUrl);
8
+ }
9
+
10
+ public function handleHeaders() {
11
+ if (!isset($this->accessToken) || !isset($this->accessSecret)) {
12
+ throw new MashapeClientException(
13
+ EXCEPTION_OAUTH1_AUTHORIZE,
14
+ EXCEPTION_OAUTH1_AUTHORIZE_CODE);
15
+ }
16
+ $headers = array();
17
+ $headers[] = "x-mashape-oauth-consumerkey: " . $this->consumerKey;
18
+ $headers[] = "x-mashape-oauth-consumersecret: " . $this->consumerSecret;
19
+ $headers[] = "x-mashape-oauth-accesstoken: " . $this->accessToken;
20
+ $headers[] = "x-mashape-oauth-accesssecret: " . $this->accessSecret;
21
+ return $headers;
22
+ }
23
+ }
24
+ ?>
app/code/local/Ajax/Face/controllers/mashape/authentication/OAuth2Authentication.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/OAuthAuthentication.php");
3
+
4
+ class OAuth2Authentication extends OAuthAuthentication {
5
+
6
+ function __construct($consumerKey, $consumerSecret, $callbackUrl) {
7
+ parent::__construct($consumerKey, $consumerSecret, $callbackUrl);
8
+ }
9
+
10
+ public function handleParams() {
11
+ if ($this->accessToken == null) {
12
+ throw new MashapeClientException(
13
+ EXCEPTION_OAUTH2_AUTHORIZE,
14
+ EXCEPTION_OAUTH2_AUTHORIZE_CODE);
15
+ }
16
+ $params = array("accesstoken" => $this->accessToken);
17
+ return $params;
18
+ }
19
+ }
20
+ ?>
app/code/local/Ajax/Face/controllers/mashape/authentication/OAuthAuthentication.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/Authentication.php");
3
+
4
+ class OAuthAuthentication implements Authentication {
5
+
6
+ protected $consumerKey;
7
+ protected $consumerSecret;
8
+ protected $callbackUrl;
9
+ protected $accessToken;
10
+ protected $accessSecret;
11
+
12
+ function __construct($consumerKey, $consumerSecret, $callbackUrl) {
13
+ $this->consumerKey = $consumerKey;
14
+ $this->consumerSecret = $consumerSecret;
15
+ $this->callbackUrl = $callbackUrl;
16
+ }
17
+
18
+ public function addAccessToken($accessToken, $accessSecret = null) {
19
+ $this->accessToken = $accessToken;
20
+ $this->accessSecret = $accessSecret;
21
+ }
22
+
23
+ public function getOAuthBaseParams() {
24
+ $params = array(
25
+ "consumerKey" => $this->consumerKey,
26
+ "consumerSecret" => $this->consumerSecret,
27
+ "callbackUrl" => $this->callbackUrl,
28
+ );
29
+ return $params;
30
+ }
31
+
32
+ public function handleParams() {
33
+ return null;
34
+ }
35
+
36
+ public function handleHeaders() {
37
+ return null;
38
+ }
39
+ }
40
+ ?>
app/code/local/Ajax/Face/controllers/mashape/authentication/QueryAuthentication.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/Authentication.php");
3
+
4
+ class QueryAuthentication implements Authentication {
5
+
6
+ private $params;
7
+
8
+ function __construct($queryKey, $queryValue) {
9
+ $this->params = array($queryKey => $queryValue);
10
+ }
11
+
12
+ public function handleHeaders() {
13
+ return null;
14
+ }
15
+
16
+ public function handleParams() {
17
+ return $this->params;
18
+ }
19
+ }
20
+ ?>
app/code/local/Ajax/Face/controllers/mashape/exceptions/ExceptionConstants.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ define("EXCEPTION_NOTSUPPORTED_HTTPMETHOD_CODE", 1003);
28
+ define("EXCEPTION_NOTSUPPORTED_HTTPMETHOD",
29
+ "HTTP method not supported. Only DELETE, GET, POST, PUT are supported");
30
+
31
+ define("EXCEPTION_CONTENT_TYPE_JSON_ARRAY_CODE", 1004);
32
+ define("EXCEPTION_CONTENT_TYPE_JSON_ARRAY",
33
+ "Content Type JSON does not accept array parameters. Parameters should be"
34
+ ." a JSON string");
35
+
36
+ define("EXCEPTION_CONTENT_TYPE_NON_ARRAY_CODE", 1005);
37
+ define("EXCEPTION_CONTENT_TYPE_NON_ARRAY",
38
+ "Parameters must be an array unless content type is set to JSON");
39
+
40
+ define("EXCEPTION_CONTENT_TYPE_JSON_QUERYAUTH_CODE", 1006);
41
+ define("EXCEPTION_CONTENT_TYPE_JSON_QUERYAUTH",
42
+ "Query Authentication cannot be used in conjunction with content type JSON");
43
+
44
+ define("EXCEPTION_OAUTH1_AUTHORIZE_CODE", 1007);
45
+ define("EXCEPTION_OAUTH1_AUTHORIZE",
46
+ "Before consuming an OAuth endpoint, you must invoke the authorize("
47
+ ."'access_token', 'access_secret') function with non-null values");
48
+
49
+ define("EXCEPTION_OAUTH2_AUTHORIZE_CODE", 1007);
50
+ define("EXCEPTION_OAUTH2_AUTHORIZE",
51
+ "Before consuming an OAuth endpoint, you must invoke the authorize("
52
+ ."'access_token') function with a non-null value");
53
+
54
+ define("EXCEPTION_NOTSUPPORTED_CONTENTTYPE_CODE", 415);
55
+ define("EXCEPTION_NOTSUPPORTED_CONTENTTYPE",
56
+ "Content Type not supported. Currently only application/x-www-form-urlencoded, "
57
+ ."application/json, and multipart/form-data are supported");
58
+
59
+ define("EXCEPTION_GET_INVALID_CONTENTTYPE_CODE", 415);
60
+ define("EXCEPTION_GET_INVALID_CONTENTTYPE", "A GET request must have a content"
61
+ ." type of application/x-www-form-urlencoded or application/json");
62
+
63
+ define("EXCEPTION_CURL_CODE", 520);
64
+ define("EXCEPTION_CURL",
65
+ "Encountered an exception making the request");
66
+
67
+ define("EXCEPTION_SYSTEM_ERROR_CODE", 2000);
68
+ define("EXCEPTION_JSONDECODE_REQUEST", "Can't deserialize the response JSON: %s");
69
+
70
+ ?>
app/code/local/Ajax/Face/controllers/mashape/exceptions/MashapeClientException.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ require_once (dirname(__FILE__) . "/ExceptionConstants.php");
28
+
29
+ class MashapeClientException extends Exception {
30
+
31
+ function __construct($message, $code) {
32
+ parent::__construct($message, $code);
33
+ }
34
+
35
+ }
36
+
37
+ ?>
app/code/local/Ajax/Face/controllers/mashape/http/Chunked.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!function_exists('http-chunked-decode')) {
4
+ /**
5
+ * dechunk an http 'transfer-encoding: chunked' message
6
+ *
7
+ * @param string $chunk the encoded message
8
+ * @return string the decoded message. If $chunk wasn't encoded properly it will be returned unmodified.
9
+ */
10
+ function http_chunked_decode($chunk) {
11
+ $pos = 0;
12
+ $len = strlen($chunk);
13
+ $dechunk = null;
14
+
15
+ while(($pos < $len)
16
+ && ($chunkLenHex = substr($chunk,$pos, ($newlineAt = strpos($chunk,"\n",$pos+1))-$pos)))
17
+ {
18
+ if (! is_hex($chunkLenHex)) {
19
+ trigger_error('Value is not properly chunk encoded', E_USER_WARNING);
20
+ return $chunk;
21
+ }
22
+
23
+ $pos = $newlineAt + 1;
24
+ $chunkLen = hexdec(rtrim($chunkLenHex,"\r\n"));
25
+ $dechunk .= substr($chunk, $pos, $chunkLen);
26
+ $pos = strpos($chunk, "\n", $pos + $chunkLen) + 1;
27
+ }
28
+ return $dechunk;
29
+ }
30
+ }
31
+
32
+ /**
33
+ * determine if a string can represent a number in hexadecimal
34
+ *
35
+ * @param string $hex
36
+ * @return boolean true if the string is a hex, otherwise false
37
+ */
38
+ function is_hex($hex) {
39
+ // regex is for weenies
40
+ $hex = strtolower(trim(ltrim($hex,"0")));
41
+ if (empty($hex)) { $hex = 0; };
42
+ $dec = hexdec($hex);
43
+ return ($hex == dechex($dec));
44
+ }
45
+
46
+ ?>
app/code/local/Ajax/Face/controllers/mashape/http/ContentType.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ class ContentType
28
+ {
29
+ const FORM = "FORM";
30
+ const MULTIPART = "MULTIPART";
31
+ const JSON = "JSON";
32
+ }
33
+
34
+ ?>
app/code/local/Ajax/Face/controllers/mashape/http/HttpClient.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ require_once(dirname(__FILE__) . "/../exceptions/MashapeClientException.php");
28
+ require_once(dirname(__FILE__) . "/HttpMethod.php");
29
+ require_once(dirname(__FILE__) . "/ContentType.php");
30
+ require_once(dirname(__FILE__) . "/UrlUtils.php");
31
+ require_once(dirname(__FILE__) . "/HttpUtils.php");
32
+ require_once(dirname(__FILE__) . "/MashapeResponse.php");
33
+ require_once(dirname(__FILE__) . "/../authentication/HeaderAuthentication.php");
34
+ require_once(dirname(__FILE__) . "/../authentication/BasicAuthentication.php");
35
+ require_once(dirname(__FILE__) . "/../authentication/CustomHeaderAuthentication.php");
36
+ require_once(dirname(__FILE__) . "/../authentication/MashapeAuthentication.php");
37
+ require_once(dirname(__FILE__) . "/../authentication/QueryAuthentication.php");
38
+ //require_once(dirname(__FILE__) . "/../authentication/Oauth10aAuthentication.php");
39
+ //require_once(dirname(__FILE__) . "/../authentication/Oauth2Authentication.php");
40
+
41
+ class HttpClient {
42
+
43
+ public static function doRequest($httpMethod, $url, $parameters,
44
+ $authHandlers, $contentType = ContentType::FORM, $encodeJson = true) {
45
+ HttpUtils::cleanParameters($parameters);
46
+
47
+ if ($authHandlers == null) {
48
+ $authHandlers = array();
49
+ }
50
+
51
+ self::validateRequest($httpMethod, $url, $parameters, $authHandlers, $contentType);
52
+ $response = self::execRequest($httpMethod, $url, $parameters, $authHandlers, $contentType, $encodeJson);
53
+
54
+ return $response;
55
+ }
56
+
57
+ private static function validateRequest($httpMethod, $url, $parameters, $authHandlers, $contentType) {
58
+ if ( !($httpMethod == HttpMethod::DELETE
59
+ || $httpMethod == HttpMethod::GET
60
+ || $httpMethod == HttpMethod::POST
61
+ || $httpMethod == HttpMethod::PUT
62
+ || $httpMethod == HttpMethod::PATCH)) {
63
+ // we only support these HTTP methods.
64
+ throw new MashapeClientException(EXCEPTION_NOTSUPPORTED_HTTPMETHOD,
65
+ EXCEPTION_NOTSUPPORTED_HTTPMETHOD_CODE);
66
+ }
67
+ if ($contentType == ContentType::JSON && is_array($parameters)) {
68
+ // Content type JSON does not allow array parameters.
69
+ throw new MashapeClientException(
70
+ EXCEPTION_CONTENT_TYPE_JSON_ARRAY,
71
+ EXCEPTION_CONTENT_TYPE_JSON_ARRAY_CODE);
72
+ }
73
+ if (!is_array($parameters) && $contentType != ContentType::JSON) {
74
+ // Raw parameters are only allows for ContentType::JSON
75
+ throw new MashapeClientException(
76
+ EXCEPTION_CONTENT_TYPE_NON_ARRAY,
77
+ EXCEPTION_CONTENT_TYPE_NON_ARRAY_CODE);
78
+ }
79
+ if ($httpMethod == HttpMethod::GET && $contentType != ContentType::FORM) {
80
+ // if we have a GET request that is anything other than urlencoded
81
+ // form data, we shouldn't allow it.
82
+ throw new MashapeClientException(
83
+ EXCEPTION_GET_INVALID_CONTENTTYPE,
84
+ EXCEPTION_GET_INVALID_CONTENTTYPE_CODE);
85
+ }
86
+ if ($contentType == ContentType::JSON) {
87
+ foreach ($authHandlers as $handler) {
88
+ if ($handler instanceof QueryAuthentication) {
89
+ // bad. No room for query auth parameters if the whole body is json
90
+ throw new MashapeClientException(
91
+ EXCEPTION_CONTENT_TYPE_JSON_QUERYAUTH,
92
+ EXCEPTION_CONTENT_TYPE_JSON_QUERYAUTH_CODE);
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ private static function execRequest($httpMethod, $url, $parameters, $authHandlers, $contentType, $encodeJson) {
99
+ // first, collect the headers and parameters we'll need from the authentication handlers
100
+ list($headers, $authParameters) = HttpUtils::handleAuthentication($authHandlers);
101
+ if (is_array($parameters)) {
102
+ $parameters = array_merge($parameters, $authParameters);
103
+ }
104
+
105
+ // prepare the request
106
+ $ch = curl_init ();
107
+
108
+ if ($httpMethod == HttpMethod::GET) {
109
+ $url = UrlUtils::buildUrlWithQueryString($url, $parameters);
110
+ } else {
111
+ $data = HttpUtils::buildDataForContentType($contentType, $parameters, $headers);
112
+ curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, $httpMethod);
113
+ curl_setopt ($ch, CURLOPT_POSTFIELDS, $data);
114
+ }
115
+ curl_setopt ($ch, CURLOPT_URL , $url);
116
+ curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
117
+ curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);
118
+ curl_setopt ($ch, CURLINFO_HEADER_OUT, true);
119
+ curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
120
+ $response = curl_exec($ch);
121
+ if (curl_error($ch)) {
122
+ throw new MashapeClientException(
123
+ EXCEPTION_CURL . ":" . curl_error($ch),
124
+ EXCEPTION_CURL_CODE);
125
+ }
126
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
127
+ $responseHeaders = curl_getinfo($ch, CURLINFO_HEADER_OUT);
128
+ curl_close($ch);
129
+
130
+ return new MashapeResponse($response, $httpCode, $responseHeaders, $encodeJson);
131
+ }
132
+ }
133
+
134
+ ?>
app/code/local/Ajax/Face/controllers/mashape/http/HttpMethod.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ class HttpMethod
28
+ {
29
+ const DELETE = "DELETE";
30
+ const GET = "GET";
31
+ const POST = "POST";
32
+ const PUT = "PUT";
33
+ const PATCH = "PATCH";
34
+ }
35
+
36
+ ?>
app/code/local/Ajax/Face/controllers/mashape/http/HttpUtils.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ class HttpUtils {
28
+
29
+ public static function cleanParameters(&$parameters) {
30
+ if ($parameters == null) {
31
+ $parameters = array();
32
+ } else if (is_array($parameters)) {
33
+ // Remove null parameters
34
+ $keys = array_keys($parameters);
35
+ for ($i = 0;$i<count($keys);$i++) {
36
+ $key = $keys[$i];
37
+ if ($parameters[$key] === null) {
38
+ unset($parameters[$key]);
39
+ } else {
40
+ $parameters[$key] = (string)$parameters[$key];
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ public static function buildDataForContentType($contentType, $parameters, &$headers) {
47
+ $data = null;
48
+ switch ($contentType) {
49
+ case ContentType::FORM:
50
+ $data = http_build_query($parameters);
51
+ break;
52
+ case ContentType::MULTIPART:
53
+ $data = $parameters;
54
+ break;
55
+ case ContentType::JSON:
56
+ $headers[] = "Content-Type: application/json";
57
+ $data = $parameters;
58
+ break;
59
+ default:
60
+ throw new MashapeClientException(
61
+ EXCEPTION_NOTSUPPORTED_CONTENTTYPE,
62
+ EXCEPTION_NOTSUPPORTED_CONTENTTYPE_CODE);
63
+ }
64
+ return $data;
65
+ }
66
+
67
+ public static function handleAuthentication($authHandlers) {
68
+ $headers = array();
69
+ $parameters = array();
70
+ $headers[] = self::generateClientHeaders();
71
+ // Authentication
72
+ foreach($authHandlers as $handler) {
73
+ if ($handler instanceof QueryAuthentication) {
74
+ $parameters = array_merge($parameters, $handler->handleParams());
75
+ } else if ($handler instanceof HeaderAuthentication) {
76
+ $headers = array_merge($headers, $handler->handleHeaders());
77
+ } else if ($handler instanceof Oauth10aAuthentication) {
78
+ $headers = array_merge($headers, $handler->handleHeaders());
79
+ } else if ($handler instanceof Oauth2Authentication) {
80
+ $parameters = array_merge($parameters, $handler->handleParams());
81
+ }
82
+ }
83
+ return array($headers, $parameters);
84
+ }
85
+
86
+ public static function generateClientHeaders() {
87
+ $headers = "User-Agent: mashape-php/1.0: ";
88
+ return $headers;
89
+ }
90
+ }
91
+
92
+ ?>
app/code/local/Ajax/Face/controllers/mashape/http/MashapeResponse.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ require_once(dirname(__FILE__) . "/../json/Json.php");
28
+ require_once(dirname(__FILE__) . "/Chunked.php");
29
+ require_once(dirname(__FILE__) . "/../exceptions/MashapeClientException.php");
30
+
31
+ class MashapeResponse {
32
+ public $statusCode;
33
+ public $body;
34
+ public $rawBody;
35
+ public $headers;
36
+
37
+ function __construct($response, $statusCode, $headers, $encodeJson = false) {
38
+ $this->rawBody = $response;
39
+ $this->headers = $headers;
40
+ $this->statusCode = $statusCode;
41
+ $this->_parseBody($encodeJson);
42
+ }
43
+
44
+ function _parseBody($encodeJson) {
45
+ if ($encodeJson) {
46
+ $this->body = json_decode($this->rawBody);
47
+ if (empty($this->body) && ($this->statusCode == 200)) {
48
+ // It may be a chunked response
49
+ //$this->body = json_decode(http_chunked_decode($this->rawBody));
50
+ if (empty($this->body)) {
51
+ throw new MashapeClientException(
52
+ sprintf(EXCEPTION_JSONDECODE_REQUEST, $this->rawBody),
53
+ EXCEPTION_SYSTEM_ERROR_CODE);
54
+ }
55
+ }
56
+ } else {
57
+ $this->body = $this->rawBody;
58
+ }
59
+ }
60
+ }
61
+ ?>
app/code/local/Ajax/Face/controllers/mashape/http/UrlUtils.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ class UrlUtils {
28
+
29
+ public static function buildUrlWithQueryString($url, $parameters) {
30
+ foreach ($parameters as $paramKey => $paramValue) {
31
+ $delimiter = (strpos($url, "?") === false) ? "?" : "&";
32
+ $url .= $delimiter . $paramKey . "=" . urlencode($paramValue);
33
+ }
34
+ return $url;
35
+ }
36
+
37
+ }
38
+
39
+ ?>
app/code/local/Ajax/Face/controllers/mashape/json/Json.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ if (!function_exists('json_decode')) {
28
+ function json_decode($content, $assoc=false) {
29
+ require_once(dirname(__FILE__) . "/Services_JSON.php");
30
+ if ($assoc) {
31
+ $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
32
+ }
33
+ else {
34
+ $json = new Services_JSON;
35
+ }
36
+ return $json->decode($content);
37
+ }
38
+ }
39
+
40
+ ?>
app/code/local/Ajax/Face/controllers/mashape/json/Services_JSON.php ADDED
@@ -0,0 +1,806 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * Converts to and from JSON format.
6
+ *
7
+ * JSON (JavaScript Object Notation) is a lightweight data-interchange
8
+ * format. It is easy for humans to read and write. It is easy for machines
9
+ * to parse and generate. It is based on a subset of the JavaScript
10
+ * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
11
+ * This feature can also be found in Python. JSON is a text format that is
12
+ * completely language independent but uses conventions that are familiar
13
+ * to programmers of the C-family of languages, including C, C++, C#, Java,
14
+ * JavaScript, Perl, TCL, and many others. These properties make JSON an
15
+ * ideal data-interchange language.
16
+ *
17
+ * This package provides a simple encoder and decoder for JSON notation. It
18
+ * is intended for use with client-side Javascript applications that make
19
+ * use of HTTPRequest to perform server communication functions - data can
20
+ * be encoded into JSON notation for use in a client-side javascript, or
21
+ * decoded from incoming Javascript requests. JSON format is native to
22
+ * Javascript, and can be directly eval()'ed with no further parsing
23
+ * overhead
24
+ *
25
+ * All strings should be in ASCII or UTF-8 format!
26
+ *
27
+ * LICENSE: Redistribution and use in source and binary forms, with or
28
+ * without modification, are permitted provided that the following
29
+ * conditions are met: Redistributions of source code must retain the
30
+ * above copyright notice, this list of conditions and the following
31
+ * disclaimer. Redistributions in binary form must reproduce the above
32
+ * copyright notice, this list of conditions and the following disclaimer
33
+ * in the documentation and/or other materials provided with the
34
+ * distribution.
35
+ *
36
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
37
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
38
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
39
+ * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
40
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
41
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
42
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
44
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
45
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
46
+ * DAMAGE.
47
+ *
48
+ * @category
49
+ * @package Services_JSON
50
+ * @author Michal Migurski <mike-json@teczno.com>
51
+ * @author Matt Knapp <mdknapp[at]gmail[dot]com>
52
+ * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
53
+ * @copyright 2005 Michal Migurski
54
+ * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
55
+ * @license http://www.opensource.org/licenses/bsd-license.php
56
+ * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
57
+ */
58
+
59
+ /**
60
+ * Marker constant for Services_JSON::decode(), used to flag stack state
61
+ */
62
+ define('SERVICES_JSON_SLICE', 1);
63
+
64
+ /**
65
+ * Marker constant for Services_JSON::decode(), used to flag stack state
66
+ */
67
+ define('SERVICES_JSON_IN_STR', 2);
68
+
69
+ /**
70
+ * Marker constant for Services_JSON::decode(), used to flag stack state
71
+ */
72
+ define('SERVICES_JSON_IN_ARR', 3);
73
+
74
+ /**
75
+ * Marker constant for Services_JSON::decode(), used to flag stack state
76
+ */
77
+ define('SERVICES_JSON_IN_OBJ', 4);
78
+
79
+ /**
80
+ * Marker constant for Services_JSON::decode(), used to flag stack state
81
+ */
82
+ define('SERVICES_JSON_IN_CMT', 5);
83
+
84
+ /**
85
+ * Behavior switch for Services_JSON::decode()
86
+ */
87
+ define('SERVICES_JSON_LOOSE_TYPE', 16);
88
+
89
+ /**
90
+ * Behavior switch for Services_JSON::decode()
91
+ */
92
+ define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
93
+
94
+ /**
95
+ * Converts to and from JSON format.
96
+ *
97
+ * Brief example of use:
98
+ *
99
+ * <code>
100
+ * // create a new instance of Services_JSON
101
+ * $json = new Services_JSON();
102
+ *
103
+ * // convert a complexe value to JSON notation, and send it to the browser
104
+ * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
105
+ * $output = $json->encode($value);
106
+ *
107
+ * print($output);
108
+ * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
109
+ *
110
+ * // accept incoming POST data, assumed to be in JSON notation
111
+ * $input = file_get_contents('php://input', 1000000);
112
+ * $value = $json->decode($input);
113
+ * </code>
114
+ */
115
+ class Services_JSON
116
+ {
117
+ /**
118
+ * constructs a new JSON instance
119
+ *
120
+ * @param int $use object behavior flags; combine with boolean-OR
121
+ *
122
+ * possible values:
123
+ * - SERVICES_JSON_LOOSE_TYPE: loose typing.
124
+ * "{...}" syntax creates associative arrays
125
+ * instead of objects in decode().
126
+ * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
127
+ * Values which can't be encoded (e.g. resources)
128
+ * appear as NULL instead of throwing errors.
129
+ * By default, a deeply-nested resource will
130
+ * bubble up with an error, so all return values
131
+ * from encode() should be checked with isError()
132
+ */
133
+ function Services_JSON($use = 0)
134
+ {
135
+ $this->use = $use;
136
+ }
137
+
138
+ /**
139
+ * convert a string from one UTF-16 char to one UTF-8 char
140
+ *
141
+ * Normally should be handled by mb_convert_encoding, but
142
+ * provides a slower PHP-only method for installations
143
+ * that lack the multibye string extension.
144
+ *
145
+ * @param string $utf16 UTF-16 character
146
+ * @return string UTF-8 character
147
+ * @access private
148
+ */
149
+ function utf162utf8($utf16)
150
+ {
151
+ // oh please oh please oh please oh please oh please
152
+ if(function_exists('mb_convert_encoding')) {
153
+ return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
154
+ }
155
+
156
+ $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
157
+
158
+ switch(true) {
159
+ case ((0x7F & $bytes) == $bytes):
160
+ // this case should never be reached, because we are in ASCII range
161
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
162
+ return chr(0x7F & $bytes);
163
+
164
+ case (0x07FF & $bytes) == $bytes:
165
+ // return a 2-byte UTF-8 character
166
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
167
+ return chr(0xC0 | (($bytes >> 6) & 0x1F))
168
+ . chr(0x80 | ($bytes & 0x3F));
169
+
170
+ case (0xFFFF & $bytes) == $bytes:
171
+ // return a 3-byte UTF-8 character
172
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
173
+ return chr(0xE0 | (($bytes >> 12) & 0x0F))
174
+ . chr(0x80 | (($bytes >> 6) & 0x3F))
175
+ . chr(0x80 | ($bytes & 0x3F));
176
+ }
177
+
178
+ // ignoring UTF-32 for now, sorry
179
+ return '';
180
+ }
181
+
182
+ /**
183
+ * convert a string from one UTF-8 char to one UTF-16 char
184
+ *
185
+ * Normally should be handled by mb_convert_encoding, but
186
+ * provides a slower PHP-only method for installations
187
+ * that lack the multibye string extension.
188
+ *
189
+ * @param string $utf8 UTF-8 character
190
+ * @return string UTF-16 character
191
+ * @access private
192
+ */
193
+ function utf82utf16($utf8)
194
+ {
195
+ // oh please oh please oh please oh please oh please
196
+ if(function_exists('mb_convert_encoding')) {
197
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
198
+ }
199
+
200
+ switch(strlen($utf8)) {
201
+ case 1:
202
+ // this case should never be reached, because we are in ASCII range
203
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
204
+ return $utf8;
205
+
206
+ case 2:
207
+ // return a UTF-16 character from a 2-byte UTF-8 char
208
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
209
+ return chr(0x07 & (ord($utf8{0}) >> 2))
210
+ . chr((0xC0 & (ord($utf8{0}) << 6))
211
+ | (0x3F & ord($utf8{1})));
212
+
213
+ case 3:
214
+ // return a UTF-16 character from a 3-byte UTF-8 char
215
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
216
+ return chr((0xF0 & (ord($utf8{0}) << 4))
217
+ | (0x0F & (ord($utf8{1}) >> 2)))
218
+ . chr((0xC0 & (ord($utf8{1}) << 6))
219
+ | (0x7F & ord($utf8{2})));
220
+ }
221
+
222
+ // ignoring UTF-32 for now, sorry
223
+ return '';
224
+ }
225
+
226
+ /**
227
+ * encodes an arbitrary variable into JSON format
228
+ *
229
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
230
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
231
+ * if var is a strng, note that encode() always expects it
232
+ * to be in ASCII or UTF-8 format!
233
+ *
234
+ * @return mixed JSON string representation of input var or an error if a problem occurs
235
+ * @access public
236
+ */
237
+ function encode($var)
238
+ {
239
+ switch (gettype($var)) {
240
+ case 'boolean':
241
+ return $var ? 'true' : 'false';
242
+
243
+ case 'NULL':
244
+ return 'null';
245
+
246
+ case 'integer':
247
+ return (int) $var;
248
+
249
+ case 'double':
250
+ case 'float':
251
+ return (float) $var;
252
+
253
+ case 'string':
254
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
255
+ $ascii = '';
256
+ $strlen_var = strlen($var);
257
+
258
+ /*
259
+ * Iterate over every character in the string,
260
+ * escaping with a slash or encoding to UTF-8 where necessary
261
+ */
262
+ for ($c = 0; $c < $strlen_var; ++$c) {
263
+
264
+ $ord_var_c = ord($var{$c});
265
+
266
+ switch (true) {
267
+ case $ord_var_c == 0x08:
268
+ $ascii .= '\b';
269
+ break;
270
+ case $ord_var_c == 0x09:
271
+ $ascii .= '\t';
272
+ break;
273
+ case $ord_var_c == 0x0A:
274
+ $ascii .= '\n';
275
+ break;
276
+ case $ord_var_c == 0x0C:
277
+ $ascii .= '\f';
278
+ break;
279
+ case $ord_var_c == 0x0D:
280
+ $ascii .= '\r';
281
+ break;
282
+
283
+ case $ord_var_c == 0x22:
284
+ case $ord_var_c == 0x2F:
285
+ case $ord_var_c == 0x5C:
286
+ // double quote, slash, slosh
287
+ $ascii .= '\\'.$var{$c};
288
+ break;
289
+
290
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
291
+ // characters U-00000000 - U-0000007F (same as ASCII)
292
+ $ascii .= $var{$c};
293
+ break;
294
+
295
+ case (($ord_var_c & 0xE0) == 0xC0):
296
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
297
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
298
+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
299
+ $c += 1;
300
+ $utf16 = $this->utf82utf16($char);
301
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
302
+ break;
303
+
304
+ case (($ord_var_c & 0xF0) == 0xE0):
305
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
306
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
307
+ $char = pack('C*', $ord_var_c,
308
+ ord($var{$c + 1}),
309
+ ord($var{$c + 2}));
310
+ $c += 2;
311
+ $utf16 = $this->utf82utf16($char);
312
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
313
+ break;
314
+
315
+ case (($ord_var_c & 0xF8) == 0xF0):
316
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
317
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
318
+ $char = pack('C*', $ord_var_c,
319
+ ord($var{$c + 1}),
320
+ ord($var{$c + 2}),
321
+ ord($var{$c + 3}));
322
+ $c += 3;
323
+ $utf16 = $this->utf82utf16($char);
324
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
325
+ break;
326
+
327
+ case (($ord_var_c & 0xFC) == 0xF8):
328
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
329
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
330
+ $char = pack('C*', $ord_var_c,
331
+ ord($var{$c + 1}),
332
+ ord($var{$c + 2}),
333
+ ord($var{$c + 3}),
334
+ ord($var{$c + 4}));
335
+ $c += 4;
336
+ $utf16 = $this->utf82utf16($char);
337
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
338
+ break;
339
+
340
+ case (($ord_var_c & 0xFE) == 0xFC):
341
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
342
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
343
+ $char = pack('C*', $ord_var_c,
344
+ ord($var{$c + 1}),
345
+ ord($var{$c + 2}),
346
+ ord($var{$c + 3}),
347
+ ord($var{$c + 4}),
348
+ ord($var{$c + 5}));
349
+ $c += 5;
350
+ $utf16 = $this->utf82utf16($char);
351
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
352
+ break;
353
+ }
354
+ }
355
+
356
+ return '"'.$ascii.'"';
357
+
358
+ case 'array':
359
+ /*
360
+ * As per JSON spec if any array key is not an integer
361
+ * we must treat the the whole array as an object. We
362
+ * also try to catch a sparsely populated associative
363
+ * array with numeric keys here because some JS engines
364
+ * will create an array with empty indexes up to
365
+ * max_index which can cause memory issues and because
366
+ * the keys, which may be relevant, will be remapped
367
+ * otherwise.
368
+ *
369
+ * As per the ECMA and JSON specification an object may
370
+ * have any string as a property. Unfortunately due to
371
+ * a hole in the ECMA specification if the key is a
372
+ * ECMA reserved word or starts with a digit the
373
+ * parameter is only accessible using ECMAScript's
374
+ * bracket notation.
375
+ */
376
+
377
+ // treat as a JSON object
378
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
379
+ $properties = array_map(array($this, 'name_value'),
380
+ array_keys($var),
381
+ array_values($var));
382
+
383
+ foreach($properties as $property) {
384
+ if(Services_JSON::isError($property)) {
385
+ return $property;
386
+ }
387
+ }
388
+
389
+ return '{' . join(',', $properties) . '}';
390
+ }
391
+
392
+ // treat it like a regular array
393
+ $elements = array_map(array($this, 'encode'), $var);
394
+
395
+ foreach($elements as $element) {
396
+ if(Services_JSON::isError($element)) {
397
+ return $element;
398
+ }
399
+ }
400
+
401
+ return '[' . join(',', $elements) . ']';
402
+
403
+ case 'object':
404
+ $vars = get_object_vars($var);
405
+
406
+ $properties = array_map(array($this, 'name_value'),
407
+ array_keys($vars),
408
+ array_values($vars));
409
+
410
+ foreach($properties as $property) {
411
+ if(Services_JSON::isError($property)) {
412
+ return $property;
413
+ }
414
+ }
415
+
416
+ return '{' . join(',', $properties) . '}';
417
+
418
+ default:
419
+ return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
420
+ ? 'null'
421
+ : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
422
+ }
423
+ }
424
+
425
+ /**
426
+ * array-walking function for use in generating JSON-formatted name-value pairs
427
+ *
428
+ * @param string $name name of key to use
429
+ * @param mixed $value reference to an array element to be encoded
430
+ *
431
+ * @return string JSON-formatted name-value pair, like '"name":value'
432
+ * @access private
433
+ */
434
+ function name_value($name, $value)
435
+ {
436
+ $encoded_value = $this->encode($value);
437
+
438
+ if(Services_JSON::isError($encoded_value)) {
439
+ return $encoded_value;
440
+ }
441
+
442
+ return $this->encode(strval($name)) . ':' . $encoded_value;
443
+ }
444
+
445
+ /**
446
+ * reduce a string by removing leading and trailing comments and whitespace
447
+ *
448
+ * @param $str string string value to strip of comments and whitespace
449
+ *
450
+ * @return string string value stripped of comments and whitespace
451
+ * @access private
452
+ */
453
+ function reduce_string($str)
454
+ {
455
+ $str = preg_replace(array(
456
+
457
+ // eliminate single line comments in '// ...' form
458
+ '#^\s*//(.+)$#m',
459
+
460
+ // eliminate multi-line comments in '/* ... */' form, at start of string
461
+ '#^\s*/\*(.+)\*/#Us',
462
+
463
+ // eliminate multi-line comments in '/* ... */' form, at end of string
464
+ '#/\*(.+)\*/\s*$#Us'
465
+
466
+ ), '', $str);
467
+
468
+ // eliminate extraneous space
469
+ return trim($str);
470
+ }
471
+
472
+ /**
473
+ * decodes a JSON string into appropriate variable
474
+ *
475
+ * @param string $str JSON-formatted string
476
+ *
477
+ * @return mixed number, boolean, string, array, or object
478
+ * corresponding to given JSON input string.
479
+ * See argument 1 to Services_JSON() above for object-output behavior.
480
+ * Note that decode() always returns strings
481
+ * in ASCII or UTF-8 format!
482
+ * @access public
483
+ */
484
+ function decode($str)
485
+ {
486
+ $str = $this->reduce_string($str);
487
+
488
+ switch (strtolower($str)) {
489
+ case 'true':
490
+ return true;
491
+
492
+ case 'false':
493
+ return false;
494
+
495
+ case 'null':
496
+ return null;
497
+
498
+ default:
499
+ $m = array();
500
+
501
+ if (is_numeric($str)) {
502
+ // Lookie-loo, it's a number
503
+
504
+ // This would work on its own, but I'm trying to be
505
+ // good about returning integers where appropriate:
506
+ // return (float)$str;
507
+
508
+ // Return float or int, as appropriate
509
+ return ((float)$str == (integer)$str)
510
+ ? (integer)$str
511
+ : (float)$str;
512
+
513
+ } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
514
+ // STRINGS RETURNED IN UTF-8 FORMAT
515
+ $delim = substr($str, 0, 1);
516
+ $chrs = substr($str, 1, -1);
517
+ $utf8 = '';
518
+ $strlen_chrs = strlen($chrs);
519
+
520
+ for ($c = 0; $c < $strlen_chrs; ++$c) {
521
+
522
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
523
+ $ord_chrs_c = ord($chrs{$c});
524
+
525
+ switch (true) {
526
+ case $substr_chrs_c_2 == '\b':
527
+ $utf8 .= chr(0x08);
528
+ ++$c;
529
+ break;
530
+ case $substr_chrs_c_2 == '\t':
531
+ $utf8 .= chr(0x09);
532
+ ++$c;
533
+ break;
534
+ case $substr_chrs_c_2 == '\n':
535
+ $utf8 .= chr(0x0A);
536
+ ++$c;
537
+ break;
538
+ case $substr_chrs_c_2 == '\f':
539
+ $utf8 .= chr(0x0C);
540
+ ++$c;
541
+ break;
542
+ case $substr_chrs_c_2 == '\r':
543
+ $utf8 .= chr(0x0D);
544
+ ++$c;
545
+ break;
546
+
547
+ case $substr_chrs_c_2 == '\\"':
548
+ case $substr_chrs_c_2 == '\\\'':
549
+ case $substr_chrs_c_2 == '\\\\':
550
+ case $substr_chrs_c_2 == '\\/':
551
+ if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
552
+ ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
553
+ $utf8 .= $chrs{++$c};
554
+ }
555
+ break;
556
+
557
+ case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
558
+ // single, escaped unicode character
559
+ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
560
+ . chr(hexdec(substr($chrs, ($c + 4), 2)));
561
+ $utf8 .= $this->utf162utf8($utf16);
562
+ $c += 5;
563
+ break;
564
+
565
+ case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
566
+ $utf8 .= $chrs{$c};
567
+ break;
568
+
569
+ case ($ord_chrs_c & 0xE0) == 0xC0:
570
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
571
+ //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
572
+ $utf8 .= substr($chrs, $c, 2);
573
+ ++$c;
574
+ break;
575
+
576
+ case ($ord_chrs_c & 0xF0) == 0xE0:
577
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
578
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
579
+ $utf8 .= substr($chrs, $c, 3);
580
+ $c += 2;
581
+ break;
582
+
583
+ case ($ord_chrs_c & 0xF8) == 0xF0:
584
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
585
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
586
+ $utf8 .= substr($chrs, $c, 4);
587
+ $c += 3;
588
+ break;
589
+
590
+ case ($ord_chrs_c & 0xFC) == 0xF8:
591
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
592
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
593
+ $utf8 .= substr($chrs, $c, 5);
594
+ $c += 4;
595
+ break;
596
+
597
+ case ($ord_chrs_c & 0xFE) == 0xFC:
598
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
599
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
600
+ $utf8 .= substr($chrs, $c, 6);
601
+ $c += 5;
602
+ break;
603
+
604
+ }
605
+
606
+ }
607
+
608
+ return $utf8;
609
+
610
+ } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
611
+ // array, or object notation
612
+
613
+ if ($str{0} == '[') {
614
+ $stk = array(SERVICES_JSON_IN_ARR);
615
+ $arr = array();
616
+ } else {
617
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
618
+ $stk = array(SERVICES_JSON_IN_OBJ);
619
+ $obj = array();
620
+ } else {
621
+ $stk = array(SERVICES_JSON_IN_OBJ);
622
+ $obj = new stdClass();
623
+ }
624
+ }
625
+
626
+ array_push($stk, array('what' => SERVICES_JSON_SLICE,
627
+ 'where' => 0,
628
+ 'delim' => false));
629
+
630
+ $chrs = substr($str, 1, -1);
631
+ $chrs = $this->reduce_string($chrs);
632
+
633
+ if ($chrs == '') {
634
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
635
+ return $arr;
636
+
637
+ } else {
638
+ return $obj;
639
+
640
+ }
641
+ }
642
+
643
+ //print("\nparsing {$chrs}\n");
644
+
645
+ $strlen_chrs = strlen($chrs);
646
+
647
+ for ($c = 0; $c <= $strlen_chrs; ++$c) {
648
+
649
+ $top = end($stk);
650
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
651
+
652
+ if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
653
+ // found a comma that is not inside a string, array, etc.,
654
+ // OR we've reached the end of the character list
655
+ $slice = substr($chrs, $top['where'], ($c - $top['where']));
656
+ array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
657
+ //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
658
+
659
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
660
+ // we are in an array, so just push an element onto the stack
661
+ array_push($arr, $this->decode($slice));
662
+
663
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
664
+ // we are in an object, so figure
665
+ // out the property name and set an
666
+ // element in an associative array,
667
+ // for now
668
+ $parts = array();
669
+
670
+ if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
671
+ // "name":value pair
672
+ $key = $this->decode($parts[1]);
673
+ $val = $this->decode($parts[2]);
674
+
675
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
676
+ $obj[$key] = $val;
677
+ } else {
678
+ $obj->$key = $val;
679
+ }
680
+ } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
681
+ // name:value pair, where name is unquoted
682
+ $key = $parts[1];
683
+ $val = $this->decode($parts[2]);
684
+
685
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
686
+ $obj[$key] = $val;
687
+ } else {
688
+ $obj->$key = $val;
689
+ }
690
+ }
691
+
692
+ }
693
+
694
+ } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
695
+ // found a quote, and we are not inside a string
696
+ array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
697
+ //print("Found start of string at {$c}\n");
698
+
699
+ } elseif (($chrs{$c} == $top['delim']) &&
700
+ ($top['what'] == SERVICES_JSON_IN_STR) &&
701
+ ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
702
+ // found a quote, we're in a string, and it's not escaped
703
+ // we know that it's not escaped becase there is _not_ an
704
+ // odd number of backslashes at the end of the string so far
705
+ array_pop($stk);
706
+ //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
707
+
708
+ } elseif (($chrs{$c} == '[') &&
709
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
710
+ // found a left-bracket, and we are in an array, object, or slice
711
+ array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
712
+ //print("Found start of array at {$c}\n");
713
+
714
+ } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
715
+ // found a right-bracket, and we're in an array
716
+ array_pop($stk);
717
+ //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
718
+
719
+ } elseif (($chrs{$c} == '{') &&
720
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
721
+ // found a left-brace, and we are in an array, object, or slice
722
+ array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
723
+ //print("Found start of object at {$c}\n");
724
+
725
+ } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
726
+ // found a right-brace, and we're in an object
727
+ array_pop($stk);
728
+ //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
729
+
730
+ } elseif (($substr_chrs_c_2 == '/*') &&
731
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
732
+ // found a comment start, and we are in an array, object, or slice
733
+ array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
734
+ $c++;
735
+ //print("Found start of comment at {$c}\n");
736
+
737
+ } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
738
+ // found a comment end, and we're in one now
739
+ array_pop($stk);
740
+ $c++;
741
+
742
+ for ($i = $top['where']; $i <= $c; ++$i)
743
+ $chrs = substr_replace($chrs, ' ', $i, 1);
744
+
745
+ //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
746
+
747
+ }
748
+
749
+ }
750
+
751
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
752
+ return $arr;
753
+
754
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
755
+ return $obj;
756
+
757
+ }
758
+
759
+ }
760
+ }
761
+ }
762
+
763
+ /**
764
+ * @todo Ultimately, this should just call PEAR::isError()
765
+ */
766
+ function isError($data, $code = null)
767
+ {
768
+ if (class_exists('pear')) {
769
+ return PEAR::isError($data, $code);
770
+ } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
771
+ is_subclass_of($data, 'services_json_error'))) {
772
+ return true;
773
+ }
774
+
775
+ return false;
776
+ }
777
+ }
778
+
779
+ if (class_exists('PEAR_Error')) {
780
+
781
+ class Services_JSON_Error extends PEAR_Error
782
+ {
783
+ function Services_JSON_Error($message = 'unknown error', $code = null,
784
+ $mode = null, $options = null, $userinfo = null)
785
+ {
786
+ parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
787
+ }
788
+ }
789
+
790
+ } else {
791
+
792
+ /**
793
+ * @todo Ultimately, this class shall be descended from PEAR_Error
794
+ */
795
+ class Services_JSON_Error
796
+ {
797
+ function Services_JSON_Error($message = 'unknown error', $code = null,
798
+ $mode = null, $options = null, $userinfo = null)
799
+ {
800
+
801
+ }
802
+ }
803
+
804
+ }
805
+
806
+ ?>
app/code/local/Ajax/Face/etc/config.xml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Ajax_Face>
5
+ <version>0.1.0</version>
6
+ </Ajax_Face>
7
+ </modules>
8
+ <frontend>
9
+ <routers>
10
+ <face>
11
+ <use>standard</use>
12
+ <args>
13
+ <module>Ajax_Face</module>
14
+ <frontName>face</frontName>
15
+ </args>
16
+ </face>
17
+ </routers>
18
+ <layout>
19
+ <updates>
20
+ <face>
21
+ <file>face.xml</file>
22
+ </face>
23
+ </updates>
24
+ </layout>
25
+ </frontend>
26
+ </config>
app/code/local/Daffodil/Tryon/Block/Product/list.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?><?php
6
+ class Daffodil_Tryon_Block_Product_list extends Mage_Catalog_Block_Product_list
7
+ {
8
+
9
+ }
app/code/local/Daffodil/Tryon/Block/Product/list.php~ ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?><?php
6
+ class Daffodil_Tryon_Block_Product_list extends Mage_Catalog_Block_Product_list
7
+ {
8
+
9
+ }
app/code/local/Daffodil/Tryon/Helper/Data.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ class Daffodil_Tryon_Helper_Data extends Mage_Core_Helper_Abstract
8
+ {
9
+
10
+ }
app/code/local/Daffodil/Tryon/Helper/Data.php~ ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ class Daffodil_Tryon_Helper_Data extends Mage_Core_Helper_Abstract
8
+ {
9
+
10
+ }
app/code/local/Daffodil/Tryon/Helper/data.php.bak ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class <Namespace>_<Module>_Helper_Data extends Mage_Core_Helper_Abstract
4
+ {
5
+
6
+ }
app/code/local/Daffodil/Tryon/Model/Avatar.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Daffodil_Tryon_Model_<Module> extends Mage_Core_Model_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('tryon/tryon');
9
+ }
10
+ }
app/code/local/Daffodil/Tryon/Model/Avatar.php~ ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Daffodil_Tryon_Model_<Module> extends Mage_Core_Model_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('tryon/tryon');
9
+ }
10
+ }
app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Daffodil_Tryon_Model_Mysql4_Avatar extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ $this->_init('tryon/tryon', 'tryon_id');
8
+ }
9
+ }
app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar.php.bak ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Photo_Avatar_Model_Mysql4_Avatar extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ $this->_init('avatar/avatar', '<module>_id');
8
+ }
9
+ }
app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar.php~ ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Daffodil_Tryon_Model_Mysql4_Avatar extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ $this->_init('tryon/tryon', 'tryon_id');
8
+ }
9
+ }
app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar/collection.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon extension by daffodil
4
+ */
5
+ class Daffodil_Tryon_Model_Mysql4_Avatar_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
6
+ {
7
+ public function _construct()
8
+ {
9
+ $this->_init('tryon/tryon');
10
+ }
11
+ }
app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar/collection.php.bak ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Photo_Avatar_Model_Mysql4_Avatar_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ //parent::__construct();
8
+ $this->_init('avatar/<module>');
9
+ }
10
+ }
app/code/local/Daffodil/Tryon/Model/Mysql4/Avatar/collection.php~ ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon extension by daffodil
4
+ */
5
+ class Daffodil_Tryon_Model_Mysql4_Avatar_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
6
+ {
7
+ public function _construct()
8
+ {
9
+ $this->_init('tryon/tryon');
10
+ }
11
+ }
app/code/local/Daffodil/Tryon/Model/System/Config/Source/Position.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Daffodil_Tryon_Model_System_Config_Source_Position
4
+ {
5
+
6
+ protected $_helper;
7
+
8
+ public function getHelper()
9
+ {
10
+ if (is_null($this->_helper)) {
11
+ $this->_helper = Mage::helper('daffodil_tryon');
12
+ }
13
+ return $this->_helper;
14
+ }
15
+
16
+ public function toOptionArray()
17
+ {
18
+ $helper = $this->getHelper();
19
+ return array(
20
+ 'right' => $helper->__('Right'),
21
+ 'left' => $helper->__('Left'),
22
+ 'top' => $helper->__('Top'),
23
+ 'bottom' => $helper->__('Bottom'),
24
+ 'inside' => $helper->__('Inside')
25
+ );
26
+ }
27
+ }
app/code/local/Daffodil/Tryon/Model/System/Config/Source/Position.php~ ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Daffodil_Tryon_Model_System_Config_Source_Position
4
+ {
5
+
6
+ protected $_helper;
7
+
8
+ public function getHelper()
9
+ {
10
+ if (is_null($this->_helper)) {
11
+ $this->_helper = Mage::helper('daffodil_tryon');
12
+ }
13
+ return $this->_helper;
14
+ }
15
+
16
+ public function toOptionArray()
17
+ {
18
+ $helper = $this->getHelper();
19
+ return array(
20
+ 'right' => $helper->__('Right'),
21
+ 'left' => $helper->__('Left'),
22
+ 'top' => $helper->__('Top'),
23
+ 'bottom' => $helper->__('Bottom'),
24
+ 'inside' => $helper->__('Inside')
25
+ );
26
+ }
27
+ }
app/code/local/Daffodil/Tryon/controllers/Face.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ require_once("mashape/MashapeClient.php");
8
+
9
+
10
+ class Face {
11
+ const PUBLIC_DNS = "lambda-face-detection-and-recognition.p.mashape.com";
12
+ private $authHandlers;
13
+
14
+ function __construct($publicKey, $privateKey) {
15
+ $this->authHandlers = array();
16
+ $this->authHandlers[] = new MashapeAuthentication($publicKey, $privateKey);
17
+
18
+ }
19
+ public function detect($images) {
20
+ $parameters = array(
21
+ "images" => $images);
22
+
23
+ $response = HttpClient::doRequest(
24
+ HttpMethod::GET,
25
+ "https://" . self::PUBLIC_DNS . "/detect",
26
+ $parameters,
27
+ $this->authHandlers,
28
+ ContentType::FORM,
29
+ true);
30
+ return $response;
31
+ }
32
+
33
+
34
+
35
+ }
36
+ ?>
app/code/local/Daffodil/Tryon/controllers/Face.php~ ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ require_once("mashape/MashapeClient.php");
8
+
9
+
10
+ class Face {
11
+ const PUBLIC_DNS = "lambda-face-detection-and-recognition.p.mashape.com";
12
+ private $authHandlers;
13
+
14
+ function __construct($publicKey, $privateKey) {
15
+ $this->authHandlers = array();
16
+ $this->authHandlers[] = new MashapeAuthentication($publicKey, $privateKey);
17
+
18
+ }
19
+ public function detect($images) {
20
+ $parameters = array(
21
+ "images" => $images);
22
+
23
+ $response = HttpClient::doRequest(
24
+ HttpMethod::GET,
25
+ "https://" . self::PUBLIC_DNS . "/detect",
26
+ $parameters,
27
+ $this->authHandlers,
28
+ ContentType::FORM,
29
+ true);
30
+ return $response;
31
+ }
32
+
33
+
34
+
35
+ }
36
+ ?>
app/code/local/Daffodil/Tryon/controllers/IndexController.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ class Daffodil_Tryon_IndexController extends Mage_Core_Controller_Front_Action
8
+ {
9
+ public function indexAction()
10
+ {
11
+ $this->loadLayout();
12
+ $this->renderLayout();
13
+
14
+ $dir = 'media/uploads/';
15
+ foreach(glob($dir.'*.*') as $v)
16
+ {
17
+ unlink($v);
18
+ }
19
+
20
+ $uploaddir = 'media/uploads/' ;
21
+ $file = $uploaddir . basename($_FILES['uploadfile']['name']);
22
+
23
+
24
+ if (move_uploaded_file($_FILES['uploadfile']['tmp_name'], $file)) {
25
+ include('SimpleImage.php');
26
+ $image = new SimpleImage();
27
+ $image->load( $file);
28
+ $image->resize(200,250);
29
+ $image->save( $file);
30
+ } else {
31
+ }
32
+
33
+ require_once("Face.php");
34
+
35
+
36
+ // basic instantiation. TODO Put your authentication keys here.
37
+ $baseImage = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
38
+ $secondpath = $baseImage."".$file;
39
+ $obj = new Face("6z1mstluneooiy1ulntokkfs08cd7w", "nirjdkl9hmqsh1cri0r3qeoklxrub9");
40
+ $response = $obj->detect($secondpath);
41
+ $top = $response->body->photos[0]->tags[0]->eye_left->y;
42
+ $left = $response->body->photos[0]->tags[0]->eye_left->x;
43
+ echo $top.',';
44
+ echo $left.',';
45
+ }
46
+ }
app/code/local/Daffodil/Tryon/controllers/IndexController.php~ ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ class Daffodil_Tryon_IndexController extends Mage_Core_Controller_Front_Action
8
+ {
9
+ public function indexAction()
10
+ {
11
+ $this->loadLayout();
12
+ $this->renderLayout();
13
+
14
+ $dir = 'media/uploads/';
15
+ foreach(glob($dir.'*.*') as $v)
16
+ {
17
+ unlink($v);
18
+ }
19
+
20
+ $uploaddir = 'media/uploads/' ;
21
+ $file = $uploaddir . basename($_FILES['uploadfile']['name']);
22
+
23
+
24
+ if (move_uploaded_file($_FILES['uploadfile']['tmp_name'], $file)) {
25
+ include('SimpleImage.php');
26
+ $image = new SimpleImage();
27
+ $image->load( $file);
28
+ $image->resize(200,250);
29
+ $image->save( $file);
30
+ } else {
31
+ }
32
+
33
+ require_once("Face.php");
34
+
35
+
36
+ // basic instantiation. TODO Put your authentication keys here.
37
+ $baseImage = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
38
+ $secondpath = $baseImage."".$file;
39
+ $obj = new Face("6z1mstluneooiy1ulntokkfs08cd7w", "nirjdkl9hmqsh1cri0r3qeoklxrub9");
40
+ $response = $obj->detect($secondpath);
41
+ $top = $response->body->photos[0]->tags[0]->eye_left->y;
42
+ $left = $response->body->photos[0]->tags[0]->eye_left->x;
43
+ echo $top.',';
44
+ echo $left.',';
45
+ }
46
+ }
app/code/local/Daffodil/Tryon/controllers/SimpleImage.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ *Tryon Extension by daffodil
5
+ */
6
+ ?>
7
+ <?php
8
+ class SimpleImage {
9
+
10
+ var $image;
11
+ var $image_type;
12
+
13
+ function load($filename) {
14
+
15
+ $image_info = getimagesize($filename);
16
+ $this->image_type = $image_info[2];
17
+ if( $this->image_type == IMAGETYPE_JPEG ) {
18
+
19
+ $this->image = imagecreatefromjpeg($filename);
20
+ } elseif( $this->image_type == IMAGETYPE_GIF ) {
21
+
22
+ $this->image = imagecreatefromgif($filename);
23
+ } elseif( $this->image_type == IMAGETYPE_PNG ) {
24
+
25
+ $this->image = imagecreatefrompng($filename);
26
+ }
27
+ }
28
+ function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
29
+
30
+ if( $image_type == IMAGETYPE_JPEG ) {
31
+ imagejpeg($this->image,$filename,$compression);
32
+ } elseif( $image_type == IMAGETYPE_GIF ) {
33
+
34
+ imagegif($this->image,$filename);
35
+ } elseif( $image_type == IMAGETYPE_PNG ) {
36
+
37
+ imagepng($this->image,$filename);
38
+ }
39
+ if( $permissions != null) {
40
+
41
+ chmod($filename,$permissions);
42
+ }
43
+ }
44
+ function output($image_type=IMAGETYPE_JPEG) {
45
+
46
+ if( $image_type == IMAGETYPE_JPEG ) {
47
+ imagejpeg($this->image);
48
+ } elseif( $image_type == IMAGETYPE_GIF ) {
49
+
50
+ imagegif($this->image);
51
+ } elseif( $image_type == IMAGETYPE_PNG ) {
52
+
53
+ imagepng($this->image);
54
+ }
55
+ }
56
+ function getWidth() {
57
+
58
+ return imagesx($this->image);
59
+ }
60
+ function getHeight() {
61
+
62
+ return imagesy($this->image);
63
+ }
64
+ function resizeToHeight($height) {
65
+
66
+ $ratio = $height / $this->getHeight();
67
+ $width = $this->getWidth() * $ratio;
68
+ $this->resize($width,$height);
69
+ }
70
+
71
+ function resizeToWidth($width) {
72
+ $ratio = $width / $this->getWidth();
73
+ $height = $this->getheight() * $ratio;
74
+ $this->resize($width,$height);
75
+ }
76
+
77
+ function scale($scale) {
78
+ $width = $this->getWidth() * $scale/100;
79
+ $height = $this->getheight() * $scale/100;
80
+ $this->resize($width,$height);
81
+ }
82
+
83
+ function resize($width,$height) {
84
+ $new_image = imagecreatetruecolor($width, $height);
85
+ imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
86
+ $this->image = $new_image;
87
+ }
88
+
89
+ }
90
+ ?>
app/code/local/Daffodil/Tryon/controllers/SimpleImage.php~ ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ *Tryon Extension by daffodil
5
+ */
6
+ ?>
7
+ <?php
8
+ class SimpleImage {
9
+
10
+ var $image;
11
+ var $image_type;
12
+
13
+ function load($filename) {
14
+
15
+ $image_info = getimagesize($filename);
16
+ $this->image_type = $image_info[2];
17
+ if( $this->image_type == IMAGETYPE_JPEG ) {
18
+
19
+ $this->image = imagecreatefromjpeg($filename);
20
+ } elseif( $this->image_type == IMAGETYPE_GIF ) {
21
+
22
+ $this->image = imagecreatefromgif($filename);
23
+ } elseif( $this->image_type == IMAGETYPE_PNG ) {
24
+
25
+ $this->image = imagecreatefrompng($filename);
26
+ }
27
+ }
28
+ function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
29
+
30
+ if( $image_type == IMAGETYPE_JPEG ) {
31
+ imagejpeg($this->image,$filename,$compression);
32
+ } elseif( $image_type == IMAGETYPE_GIF ) {
33
+
34
+ imagegif($this->image,$filename);
35
+ } elseif( $image_type == IMAGETYPE_PNG ) {
36
+
37
+ imagepng($this->image,$filename);
38
+ }
39
+ if( $permissions != null) {
40
+
41
+ chmod($filename,$permissions);
42
+ }
43
+ }
44
+ function output($image_type=IMAGETYPE_JPEG) {
45
+
46
+ if( $image_type == IMAGETYPE_JPEG ) {
47
+ imagejpeg($this->image);
48
+ } elseif( $image_type == IMAGETYPE_GIF ) {
49
+
50
+ imagegif($this->image);
51
+ } elseif( $image_type == IMAGETYPE_PNG ) {
52
+
53
+ imagepng($this->image);
54
+ }
55
+ }
56
+ function getWidth() {
57
+
58
+ return imagesx($this->image);
59
+ }
60
+ function getHeight() {
61
+
62
+ return imagesy($this->image);
63
+ }
64
+ function resizeToHeight($height) {
65
+
66
+ $ratio = $height / $this->getHeight();
67
+ $width = $this->getWidth() * $ratio;
68
+ $this->resize($width,$height);
69
+ }
70
+
71
+ function resizeToWidth($width) {
72
+ $ratio = $width / $this->getWidth();
73
+ $height = $this->getheight() * $ratio;
74
+ $this->resize($width,$height);
75
+ }
76
+
77
+ function scale($scale) {
78
+ $width = $this->getWidth() * $scale/100;
79
+ $height = $this->getheight() * $scale/100;
80
+ $this->resize($width,$height);
81
+ }
82
+
83
+ function resize($width,$height) {
84
+ $new_image = imagecreatetruecolor($width, $height);
85
+ imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
86
+ $this->image = $new_image;
87
+ }
88
+
89
+ }
90
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/MashapeClient.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ require_once(dirname(__FILE__) . "/http/HttpClient.php");
28
+ require_once(dirname(__FILE__) . "/http/MashapeResponse.php");
29
+
30
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/Authentication.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?><?php
6
+ interface Authentication {
7
+ public function handleHeaders();
8
+
9
+ public function handleParams();
10
+ }
11
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/Authentication.php~ ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?><?php
6
+ interface Authentication {
7
+ public function handleHeaders();
8
+
9
+ public function handleParams();
10
+ }
11
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/AuthenticationUtil.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ class AuthenticationUtil {
8
+
9
+ public static function generateAuthenticationHeader($publicKey, $privateKey) {
10
+ $header = "";
11
+ if (!($publicKey == null || $privateKey == null)) {
12
+ $hash = hash_hmac("sha1", $publicKey, $privateKey);
13
+ $header = "X-Mashape-Authorization: " . base64_encode($publicKey . ":" . $hash);
14
+ }
15
+ return $header;
16
+ }
17
+
18
+ }
19
+
20
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/AuthenticationUtil.php~ ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ class AuthenticationUtil {
8
+
9
+ public static function generateAuthenticationHeader($publicKey, $privateKey) {
10
+ $header = "";
11
+ if (!($publicKey == null || $privateKey == null)) {
12
+ $hash = hash_hmac("sha1", $publicKey, $privateKey);
13
+ $header = "X-Mashape-Authorization: " . base64_encode($publicKey . ":" . $hash);
14
+ }
15
+ return $header;
16
+ }
17
+
18
+ }
19
+
20
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/BasicAuthentication.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/HeaderAuthentication.php");
3
+
4
+ class BasicAuthentication extends HeaderAuthentication {
5
+
6
+ private $headers;
7
+
8
+ function __construct($username, $password) {
9
+ $headerValue = $username . ":" . $password;
10
+ $this->headers = array("Authorization: Basic " . base64_encode($headerValue));
11
+ }
12
+
13
+ public function handleHeaders() {
14
+ return $this->headers;
15
+ }
16
+
17
+ public function handleParams() {
18
+ return null;
19
+ }
20
+ }
21
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/CustomHeaderAuthentication.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/HeaderAuthentication.php");
3
+
4
+ class CustomHeaderAuthentication extends HeaderAuthentication {
5
+
6
+ private $headers;
7
+
8
+ function __construct($headerName, $headerValue) {
9
+ $this->headers = array($headerName . ": " . $headerValue);
10
+ }
11
+
12
+ public function handleHeaders() {
13
+ return $this->headers;
14
+ }
15
+
16
+ public function handleParams() {
17
+ return null;
18
+ }
19
+ }
20
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/HeaderAuthentication.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/Authentication.php");
3
+
4
+ abstract class HeaderAuthentication implements Authentication {
5
+ public function handleParams() {
6
+ return null;
7
+ }
8
+ }
9
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/MashapeAuthentication.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/AuthenticationUtil.php");
3
+ require_once(dirname(__FILE__) . "/HeaderAuthentication.php");
4
+
5
+ class MashapeAuthentication extends HeaderAuthentication {
6
+
7
+ private $headers;
8
+
9
+ function __construct($publicKey, $privateKey) {
10
+ $this->headers = array(AuthenticationUtil::generateAuthenticationHeader($publicKey, $privateKey));
11
+ }
12
+
13
+ public function handleHeaders() {
14
+ return $this->headers;
15
+ }
16
+ }
17
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/OAuth10aAuthentication.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/OAuthAuthentication.php");
3
+
4
+ class OAuth10aAuthentication extends OAuthAuthentication {
5
+
6
+ function __construct($consumerKey, $consumerSecret, $callbackUrl) {
7
+ parent::__construct($consumerKey, $consumerSecret, $callbackUrl);
8
+ }
9
+
10
+ public function handleHeaders() {
11
+ if (!isset($this->accessToken) || !isset($this->accessSecret)) {
12
+ throw new MashapeClientException(
13
+ EXCEPTION_OAUTH1_AUTHORIZE,
14
+ EXCEPTION_OAUTH1_AUTHORIZE_CODE);
15
+ }
16
+ $headers = array();
17
+ $headers[] = "x-mashape-oauth-consumerkey: " . $this->consumerKey;
18
+ $headers[] = "x-mashape-oauth-consumersecret: " . $this->consumerSecret;
19
+ $headers[] = "x-mashape-oauth-accesstoken: " . $this->accessToken;
20
+ $headers[] = "x-mashape-oauth-accesssecret: " . $this->accessSecret;
21
+ return $headers;
22
+ }
23
+ }
24
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/OAuth2Authentication.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/OAuthAuthentication.php");
3
+
4
+ class OAuth2Authentication extends OAuthAuthentication {
5
+
6
+ function __construct($consumerKey, $consumerSecret, $callbackUrl) {
7
+ parent::__construct($consumerKey, $consumerSecret, $callbackUrl);
8
+ }
9
+
10
+ public function handleParams() {
11
+ if ($this->accessToken == null) {
12
+ throw new MashapeClientException(
13
+ EXCEPTION_OAUTH2_AUTHORIZE,
14
+ EXCEPTION_OAUTH2_AUTHORIZE_CODE);
15
+ }
16
+ $params = array("accesstoken" => $this->accessToken);
17
+ return $params;
18
+ }
19
+ }
20
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/OAuthAuthentication.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/Authentication.php");
3
+
4
+ class OAuthAuthentication implements Authentication {
5
+
6
+ protected $consumerKey;
7
+ protected $consumerSecret;
8
+ protected $callbackUrl;
9
+ protected $accessToken;
10
+ protected $accessSecret;
11
+
12
+ function __construct($consumerKey, $consumerSecret, $callbackUrl) {
13
+ $this->consumerKey = $consumerKey;
14
+ $this->consumerSecret = $consumerSecret;
15
+ $this->callbackUrl = $callbackUrl;
16
+ }
17
+
18
+ public function addAccessToken($accessToken, $accessSecret = null) {
19
+ $this->accessToken = $accessToken;
20
+ $this->accessSecret = $accessSecret;
21
+ }
22
+
23
+ public function getOAuthBaseParams() {
24
+ $params = array(
25
+ "consumerKey" => $this->consumerKey,
26
+ "consumerSecret" => $this->consumerSecret,
27
+ "callbackUrl" => $this->callbackUrl,
28
+ );
29
+ return $params;
30
+ }
31
+
32
+ public function handleParams() {
33
+ return null;
34
+ }
35
+
36
+ public function handleHeaders() {
37
+ return null;
38
+ }
39
+ }
40
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/authentication/QueryAuthentication.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/Authentication.php");
3
+
4
+ class QueryAuthentication implements Authentication {
5
+
6
+ private $params;
7
+
8
+ function __construct($queryKey, $queryValue) {
9
+ $this->params = array($queryKey => $queryValue);
10
+ }
11
+
12
+ public function handleHeaders() {
13
+ return null;
14
+ }
15
+
16
+ public function handleParams() {
17
+ return $this->params;
18
+ }
19
+ }
20
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/exceptions/ExceptionConstants.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ define("EXCEPTION_NOTSUPPORTED_HTTPMETHOD_CODE", 1003);
8
+ define("EXCEPTION_NOTSUPPORTED_HTTPMETHOD",
9
+ "HTTP method not supported. Only DELETE, GET, POST, PUT are supported");
10
+
11
+ define("EXCEPTION_CONTENT_TYPE_JSON_ARRAY_CODE", 1004);
12
+ define("EXCEPTION_CONTENT_TYPE_JSON_ARRAY",
13
+ "Content Type JSON does not accept array parameters. Parameters should be"
14
+ ." a JSON string");
15
+
16
+ define("EXCEPTION_CONTENT_TYPE_NON_ARRAY_CODE", 1005);
17
+ define("EXCEPTION_CONTENT_TYPE_NON_ARRAY",
18
+ "Parameters must be an array unless content type is set to JSON");
19
+
20
+ define("EXCEPTION_CONTENT_TYPE_JSON_QUERYAUTH_CODE", 1006);
21
+ define("EXCEPTION_CONTENT_TYPE_JSON_QUERYAUTH",
22
+ "Query Authentication cannot be used in conjunction with content type JSON");
23
+
24
+ define("EXCEPTION_OAUTH1_AUTHORIZE_CODE", 1007);
25
+ define("EXCEPTION_OAUTH1_AUTHORIZE",
26
+ "Before consuming an OAuth endpoint, you must invoke the authorize("
27
+ ."'access_token', 'access_secret') function with non-null values");
28
+
29
+ define("EXCEPTION_OAUTH2_AUTHORIZE_CODE", 1007);
30
+ define("EXCEPTION_OAUTH2_AUTHORIZE",
31
+ "Before consuming an OAuth endpoint, you must invoke the authorize("
32
+ ."'access_token') function with a non-null value");
33
+
34
+ define("EXCEPTION_NOTSUPPORTED_CONTENTTYPE_CODE", 415);
35
+ define("EXCEPTION_NOTSUPPORTED_CONTENTTYPE",
36
+ "Content Type not supported. Currently only application/x-www-form-urlencoded, "
37
+ ."application/json, and multipart/form-data are supported");
38
+
39
+ define("EXCEPTION_GET_INVALID_CONTENTTYPE_CODE", 415);
40
+ define("EXCEPTION_GET_INVALID_CONTENTTYPE", "A GET request must have a content"
41
+ ." type of application/x-www-form-urlencoded or application/json");
42
+
43
+ define("EXCEPTION_CURL_CODE", 520);
44
+ define("EXCEPTION_CURL",
45
+ "Encountered an exception making the request");
46
+
47
+ define("EXCEPTION_SYSTEM_ERROR_CODE", 2000);
48
+ define("EXCEPTION_JSONDECODE_REQUEST", "Can't deserialize the response JSON: %s");
49
+
50
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/exceptions/ExceptionConstants.php~ ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ define("EXCEPTION_NOTSUPPORTED_HTTPMETHOD_CODE", 1003);
8
+ define("EXCEPTION_NOTSUPPORTED_HTTPMETHOD",
9
+ "HTTP method not supported. Only DELETE, GET, POST, PUT are supported");
10
+
11
+ define("EXCEPTION_CONTENT_TYPE_JSON_ARRAY_CODE", 1004);
12
+ define("EXCEPTION_CONTENT_TYPE_JSON_ARRAY",
13
+ "Content Type JSON does not accept array parameters. Parameters should be"
14
+ ." a JSON string");
15
+
16
+ define("EXCEPTION_CONTENT_TYPE_NON_ARRAY_CODE", 1005);
17
+ define("EXCEPTION_CONTENT_TYPE_NON_ARRAY",
18
+ "Parameters must be an array unless content type is set to JSON");
19
+
20
+ define("EXCEPTION_CONTENT_TYPE_JSON_QUERYAUTH_CODE", 1006);
21
+ define("EXCEPTION_CONTENT_TYPE_JSON_QUERYAUTH",
22
+ "Query Authentication cannot be used in conjunction with content type JSON");
23
+
24
+ define("EXCEPTION_OAUTH1_AUTHORIZE_CODE", 1007);
25
+ define("EXCEPTION_OAUTH1_AUTHORIZE",
26
+ "Before consuming an OAuth endpoint, you must invoke the authorize("
27
+ ."'access_token', 'access_secret') function with non-null values");
28
+
29
+ define("EXCEPTION_OAUTH2_AUTHORIZE_CODE", 1007);
30
+ define("EXCEPTION_OAUTH2_AUTHORIZE",
31
+ "Before consuming an OAuth endpoint, you must invoke the authorize("
32
+ ."'access_token') function with a non-null value");
33
+
34
+ define("EXCEPTION_NOTSUPPORTED_CONTENTTYPE_CODE", 415);
35
+ define("EXCEPTION_NOTSUPPORTED_CONTENTTYPE",
36
+ "Content Type not supported. Currently only application/x-www-form-urlencoded, "
37
+ ."application/json, and multipart/form-data are supported");
38
+
39
+ define("EXCEPTION_GET_INVALID_CONTENTTYPE_CODE", 415);
40
+ define("EXCEPTION_GET_INVALID_CONTENTTYPE", "A GET request must have a content"
41
+ ." type of application/x-www-form-urlencoded or application/json");
42
+
43
+ define("EXCEPTION_CURL_CODE", 520);
44
+ define("EXCEPTION_CURL",
45
+ "Encountered an exception making the request");
46
+
47
+ define("EXCEPTION_SYSTEM_ERROR_CODE", 2000);
48
+ define("EXCEPTION_JSONDECODE_REQUEST", "Can't deserialize the response JSON: %s");
49
+
50
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/exceptions/MashapeClientException.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ require_once (dirname(__FILE__) . "/ExceptionConstants.php");
28
+
29
+ class MashapeClientException extends Exception {
30
+
31
+ function __construct($message, $code) {
32
+ parent::__construct($message, $code);
33
+ }
34
+
35
+ }
36
+
37
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/http/Chunked.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!function_exists('http-chunked-decode')) {
4
+ /**
5
+ * dechunk an http 'transfer-encoding: chunked' message
6
+ *
7
+ * @param string $chunk the encoded message
8
+ * @return string the decoded message. If $chunk wasn't encoded properly it will be returned unmodified.
9
+ */
10
+ function http_chunked_decode($chunk) {
11
+ $pos = 0;
12
+ $len = strlen($chunk);
13
+ $dechunk = null;
14
+
15
+ while(($pos < $len)
16
+ && ($chunkLenHex = substr($chunk,$pos, ($newlineAt = strpos($chunk,"\n",$pos+1))-$pos)))
17
+ {
18
+ if (! is_hex($chunkLenHex)) {
19
+ trigger_error('Value is not properly chunk encoded', E_USER_WARNING);
20
+ return $chunk;
21
+ }
22
+
23
+ $pos = $newlineAt + 1;
24
+ $chunkLen = hexdec(rtrim($chunkLenHex,"\r\n"));
25
+ $dechunk .= substr($chunk, $pos, $chunkLen);
26
+ $pos = strpos($chunk, "\n", $pos + $chunkLen) + 1;
27
+ }
28
+ return $dechunk;
29
+ }
30
+ }
31
+
32
+ /**
33
+ * determine if a string can represent a number in hexadecimal
34
+ *
35
+ * @param string $hex
36
+ * @return boolean true if the string is a hex, otherwise false
37
+ */
38
+ function is_hex($hex) {
39
+ // regex is for weenies
40
+ $hex = strtolower(trim(ltrim($hex,"0")));
41
+ if (empty($hex)) { $hex = 0; };
42
+ $dec = hexdec($hex);
43
+ return ($hex == dechex($dec));
44
+ }
45
+
46
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/http/ContentType.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ class ContentType
28
+ {
29
+ const FORM = "FORM";
30
+ const MULTIPART = "MULTIPART";
31
+ const JSON = "JSON";
32
+ }
33
+
34
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/http/HttpClient.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ require_once(dirname(__FILE__) . "/../exceptions/MashapeClientException.php");
28
+ require_once(dirname(__FILE__) . "/HttpMethod.php");
29
+ require_once(dirname(__FILE__) . "/ContentType.php");
30
+ require_once(dirname(__FILE__) . "/UrlUtils.php");
31
+ require_once(dirname(__FILE__) . "/HttpUtils.php");
32
+ require_once(dirname(__FILE__) . "/MashapeResponse.php");
33
+ require_once(dirname(__FILE__) . "/../authentication/HeaderAuthentication.php");
34
+ require_once(dirname(__FILE__) . "/../authentication/BasicAuthentication.php");
35
+ require_once(dirname(__FILE__) . "/../authentication/CustomHeaderAuthentication.php");
36
+ require_once(dirname(__FILE__) . "/../authentication/MashapeAuthentication.php");
37
+ require_once(dirname(__FILE__) . "/../authentication/QueryAuthentication.php");
38
+ //require_once(dirname(__FILE__) . "/../authentication/Oauth10aAuthentication.php");
39
+ //require_once(dirname(__FILE__) . "/../authentication/Oauth2Authentication.php");
40
+
41
+ class HttpClient {
42
+
43
+ public static function doRequest($httpMethod, $url, $parameters,
44
+ $authHandlers, $contentType = ContentType::FORM, $encodeJson = true) {
45
+ HttpUtils::cleanParameters($parameters);
46
+
47
+ if ($authHandlers == null) {
48
+ $authHandlers = array();
49
+ }
50
+
51
+ self::validateRequest($httpMethod, $url, $parameters, $authHandlers, $contentType);
52
+ $response = self::execRequest($httpMethod, $url, $parameters, $authHandlers, $contentType, $encodeJson);
53
+
54
+ return $response;
55
+ }
56
+
57
+ private static function validateRequest($httpMethod, $url, $parameters, $authHandlers, $contentType) {
58
+ if ( !($httpMethod == HttpMethod::DELETE
59
+ || $httpMethod == HttpMethod::GET
60
+ || $httpMethod == HttpMethod::POST
61
+ || $httpMethod == HttpMethod::PUT
62
+ || $httpMethod == HttpMethod::PATCH)) {
63
+ // we only support these HTTP methods.
64
+ throw new MashapeClientException(EXCEPTION_NOTSUPPORTED_HTTPMETHOD,
65
+ EXCEPTION_NOTSUPPORTED_HTTPMETHOD_CODE);
66
+ }
67
+ if ($contentType == ContentType::JSON && is_array($parameters)) {
68
+ // Content type JSON does not allow array parameters.
69
+ throw new MashapeClientException(
70
+ EXCEPTION_CONTENT_TYPE_JSON_ARRAY,
71
+ EXCEPTION_CONTENT_TYPE_JSON_ARRAY_CODE);
72
+ }
73
+ if (!is_array($parameters) && $contentType != ContentType::JSON) {
74
+ // Raw parameters are only allows for ContentType::JSON
75
+ throw new MashapeClientException(
76
+ EXCEPTION_CONTENT_TYPE_NON_ARRAY,
77
+ EXCEPTION_CONTENT_TYPE_NON_ARRAY_CODE);
78
+ }
79
+ if ($httpMethod == HttpMethod::GET && $contentType != ContentType::FORM) {
80
+ // if we have a GET request that is anything other than urlencoded
81
+ // form data, we shouldn't allow it.
82
+ throw new MashapeClientException(
83
+ EXCEPTION_GET_INVALID_CONTENTTYPE,
84
+ EXCEPTION_GET_INVALID_CONTENTTYPE_CODE);
85
+ }
86
+ if ($contentType == ContentType::JSON) {
87
+ foreach ($authHandlers as $handler) {
88
+ if ($handler instanceof QueryAuthentication) {
89
+ // bad. No room for query auth parameters if the whole body is json
90
+ throw new MashapeClientException(
91
+ EXCEPTION_CONTENT_TYPE_JSON_QUERYAUTH,
92
+ EXCEPTION_CONTENT_TYPE_JSON_QUERYAUTH_CODE);
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ private static function execRequest($httpMethod, $url, $parameters, $authHandlers, $contentType, $encodeJson) {
99
+ // first, collect the headers and parameters we'll need from the authentication handlers
100
+ list($headers, $authParameters) = HttpUtils::handleAuthentication($authHandlers);
101
+ if (is_array($parameters)) {
102
+ $parameters = array_merge($parameters, $authParameters);
103
+ }
104
+
105
+ // prepare the request
106
+ $ch = curl_init ();
107
+
108
+ if ($httpMethod == HttpMethod::GET) {
109
+ $url = UrlUtils::buildUrlWithQueryString($url, $parameters);
110
+ } else {
111
+ $data = HttpUtils::buildDataForContentType($contentType, $parameters, $headers);
112
+ curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, $httpMethod);
113
+ curl_setopt ($ch, CURLOPT_POSTFIELDS, $data);
114
+ }
115
+ curl_setopt ($ch, CURLOPT_URL , $url);
116
+ curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
117
+ curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);
118
+ curl_setopt ($ch, CURLINFO_HEADER_OUT, true);
119
+ curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
120
+ $response = curl_exec($ch);
121
+ if (curl_error($ch)) {
122
+ throw new MashapeClientException(
123
+ EXCEPTION_CURL . ":" . curl_error($ch),
124
+ EXCEPTION_CURL_CODE);
125
+ }
126
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
127
+ $responseHeaders = curl_getinfo($ch, CURLINFO_HEADER_OUT);
128
+ curl_close($ch);
129
+
130
+ return new MashapeResponse($response, $httpCode, $responseHeaders, $encodeJson);
131
+ }
132
+ }
133
+
134
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/http/HttpMethod.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ class HttpMethod
28
+ {
29
+ const DELETE = "DELETE";
30
+ const GET = "GET";
31
+ const POST = "POST";
32
+ const PUT = "PUT";
33
+ const PATCH = "PATCH";
34
+ }
35
+
36
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/http/HttpUtils.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ class HttpUtils {
8
+
9
+ public static function cleanParameters(&$parameters) {
10
+ if ($parameters == null) {
11
+ $parameters = array();
12
+ } else if (is_array($parameters)) {
13
+ // Remove null parameters
14
+ $keys = array_keys($parameters);
15
+ for ($i = 0;$i<count($keys);$i++) {
16
+ $key = $keys[$i];
17
+ if ($parameters[$key] === null) {
18
+ unset($parameters[$key]);
19
+ } else {
20
+ $parameters[$key] = (string)$parameters[$key];
21
+ }
22
+ }
23
+ }
24
+ }
25
+
26
+ public static function buildDataForContentType($contentType, $parameters, &$headers) {
27
+ $data = null;
28
+ switch ($contentType) {
29
+ case ContentType::FORM:
30
+ $data = http_build_query($parameters);
31
+ break;
32
+ case ContentType::MULTIPART:
33
+ $data = $parameters;
34
+ break;
35
+ case ContentType::JSON:
36
+ $headers[] = "Content-Type: application/json";
37
+ $data = $parameters;
38
+ break;
39
+ default:
40
+ throw new MashapeClientException(
41
+ EXCEPTION_NOTSUPPORTED_CONTENTTYPE,
42
+ EXCEPTION_NOTSUPPORTED_CONTENTTYPE_CODE);
43
+ }
44
+ return $data;
45
+ }
46
+
47
+ public static function handleAuthentication($authHandlers) {
48
+ $headers = array();
49
+ $parameters = array();
50
+ $headers[] = self::generateClientHeaders();
51
+ // Authentication
52
+ foreach($authHandlers as $handler) {
53
+ if ($handler instanceof QueryAuthentication) {
54
+ $parameters = array_merge($parameters, $handler->handleParams());
55
+ } else if ($handler instanceof HeaderAuthentication) {
56
+ $headers = array_merge($headers, $handler->handleHeaders());
57
+ } else if ($handler instanceof Oauth10aAuthentication) {
58
+ $headers = array_merge($headers, $handler->handleHeaders());
59
+ } else if ($handler instanceof Oauth2Authentication) {
60
+ $parameters = array_merge($parameters, $handler->handleParams());
61
+ }
62
+ }
63
+ return array($headers, $parameters);
64
+ }
65
+
66
+ public static function generateClientHeaders() {
67
+ $headers = "User-Agent: mashape-php/1.0: ";
68
+ return $headers;
69
+ }
70
+ }
71
+
72
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/http/HttpUtils.php~ ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ *Tryon Extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ class HttpUtils {
8
+
9
+ public static function cleanParameters(&$parameters) {
10
+ if ($parameters == null) {
11
+ $parameters = array();
12
+ } else if (is_array($parameters)) {
13
+ // Remove null parameters
14
+ $keys = array_keys($parameters);
15
+ for ($i = 0;$i<count($keys);$i++) {
16
+ $key = $keys[$i];
17
+ if ($parameters[$key] === null) {
18
+ unset($parameters[$key]);
19
+ } else {
20
+ $parameters[$key] = (string)$parameters[$key];
21
+ }
22
+ }
23
+ }
24
+ }
25
+
26
+ public static function buildDataForContentType($contentType, $parameters, &$headers) {
27
+ $data = null;
28
+ switch ($contentType) {
29
+ case ContentType::FORM:
30
+ $data = http_build_query($parameters);
31
+ break;
32
+ case ContentType::MULTIPART:
33
+ $data = $parameters;
34
+ break;
35
+ case ContentType::JSON:
36
+ $headers[] = "Content-Type: application/json";
37
+ $data = $parameters;
38
+ break;
39
+ default:
40
+ throw new MashapeClientException(
41
+ EXCEPTION_NOTSUPPORTED_CONTENTTYPE,
42
+ EXCEPTION_NOTSUPPORTED_CONTENTTYPE_CODE);
43
+ }
44
+ return $data;
45
+ }
46
+
47
+ public static function handleAuthentication($authHandlers) {
48
+ $headers = array();
49
+ $parameters = array();
50
+ $headers[] = self::generateClientHeaders();
51
+ // Authentication
52
+ foreach($authHandlers as $handler) {
53
+ if ($handler instanceof QueryAuthentication) {
54
+ $parameters = array_merge($parameters, $handler->handleParams());
55
+ } else if ($handler instanceof HeaderAuthentication) {
56
+ $headers = array_merge($headers, $handler->handleHeaders());
57
+ } else if ($handler instanceof Oauth10aAuthentication) {
58
+ $headers = array_merge($headers, $handler->handleHeaders());
59
+ } else if ($handler instanceof Oauth2Authentication) {
60
+ $parameters = array_merge($parameters, $handler->handleParams());
61
+ }
62
+ }
63
+ return array($headers, $parameters);
64
+ }
65
+
66
+ public static function generateClientHeaders() {
67
+ $headers = "User-Agent: mashape-php/1.0: ";
68
+ return $headers;
69
+ }
70
+ }
71
+
72
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/http/MashapeResponse.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ require_once(dirname(__FILE__) . "/../json/Json.php");
28
+ require_once(dirname(__FILE__) . "/Chunked.php");
29
+ require_once(dirname(__FILE__) . "/../exceptions/MashapeClientException.php");
30
+
31
+ class MashapeResponse {
32
+ public $statusCode;
33
+ public $body;
34
+ public $rawBody;
35
+ public $headers;
36
+
37
+ function __construct($response, $statusCode, $headers, $encodeJson = false) {
38
+ $this->rawBody = $response;
39
+ $this->headers = $headers;
40
+ $this->statusCode = $statusCode;
41
+ $this->_parseBody($encodeJson);
42
+ }
43
+
44
+ function _parseBody($encodeJson) {
45
+ if ($encodeJson) {
46
+ $this->body = json_decode($this->rawBody);
47
+ if (empty($this->body) && ($this->statusCode == 200)) {
48
+ // It may be a chunked response
49
+ //$this->body = json_decode(http_chunked_decode($this->rawBody));
50
+ if (empty($this->body)) {
51
+ throw new MashapeClientException(
52
+ sprintf(EXCEPTION_JSONDECODE_REQUEST, $this->rawBody),
53
+ EXCEPTION_SYSTEM_ERROR_CODE);
54
+ }
55
+ }
56
+ } else {
57
+ $this->body = $this->rawBody;
58
+ }
59
+ }
60
+ }
61
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/http/UrlUtils.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ class UrlUtils {
28
+
29
+ public static function buildUrlWithQueryString($url, $parameters) {
30
+ foreach ($parameters as $paramKey => $paramValue) {
31
+ $delimiter = (strpos($url, "?") === false) ? "?" : "&";
32
+ $url .= $delimiter . $paramKey . "=" . urlencode($paramValue);
33
+ }
34
+ return $url;
35
+ }
36
+
37
+ }
38
+
39
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/json/Json.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Mashape PHP Client library.
5
+ *
6
+ * Copyright (C) 2011 Mashape, Inc.
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU Affero General Public License as
10
+ * published by the Free Software Foundation, either version 3 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU Affero General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Affero General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ *
22
+ * The author of this software is Mashape, Inc.
23
+ * For any question or feedback please contact us at: support@mashape.com
24
+ *
25
+ */
26
+
27
+ if (!function_exists('json_decode')) {
28
+ function json_decode($content, $assoc=false) {
29
+ require_once(dirname(__FILE__) . "/Services_JSON.php");
30
+ if ($assoc) {
31
+ $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
32
+ }
33
+ else {
34
+ $json = new Services_JSON;
35
+ }
36
+ return $json->decode($content);
37
+ }
38
+ }
39
+
40
+ ?>
app/code/local/Daffodil/Tryon/controllers/mashape/json/Services_JSON.php ADDED
@@ -0,0 +1,806 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * Converts to and from JSON format.
6
+ *
7
+ * JSON (JavaScript Object Notation) is a lightweight data-interchange
8
+ * format. It is easy for humans to read and write. It is easy for machines
9
+ * to parse and generate. It is based on a subset of the JavaScript
10
+ * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
11
+ * This feature can also be found in Python. JSON is a text format that is
12
+ * completely language independent but uses conventions that are familiar
13
+ * to programmers of the C-family of languages, including C, C++, C#, Java,
14
+ * JavaScript, Perl, TCL, and many others. These properties make JSON an
15
+ * ideal data-interchange language.
16
+ *
17
+ * This package provides a simple encoder and decoder for JSON notation. It
18
+ * is intended for use with client-side Javascript applications that make
19
+ * use of HTTPRequest to perform server communication functions - data can
20
+ * be encoded into JSON notation for use in a client-side javascript, or
21
+ * decoded from incoming Javascript requests. JSON format is native to
22
+ * Javascript, and can be directly eval()'ed with no further parsing
23
+ * overhead
24
+ *
25
+ * All strings should be in ASCII or UTF-8 format!
26
+ *
27
+ * LICENSE: Redistribution and use in source and binary forms, with or
28
+ * without modification, are permitted provided that the following
29
+ * conditions are met: Redistributions of source code must retain the
30
+ * above copyright notice, this list of conditions and the following
31
+ * disclaimer. Redistributions in binary form must reproduce the above
32
+ * copyright notice, this list of conditions and the following disclaimer
33
+ * in the documentation and/or other materials provided with the
34
+ * distribution.
35
+ *
36
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
37
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
38
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
39
+ * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
40
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
41
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
42
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
44
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
45
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
46
+ * DAMAGE.
47
+ *
48
+ * @category
49
+ * @package Services_JSON
50
+ * @author Michal Migurski <mike-json@teczno.com>
51
+ * @author Matt Knapp <mdknapp[at]gmail[dot]com>
52
+ * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
53
+ * @copyright 2005 Michal Migurski
54
+ * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
55
+ * @license http://www.opensource.org/licenses/bsd-license.php
56
+ * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
57
+ */
58
+
59
+ /**
60
+ * Marker constant for Services_JSON::decode(), used to flag stack state
61
+ */
62
+ define('SERVICES_JSON_SLICE', 1);
63
+
64
+ /**
65
+ * Marker constant for Services_JSON::decode(), used to flag stack state
66
+ */
67
+ define('SERVICES_JSON_IN_STR', 2);
68
+
69
+ /**
70
+ * Marker constant for Services_JSON::decode(), used to flag stack state
71
+ */
72
+ define('SERVICES_JSON_IN_ARR', 3);
73
+
74
+ /**
75
+ * Marker constant for Services_JSON::decode(), used to flag stack state
76
+ */
77
+ define('SERVICES_JSON_IN_OBJ', 4);
78
+
79
+ /**
80
+ * Marker constant for Services_JSON::decode(), used to flag stack state
81
+ */
82
+ define('SERVICES_JSON_IN_CMT', 5);
83
+
84
+ /**
85
+ * Behavior switch for Services_JSON::decode()
86
+ */
87
+ define('SERVICES_JSON_LOOSE_TYPE', 16);
88
+
89
+ /**
90
+ * Behavior switch for Services_JSON::decode()
91
+ */
92
+ define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
93
+
94
+ /**
95
+ * Converts to and from JSON format.
96
+ *
97
+ * Brief example of use:
98
+ *
99
+ * <code>
100
+ * // create a new instance of Services_JSON
101
+ * $json = new Services_JSON();
102
+ *
103
+ * // convert a complexe value to JSON notation, and send it to the browser
104
+ * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
105
+ * $output = $json->encode($value);
106
+ *
107
+ * print($output);
108
+ * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
109
+ *
110
+ * // accept incoming POST data, assumed to be in JSON notation
111
+ * $input = file_get_contents('php://input', 1000000);
112
+ * $value = $json->decode($input);
113
+ * </code>
114
+ */
115
+ class Services_JSON
116
+ {
117
+ /**
118
+ * constructs a new JSON instance
119
+ *
120
+ * @param int $use object behavior flags; combine with boolean-OR
121
+ *
122
+ * possible values:
123
+ * - SERVICES_JSON_LOOSE_TYPE: loose typing.
124
+ * "{...}" syntax creates associative arrays
125
+ * instead of objects in decode().
126
+ * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
127
+ * Values which can't be encoded (e.g. resources)
128
+ * appear as NULL instead of throwing errors.
129
+ * By default, a deeply-nested resource will
130
+ * bubble up with an error, so all return values
131
+ * from encode() should be checked with isError()
132
+ */
133
+ function Services_JSON($use = 0)
134
+ {
135
+ $this->use = $use;
136
+ }
137
+
138
+ /**
139
+ * convert a string from one UTF-16 char to one UTF-8 char
140
+ *
141
+ * Normally should be handled by mb_convert_encoding, but
142
+ * provides a slower PHP-only method for installations
143
+ * that lack the multibye string extension.
144
+ *
145
+ * @param string $utf16 UTF-16 character
146
+ * @return string UTF-8 character
147
+ * @access private
148
+ */
149
+ function utf162utf8($utf16)
150
+ {
151
+ // oh please oh please oh please oh please oh please
152
+ if(function_exists('mb_convert_encoding')) {
153
+ return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
154
+ }
155
+
156
+ $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
157
+
158
+ switch(true) {
159
+ case ((0x7F & $bytes) == $bytes):
160
+ // this case should never be reached, because we are in ASCII range
161
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
162
+ return chr(0x7F & $bytes);
163
+
164
+ case (0x07FF & $bytes) == $bytes:
165
+ // return a 2-byte UTF-8 character
166
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
167
+ return chr(0xC0 | (($bytes >> 6) & 0x1F))
168
+ . chr(0x80 | ($bytes & 0x3F));
169
+
170
+ case (0xFFFF & $bytes) == $bytes:
171
+ // return a 3-byte UTF-8 character
172
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
173
+ return chr(0xE0 | (($bytes >> 12) & 0x0F))
174
+ . chr(0x80 | (($bytes >> 6) & 0x3F))
175
+ . chr(0x80 | ($bytes & 0x3F));
176
+ }
177
+
178
+ // ignoring UTF-32 for now, sorry
179
+ return '';
180
+ }
181
+
182
+ /**
183
+ * convert a string from one UTF-8 char to one UTF-16 char
184
+ *
185
+ * Normally should be handled by mb_convert_encoding, but
186
+ * provides a slower PHP-only method for installations
187
+ * that lack the multibye string extension.
188
+ *
189
+ * @param string $utf8 UTF-8 character
190
+ * @return string UTF-16 character
191
+ * @access private
192
+ */
193
+ function utf82utf16($utf8)
194
+ {
195
+ // oh please oh please oh please oh please oh please
196
+ if(function_exists('mb_convert_encoding')) {
197
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
198
+ }
199
+
200
+ switch(strlen($utf8)) {
201
+ case 1:
202
+ // this case should never be reached, because we are in ASCII range
203
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
204
+ return $utf8;
205
+
206
+ case 2:
207
+ // return a UTF-16 character from a 2-byte UTF-8 char
208
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
209
+ return chr(0x07 & (ord($utf8{0}) >> 2))
210
+ . chr((0xC0 & (ord($utf8{0}) << 6))
211
+ | (0x3F & ord($utf8{1})));
212
+
213
+ case 3:
214
+ // return a UTF-16 character from a 3-byte UTF-8 char
215
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
216
+ return chr((0xF0 & (ord($utf8{0}) << 4))
217
+ | (0x0F & (ord($utf8{1}) >> 2)))
218
+ . chr((0xC0 & (ord($utf8{1}) << 6))
219
+ | (0x7F & ord($utf8{2})));
220
+ }
221
+
222
+ // ignoring UTF-32 for now, sorry
223
+ return '';
224
+ }
225
+
226
+ /**
227
+ * encodes an arbitrary variable into JSON format
228
+ *
229
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
230
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
231
+ * if var is a strng, note that encode() always expects it
232
+ * to be in ASCII or UTF-8 format!
233
+ *
234
+ * @return mixed JSON string representation of input var or an error if a problem occurs
235
+ * @access public
236
+ */
237
+ function encode($var)
238
+ {
239
+ switch (gettype($var)) {
240
+ case 'boolean':
241
+ return $var ? 'true' : 'false';
242
+
243
+ case 'NULL':
244
+ return 'null';
245
+
246
+ case 'integer':
247
+ return (int) $var;
248
+
249
+ case 'double':
250
+ case 'float':
251
+ return (float) $var;
252
+
253
+ case 'string':
254
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
255
+ $ascii = '';
256
+ $strlen_var = strlen($var);
257
+
258
+ /*
259
+ * Iterate over every character in the string,
260
+ * escaping with a slash or encoding to UTF-8 where necessary
261
+ */
262
+ for ($c = 0; $c < $strlen_var; ++$c) {
263
+
264
+ $ord_var_c = ord($var{$c});
265
+
266
+ switch (true) {
267
+ case $ord_var_c == 0x08:
268
+ $ascii .= '\b';
269
+ break;
270
+ case $ord_var_c == 0x09:
271
+ $ascii .= '\t';
272
+ break;
273
+ case $ord_var_c == 0x0A:
274
+ $ascii .= '\n';
275
+ break;
276
+ case $ord_var_c == 0x0C:
277
+ $ascii .= '\f';
278
+ break;
279
+ case $ord_var_c == 0x0D:
280
+ $ascii .= '\r';
281
+ break;
282
+
283
+ case $ord_var_c == 0x22:
284
+ case $ord_var_c == 0x2F:
285
+ case $ord_var_c == 0x5C:
286
+ // double quote, slash, slosh
287
+ $ascii .= '\\'.$var{$c};
288
+ break;
289
+
290
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
291
+ // characters U-00000000 - U-0000007F (same as ASCII)
292
+ $ascii .= $var{$c};
293
+ break;
294
+
295
+ case (($ord_var_c & 0xE0) == 0xC0):
296
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
297
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
298
+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
299
+ $c += 1;
300
+ $utf16 = $this->utf82utf16($char);
301
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
302
+ break;
303
+
304
+ case (($ord_var_c & 0xF0) == 0xE0):
305
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
306
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
307
+ $char = pack('C*', $ord_var_c,
308
+ ord($var{$c + 1}),
309
+ ord($var{$c + 2}));
310
+ $c += 2;
311
+ $utf16 = $this->utf82utf16($char);
312
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
313
+ break;
314
+
315
+ case (($ord_var_c & 0xF8) == 0xF0):
316
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
317
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
318
+ $char = pack('C*', $ord_var_c,
319
+ ord($var{$c + 1}),
320
+ ord($var{$c + 2}),
321
+ ord($var{$c + 3}));
322
+ $c += 3;
323
+ $utf16 = $this->utf82utf16($char);
324
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
325
+ break;
326
+
327
+ case (($ord_var_c & 0xFC) == 0xF8):
328
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
329
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
330
+ $char = pack('C*', $ord_var_c,
331
+ ord($var{$c + 1}),
332
+ ord($var{$c + 2}),
333
+ ord($var{$c + 3}),
334
+ ord($var{$c + 4}));
335
+ $c += 4;
336
+ $utf16 = $this->utf82utf16($char);
337
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
338
+ break;
339
+
340
+ case (($ord_var_c & 0xFE) == 0xFC):
341
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
342
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
343
+ $char = pack('C*', $ord_var_c,
344
+ ord($var{$c + 1}),
345
+ ord($var{$c + 2}),
346
+ ord($var{$c + 3}),
347
+ ord($var{$c + 4}),
348
+ ord($var{$c + 5}));
349
+ $c += 5;
350
+ $utf16 = $this->utf82utf16($char);
351
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
352
+ break;
353
+ }
354
+ }
355
+
356
+ return '"'.$ascii.'"';
357
+
358
+ case 'array':
359
+ /*
360
+ * As per JSON spec if any array key is not an integer
361
+ * we must treat the the whole array as an object. We
362
+ * also try to catch a sparsely populated associative
363
+ * array with numeric keys here because some JS engines
364
+ * will create an array with empty indexes up to
365
+ * max_index which can cause memory issues and because
366
+ * the keys, which may be relevant, will be remapped
367
+ * otherwise.
368
+ *
369
+ * As per the ECMA and JSON specification an object may
370
+ * have any string as a property. Unfortunately due to
371
+ * a hole in the ECMA specification if the key is a
372
+ * ECMA reserved word or starts with a digit the
373
+ * parameter is only accessible using ECMAScript's
374
+ * bracket notation.
375
+ */
376
+
377
+ // treat as a JSON object
378
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
379
+ $properties = array_map(array($this, 'name_value'),
380
+ array_keys($var),
381
+ array_values($var));
382
+
383
+ foreach($properties as $property) {
384
+ if(Services_JSON::isError($property)) {
385
+ return $property;
386
+ }
387
+ }
388
+
389
+ return '{' . join(',', $properties) . '}';
390
+ }
391
+
392
+ // treat it like a regular array
393
+ $elements = array_map(array($this, 'encode'), $var);
394
+
395
+ foreach($elements as $element) {
396
+ if(Services_JSON::isError($element)) {
397
+ return $element;
398
+ }
399
+ }
400
+
401
+ return '[' . join(',', $elements) . ']';
402
+
403
+ case 'object':
404
+ $vars = get_object_vars($var);
405
+
406
+ $properties = array_map(array($this, 'name_value'),
407
+ array_keys($vars),
408
+ array_values($vars));
409
+
410
+ foreach($properties as $property) {
411
+ if(Services_JSON::isError($property)) {
412
+ return $property;
413
+ }
414
+ }
415
+
416
+ return '{' . join(',', $properties) . '}';
417
+
418
+ default:
419
+ return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
420
+ ? 'null'
421
+ : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
422
+ }
423
+ }
424
+
425
+ /**
426
+ * array-walking function for use in generating JSON-formatted name-value pairs
427
+ *
428
+ * @param string $name name of key to use
429
+ * @param mixed $value reference to an array element to be encoded
430
+ *
431
+ * @return string JSON-formatted name-value pair, like '"name":value'
432
+ * @access private
433
+ */
434
+ function name_value($name, $value)
435
+ {
436
+ $encoded_value = $this->encode($value);
437
+
438
+ if(Services_JSON::isError($encoded_value)) {
439
+ return $encoded_value;
440
+ }
441
+
442
+ return $this->encode(strval($name)) . ':' . $encoded_value;
443
+ }
444
+
445
+ /**
446
+ * reduce a string by removing leading and trailing comments and whitespace
447
+ *
448
+ * @param $str string string value to strip of comments and whitespace
449
+ *
450
+ * @return string string value stripped of comments and whitespace
451
+ * @access private
452
+ */
453
+ function reduce_string($str)
454
+ {
455
+ $str = preg_replace(array(
456
+
457
+ // eliminate single line comments in '// ...' form
458
+ '#^\s*//(.+)$#m',
459
+
460
+ // eliminate multi-line comments in '/* ... */' form, at start of string
461
+ '#^\s*/\*(.+)\*/#Us',
462
+
463
+ // eliminate multi-line comments in '/* ... */' form, at end of string
464
+ '#/\*(.+)\*/\s*$#Us'
465
+
466
+ ), '', $str);
467
+
468
+ // eliminate extraneous space
469
+ return trim($str);
470
+ }
471
+
472
+ /**
473
+ * decodes a JSON string into appropriate variable
474
+ *
475
+ * @param string $str JSON-formatted string
476
+ *
477
+ * @return mixed number, boolean, string, array, or object
478
+ * corresponding to given JSON input string.
479
+ * See argument 1 to Services_JSON() above for object-output behavior.
480
+ * Note that decode() always returns strings
481
+ * in ASCII or UTF-8 format!
482
+ * @access public
483
+ */
484
+ function decode($str)
485
+ {
486
+ $str = $this->reduce_string($str);
487
+
488
+ switch (strtolower($str)) {
489
+ case 'true':
490
+ return true;
491
+
492
+ case 'false':
493
+ return false;
494
+
495
+ case 'null':
496
+ return null;
497
+
498
+ default:
499
+ $m = array();
500
+
501
+ if (is_numeric($str)) {
502
+ // Lookie-loo, it's a number
503
+
504
+ // This would work on its own, but I'm trying to be
505
+ // good about returning integers where appropriate:
506
+ // return (float)$str;
507
+
508
+ // Return float or int, as appropriate
509
+ return ((float)$str == (integer)$str)
510
+ ? (integer)$str
511
+ : (float)$str;
512
+
513
+ } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
514
+ // STRINGS RETURNED IN UTF-8 FORMAT
515
+ $delim = substr($str, 0, 1);
516
+ $chrs = substr($str, 1, -1);
517
+ $utf8 = '';
518
+ $strlen_chrs = strlen($chrs);
519
+
520
+ for ($c = 0; $c < $strlen_chrs; ++$c) {
521
+
522
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
523
+ $ord_chrs_c = ord($chrs{$c});
524
+
525
+ switch (true) {
526
+ case $substr_chrs_c_2 == '\b':
527
+ $utf8 .= chr(0x08);
528
+ ++$c;
529
+ break;
530
+ case $substr_chrs_c_2 == '\t':
531
+ $utf8 .= chr(0x09);
532
+ ++$c;
533
+ break;
534
+ case $substr_chrs_c_2 == '\n':
535
+ $utf8 .= chr(0x0A);
536
+ ++$c;
537
+ break;
538
+ case $substr_chrs_c_2 == '\f':
539
+ $utf8 .= chr(0x0C);
540
+ ++$c;
541
+ break;
542
+ case $substr_chrs_c_2 == '\r':
543
+ $utf8 .= chr(0x0D);
544
+ ++$c;
545
+ break;
546
+
547
+ case $substr_chrs_c_2 == '\\"':
548
+ case $substr_chrs_c_2 == '\\\'':
549
+ case $substr_chrs_c_2 == '\\\\':
550
+ case $substr_chrs_c_2 == '\\/':
551
+ if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
552
+ ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
553
+ $utf8 .= $chrs{++$c};
554
+ }
555
+ break;
556
+
557
+ case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
558
+ // single, escaped unicode character
559
+ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
560
+ . chr(hexdec(substr($chrs, ($c + 4), 2)));
561
+ $utf8 .= $this->utf162utf8($utf16);
562
+ $c += 5;
563
+ break;
564
+
565
+ case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
566
+ $utf8 .= $chrs{$c};
567
+ break;
568
+
569
+ case ($ord_chrs_c & 0xE0) == 0xC0:
570
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
571
+ //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
572
+ $utf8 .= substr($chrs, $c, 2);
573
+ ++$c;
574
+ break;
575
+
576
+ case ($ord_chrs_c & 0xF0) == 0xE0:
577
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
578
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
579
+ $utf8 .= substr($chrs, $c, 3);
580
+ $c += 2;
581
+ break;
582
+
583
+ case ($ord_chrs_c & 0xF8) == 0xF0:
584
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
585
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
586
+ $utf8 .= substr($chrs, $c, 4);
587
+ $c += 3;
588
+ break;
589
+
590
+ case ($ord_chrs_c & 0xFC) == 0xF8:
591
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
592
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
593
+ $utf8 .= substr($chrs, $c, 5);
594
+ $c += 4;
595
+ break;
596
+
597
+ case ($ord_chrs_c & 0xFE) == 0xFC:
598
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
599
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
600
+ $utf8 .= substr($chrs, $c, 6);
601
+ $c += 5;
602
+ break;
603
+
604
+ }
605
+
606
+ }
607
+
608
+ return $utf8;
609
+
610
+ } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
611
+ // array, or object notation
612
+
613
+ if ($str{0} == '[') {
614
+ $stk = array(SERVICES_JSON_IN_ARR);
615
+ $arr = array();
616
+ } else {
617
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
618
+ $stk = array(SERVICES_JSON_IN_OBJ);
619
+ $obj = array();
620
+ } else {
621
+ $stk = array(SERVICES_JSON_IN_OBJ);
622
+ $obj = new stdClass();
623
+ }
624
+ }
625
+
626
+ array_push($stk, array('what' => SERVICES_JSON_SLICE,
627
+ 'where' => 0,
628
+ 'delim' => false));
629
+
630
+ $chrs = substr($str, 1, -1);
631
+ $chrs = $this->reduce_string($chrs);
632
+
633
+ if ($chrs == '') {
634
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
635
+ return $arr;
636
+
637
+ } else {
638
+ return $obj;
639
+
640
+ }
641
+ }
642
+
643
+ //print("\nparsing {$chrs}\n");
644
+
645
+ $strlen_chrs = strlen($chrs);
646
+
647
+ for ($c = 0; $c <= $strlen_chrs; ++$c) {
648
+
649
+ $top = end($stk);
650
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
651
+
652
+ if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
653
+ // found a comma that is not inside a string, array, etc.,
654
+ // OR we've reached the end of the character list
655
+ $slice = substr($chrs, $top['where'], ($c - $top['where']));
656
+ array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
657
+ //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
658
+
659
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
660
+ // we are in an array, so just push an element onto the stack
661
+ array_push($arr, $this->decode($slice));
662
+
663
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
664
+ // we are in an object, so figure
665
+ // out the property name and set an
666
+ // element in an associative array,
667
+ // for now
668
+ $parts = array();
669
+
670
+ if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
671
+ // "name":value pair
672
+ $key = $this->decode($parts[1]);
673
+ $val = $this->decode($parts[2]);
674
+
675
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
676
+ $obj[$key] = $val;
677
+ } else {
678
+ $obj->$key = $val;
679
+ }
680
+ } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
681
+ // name:value pair, where name is unquoted
682
+ $key = $parts[1];
683
+ $val = $this->decode($parts[2]);
684
+
685
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
686
+ $obj[$key] = $val;
687
+ } else {
688
+ $obj->$key = $val;
689
+ }
690
+ }
691
+
692
+ }
693
+
694
+ } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
695
+ // found a quote, and we are not inside a string
696
+ array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
697
+ //print("Found start of string at {$c}\n");
698
+
699
+ } elseif (($chrs{$c} == $top['delim']) &&
700
+ ($top['what'] == SERVICES_JSON_IN_STR) &&
701
+ ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
702
+ // found a quote, we're in a string, and it's not escaped
703
+ // we know that it's not escaped becase there is _not_ an
704
+ // odd number of backslashes at the end of the string so far
705
+ array_pop($stk);
706
+ //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
707
+
708
+ } elseif (($chrs{$c} == '[') &&
709
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
710
+ // found a left-bracket, and we are in an array, object, or slice
711
+ array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
712
+ //print("Found start of array at {$c}\n");
713
+
714
+ } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
715
+ // found a right-bracket, and we're in an array
716
+ array_pop($stk);
717
+ //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
718
+
719
+ } elseif (($chrs{$c} == '{') &&
720
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
721
+ // found a left-brace, and we are in an array, object, or slice
722
+ array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
723
+ //print("Found start of object at {$c}\n");
724
+
725
+ } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
726
+ // found a right-brace, and we're in an object
727
+ array_pop($stk);
728
+ //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
729
+
730
+ } elseif (($substr_chrs_c_2 == '/*') &&
731
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
732
+ // found a comment start, and we are in an array, object, or slice
733
+ array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
734
+ $c++;
735
+ //print("Found start of comment at {$c}\n");
736
+
737
+ } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
738
+ // found a comment end, and we're in one now
739
+ array_pop($stk);
740
+ $c++;
741
+
742
+ for ($i = $top['where']; $i <= $c; ++$i)
743
+ $chrs = substr_replace($chrs, ' ', $i, 1);
744
+
745
+ //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
746
+
747
+ }
748
+
749
+ }
750
+
751
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
752
+ return $arr;
753
+
754
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
755
+ return $obj;
756
+
757
+ }
758
+
759
+ }
760
+ }
761
+ }
762
+
763
+ /**
764
+ * @todo Ultimately, this should just call PEAR::isError()
765
+ */
766
+ function isError($data, $code = null)
767
+ {
768
+ if (class_exists('pear')) {
769
+ return PEAR::isError($data, $code);
770
+ } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
771
+ is_subclass_of($data, 'services_json_error'))) {
772
+ return true;
773
+ }
774
+
775
+ return false;
776
+ }
777
+ }
778
+
779
+ if (class_exists('PEAR_Error')) {
780
+
781
+ class Services_JSON_Error extends PEAR_Error
782
+ {
783
+ function Services_JSON_Error($message = 'unknown error', $code = null,
784
+ $mode = null, $options = null, $userinfo = null)
785
+ {
786
+ parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
787
+ }
788
+ }
789
+
790
+ } else {
791
+
792
+ /**
793
+ * @todo Ultimately, this class shall be descended from PEAR_Error
794
+ */
795
+ class Services_JSON_Error
796
+ {
797
+ function Services_JSON_Error($message = 'unknown error', $code = null,
798
+ $mode = null, $options = null, $userinfo = null)
799
+ {
800
+
801
+ }
802
+ }
803
+
804
+ }
805
+
806
+ ?>
app/code/local/Daffodil/Tryon/etc/config.xml ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Daffodil_Tryon>
5
+ <version>0.1.0</version>
6
+ </Daffodil_Tryon>
7
+ </modules>
8
+ <global>
9
+ <helpers>
10
+ <tryon>
11
+ <class>Daffodil_Tryon_Helper</class>
12
+ </tryon>
13
+ </helpers>
14
+ </global>
15
+ <frontend>
16
+ <routers>
17
+ <tryon>
18
+ <use>standard</use>
19
+ <args>
20
+ <module>Daffodil_Tryon</module>
21
+ <frontName>tryon</frontName>
22
+ </args>
23
+ </tryon>
24
+ </routers>
25
+ <layout>
26
+ <updates>
27
+ <tryon>
28
+ <file>tryon.xml</file>
29
+ </tryon>
30
+ </updates>
31
+ </layout>
32
+ </frontend>
33
+ <adminhtml>
34
+ <acl>
35
+ <resources>
36
+ <admin>
37
+ <children>
38
+ <system>
39
+ <children>
40
+ <config>
41
+ <children>
42
+ <tryon>
43
+ <title>Tryon</title>
44
+ </tryon>
45
+ </children>
46
+ </config>
47
+ </children>
48
+ </system>
49
+ </children>
50
+ </admin>
51
+ </resources>
52
+ </acl>
53
+ </adminhtml>
54
+ <default>
55
+ <tryon>
56
+ <all_settings>
57
+ <enabled>1</enabled>
58
+ </all_settings>
59
+ </tryon>
60
+ </default>
61
+ </config>
app/code/local/Daffodil/Tryon/etc/config.xml~ ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Daffodil_Tryon>
5
+ <version>0.1.0</version>
6
+ </Daffodil_Tryon>
7
+ </modules>
8
+ <global>
9
+ <helpers>
10
+ <tryon>
11
+ <class>Daffodil_Tryon_Helper</class>
12
+ </tryon>
13
+ </helpers>
14
+ </global>
15
+ <frontend>
16
+ <routers>
17
+ <tryon>
18
+ <use>standard</use>
19
+ <args>
20
+ <module>Daffodil_Tryon</module>
21
+ <frontName>tryon</frontName>
22
+ </args>
23
+ </tryon>
24
+ </routers>
25
+ <layout>
26
+ <updates>
27
+ <tryon>
28
+ <file>tryon.xml</file>
29
+ </tryon>
30
+ </updates>
31
+ </layout>
32
+ </frontend>
33
+ <adminhtml>
34
+ <acl>
35
+ <resources>
36
+ <admin>
37
+ <children>
38
+ <system>
39
+ <children>
40
+ <config>
41
+ <children>
42
+ <tryon>
43
+ <title>Tryon</title>
44
+ </tryon>
45
+ </children>
46
+ </config>
47
+ </children>
48
+ </system>
49
+ </children>
50
+ </admin>
51
+ </resources>
52
+ </acl>
53
+ </adminhtml>
54
+ <default>
55
+ <tryon>
56
+ <all_settings>
57
+ <enabled>1</enabled>
58
+ </all_settings>
59
+ </tryon>
60
+ </default>
61
+ </config>
app/code/local/Daffodil/Tryon/etc/system.xml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <tabs>
4
+ <tryon translate="label" module="tryon">
5
+ <label>try on your face setting</label>
6
+ <sort_order>800</sort_order>
7
+ </tryon>
8
+ </tabs>
9
+ <sections>
10
+ <tryon translate="label" module="tryon">
11
+ <tab>tryon</tab>
12
+ <label>try on your face configuration</label>
13
+ <frontend_type>text</frontend_type>
14
+ <sort_order>2000</sort_order>
15
+ <show_in_default>1</show_in_default>
16
+ <show_in_website>1</show_in_website>
17
+ <show_in_store>1</show_in_store>
18
+ <groups>
19
+ <all_settings translate="label">
20
+ <label>Try this on your face settings</label>
21
+ <frontend_type>text</frontend_type>
22
+ <sort_order>10</sort_order>
23
+ <show_in_default>1</show_in_default>
24
+ <show_in_website>1</show_in_website>
25
+ <show_in_store>0</show_in_store>
26
+ <fields>
27
+ <enabled translate="label">
28
+ <label>Enable try this</label>
29
+ <frontend_type>select</frontend_type>
30
+ <source_model>adminhtml/system_config_source_yesno</source_model>
31
+ <sort_order>1</sort_order>
32
+ <show_in_default>1</show_in_default>
33
+ <show_in_website>1</show_in_website>
34
+ <show_in_store>1</show_in_store>
35
+ </enabled>
36
+ </fields>
37
+ </all_settings>
38
+ </groups>
39
+ </tryon>
40
+ </sections>
41
+ </config>
app/code/local/Daffodil/Tryon/etc/system.xml~ ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <tabs>
4
+ <tryon translate="label" module="tryon">
5
+ <label>try on your face setting</label>
6
+ <sort_order>800</sort_order>
7
+ </tryon>
8
+ </tabs>
9
+ <sections>
10
+ <tryon translate="label" module="tryon">
11
+ <tab>tryon</tab>
12
+ <label>try on your face configuration</label>
13
+ <frontend_type>text</frontend_type>
14
+ <sort_order>2000</sort_order>
15
+ <show_in_default>1</show_in_default>
16
+ <show_in_website>1</show_in_website>
17
+ <show_in_store>1</show_in_store>
18
+ <groups>
19
+ <all_settings translate="label">
20
+ <label>Try this on your face settings</label>
21
+ <frontend_type>text</frontend_type>
22
+ <sort_order>10</sort_order>
23
+ <show_in_default>1</show_in_default>
24
+ <show_in_website>1</show_in_website>
25
+ <show_in_store>0</show_in_store>
26
+ <fields>
27
+ <enabled translate="label">
28
+ <label>Enable try this</label>
29
+ <frontend_type>select</frontend_type>
30
+ <source_model>adminhtml/system_config_source_yesno</source_model>
31
+ <sort_order>1</sort_order>
32
+ <show_in_default>1</show_in_default>
33
+ <show_in_website>1</show_in_website>
34
+ <show_in_store>1</show_in_store>
35
+ </enabled>
36
+ </fields>
37
+ </all_settings>
38
+ </groups>
39
+ </tryon>
40
+ </sections>
41
+ </config>
app/code/local/Daffodil/Tryon/sql/avatar_setup/mysql4-install-0.1.0.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $installer->run("
8
+
9
+ -- DROP TABLE IF EXISTS {$this->getTable('tryon')};
10
+ CREATE TABLE {$this->getTable('tryon')} (
11
+ `tryon_id` int(11) unsigned NOT NULL auto_increment,
12
+ `title` varchar(255) NOT NULL default '',
13
+ `content` text NOT NULL default '',
14
+ `status` smallint(6) NOT NULL default '0',
15
+ `created_time` datetime NULL,
16
+ `update_time` datetime NULL,
17
+ PRIMARY KEY (`tryon_id`)
18
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
19
+
20
+ ");
21
+
22
+ $installer->endSetup();
app/code/local/Daffodil/Tryon/sql/avatar_setup/mysql4-install-0.1.0.php~ ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $installer->run("
8
+
9
+ -- DROP TABLE IF EXISTS {$this->getTable('tryon')};
10
+ CREATE TABLE {$this->getTable('tryon')} (
11
+ `tryon_id` int(11) unsigned NOT NULL auto_increment,
12
+ `title` varchar(255) NOT NULL default '',
13
+ `content` text NOT NULL default '',
14
+ `status` smallint(6) NOT NULL default '0',
15
+ `created_time` datetime NULL,
16
+ `update_time` datetime NULL,
17
+ PRIMARY KEY (`tryon_id`)
18
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
19
+
20
+ ");
21
+
22
+ $installer->endSetup();
app/design/frontend/default/default/layout/tryon.xml ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <default>
4
+ <reference name="head">
5
+ <action method="addJs"><script>tryon/jquery-1.8.2.js</script></action>
6
+ <action method="addJs"><script>tryon/jquery-ui.min.js</script></action>
7
+ <action method="addJs"><script>tryon/ajaxupload.3.5.js</script></action>
8
+ <action method="addJs"><script>tryon/jquery.hoverscroll.js</script></action>
9
+ <action method="addItem"><type>skin_css</type><name>tryon/tryon.css</name></action>
10
+
11
+ </reference>
12
+ </default>
13
+ <tryon_index_index>
14
+ <reference name="root">
15
+ <action method="setTemplate"><template>page/2columns-right.phtml</template></action>
16
+ </reference>
17
+ </tryon_index_index>
18
+ <catalog_category_default translate="label">
19
+ <reference name="root">
20
+ <action method="setTemplate"><template>page/2columns-right.phtml</template></action>
21
+ </reference>
22
+
23
+ <reference name="product_list">
24
+ <action method="setTemplate" ifconfig="tryon/all_settings/enabled"><template>tryon/list.phtml</template></action>
25
+ </reference>
26
+ <reference name="right">
27
+ <block type="core/template" name="trynow" before="-" >
28
+ <action method="setTemplate" ifconfig="tryon/all_settings/enabled"><template>tryon/rightsection.phtml</template></action>
29
+ </block>
30
+ </reference>
31
+ </catalog_category_default>
32
+ <catalog_product_view>
33
+ <reference name="product.info">
34
+ <action method="setTemplate" ifconfig="tryon/all_settings/enabled"><template>tryon/view.phtml</template></action>
35
+ </reference>
36
+ <reference name="right">
37
+ <block type="core/template" name="trynow" before="-" >
38
+ <action method="setTemplate" ifconfig="tryon/all_settings/enabled"><template>tryon/rightsection.phtml</template></action>
39
+ </block>
40
+ </reference>
41
+ </catalog_product_view>
42
+ </layout>
app/design/frontend/default/default/template/tryon/list.phtml ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ *tryon extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ /**
8
+ * Product list template
9
+ *
10
+ * @see Mage_Catalog_Block_Product_List
11
+ */
12
+ ?>
13
+ <?php
14
+ $_productCollection=$this->getLoadedProductCollection();
15
+ $_helper = $this->helper('catalog/output');
16
+ ?>
17
+ <?php if(!$_productCollection->count()): ?>
18
+ <p class="note-msg"><?php echo $this->__('There are no products matching the selection.') ?></p>
19
+ <?php else: ?>
20
+ <div class="category-products">
21
+ <?php echo $this->getToolbarHtml() ?>
22
+ <?php // List mode ?>
23
+ <?php if($this->getMode()!='grid'): ?>
24
+ <?php $_iterator = 0; ?>
25
+ <ol class="products-list" id="products-list">
26
+ <?php foreach ($_productCollection as $_product): ?>
27
+ <li class="item<?php if( ++$_iterator == sizeof($_productCollection) ): ?> last<?php endif; ?>">
28
+ <?php // Product Image ?>
29
+ <a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" class="product-image"><img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(135); ?>" width="135" height="135" alt="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" /></a>
30
+ <?php // Product description ?>
31
+ <div class="product-shop">
32
+ <div class="f-fix">
33
+ <?php $_productNameStripped = $this->stripTags($_product->getName(), null, true); ?>
34
+ <h2 class="product-name"><a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $_productNameStripped; ?>"><?php echo $_helper->productAttribute($_product, $_product->getName() , 'name'); ?></a></h2>
35
+ <?php if($_product->getRatingSummary()): ?>
36
+ <?php echo $this->getReviewsSummaryHtml($_product) ?>
37
+ <?php endif; ?>
38
+ <?php echo $this->getPriceHtml($_product, true) ?>
39
+ <?php if($_product->isSaleable()): ?>
40
+ <p><button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button></p>
41
+ <?php else: ?>
42
+ <p class="availability out-of-stock"><span><?php echo $this->__('Out of stock') ?></span></p>
43
+ <?php endif; ?>
44
+ <div class="desc std">
45
+ <?php echo $_helper->productAttribute($_product, $_product->getShortDescription(), 'short_description') ?>
46
+ <a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $_productNameStripped ?>" class="link-learn"><?php echo $this->__('Learn More') ?></a>
47
+ </div>
48
+ <ul class="add-to-links">
49
+ <?php if ($this->helper('wishlist')->isAllow()) : ?>
50
+ <li><a href="<?php echo $this->helper('wishlist')->getAddUrl($_product) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
51
+ <?php endif; ?>
52
+ <?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
53
+ <li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?>" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
54
+ <?php endif; ?>
55
+ </ul>
56
+ </div>
57
+ </div>
58
+ </li>
59
+ <?php endforeach; ?>
60
+ </ol>
61
+ <script type="text/javascript">decorateList('products-list', 'none-recursive')</script>
62
+
63
+ <?php else: ?>
64
+
65
+ <?php // Grid Mode ?>
66
+
67
+ <?php $_collectionSize = $_productCollection->count() ?>
68
+ <?php $_columnCount = $this->getColumnCount(); ?>
69
+ <?php $i=0; foreach ($_productCollection as $_product): ?>
70
+ <?php if ($i++%$_columnCount==0): ?>
71
+ <ul class="products-grid">
72
+ <?php endif ?>
73
+ <li class="item<?php if(($i-1)%$_columnCount==0): ?> first<?php elseif($i%$_columnCount==0): ?> last<?php endif; ?>">
74
+ <a class="try" href="#" rel="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail')->resize(135); ?>">Try this</a>
75
+ <a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" class="product-image"><img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(135); ?>" width="135" height="135" alt="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" /></a>
76
+ <h2 class="product-name"><a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($_product->getName(), null, true) ?>"><?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?></a></h2>
77
+
78
+ <?php if($_product->getRatingSummary()): ?>
79
+ <?php echo $this->getReviewsSummaryHtml($_product, 'short') ?>
80
+ <?php endif; ?>
81
+ <?php echo $this->getPriceHtml($_product, true) ?>
82
+ <div class="actions">
83
+ <?php if($_product->isSaleable()): ?>
84
+ <button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
85
+ <?php else: ?>
86
+ <p class="availability out-of-stock"><span><?php echo $this->__('Out of stock') ?></span></p>
87
+ <?php endif; ?>
88
+ <ul class="add-to-links">
89
+ <?php if ($this->helper('wishlist')->isAllow()) : ?>
90
+ <li><a href="<?php echo $this->helper('wishlist')->getAddUrl($_product) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
91
+ <?php endif; ?>
92
+ <?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
93
+ <li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?>" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
94
+ <?php endif; ?>
95
+ </ul>
96
+ </div>
97
+ </li>
98
+ <?php if ($i%$_columnCount==0 || $i==$_collectionSize): ?>
99
+ </ul>
100
+ <?php endif ?>
101
+ <?php endforeach ?>
102
+ <script type="text/javascript">decorateGeneric($$('ul.products-grid'), ['odd','even','first','last'])</script>
103
+ <?php endif; ?>
104
+
105
+ <div class="toolbar-bottom">
106
+ <?php echo $this->getToolbarHtml() ?>
107
+ </div>
108
+ </div>
109
+ <?php endif; ?>
app/design/frontend/default/default/template/tryon/list.phtml~ ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ *tryon extension by daffodil
4
+ */
5
+ ?>
6
+ <?php
7
+ /**
8
+ * Product list template
9
+ *
10
+ * @see Mage_Catalog_Block_Product_List
11
+ */
12
+ ?>
13
+ <?php
14
+ $_productCollection=$this->getLoadedProductCollection();
15
+ $_helper = $this->helper('catalog/output');
16
+ ?>
17
+ <?php if(!$_productCollection->count()): ?>
18
+ <p class="note-msg"><?php echo $this->__('There are no products matching the selection.') ?></p>
19
+ <?php else: ?>
20
+ <div class="category-products">
21
+ <?php echo $this->getToolbarHtml() ?>
22
+ <?php // List mode ?>
23
+ <?php if($this->getMode()!='grid'): ?>
24
+ <?php $_iterator = 0; ?>
25
+ <ol class="products-list" id="products-list">
26
+ <?php foreach ($_productCollection as $_product): ?>
27
+ <li class="item<?php if( ++$_iterator == sizeof($_productCollection) ): ?> last<?php endif; ?>">
28
+ <?php // Product Image ?>
29
+ <a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" class="product-image"><img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(135); ?>" width="135" height="135" alt="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" /></a>
30
+ <?php // Product description ?>
31
+ <div class="product-shop">
32
+ <div class="f-fix">
33
+ <?php $_productNameStripped = $this->stripTags($_product->getName(), null, true); ?>
34
+ <h2 class="product-name"><a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $_productNameStripped; ?>"><?php echo $_helper->productAttribute($_product, $_product->getName() , 'name'); ?></a></h2>
35
+ <?php if($_product->getRatingSummary()): ?>
36
+ <?php echo $this->getReviewsSummaryHtml($_product) ?>
37
+ <?php endif; ?>
38
+ <?php echo $this->getPriceHtml($_product, true) ?>
39
+ <?php if($_product->isSaleable()): ?>
40
+ <p><button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button></p>
41
+ <?php else: ?>
42
+ <p class="availability out-of-stock"><span><?php echo $this->__('Out of stock') ?></span></p>
43
+ <?php endif; ?>
44
+ <div class="desc std">
45
+ <?php echo $_helper->productAttribute($_product, $_product->getShortDescription(), 'short_description') ?>
46
+ <a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $_productNameStripped ?>" class="link-learn"><?php echo $this->__('Learn More') ?></a>
47
+ </div>
48
+ <ul class="add-to-links">
49
+ <?php if ($this->helper('wishlist')->isAllow()) : ?>
50
+ <li><a href="<?php echo $this->helper('wishlist')->getAddUrl($_product) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
51
+ <?php endif; ?>
52
+ <?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
53
+ <li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?>" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
54
+ <?php endif; ?>
55
+ </ul>
56
+ </div>
57
+ </div>
58
+ </li>
59
+ <?php endforeach; ?>
60
+ </ol>
61
+ <script type="text/javascript">decorateList('products-list', 'none-recursive')</script>
62
+
63
+ <?php else: ?>
64
+
65
+ <?php // Grid Mode ?>
66
+
67
+ <?php $_collectionSize = $_productCollection->count() ?>
68
+ <?php $_columnCount = $this->getColumnCount(); ?>
69
+ <?php $i=0; foreach ($_productCollection as $_product): ?>
70
+ <?php if ($i++%$_columnCount==0): ?>
71
+ <ul class="products-grid">
72
+ <?php endif ?>
73
+ <li class="item<?php if(($i-1)%$_columnCount==0): ?> first<?php elseif($i%$_columnCount==0): ?> last<?php endif; ?>">
74
+ <a class="try" href="#" rel="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail')->resize(135); ?>">Try this</a>
75
+ <a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" class="product-image"><img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(135); ?>" width="135" height="135" alt="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" /></a>
76
+ <h2 class="product-name"><a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($_product->getName(), null, true) ?>"><?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?></a></h2>
77
+
78
+ <?php if($_product->getRatingSummary()): ?>
79
+ <?php echo $this->getReviewsSummaryHtml($_product, 'short') ?>
80
+ <?php endif; ?>
81
+ <?php echo $this->getPriceHtml($_product, true) ?>
82
+ <div class="actions">
83
+ <?php if($_product->isSaleable()): ?>
84
+ <button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
85
+ <?php else: ?>
86
+ <p class="availability out-of-stock"><span><?php echo $this->__('Out of stock') ?></span></p>
87
+ <?php endif; ?>
88
+ <ul class="add-to-links">
89
+ <?php if ($this->helper('wishlist')->isAllow()) : ?>
90
+ <li><a href="<?php echo $this->helper('wishlist')->getAddUrl($_product) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
91
+ <?php endif; ?>
92
+ <?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
93
+ <li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?>" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
94
+ <?php endif; ?>
95
+ </ul>
96
+ </div>
97
+ </li>
98
+ <?php if ($i%$_columnCount==0 || $i==$_collectionSize): ?>
99
+ </ul>
100
+ <?php endif ?>
101
+ <?php endforeach ?>
102
+ <script type="text/javascript">decorateGeneric($$('ul.products-grid'), ['odd','even','first','last'])</script>
103
+ <?php endif; ?>
104
+
105
+ <div class="toolbar-bottom">
106
+ <?php echo $this->getToolbarHtml() ?>
107
+ </div>
108
+ </div>
109
+ <?php endif; ?>
app/design/frontend/default/default/template/tryon/rightsection.phtml ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script>
2
+ jQuery(function() {
3
+
4
+ <!--jQuery('.firstdiv').stickyfloat({ duration: 100 }); -->
5
+ jQuery( "#draggable" ).draggable();
6
+ jQuery('a.try').click(function() {
7
+ jQuery('#draggable').hide();
8
+ var firstele= jQuery(this).attr("rel");
9
+ jQuery('.second img').attr("src", firstele);
10
+ // jQuery('.second img').attr("width","121px");
11
+ //jQuery('.second img').attr("height","120px");
12
+ jQuery('#draggable').fadeIn(800);
13
+ jQuery('.remove-option').show();
14
+ var p = jQuery(".second");
15
+ var position = p.position();
16
+ var one = position.top;
17
+ return false;
18
+ });
19
+
20
+ jQuery('.thumb img').click(function() {
21
+ var thumbImage = jQuery(this).attr("src");
22
+ jQuery('.bigimage').attr("src", thumbImage);
23
+ jQuery('.thumb').slideUp(200);
24
+ jQuery('.remove-model').hide();
25
+
26
+ });
27
+
28
+ jQuery('.pic').click(function() {
29
+ jQuery('.thumb').slideDown(500);
30
+ jQuery('#my-list').hoverscroll({ });
31
+ jQuery('.remove-model').show();
32
+
33
+ });
34
+ jQuery('.remove-model').click(function(){
35
+ jQuery('.thumb').hide();
36
+ jQuery('.remove-model').hide();
37
+ });
38
+ jQuery('.remove-option').click(function(){
39
+ jQuery('#draggable').hide();
40
+ jQuery('.remove-option').hide();
41
+ });
42
+ });
43
+ </script>
44
+
45
+ <?php $baseImage = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);?>
46
+ <script type="text/javascript" >
47
+ jQuery(function(){
48
+ var btnUpload=jQuery('#upload');
49
+ var status=jQuery('#status');
50
+ new AjaxUpload(btnUpload, {
51
+ action: '<?php echo $baseImage ?>tryon/index/index',
52
+ name: 'uploadfile',
53
+ onSubmit: function(file, ext){
54
+ if (! (ext && /^(jpg|png|jpeg|gif)$/.test(ext))){
55
+ // extension is not allowed
56
+ alert('Only JPG, PNG or GIF files are allowed');
57
+ return false;
58
+ }
59
+ jQuery(".ajaxloader").show();
60
+ if(jQuery('#draggable').is(':visible')) {
61
+ jQuery('#draggable').hide();
62
+ jQuery('.remove-option').hide();
63
+ } else {
64
+
65
+ }
66
+ },
67
+ onComplete: function(file, response){
68
+
69
+ var newContent = response;
70
+ //alert(newContent);
71
+ var firstCont = newContent.split(",");
72
+ var eyex = parseInt(firstCont[0]);
73
+ var eyey = parseInt(firstCont[1]);
74
+
75
+ if(isNaN(eyex)) {
76
+ //alert('blank');
77
+ alert('Image Not Supported');
78
+ jQuery('#draggable').hide();
79
+ //jQuery('.textdisplay').show();
80
+ jQuery(".ajaxloader").hide();
81
+ jQuery(".ajaxloader").hide();
82
+ jQuery('.remove-option').hide();
83
+
84
+
85
+ } else {
86
+ //jQuery('.textdisplay').hide();
87
+
88
+ //alert('has');
89
+
90
+ var neweyex = eyex - 50;
91
+ var neweyey = eyey - 37;
92
+ jQuery("#draggable").css("left", neweyey );
93
+ jQuery("#draggable").css("top", neweyex);
94
+ jQuery(".ajaxloader").hide();
95
+ if(jQuery('#draggable').is(':visible')) {
96
+ } else {
97
+ jQuery('#draggable').show();
98
+ jQuery('.remove-option').show();
99
+ }
100
+
101
+ }
102
+ var uploadimage = '<?php echo $baseImage ?>media/uploads/'+file;
103
+ //alert(uploadimage);
104
+ jQuery(".bigimage").attr("src", uploadimage);
105
+ //On completion clear the status
106
+ status.text('');
107
+ //Add uploaded file to list
108
+ if(response==="success"){
109
+
110
+ //alert("success")
111
+ //jQuery('<li></li>').appendTo('#files').html('<img src="http://localhost:8080/magento/testmagento/media/uploads/'+file+'" alt="" /><br />'+file).addClass('success');
112
+ } else{
113
+ //jQuery('<li></li>').appendTo('#files').text(file).addClass('error');
114
+ }
115
+ }
116
+ });
117
+
118
+ });
119
+ </script>
120
+ <div class="try-this-right-setting">
121
+ <h4>Check this out</h4>
122
+ <div class="firstdiv" >
123
+ <div class="second ui-widget-content" id="draggable">
124
+ <img src=" " width="120" height="121" border="0" alt="">
125
+ </div>
126
+ <div class="ajaxloader" >
127
+ <img src="<?php echo $this->getSkinUrl('images/ajax-loader.gif') ?>" alt="">
128
+ </div>
129
+ <div class="textdisplay">
130
+ <span>Image Not Supported</span>
131
+ </div>
132
+ <img id="imgselect" src="<?php echo $this->getSkinUrl('images/model2.jpg') ?>" class="bigimage"/>
133
+ </div>
134
+ <?php $baseImage = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
135
+ ?>
136
+ <div class="maincontainer" >
137
+ <div class="thumb" >
138
+ <div class="undersec" >
139
+ <ul id="my-list">
140
+ <?php
141
+ $newPath = $baseImage."/media/modelphotos/";
142
+ if ($handle = opendir('media/modelphotos/')) {
143
+ while (false !== ($file = readdir($handle)))
144
+ {
145
+ if ($file != "." && $file != "..")
146
+ { ?>
147
+ <li><img src="<?php echo $newPath.$file ?>" width="35" height="35" /></li>
148
+
149
+ <?php }
150
+ }
151
+ closedir($handle);
152
+ //echo $thelist;
153
+ }
154
+ ?>
155
+ </ul>
156
+ </div>
157
+ </div>
158
+
159
+ <div id="mainbody" >
160
+ <!-- Upload Button, use any id you wish-->
161
+ <div id="upload" style="cursor:pointer">
162
+ <span>Upload image</span>
163
+ </div>
164
+ <span id="status" ></span>
165
+ <ul id="files" ></ul>
166
+ </div>
167
+ <div class="pic">Select Model</div>
168
+ <div class="remove-model" style="display:none">
169
+ <img src="<?php echo $this->getSkinUrl('images/cross.png') ?>" title="Click here to remove modules"/>
170
+ </div>
171
+ </div>
172
+ <div class="remove-option" style="display:none">
173
+ <img src="<?php echo $this->getSkinUrl('images/cross.png') ?>" title="Click here to Remove Spects"/>
174
+ </div>
175
+ </div>
176
+ <script type="text/javascript">
177
+
178
+ jQuery(function() {
179
+ jQuery('#my-list li img').click(function() {
180
+ var dataString = jQuery(this).attr("src");
181
+ jQuery.ajax({ url: '<?php echo $baseImage ?>face/index/index',
182
+ type: 'post',
183
+ data: { 'dataString': dataString },
184
+ success: function(output) {
185
+ var description = output;
186
+ //alert(description);
187
+ var desbreak = description.split(",");
188
+ var deseyex = parseInt(desbreak[1]);
189
+ var deseyey = parseInt(desbreak[2]);
190
+ if(isNaN(deseyex)) {
191
+ //alert('blank');
192
+ alert('Image Not Supported');
193
+ //jQuery('.textdisplay').show();
194
+ jQuery('#draggable').hide();
195
+ jQuery(".ajaxloader").hide();
196
+ jQuery('.remove-option').hide();
197
+
198
+
199
+ } else {
200
+ //jQuery('.textdisplay').hide();
201
+
202
+ //alert('has');
203
+
204
+
205
+ var modeyex = deseyex - 50;
206
+ var modeyey = deseyey - 37;
207
+ jQuery("#draggable").css("left", modeyey );
208
+ jQuery("#draggable").css("top", modeyex);
209
+ jQuery(".ajaxloader").hide();
210
+ //jQuery('#draggable').fadeIn(600);
211
+ if(jQuery('#draggable').is(':visible')) {
212
+ } else {
213
+ jQuery('#draggable').show();
214
+ jQuery('.remove-option').show();
215
+ } }
216
+ //alert(deseyex);
217
+ //alert(deseyey);
218
+ },
219
+
220
+ beforeSend: function() {
221
+ jQuery(".ajaxloader").show();
222
+ if(jQuery('#draggable').is(':visible')) {
223
+ jQuery('#draggable').hide();
224
+ jQuery('.remove-option').hide();
225
+ } else {
226
+
227
+ }
228
+
229
+ }
230
+ })
231
+ });
232
+
233
+ });
234
+
235
+
236
+ </script>
app/design/frontend/default/default/template/tryon/rightsection.phtml~ ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script>
2
+ jQuery(function() {
3
+
4
+ <!--jQuery('.firstdiv').stickyfloat({ duration: 100 }); -->
5
+ jQuery( "#draggable" ).draggable();
6
+ jQuery('a.try').click(function() {
7
+ jQuery('#draggable').hide();
8
+ var firstele= jQuery(this).attr("rel");
9
+ jQuery('.second img').attr("src", firstele);
10
+ // jQuery('.second img').attr("width","121px");
11
+ //jQuery('.second img').attr("height","120px");
12
+ jQuery('#draggable').fadeIn(800);
13
+ jQuery('.remove-option').show();
14
+ var p = jQuery(".second");
15
+ var position = p.position();
16
+ var one = position.top;
17
+ return false;
18
+ });
19
+
20
+ jQuery('.thumb img').click(function() {
21
+ var thumbImage = jQuery(this).attr("src");
22
+ jQuery('.bigimage').attr("src", thumbImage);
23
+ jQuery('.thumb').slideUp(200);
24
+ jQuery('.remove-model').hide();
25
+
26
+ });
27
+
28
+ jQuery('.pic').click(function() {
29
+ jQuery('.thumb').slideDown(500);
30
+ jQuery('#my-list').hoverscroll({ });
31
+ jQuery('.remove-model').show();
32
+
33
+ });
34
+ jQuery('.remove-model').click(function(){
35
+ jQuery('.thumb').hide();
36
+ jQuery('.remove-model').hide();
37
+ });
38
+ jQuery('.remove-option').click(function(){
39
+ jQuery('#draggable').hide();
40
+ jQuery('.remove-option').hide();
41
+ });
42
+ });
43
+ </script>
44
+
45
+ <?php $baseImage = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);?>
46
+ <script type="text/javascript" >
47
+ jQuery(function(){
48
+ var btnUpload=jQuery('#upload');
49
+ var status=jQuery('#status');
50
+ new AjaxUpload(btnUpload, {
51
+ action: '<?php echo $baseImage ?>tryon/index/index',
52
+ name: 'uploadfile',
53
+ onSubmit: function(file, ext){
54
+ if (! (ext && /^(jpg|png|jpeg|gif)$/.test(ext))){
55
+ // extension is not allowed
56
+ status.text('Only JPG, PNG or GIF files are allowed');
57
+ return false;
58
+ }
59
+ jQuery(".ajaxloader").show();
60
+ if(jQuery('#draggable').is(':visible')) {
61
+ jQuery('#draggable').hide();
62
+ jQuery('.remove-option').hide();
63
+ } else {
64
+
65
+ }
66
+ },
67
+ onComplete: function(file, response){
68
+
69
+ var newContent = response;
70
+ //alert(newContent);
71
+ var firstCont = newContent.split(",");
72
+ var eyex = parseInt(firstCont[0]);
73
+ var eyey = parseInt(firstCont[1]);
74
+
75
+ if(isNaN(eyex)) {
76
+ //alert('blank');
77
+ alert('Image Not Supported');
78
+ jQuery('#draggable').hide();
79
+ //jQuery('.textdisplay').show();
80
+ jQuery(".ajaxloader").hide();
81
+ jQuery(".ajaxloader").hide();
82
+ jQuery('.remove-option').hide();
83
+
84
+
85
+ } else {
86
+ //jQuery('.textdisplay').hide();
87
+
88
+ //alert('has');
89
+
90
+ var neweyex = eyex - 50;
91
+ var neweyey = eyey - 37;
92
+ jQuery("#draggable").css("left", neweyey );
93
+ jQuery("#draggable").css("top", neweyex);
94
+ jQuery(".ajaxloader").hide();
95
+ if(jQuery('#draggable').is(':visible')) {
96
+ } else {
97
+ jQuery('#draggable').show();
98
+ jQuery('.remove-option').show();
99
+ }
100
+
101
+ }
102
+ var uploadimage = '<?php echo $baseImage ?>media/uploads/'+file;
103
+ //alert(uploadimage);
104
+ jQuery(".bigimage").attr("src", uploadimage);
105
+ //On completion clear the status
106
+ status.text('');
107
+ //Add uploaded file to list
108
+ if(response==="success"){
109
+
110
+ //alert("success")
111
+ //jQuery('<li></li>').appendTo('#files').html('<img src="http://localhost:8080/magento/testmagento/media/uploads/'+file+'" alt="" /><br />'+file).addClass('success');
112
+ } else{
113
+ //jQuery('<li></li>').appendTo('#files').text(file).addClass('error');
114
+ }
115
+ }
116
+ });
117
+
118
+ });
119
+ </script>
120
+ <div class="try-this-right-setting">
121
+ <h4>Check this out</h4>
122
+ <div class="firstdiv" >
123
+ <div class="second ui-widget-content" id="draggable">
124
+ <img src=" " width="120" height="121" border="0" alt="">
125
+ </div>
126
+ <div class="ajaxloader" >
127
+ <img src="<?php echo $this->getSkinUrl('images/ajax-loader.gif') ?>" alt="">
128
+ </div>
129
+ <div class="textdisplay">
130
+ <span>Image Not Supported</span>
131
+ </div>
132
+ <img id="imgselect" src="<?php echo $this->getSkinUrl('images/model2.jpg') ?>" class="bigimage"/>
133
+ </div>
134
+ <?php $baseImage = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
135
+ ?>
136
+ <div class="maincontainer" >
137
+ <div class="thumb" >
138
+ <div class="undersec" >
139
+ <ul id="my-list">
140
+ <?php
141
+ $newPath = $baseImage."/media/modelphotos/";
142
+ if ($handle = opendir('media/modelphotos/')) {
143
+ while (false !== ($file = readdir($handle)))
144
+ {
145
+ if ($file != "." && $file != "..")
146
+ { ?>
147
+ <li><img src="<?php echo $newPath.$file ?>" width="35" height="35" /></li>
148
+
149
+ <?php }
150
+ }
151
+ closedir($handle);
152
+ //echo $thelist;
153
+ }
154
+ ?>
155
+ </ul>
156
+ </div>
157
+ </div>
158
+
159
+ <div id="mainbody" >
160
+ <!-- Upload Button, use any id you wish-->
161
+ <div id="upload" style="cursor:pointer">
162
+ <span>Upload image</span>
163
+ </div>
164
+ <span id="status" ></span>
165
+ <ul id="files" ></ul>
166
+ </div>
167
+ <div class="pic">Select Model</div>
168
+ <div class="remove-model" style="display:none">
169
+ <img src="<?php echo $this->getSkinUrl('images/cross.png') ?>" title="Click here to remove modules"/>
170
+ </div>
171
+ </div>
172
+ <div class="remove-option" style="display:none">
173
+ <img src="<?php echo $this->getSkinUrl('images/cross.png') ?>" title="Click here to Remove Spects"/>
174
+ </div>
175
+ </div>
176
+ <script type="text/javascript">
177
+
178
+ jQuery(function() {
179
+ jQuery('#my-list li img').click(function() {
180
+ var dataString = jQuery(this).attr("src");
181
+ jQuery.ajax({ url: '<?php echo $baseImage ?>face/index/index',
182
+ type: 'post',
183
+ data: { 'dataString': dataString },
184
+ success: function(output) {
185
+ var description = output;
186
+ //alert(description);
187
+ var desbreak = description.split(",");
188
+ var deseyex = parseInt(desbreak[1]);
189
+ var deseyey = parseInt(desbreak[2]);
190
+ if(isNaN(deseyex)) {
191
+ //alert('blank');
192
+ alert('Image Not Supported');
193
+ //jQuery('.textdisplay').show();
194
+ jQuery('#draggable').hide();
195
+ jQuery(".ajaxloader").hide();
196
+ jQuery('.remove-option').hide();
197
+
198
+
199
+ } else {
200
+ //jQuery('.textdisplay').hide();
201
+
202
+ //alert('has');
203
+
204
+
205
+ var modeyex = deseyex - 50;
206
+ var modeyey = deseyey - 37;
207
+ jQuery("#draggable").css("left", modeyey );
208
+ jQuery("#draggable").css("top", modeyex);
209
+ jQuery(".ajaxloader").hide();
210
+ //jQuery('#draggable').fadeIn(600);
211
+ if(jQuery('#draggable').is(':visible')) {
212
+ } else {
213
+ jQuery('#draggable').show();
214
+ jQuery('.remove-option').show();
215
+ } }
216
+ //alert(deseyex);
217
+ //alert(deseyey);
218
+ },
219
+
220
+ beforeSend: function() {
221
+ jQuery(".ajaxloader").show();
222
+ if(jQuery('#draggable').is(':visible')) {
223
+ jQuery('#draggable').hide();
224
+ jQuery('.remove-option').hide();
225
+ } else {
226
+
227
+ }
228
+
229
+ }
230
+ })
231
+ });
232
+
233
+ });
234
+
235
+
236
+ </script>
app/design/frontend/default/default/template/tryon/view.phtml ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * tryon extension
4
+ */
5
+
6
+ ?>
7
+ <?php $_helper = $this->helper('catalog/output'); ?>
8
+ <?php $_product = $this->getProduct(); ?>
9
+ <script type="text/javascript">
10
+ var optionsPrice = new Product.OptionsPrice(<?php echo $this->getJsonConfig() ?>);
11
+ </script>
12
+ <div id="messages_product_view"><?php echo $this->getMessagesBlock()->getGroupedHtml() ?></div>
13
+ <div class="product-view">
14
+ <div class="product-essential">
15
+ <form action="<?php echo $this->getSubmitUrl($_product) ?>" method="post" id="product_addtocart_form"<?php if($_product->getOptions()): ?> enctype="multipart/form-data"<?php endif; ?>>
16
+ <div class="no-display">
17
+ <input type="hidden" name="product" value="<?php echo $_product->getId() ?>" />
18
+ <input type="hidden" name="related_product" id="related-products-field" value="" />
19
+ </div>
20
+
21
+ <div class="product-shop">
22
+ <div class="product-name">
23
+ <h1><?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?></h1>
24
+ </div>
25
+ <a class="try" href="#" rel="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail')->resize(135); ?>">Try this</a>
26
+ <?php if ($this->canEmailToFriend()): ?>
27
+ <p class="email-friend"><a href="<?php echo $this->helper('catalog/product')->getEmailToFriendUrl($_product) ?>"><?php echo $this->__('Email to a Friend') ?></a></p>
28
+ <?php endif; ?>
29
+
30
+ <?php echo $this->getReviewsSummaryHtml($_product, false, true)?>
31
+ <?php echo $this->getChildHtml('alert_urls') ?>
32
+ <?php echo $this->getChildHtml('product_type_data') ?>
33
+ <?php echo $this->getTierPriceHtml() ?>
34
+ <?php echo $this->getChildHtml('extrahint') ?>
35
+
36
+ <?php if (!$this->hasOptions()):?>
37
+ <div class="add-to-box">
38
+ <?php if($_product->isSaleable()): ?>
39
+ <?php echo $this->getChildHtml('addtocart') ?>
40
+ <?php if( $this->helper('wishlist')->isAllow() || $_compareUrl=$this->helper('catalog/product_compare')->getAddUrl($_product)): ?>
41
+ <span class="or"><?php echo $this->__('OR') ?></span>
42
+ <?php endif; ?>
43
+ <?php endif; ?>
44
+ <?php echo $this->getChildHtml('addto') ?>
45
+ </div>
46
+ <?php echo $this->getChildHtml('extra_buttons') ?>
47
+ <?php elseif (!$_product->isSaleable()): ?>
48
+ <div class="add-to-box">
49
+ <?php echo $this->getChildHtml('addto') ?>
50
+ </div>
51
+ <?php endif; ?>
52
+
53
+ <?php if ($_product->getShortDescription()):?>
54
+ <div class="short-description">
55
+ <h2><?php echo $this->__('Quick Overview') ?></h2>
56
+ <div class="std"><?php echo $_helper->productAttribute($_product, nl2br($_product->getShortDescription()), 'short_description') ?></div>
57
+ </div>
58
+ <?php endif;?>
59
+
60
+ <?php echo $this->getChildHtml('other');?>
61
+
62
+ <?php if ($_product->isSaleable() && $this->hasOptions()):?>
63
+ <?php echo $this->getChildChildHtml('container1', '', true, true) ?>
64
+ <?php endif;?>
65
+
66
+ </div>
67
+
68
+ <div class="product-img-box">
69
+ <?php echo $this->getChildHtml('media') ?>
70
+ </div>
71
+
72
+ <div class="clearer"></div>
73
+ <?php if ($_product->isSaleable() && $this->hasOptions()):?>
74
+ <?php echo $this->getChildChildHtml('container2', '', true, true) ?>
75
+ <?php endif;?>
76
+ </form>
77
+ <script type="text/javascript">
78
+ //<![CDATA[
79
+ var productAddToCartForm = new VarienForm('product_addtocart_form');
80
+ productAddToCartForm.submit = function(button, url) {
81
+ if (this.validator.validate()) {
82
+ var form = this.form;
83
+ var oldUrl = form.action;
84
+
85
+ if (url) {
86
+ form.action = url;
87
+ }
88
+ var e = null;
89
+ try {
90
+ this.form.submit();
91
+ } catch (e) {
92
+ }
93
+ this.form.action = oldUrl;
94
+ if (e) {
95
+ throw e;
96
+ }
97
+
98
+ if (button && button != 'undefined') {
99
+ button.disabled = true;
100
+ }
101
+ }
102
+ }.bind(productAddToCartForm);
103
+
104
+ productAddToCartForm.submitLight = function(button, url){
105
+ if(this.validator) {
106
+ var nv = Validation.methods;
107
+ delete Validation.methods['required-entry'];
108
+ delete Validation.methods['validate-one-required'];
109
+ delete Validation.methods['validate-one-required-by-name'];
110
+ // Remove custom datetime validators
111
+ for (var methodName in Validation.methods) {
112
+ if (methodName.match(/^validate-datetime-.*/i)) {
113
+ delete Validation.methods[methodName];
114
+ }
115
+ }
116
+
117
+ if (this.validator.validate()) {
118
+ if (url) {
119
+ this.form.action = url;
120
+ }
121
+ this.form.submit();
122
+ }
123
+ Object.extend(Validation.methods, nv);
124
+ }
125
+ }.bind(productAddToCartForm);
126
+ //]]>
127
+ </script>
128
+ </div>
129
+
130
+ <div class="product-collateral">
131
+ <?php foreach ($this->getChildGroup('detailed_info', 'getChildHtml') as $alias => $html):?>
132
+ <div class="box-collateral <?php echo "box-{$alias}"?>">
133
+ <?php if ($title = $this->getChildData($alias, 'title')):?>
134
+ <h2><?php echo $this->escapeHtml($title); ?></h2>
135
+ <?php endif;?>
136
+ <?php echo $html; ?>
137
+ </div>
138
+ <?php endforeach;?>
139
+ <?php echo $this->getChildHtml('upsell_products') ?>
140
+ <?php echo $this->getChildHtml('product_additional_data') ?>
141
+ </div>
142
+ </div>
app/design/frontend/default/default/template/tryon/view.phtml~ ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * tryon extension
4
+ */
5
+
6
+ ?>
7
+ <?php $_helper = $this->helper('catalog/output'); ?>
8
+ <?php $_product = $this->getProduct(); ?>
9
+ <script type="text/javascript">
10
+ var optionsPrice = new Product.OptionsPrice(<?php echo $this->getJsonConfig() ?>);
11
+ </script>
12
+ <div id="messages_product_view"><?php echo $this->getMessagesBlock()->getGroupedHtml() ?></div>
13
+ <div class="product-view">
14
+ <div class="product-essential">
15
+ <form action="<?php echo $this->getSubmitUrl($_product) ?>" method="post" id="product_addtocart_form"<?php if($_product->getOptions()): ?> enctype="multipart/form-data"<?php endif; ?>>
16
+ <div class="no-display">
17
+ <input type="hidden" name="product" value="<?php echo $_product->getId() ?>" />
18
+ <input type="hidden" name="related_product" id="related-products-field" value="" />
19
+ </div>
20
+
21
+ <div class="product-shop">
22
+ <div class="product-name">
23
+ <h1><?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?></h1>
24
+ </div>
25
+ <a class="try" href="#" rel="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail')->resize(135); ?>">Try this</a>
26
+ <?php if ($this->canEmailToFriend()): ?>
27
+ <p class="email-friend"><a href="<?php echo $this->helper('catalog/product')->getEmailToFriendUrl($_product) ?>"><?php echo $this->__('Email to a Friend') ?></a></p>
28
+ <?php endif; ?>
29
+
30
+ <?php echo $this->getReviewsSummaryHtml($_product, false, true)?>
31
+ <?php echo $this->getChildHtml('alert_urls') ?>
32
+ <?php echo $this->getChildHtml('product_type_data') ?>
33
+ <?php echo $this->getTierPriceHtml() ?>
34
+ <?php echo $this->getChildHtml('extrahint') ?>
35
+
36
+ <?php if (!$this->hasOptions()):?>
37
+ <div class="add-to-box">
38
+ <?php if($_product->isSaleable()): ?>
39
+ <?php echo $this->getChildHtml('addtocart') ?>
40
+ <?php if( $this->helper('wishlist')->isAllow() || $_compareUrl=$this->helper('catalog/product_compare')->getAddUrl($_product)): ?>
41
+ <span class="or"><?php echo $this->__('OR') ?></span>
42
+ <?php endif; ?>
43
+ <?php endif; ?>
44
+ <?php echo $this->getChildHtml('addto') ?>
45
+ </div>
46
+ <?php echo $this->getChildHtml('extra_buttons') ?>
47
+ <?php elseif (!$_product->isSaleable()): ?>
48
+ <div class="add-to-box">
49
+ <?php echo $this->getChildHtml('addto') ?>
50
+ </div>
51
+ <?php endif; ?>
52
+
53
+ <?php if ($_product->getShortDescription()):?>
54
+ <div class="short-description">
55
+ <h2><?php echo $this->__('Quick Overview') ?></h2>
56
+ <div class="std"><?php echo $_helper->productAttribute($_product, nl2br($_product->getShortDescription()), 'short_description') ?></div>
57
+ </div>
58
+ <?php endif;?>
59
+
60
+ <?php echo $this->getChildHtml('other');?>
61
+
62
+ <?php if ($_product->isSaleable() && $this->hasOptions()):?>
63
+ <?php echo $this->getChildChildHtml('container1', '', true, true) ?>
64
+ <?php endif;?>
65
+
66
+ </div>
67
+
68
+ <div class="product-img-box">
69
+ <?php echo $this->getChildHtml('media') ?>
70
+ </div>
71
+
72
+ <div class="clearer"></div>
73
+ <?php if ($_product->isSaleable() && $this->hasOptions()):?>
74
+ <?php echo $this->getChildChildHtml('container2', '', true, true) ?>
75
+ <?php endif;?>
76
+ </form>
77
+ <script type="text/javascript">
78
+ //<![CDATA[
79
+ var productAddToCartForm = new VarienForm('product_addtocart_form');
80
+ productAddToCartForm.submit = function(button, url) {
81
+ if (this.validator.validate()) {
82
+ var form = this.form;
83
+ var oldUrl = form.action;
84
+
85
+ if (url) {
86
+ form.action = url;
87
+ }
88
+ var e = null;
89
+ try {
90
+ this.form.submit();
91
+ } catch (e) {
92
+ }
93
+ this.form.action = oldUrl;
94
+ if (e) {
95
+ throw e;
96
+ }
97
+
98
+ if (button && button != 'undefined') {
99
+ button.disabled = true;
100
+ }
101
+ }
102
+ }.bind(productAddToCartForm);
103
+
104
+ productAddToCartForm.submitLight = function(button, url){
105
+ if(this.validator) {
106
+ var nv = Validation.methods;
107
+ delete Validation.methods['required-entry'];
108
+ delete Validation.methods['validate-one-required'];
109
+ delete Validation.methods['validate-one-required-by-name'];
110
+ // Remove custom datetime validators
111
+ for (var methodName in Validation.methods) {
112
+ if (methodName.match(/^validate-datetime-.*/i)) {
113
+ delete Validation.methods[methodName];
114
+ }
115
+ }
116
+
117
+ if (this.validator.validate()) {
118
+ if (url) {
119
+ this.form.action = url;
120
+ }
121
+ this.form.submit();
122
+ }
123
+ Object.extend(Validation.methods, nv);
124
+ }
125
+ }.bind(productAddToCartForm);
126
+ //]]>
127
+ </script>
128
+ </div>
129
+
130
+ <div class="product-collateral">
131
+ <?php foreach ($this->getChildGroup('detailed_info', 'getChildHtml') as $alias => $html):?>
132
+ <div class="box-collateral <?php echo "box-{$alias}"?>">
133
+ <?php if ($title = $this->getChildData($alias, 'title')):?>
134
+ <h2><?php echo $this->escapeHtml($title); ?></h2>
135
+ <?php endif;?>
136
+ <?php echo $html; ?>
137
+ </div>
138
+ <?php endforeach;?>
139
+ <?php echo $this->getChildHtml('upsell_products') ?>
140
+ <?php echo $this->getChildHtml('product_additional_data') ?>
141
+ </div>
142
+ </div>
app/etc/modules/Ajax_Face.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Ajax_Face>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ </Ajax_Face>
8
+ </modules>
9
+ </config>
app/etc/modules/Daffodil_Tryon.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Tryon_Avatar>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ </Tryon_Avatar>
8
+ </modules>
9
+ </config>
js/tryon/ajaxupload.3.5.js ADDED
@@ -0,0 +1,546 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Ajax upload
3
+ * Project page - http://valums.com/ajax-upload/
4
+ * Copyright (c) 2008 Andris Valums, http://valums.com
5
+ * Licensed under the MIT license (http://valums.com/mit-license/)
6
+ * Version 3.5 (23.06.2009)
7
+ */
8
+
9
+ /**
10
+ * Changes from the previous version:
11
+ * 1. Added better JSON handling that allows to use 'application/javascript' as a response
12
+ * 2. Added demo for usage with jQuery UI dialog
13
+ * 3. Fixed IE "mixed content" issue when used with secure connections
14
+ *
15
+ * For the full changelog please visit:
16
+ * http://valums.com/ajax-upload-changelog/
17
+ */
18
+
19
+ (function(){
20
+
21
+ var d = document, w = window;
22
+
23
+ /**
24
+ * Get element by id
25
+ */
26
+ function get(element){
27
+ if (typeof element == "string")
28
+ element = d.getElementById(element);
29
+ return element;
30
+ }
31
+
32
+ /**
33
+ * Attaches event to a dom element
34
+ */
35
+ function addEvent(el, type, fn){
36
+ if (w.addEventListener){
37
+ el.addEventListener(type, fn, false);
38
+ } else if (w.attachEvent){
39
+ var f = function(){
40
+ fn.call(el, w.event);
41
+ };
42
+ el.attachEvent('on' + type, f)
43
+ }
44
+ }
45
+
46
+
47
+ /**
48
+ * Creates and returns element from html chunk
49
+ */
50
+ var toElement = function(){
51
+ var div = d.createElement('div');
52
+ return function(html){
53
+ div.innerHTML = html;
54
+ var el = div.childNodes[0];
55
+ div.removeChild(el);
56
+ return el;
57
+ }
58
+ }();
59
+
60
+ function hasClass(ele,cls){
61
+ return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
62
+ }
63
+ function addClass(ele,cls) {
64
+ if (!hasClass(ele,cls)) ele.className += " "+cls;
65
+ }
66
+ function removeClass(ele,cls) {
67
+ var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
68
+ ele.className=ele.className.replace(reg,' ');
69
+ }
70
+
71
+ // getOffset function copied from jQuery lib (http://jquery.com/)
72
+ if (document.documentElement["getBoundingClientRect"]){
73
+ // Get Offset using getBoundingClientRect
74
+ // http://ejohn.org/blog/getboundingclientrect-is-awesome/
75
+ var getOffset = function(el){
76
+ var box = el.getBoundingClientRect(),
77
+ doc = el.ownerDocument,
78
+ body = doc.body,
79
+ docElem = doc.documentElement,
80
+
81
+ // for ie
82
+ clientTop = docElem.clientTop || body.clientTop || 0,
83
+ clientLeft = docElem.clientLeft || body.clientLeft || 0,
84
+
85
+ // In Internet Explorer 7 getBoundingClientRect property is treated as physical,
86
+ // while others are logical. Make all logical, like in IE8.
87
+
88
+
89
+ zoom = 1;
90
+ if (body.getBoundingClientRect) {
91
+ var bound = body.getBoundingClientRect();
92
+ zoom = (bound.right - bound.left)/body.clientWidth;
93
+ }
94
+ if (zoom > 1){
95
+ clientTop = 0;
96
+ clientLeft = 0;
97
+ }
98
+ var top = box.top/zoom + (window.pageYOffset || docElem && docElem.scrollTop/zoom || body.scrollTop/zoom) - clientTop,
99
+ left = box.left/zoom + (window.pageXOffset|| docElem && docElem.scrollLeft/zoom || body.scrollLeft/zoom) - clientLeft;
100
+
101
+ return {
102
+ top: top,
103
+ left: left
104
+ };
105
+ }
106
+
107
+ } else {
108
+ // Get offset adding all offsets
109
+ var getOffset = function(el){
110
+ if (w.jQuery){
111
+ return jQuery(el).offset();
112
+ }
113
+
114
+ var top = 0, left = 0;
115
+ do {
116
+ top += el.offsetTop || 0;
117
+ left += el.offsetLeft || 0;
118
+ }
119
+ while (el = el.offsetParent);
120
+
121
+ return {
122
+ left: left,
123
+ top: top
124
+ };
125
+ }
126
+ }
127
+
128
+ function getBox(el){
129
+ var left, right, top, bottom;
130
+ var offset = getOffset(el);
131
+ left = offset.left;
132
+ top = offset.top;
133
+
134
+ right = left + el.offsetWidth;
135
+ bottom = top + el.offsetHeight;
136
+
137
+ return {
138
+ left: left,
139
+ right: right,
140
+ top: top,
141
+ bottom: bottom
142
+ };
143
+ }
144
+
145
+ /**
146
+ * Crossbrowser mouse coordinates
147
+ */
148
+ function getMouseCoords(e){
149
+ // pageX/Y is not supported in IE
150
+ // http://www.quirksmode.org/dom/w3c_cssom.html
151
+ if (!e.pageX && e.clientX){
152
+ // In Internet Explorer 7 some properties (mouse coordinates) are treated as physical,
153
+ // while others are logical (offset).
154
+ var zoom = 1;
155
+ var body = document.body;
156
+
157
+ if (body.getBoundingClientRect) {
158
+ var bound = body.getBoundingClientRect();
159
+ zoom = (bound.right - bound.left)/body.clientWidth;
160
+ }
161
+
162
+ return {
163
+ x: e.clientX / zoom + d.body.scrollLeft + d.documentElement.scrollLeft,
164
+ y: e.clientY / zoom + d.body.scrollTop + d.documentElement.scrollTop
165
+ };
166
+ }
167
+
168
+ return {
169
+ x: e.pageX,
170
+ y: e.pageY
171
+ };
172
+
173
+ }
174
+ /**
175
+ * Function generates unique id
176
+ */
177
+ var getUID = function(){
178
+ var id = 0;
179
+ return function(){
180
+ return 'ValumsAjaxUpload' + id++;
181
+ }
182
+ }();
183
+
184
+ function fileFromPath(file){
185
+ return file.replace(/.*(\/|\\)/, "");
186
+ }
187
+
188
+ function getExt(file){
189
+ return (/[.]/.exec(file)) ? /[^.]+$/.exec(file.toLowerCase()) : '';
190
+ }
191
+
192
+ // Please use AjaxUpload , Ajax_upload will be removed in the next version
193
+ Ajax_upload = AjaxUpload = function(button, options){
194
+ if (button.jquery){
195
+ // jquery object was passed
196
+ button = button[0];
197
+ } else if (typeof button == "string" && /^#.*/.test(button)){
198
+ button = button.slice(1);
199
+ }
200
+ button = get(button);
201
+
202
+ this._input = null;
203
+ this._button = button;
204
+ this._disabled = false;
205
+ this._submitting = false;
206
+ // Variable changes to true if the button was clicked
207
+ // 3 seconds ago (requred to fix Safari on Mac error)
208
+ this._justClicked = false;
209
+ this._parentDialog = d.body;
210
+
211
+ if (window.jQuery && jQuery.ui && jQuery.ui.dialog){
212
+ var parentDialog = jQuery(this._button).parents('.ui-dialog');
213
+ if (parentDialog.length){
214
+ this._parentDialog = parentDialog[0];
215
+ }
216
+ }
217
+
218
+ this._settings = {
219
+ // Location of the server-side upload script
220
+ action: 'upload.php',
221
+ // File upload name
222
+ name: 'userfile',
223
+ // Additional data to send
224
+ data: {},
225
+ // Submit file as soon as it's selected
226
+ autoSubmit: true,
227
+ // The type of data that you're expecting back from the server.
228
+ // Html and xml are detected automatically.
229
+ // Only useful when you are using json data as a response.
230
+ // Set to "json" in that case.
231
+ responseType: false,
232
+ // When user selects a file, useful with autoSubmit disabled
233
+ onChange: function(file, extension){},
234
+ // Callback to fire before file is uploaded
235
+ // You can return false to cancel upload
236
+ onSubmit: function(file, extension){},
237
+ // Fired when file upload is completed
238
+ // WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!
239
+ onComplete: function(file, response) {}
240
+ };
241
+
242
+ // Merge the users options with our defaults
243
+ for (var i in options) {
244
+ this._settings[i] = options[i];
245
+ }
246
+
247
+ this._createInput();
248
+ this._rerouteClicks();
249
+ }
250
+
251
+ // assigning methods to our class
252
+ AjaxUpload.prototype = {
253
+ setData : function(data){
254
+ this._settings.data = data;
255
+ },
256
+ disable : function(){
257
+ this._disabled = true;
258
+ },
259
+ enable : function(){
260
+ this._disabled = false;
261
+ },
262
+ // removes ajaxupload
263
+ destroy : function(){
264
+ if(this._input){
265
+ if(this._input.parentNode){
266
+ this._input.parentNode.removeChild(this._input);
267
+ }
268
+ this._input = null;
269
+ }
270
+ },
271
+ /**
272
+ * Creates invisible file input above the button
273
+ */
274
+ _createInput : function(){
275
+ var self = this;
276
+ var input = d.createElement("input");
277
+ input.setAttribute('type', 'file');
278
+ input.setAttribute('name', this._settings.name);
279
+ var styles = {
280
+ 'position' : 'absolute'
281
+ ,'margin': '-5px 0 0 -175px'
282
+ ,'padding': 0
283
+ ,'width': '220px'
284
+ ,'height': '30px'
285
+ ,'fontSize': '14px'
286
+ ,'opacity': 0
287
+ ,'cursor': 'pointer'
288
+ ,'display' : 'none'
289
+ ,'zIndex' : 2147483583 //Max zIndex supported by Opera 9.0-9.2x
290
+ // Strange, I expected 2147483647
291
+ };
292
+ for (var i in styles){
293
+ input.style[i] = styles[i];
294
+ }
295
+
296
+ // Make sure that element opacity exists
297
+ // (IE uses filter instead)
298
+ if ( ! (input.style.opacity === "0")){
299
+ input.style.filter = "alpha(opacity=0)";
300
+ }
301
+
302
+ this._parentDialog.appendChild(input);
303
+
304
+ addEvent(input, 'change', function(){
305
+ // get filename from input
306
+ var file = fileFromPath(this.value);
307
+ if(self._settings.onChange.call(self, file, getExt(file)) == false ){
308
+ return;
309
+ }
310
+ // Submit form when value is changed
311
+ if (self._settings.autoSubmit){
312
+ self.submit();
313
+ }
314
+ });
315
+
316
+ // Fixing problem with Safari
317
+ // The problem is that if you leave input before the file select dialog opens
318
+ // it does not upload the file.
319
+ // As dialog opens slowly (it is a sheet dialog which takes some time to open)
320
+ // there is some time while you can leave the button.
321
+ // So we should not change display to none immediately
322
+ addEvent(input, 'click', function(){
323
+ self.justClicked = true;
324
+ setTimeout(function(){
325
+ // we will wait 3 seconds for dialog to open
326
+ self.justClicked = false;
327
+ }, 3000);
328
+ });
329
+
330
+ this._input = input;
331
+ },
332
+ _rerouteClicks : function (){
333
+ var self = this;
334
+
335
+ // IE displays 'access denied' error when using this method
336
+ // other browsers just ignore click()
337
+ // addEvent(this._button, 'click', function(e){
338
+ // self._input.click();
339
+ // });
340
+
341
+ var box, dialogOffset = {top:0, left:0}, over = false;
342
+ addEvent(self._button, 'mouseover', function(e){
343
+ if (!self._input || over) return;
344
+ over = true;
345
+ box = getBox(self._button);
346
+
347
+ if (self._parentDialog != d.body){
348
+ dialogOffset = getOffset(self._parentDialog);
349
+ }
350
+ });
351
+
352
+
353
+ // we can't use mouseout on the button,
354
+ // because invisible input is over it
355
+ addEvent(document, 'mousemove', function(e){
356
+ var input = self._input;
357
+ if (!input || !over) return;
358
+
359
+ if (self._disabled){
360
+ removeClass(self._button, 'hover');
361
+ input.style.display = 'none';
362
+ return;
363
+ }
364
+
365
+ var c = getMouseCoords(e);
366
+
367
+ if ((c.x >= box.left) && (c.x <= box.right) &&
368
+ (c.y >= box.top) && (c.y <= box.bottom)){
369
+ input.style.top = c.y - dialogOffset.top + 'px';
370
+ input.style.left = c.x - dialogOffset.left + 'px';
371
+ input.style.display = 'block';
372
+ addClass(self._button, 'hover');
373
+ } else {
374
+ // mouse left the button
375
+ over = false;
376
+ if (!self.justClicked){
377
+ input.style.display = 'none';
378
+ }
379
+ removeClass(self._button, 'hover');
380
+ }
381
+ });
382
+
383
+ },
384
+ /**
385
+ * Creates iframe with unique name
386
+ */
387
+ _createIframe : function(){
388
+ // unique name
389
+ // We cannot use getTime, because it sometimes return
390
+ // same value in safari :(
391
+ var id = getUID();
392
+
393
+ // Remove ie6 "This page contains both secure and nonsecure items" prompt
394
+ // http://tinyurl.com/77w9wh
395
+ var iframe = toElement('<iframe src="javascript:false;" name="' + id + '" />');
396
+ iframe.id = id;
397
+ iframe.style.display = 'none';
398
+ d.body.appendChild(iframe);
399
+ return iframe;
400
+ },
401
+ /**
402
+ * Upload file without refreshing the page
403
+ */
404
+ submit : function(){
405
+ var self = this, settings = this._settings;
406
+
407
+ if (this._input.value === ''){
408
+ // there is no file
409
+ return;
410
+ }
411
+
412
+ // get filename from input
413
+ var file = fileFromPath(this._input.value);
414
+
415
+ // execute user event
416
+ if (! (settings.onSubmit.call(this, file, getExt(file)) == false)) {
417
+ // Create new iframe for this submission
418
+ var iframe = this._createIframe();
419
+
420
+ // Do not submit if user function returns false
421
+ var form = this._createForm(iframe);
422
+ form.appendChild(this._input);
423
+
424
+ form.submit();
425
+
426
+ d.body.removeChild(form);
427
+ form = null;
428
+ this._input = null;
429
+
430
+ // create new input
431
+ this._createInput();
432
+
433
+ var toDeleteFlag = false;
434
+
435
+ addEvent(iframe, 'load', function(e){
436
+
437
+ if (// For Safari
438
+ iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" ||
439
+ // For FF, IE
440
+ iframe.src == "javascript:'<html></html>';"){
441
+
442
+ // First time around, do not delete.
443
+ if( toDeleteFlag ){
444
+ // Fix busy state in FF3
445
+ setTimeout( function() {
446
+ d.body.removeChild(iframe);
447
+ }, 0);
448
+ }
449
+ return;
450
+ }
451
+
452
+ var doc = iframe.contentDocument ? iframe.contentDocument : frames[iframe.id].document;
453
+
454
+ // fixing Opera 9.26
455
+ if (doc.readyState && doc.readyState != 'complete'){
456
+ // Opera fires load event multiple times
457
+ // Even when the DOM is not ready yet
458
+ // this fix should not affect other browsers
459
+ return;
460
+ }
461
+
462
+ // fixing Opera 9.64
463
+ if (doc.body && doc.body.innerHTML == "false"){
464
+ // In Opera 9.64 event was fired second time
465
+ // when body.innerHTML changed from false
466
+ // to server response approx. after 1 sec
467
+ return;
468
+ }
469
+
470
+ var response;
471
+
472
+ if (doc.XMLDocument){
473
+ // response is a xml document IE property
474
+ response = doc.XMLDocument;
475
+ } else if (doc.body){
476
+ // response is html document or plain text
477
+ response = doc.body.innerHTML;
478
+ if (settings.responseType && settings.responseType.toLowerCase() == 'json'){
479
+ // If the document was sent as 'application/javascript' or
480
+ // 'text/javascript', then the browser wraps the text in a <pre>
481
+ // tag and performs html encoding on the contents. In this case,
482
+ // we need to pull the original text content from the text node's
483
+ // nodeValue property to retrieve the unmangled content.
484
+ // Note that IE6 only understands text/html
485
+ if (doc.body.firstChild && doc.body.firstChild.nodeName.toUpperCase() == 'PRE'){
486
+ response = doc.body.firstChild.firstChild.nodeValue;
487
+ }
488
+ if (response) {
489
+ response = window["eval"]("(" + response + ")");
490
+ } else {
491
+ response = {};
492
+ }
493
+ }
494
+ } else {
495
+ // response is a xml document
496
+ var response = doc;
497
+ }
498
+
499
+ settings.onComplete.call(self, file, response);
500
+
501
+ // Reload blank page, so that reloading main page
502
+ // does not re-submit the post. Also, remember to
503
+ // delete the frame
504
+ toDeleteFlag = true;
505
+
506
+ // Fix IE mixed content issue
507
+ iframe.src = "javascript:'<html></html>';";
508
+ });
509
+
510
+ } else {
511
+ // clear input to allow user to select same file
512
+ // Doesn't work in IE6
513
+ // this._input.value = '';
514
+ d.body.removeChild(this._input);
515
+ this._input = null;
516
+
517
+ // create new input
518
+ this._createInput();
519
+ }
520
+ },
521
+ /**
522
+ * Creates form, that will be submitted to iframe
523
+ */
524
+ _createForm : function(iframe){
525
+ var settings = this._settings;
526
+
527
+ // method, enctype must be specified here
528
+ // because changing this attr on the fly is not allowed in IE 6/7
529
+ var form = toElement('<form method="post" enctype="multipart/form-data"></form>');
530
+ form.style.display = 'none';
531
+ form.action = settings.action;
532
+ form.target = iframe.name;
533
+ d.body.appendChild(form);
534
+
535
+ // Create hidden input element for each data key
536
+ for (var prop in settings.data){
537
+ var el = d.createElement("input");
538
+ el.type = 'hidden';
539
+ el.name = prop;
540
+ el.value = settings.data[prop];
541
+ form.appendChild(el);
542
+ }
543
+ return form;
544
+ }
545
+ };
546
+ })();
js/tryon/jquery-1.8.2.js ADDED
@@ -0,0 +1,9441 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery JavaScript Library v1.8.2
3
+ * http://jquery.com/
4
+ *
5
+ * Includes Sizzle.js
6
+ * http://sizzlejs.com/
7
+ *
8
+ * Copyright 2012 jQuery Foundation and other contributors
9
+ * Released under the MIT license
10
+ * http://jquery.org/license
11
+ *
12
+ * Date: Thu Sep 20 2012 21:13:05 GMT-0400 (Eastern Daylight Time)
13
+ */
14
+ (function( window, undefined ) {
15
+ var
16
+ // A central reference to the root jQuery(document)
17
+ rootjQuery,
18
+
19
+ // The deferred used on DOM ready
20
+ readyList,
21
+
22
+ // Use the correct document accordingly with window argument (sandbox)
23
+ document = window.document,
24
+ location = window.location,
25
+ navigator = window.navigator,
26
+
27
+ // Map over jQuery in case of overwrite
28
+ _jQuery = window.jQuery,
29
+
30
+ // Map over the $ in case of overwrite
31
+ _$ = window.$,
32
+
33
+ // Save a reference to some core methods
34
+ core_push = Array.prototype.push,
35
+ core_slice = Array.prototype.slice,
36
+ core_indexOf = Array.prototype.indexOf,
37
+ core_toString = Object.prototype.toString,
38
+ core_hasOwn = Object.prototype.hasOwnProperty,
39
+ core_trim = String.prototype.trim,
40
+
41
+ // Define a local copy of jQuery
42
+ jQuery = function( selector, context ) {
43
+ // The jQuery object is actually just the init constructor 'enhanced'
44
+ return new jQuery.fn.init( selector, context, rootjQuery );
45
+ },
46
+
47
+ // Used for matching numbers
48
+ core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,
49
+
50
+ // Used for detecting and trimming whitespace
51
+ core_rnotwhite = /\S/,
52
+ core_rspace = /\s+/,
53
+
54
+ // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
55
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
56
+
57
+ // A simple way to check for HTML strings
58
+ // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
59
+ rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
60
+
61
+ // Match a standalone tag
62
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
63
+
64
+ // JSON RegExp
65
+ rvalidchars = /^[\],:{}\s]*$/,
66
+ rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
67
+ rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
68
+ rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,
69
+
70
+ // Matches dashed string for camelizing
71
+ rmsPrefix = /^-ms-/,
72
+ rdashAlpha = /-([\da-z])/gi,
73
+
74
+ // Used by jQuery.camelCase as callback to replace()
75
+ fcamelCase = function( all, letter ) {
76
+ return ( letter + "" ).toUpperCase();
77
+ },
78
+
79
+ // The ready event handler and self cleanup method
80
+ DOMContentLoaded = function() {
81
+ if ( document.addEventListener ) {
82
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
83
+ jQuery.ready();
84
+ } else if ( document.readyState === "complete" ) {
85
+ // we're here because readyState === "complete" in oldIE
86
+ // which is good enough for us to call the dom ready!
87
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
88
+ jQuery.ready();
89
+ }
90
+ },
91
+
92
+ // [[Class]] -> type pairs
93
+ class2type = {};
94
+
95
+ jQuery.fn = jQuery.prototype = {
96
+ constructor: jQuery,
97
+ init: function( selector, context, rootjQuery ) {
98
+ var match, elem, ret, doc;
99
+
100
+ // Handle $(""), $(null), $(undefined), $(false)
101
+ if ( !selector ) {
102
+ return this;
103
+ }
104
+
105
+ // Handle $(DOMElement)
106
+ if ( selector.nodeType ) {
107
+ this.context = this[0] = selector;
108
+ this.length = 1;
109
+ return this;
110
+ }
111
+
112
+ // Handle HTML strings
113
+ if ( typeof selector === "string" ) {
114
+ if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
115
+ // Assume that strings that start and end with <> are HTML and skip the regex check
116
+ match = [ null, selector, null ];
117
+
118
+ } else {
119
+ match = rquickExpr.exec( selector );
120
+ }
121
+
122
+ // Match html or make sure no context is specified for #id
123
+ if ( match && (match[1] || !context) ) {
124
+
125
+ // HANDLE: $(html) -> $(array)
126
+ if ( match[1] ) {
127
+ context = context instanceof jQuery ? context[0] : context;
128
+ doc = ( context && context.nodeType ? context.ownerDocument || context : document );
129
+
130
+ // scripts is true for back-compat
131
+ selector = jQuery.parseHTML( match[1], doc, true );
132
+ if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
133
+ this.attr.call( selector, context, true );
134
+ }
135
+
136
+ return jQuery.merge( this, selector );
137
+
138
+ // HANDLE: $(#id)
139
+ } else {
140
+ elem = document.getElementById( match[2] );
141
+
142
+ // Check parentNode to catch when Blackberry 4.6 returns
143
+ // nodes that are no longer in the document #6963
144
+ if ( elem && elem.parentNode ) {
145
+ // Handle the case where IE and Opera return items
146
+ // by name instead of ID
147
+ if ( elem.id !== match[2] ) {
148
+ return rootjQuery.find( selector );
149
+ }
150
+
151
+ // Otherwise, we inject the element directly into the jQuery object
152
+ this.length = 1;
153
+ this[0] = elem;
154
+ }
155
+
156
+ this.context = document;
157
+ this.selector = selector;
158
+ return this;
159
+ }
160
+
161
+ // HANDLE: $(expr, $(...))
162
+ } else if ( !context || context.jquery ) {
163
+ return ( context || rootjQuery ).find( selector );
164
+
165
+ // HANDLE: $(expr, context)
166
+ // (which is just equivalent to: $(context).find(expr)
167
+ } else {
168
+ return this.constructor( context ).find( selector );
169
+ }
170
+
171
+ // HANDLE: $(function)
172
+ // Shortcut for document ready
173
+ } else if ( jQuery.isFunction( selector ) ) {
174
+ return rootjQuery.ready( selector );
175
+ }
176
+
177
+ if ( selector.selector !== undefined ) {
178
+ this.selector = selector.selector;
179
+ this.context = selector.context;
180
+ }
181
+
182
+ return jQuery.makeArray( selector, this );
183
+ },
184
+
185
+ // Start with an empty selector
186
+ selector: "",
187
+
188
+ // The current version of jQuery being used
189
+ jquery: "1.8.2",
190
+
191
+ // The default length of a jQuery object is 0
192
+ length: 0,
193
+
194
+ // The number of elements contained in the matched element set
195
+ size: function() {
196
+ return this.length;
197
+ },
198
+
199
+ toArray: function() {
200
+ return core_slice.call( this );
201
+ },
202
+
203
+ // Get the Nth element in the matched element set OR
204
+ // Get the whole matched element set as a clean array
205
+ get: function( num ) {
206
+ return num == null ?
207
+
208
+ // Return a 'clean' array
209
+ this.toArray() :
210
+
211
+ // Return just the object
212
+ ( num < 0 ? this[ this.length + num ] : this[ num ] );
213
+ },
214
+
215
+ // Take an array of elements and push it onto the stack
216
+ // (returning the new matched element set)
217
+ pushStack: function( elems, name, selector ) {
218
+
219
+ // Build a new jQuery matched element set
220
+ var ret = jQuery.merge( this.constructor(), elems );
221
+
222
+ // Add the old object onto the stack (as a reference)
223
+ ret.prevObject = this;
224
+
225
+ ret.context = this.context;
226
+
227
+ if ( name === "find" ) {
228
+ ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
229
+ } else if ( name ) {
230
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
231
+ }
232
+
233
+ // Return the newly-formed element set
234
+ return ret;
235
+ },
236
+
237
+ // Execute a callback for every element in the matched set.
238
+ // (You can seed the arguments with an array of args, but this is
239
+ // only used internally.)
240
+ each: function( callback, args ) {
241
+ return jQuery.each( this, callback, args );
242
+ },
243
+
244
+ ready: function( fn ) {
245
+ // Add the callback
246
+ jQuery.ready.promise().done( fn );
247
+
248
+ return this;
249
+ },
250
+
251
+ eq: function( i ) {
252
+ i = +i;
253
+ return i === -1 ?
254
+ this.slice( i ) :
255
+ this.slice( i, i + 1 );
256
+ },
257
+
258
+ first: function() {
259
+ return this.eq( 0 );
260
+ },
261
+
262
+ last: function() {
263
+ return this.eq( -1 );
264
+ },
265
+
266
+ slice: function() {
267
+ return this.pushStack( core_slice.apply( this, arguments ),
268
+ "slice", core_slice.call(arguments).join(",") );
269
+ },
270
+
271
+ map: function( callback ) {
272
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
273
+ return callback.call( elem, i, elem );
274
+ }));
275
+ },
276
+
277
+ end: function() {
278
+ return this.prevObject || this.constructor(null);
279
+ },
280
+
281
+ // For internal use only.
282
+ // Behaves like an Array's method, not like a jQuery method.
283
+ push: core_push,
284
+ sort: [].sort,
285
+ splice: [].splice
286
+ };
287
+
288
+ // Give the init function the jQuery prototype for later instantiation
289
+ jQuery.fn.init.prototype = jQuery.fn;
290
+
291
+ jQuery.extend = jQuery.fn.extend = function() {
292
+ var options, name, src, copy, copyIsArray, clone,
293
+ target = arguments[0] || {},
294
+ i = 1,
295
+ length = arguments.length,
296
+ deep = false;
297
+
298
+ // Handle a deep copy situation
299
+ if ( typeof target === "boolean" ) {
300
+ deep = target;
301
+ target = arguments[1] || {};
302
+ // skip the boolean and the target
303
+ i = 2;
304
+ }
305
+
306
+ // Handle case when target is a string or something (possible in deep copy)
307
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
308
+ target = {};
309
+ }
310
+
311
+ // extend jQuery itself if only one argument is passed
312
+ if ( length === i ) {
313
+ target = this;
314
+ --i;
315
+ }
316
+
317
+ for ( ; i < length; i++ ) {
318
+ // Only deal with non-null/undefined values
319
+ if ( (options = arguments[ i ]) != null ) {
320
+ // Extend the base object
321
+ for ( name in options ) {
322
+ src = target[ name ];
323
+ copy = options[ name ];
324
+
325
+ // Prevent never-ending loop
326
+ if ( target === copy ) {
327
+ continue;
328
+ }
329
+
330
+ // Recurse if we're merging plain objects or arrays
331
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
332
+ if ( copyIsArray ) {
333
+ copyIsArray = false;
334
+ clone = src && jQuery.isArray(src) ? src : [];
335
+
336
+ } else {
337
+ clone = src && jQuery.isPlainObject(src) ? src : {};
338
+ }
339
+
340
+ // Never move original objects, clone them
341
+ target[ name ] = jQuery.extend( deep, clone, copy );
342
+
343
+ // Don't bring in undefined values
344
+ } else if ( copy !== undefined ) {
345
+ target[ name ] = copy;
346
+ }
347
+ }
348
+ }
349
+ }
350
+
351
+ // Return the modified object
352
+ return target;
353
+ };
354
+
355
+ jQuery.extend({
356
+ noConflict: function( deep ) {
357
+ if ( window.$ === jQuery ) {
358
+ window.$ = _$;
359
+ }
360
+
361
+ if ( deep && window.jQuery === jQuery ) {
362
+ window.jQuery = _jQuery;
363
+ }
364
+
365
+ return jQuery;
366
+ },
367
+
368
+ // Is the DOM ready to be used? Set to true once it occurs.
369
+ isReady: false,
370
+
371
+ // A counter to track how many items to wait for before
372
+ // the ready event fires. See #6781
373
+ readyWait: 1,
374
+
375
+ // Hold (or release) the ready event
376
+ holdReady: function( hold ) {
377
+ if ( hold ) {
378
+ jQuery.readyWait++;
379
+ } else {
380
+ jQuery.ready( true );
381
+ }
382
+ },
383
+
384
+ // Handle when the DOM is ready
385
+ ready: function( wait ) {
386
+
387
+ // Abort if there are pending holds or we're already ready
388
+ if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
389
+ return;
390
+ }
391
+
392
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
393
+ if ( !document.body ) {
394
+ return setTimeout( jQuery.ready, 1 );
395
+ }
396
+
397
+ // Remember that the DOM is ready
398
+ jQuery.isReady = true;
399
+
400
+ // If a normal DOM Ready event fired, decrement, and wait if need be
401
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
402
+ return;
403
+ }
404
+
405
+ // If there are functions bound, to execute
406
+ readyList.resolveWith( document, [ jQuery ] );
407
+
408
+ // Trigger any bound ready events
409
+ if ( jQuery.fn.trigger ) {
410
+ jQuery( document ).trigger("ready").off("ready");
411
+ }
412
+ },
413
+
414
+ // See test/unit/core.js for details concerning isFunction.
415
+ // Since version 1.3, DOM methods and functions like alert
416
+ // aren't supported. They return false on IE (#2968).
417
+ isFunction: function( obj ) {
418
+ return jQuery.type(obj) === "function";
419
+ },
420
+
421
+ isArray: Array.isArray || function( obj ) {
422
+ return jQuery.type(obj) === "array";
423
+ },
424
+
425
+ isWindow: function( obj ) {
426
+ return obj != null && obj == obj.window;
427
+ },
428
+
429
+ isNumeric: function( obj ) {
430
+ return !isNaN( parseFloat(obj) ) && isFinite( obj );
431
+ },
432
+
433
+ type: function( obj ) {
434
+ return obj == null ?
435
+ String( obj ) :
436
+ class2type[ core_toString.call(obj) ] || "object";
437
+ },
438
+
439
+ isPlainObject: function( obj ) {
440
+ // Must be an Object.
441
+ // Because of IE, we also have to check the presence of the constructor property.
442
+ // Make sure that DOM nodes and window objects don't pass through, as well
443
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
444
+ return false;
445
+ }
446
+
447
+ try {
448
+ // Not own constructor property must be Object
449
+ if ( obj.constructor &&
450
+ !core_hasOwn.call(obj, "constructor") &&
451
+ !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
452
+ return false;
453
+ }
454
+ } catch ( e ) {
455
+ // IE8,9 Will throw exceptions on certain host objects #9897
456
+ return false;
457
+ }
458
+
459
+ // Own properties are enumerated firstly, so to speed up,
460
+ // if last one is own, then all properties are own.
461
+
462
+ var key;
463
+ for ( key in obj ) {}
464
+
465
+ return key === undefined || core_hasOwn.call( obj, key );
466
+ },
467
+
468
+ isEmptyObject: function( obj ) {
469
+ var name;
470
+ for ( name in obj ) {
471
+ return false;
472
+ }
473
+ return true;
474
+ },
475
+
476
+ error: function( msg ) {
477
+ throw new Error( msg );
478
+ },
479
+
480
+ // data: string of html
481
+ // context (optional): If specified, the fragment will be created in this context, defaults to document
482
+ // scripts (optional): If true, will include scripts passed in the html string
483
+ parseHTML: function( data, context, scripts ) {
484
+ var parsed;
485
+ if ( !data || typeof data !== "string" ) {
486
+ return null;
487
+ }
488
+ if ( typeof context === "boolean" ) {
489
+ scripts = context;
490
+ context = 0;
491
+ }
492
+ context = context || document;
493
+
494
+ // Single tag
495
+ if ( (parsed = rsingleTag.exec( data )) ) {
496
+ return [ context.createElement( parsed[1] ) ];
497
+ }
498
+
499
+ parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );
500
+ return jQuery.merge( [],
501
+ (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );
502
+ },
503
+
504
+ parseJSON: function( data ) {
505
+ if ( !data || typeof data !== "string") {
506
+ return null;
507
+ }
508
+
509
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
510
+ data = jQuery.trim( data );
511
+
512
+ // Attempt to parse using the native JSON parser first
513
+ if ( window.JSON && window.JSON.parse ) {
514
+ return window.JSON.parse( data );
515
+ }
516
+
517
+ // Make sure the incoming data is actual JSON
518
+ // Logic borrowed from http://json.org/json2.js
519
+ if ( rvalidchars.test( data.replace( rvalidescape, "@" )
520
+ .replace( rvalidtokens, "]" )
521
+ .replace( rvalidbraces, "")) ) {
522
+
523
+ return ( new Function( "return " + data ) )();
524
+
525
+ }
526
+ jQuery.error( "Invalid JSON: " + data );
527
+ },
528
+
529
+ // Cross-browser xml parsing
530
+ parseXML: function( data ) {
531
+ var xml, tmp;
532
+ if ( !data || typeof data !== "string" ) {
533
+ return null;
534
+ }
535
+ try {
536
+ if ( window.DOMParser ) { // Standard
537
+ tmp = new DOMParser();
538
+ xml = tmp.parseFromString( data , "text/xml" );
539
+ } else { // IE
540
+ xml = new ActiveXObject( "Microsoft.XMLDOM" );
541
+ xml.async = "false";
542
+ xml.loadXML( data );
543
+ }
544
+ } catch( e ) {
545
+ xml = undefined;
546
+ }
547
+ if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
548
+ jQuery.error( "Invalid XML: " + data );
549
+ }
550
+ return xml;
551
+ },
552
+
553
+ noop: function() {},
554
+
555
+ // Evaluates a script in a global context
556
+ // Workarounds based on findings by Jim Driscoll
557
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
558
+ globalEval: function( data ) {
559
+ if ( data && core_rnotwhite.test( data ) ) {
560
+ // We use execScript on Internet Explorer
561
+ // We use an anonymous function so that context is window
562
+ // rather than jQuery in Firefox
563
+ ( window.execScript || function( data ) {
564
+ window[ "eval" ].call( window, data );
565
+ } )( data );
566
+ }
567
+ },
568
+
569
+ // Convert dashed to camelCase; used by the css and data modules
570
+ // Microsoft forgot to hump their vendor prefix (#9572)
571
+ camelCase: function( string ) {
572
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
573
+ },
574
+
575
+ nodeName: function( elem, name ) {
576
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
577
+ },
578
+
579
+ // args is for internal usage only
580
+ each: function( obj, callback, args ) {
581
+ var name,
582
+ i = 0,
583
+ length = obj.length,
584
+ isObj = length === undefined || jQuery.isFunction( obj );
585
+
586
+ if ( args ) {
587
+ if ( isObj ) {
588
+ for ( name in obj ) {
589
+ if ( callback.apply( obj[ name ], args ) === false ) {
590
+ break;
591
+ }
592
+ }
593
+ } else {
594
+ for ( ; i < length; ) {
595
+ if ( callback.apply( obj[ i++ ], args ) === false ) {
596
+ break;
597
+ }
598
+ }
599
+ }
600
+
601
+ // A special, fast, case for the most common use of each
602
+ } else {
603
+ if ( isObj ) {
604
+ for ( name in obj ) {
605
+ if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) {
606
+ break;
607
+ }
608
+ }
609
+ } else {
610
+ for ( ; i < length; ) {
611
+ if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {
612
+ break;
613
+ }
614
+ }
615
+ }
616
+ }
617
+
618
+ return obj;
619
+ },
620
+
621
+ // Use native String.trim function wherever possible
622
+ trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
623
+ function( text ) {
624
+ return text == null ?
625
+ "" :
626
+ core_trim.call( text );
627
+ } :
628
+
629
+ // Otherwise use our own trimming functionality
630
+ function( text ) {
631
+ return text == null ?
632
+ "" :
633
+ ( text + "" ).replace( rtrim, "" );
634
+ },
635
+
636
+ // results is for internal usage only
637
+ makeArray: function( arr, results ) {
638
+ var type,
639
+ ret = results || [];
640
+
641
+ if ( arr != null ) {
642
+ // The window, strings (and functions) also have 'length'
643
+ // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
644
+ type = jQuery.type( arr );
645
+
646
+ if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) {
647
+ core_push.call( ret, arr );
648
+ } else {
649
+ jQuery.merge( ret, arr );
650
+ }
651
+ }
652
+
653
+ return ret;
654
+ },
655
+
656
+ inArray: function( elem, arr, i ) {
657
+ var len;
658
+
659
+ if ( arr ) {
660
+ if ( core_indexOf ) {
661
+ return core_indexOf.call( arr, elem, i );
662
+ }
663
+
664
+ len = arr.length;
665
+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
666
+
667
+ for ( ; i < len; i++ ) {
668
+ // Skip accessing in sparse arrays
669
+ if ( i in arr && arr[ i ] === elem ) {
670
+ return i;
671
+ }
672
+ }
673
+ }
674
+
675
+ return -1;
676
+ },
677
+
678
+ merge: function( first, second ) {
679
+ var l = second.length,
680
+ i = first.length,
681
+ j = 0;
682
+
683
+ if ( typeof l === "number" ) {
684
+ for ( ; j < l; j++ ) {
685
+ first[ i++ ] = second[ j ];
686
+ }
687
+
688
+ } else {
689
+ while ( second[j] !== undefined ) {
690
+ first[ i++ ] = second[ j++ ];
691
+ }
692
+ }
693
+
694
+ first.length = i;
695
+
696
+ return first;
697
+ },
698
+
699
+ grep: function( elems, callback, inv ) {
700
+ var retVal,
701
+ ret = [],
702
+ i = 0,
703
+ length = elems.length;
704
+ inv = !!inv;
705
+
706
+ // Go through the array, only saving the items
707
+ // that pass the validator function
708
+ for ( ; i < length; i++ ) {
709
+ retVal = !!callback( elems[ i ], i );
710
+ if ( inv !== retVal ) {
711
+ ret.push( elems[ i ] );
712
+ }
713
+ }
714
+
715
+ return ret;
716
+ },
717
+
718
+ // arg is for internal usage only
719
+ map: function( elems, callback, arg ) {
720
+ var value, key,
721
+ ret = [],
722
+ i = 0,
723
+ length = elems.length,
724
+ // jquery objects are treated as arrays
725
+ isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
726
+
727
+ // Go through the array, translating each of the items to their
728
+ if ( isArray ) {
729
+ for ( ; i < length; i++ ) {
730
+ value = callback( elems[ i ], i, arg );
731
+
732
+ if ( value != null ) {
733
+ ret[ ret.length ] = value;
734
+ }
735
+ }
736
+
737
+ // Go through every key on the object,
738
+ } else {
739
+ for ( key in elems ) {
740
+ value = callback( elems[ key ], key, arg );
741
+
742
+ if ( value != null ) {
743
+ ret[ ret.length ] = value;
744
+ }
745
+ }
746
+ }
747
+
748
+ // Flatten any nested arrays
749
+ return ret.concat.apply( [], ret );
750
+ },
751
+
752
+ // A global GUID counter for objects
753
+ guid: 1,
754
+
755
+ // Bind a function to a context, optionally partially applying any
756
+ // arguments.
757
+ proxy: function( fn, context ) {
758
+ var tmp, args, proxy;
759
+
760
+ if ( typeof context === "string" ) {
761
+ tmp = fn[ context ];
762
+ context = fn;
763
+ fn = tmp;
764
+ }
765
+
766
+ // Quick check to determine if target is callable, in the spec
767
+ // this throws a TypeError, but we will just return undefined.
768
+ if ( !jQuery.isFunction( fn ) ) {
769
+ return undefined;
770
+ }
771
+
772
+ // Simulated bind
773
+ args = core_slice.call( arguments, 2 );
774
+ proxy = function() {
775
+ return fn.apply( context, args.concat( core_slice.call( arguments ) ) );
776
+ };
777
+
778
+ // Set the guid of unique handler to the same of original handler, so it can be removed
779
+ proxy.guid = fn.guid = fn.guid || jQuery.guid++;
780
+
781
+ return proxy;
782
+ },
783
+
784
+ // Multifunctional method to get and set values of a collection
785
+ // The value/s can optionally be executed if it's a function
786
+ access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
787
+ var exec,
788
+ bulk = key == null,
789
+ i = 0,
790
+ length = elems.length;
791
+
792
+ // Sets many values
793
+ if ( key && typeof key === "object" ) {
794
+ for ( i in key ) {
795
+ jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
796
+ }
797
+ chainable = 1;
798
+
799
+ // Sets one value
800
+ } else if ( value !== undefined ) {
801
+ // Optionally, function values get executed if exec is true
802
+ exec = pass === undefined && jQuery.isFunction( value );
803
+
804
+ if ( bulk ) {
805
+ // Bulk operations only iterate when executing function values
806
+ if ( exec ) {
807
+ exec = fn;
808
+ fn = function( elem, key, value ) {
809
+ return exec.call( jQuery( elem ), value );
810
+ };
811
+
812
+ // Otherwise they run against the entire set
813
+ } else {
814
+ fn.call( elems, value );
815
+ fn = null;
816
+ }
817
+ }
818
+
819
+ if ( fn ) {
820
+ for (; i < length; i++ ) {
821
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
822
+ }
823
+ }
824
+
825
+ chainable = 1;
826
+ }
827
+
828
+ return chainable ?
829
+ elems :
830
+
831
+ // Gets
832
+ bulk ?
833
+ fn.call( elems ) :
834
+ length ? fn( elems[0], key ) : emptyGet;
835
+ },
836
+
837
+ now: function() {
838
+ return ( new Date() ).getTime();
839
+ }
840
+ });
841
+
842
+ jQuery.ready.promise = function( obj ) {
843
+ if ( !readyList ) {
844
+
845
+ readyList = jQuery.Deferred();
846
+
847
+ // Catch cases where $(document).ready() is called after the browser event has already occurred.
848
+ // we once tried to use readyState "interactive" here, but it caused issues like the one
849
+ // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
850
+ if ( document.readyState === "complete" ) {
851
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
852
+ setTimeout( jQuery.ready, 1 );
853
+
854
+ // Standards-based browsers support DOMContentLoaded
855
+ } else if ( document.addEventListener ) {
856
+ // Use the handy event callback
857
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
858
+
859
+ // A fallback to window.onload, that will always work
860
+ window.addEventListener( "load", jQuery.ready, false );
861
+
862
+ // If IE event model is used
863
+ } else {
864
+ // Ensure firing before onload, maybe late but safe also for iframes
865
+ document.attachEvent( "onreadystatechange", DOMContentLoaded );
866
+
867
+ // A fallback to window.onload, that will always work
868
+ window.attachEvent( "onload", jQuery.ready );
869
+
870
+ // If IE and not a frame
871
+ // continually check to see if the document is ready
872
+ var top = false;
873
+
874
+ try {
875
+ top = window.frameElement == null && document.documentElement;
876
+ } catch(e) {}
877
+
878
+ if ( top && top.doScroll ) {
879
+ (function doScrollCheck() {
880
+ if ( !jQuery.isReady ) {
881
+
882
+ try {
883
+ // Use the trick by Diego Perini
884
+ // http://javascript.nwbox.com/IEContentLoaded/
885
+ top.doScroll("left");
886
+ } catch(e) {
887
+ return setTimeout( doScrollCheck, 50 );
888
+ }
889
+
890
+ // and execute any waiting functions
891
+ jQuery.ready();
892
+ }
893
+ })();
894
+ }
895
+ }
896
+ }
897
+ return readyList.promise( obj );
898
+ };
899
+
900
+ // Populate the class2type map
901
+ jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
902
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
903
+ });
904
+
905
+ // All jQuery objects should point back to these
906
+ rootjQuery = jQuery(document);
907
+ // String to Object options format cache
908
+ var optionsCache = {};
909
+
910
+ // Convert String-formatted options into Object-formatted ones and store in cache
911
+ function createOptions( options ) {
912
+ var object = optionsCache[ options ] = {};
913
+ jQuery.each( options.split( core_rspace ), function( _, flag ) {
914
+ object[ flag ] = true;
915
+ });
916
+ return object;
917
+ }
918
+
919
+ /*
920
+ * Create a callback list using the following parameters:
921
+ *
922
+ * options: an optional list of space-separated options that will change how
923
+ * the callback list behaves or a more traditional option object
924
+ *
925
+ * By default a callback list will act like an event callback list and can be
926
+ * "fired" multiple times.
927
+ *
928
+ * Possible options:
929
+ *
930
+ * once: will ensure the callback list can only be fired once (like a Deferred)
931
+ *
932
+ * memory: will keep track of previous values and will call any callback added
933
+ * after the list has been fired right away with the latest "memorized"
934
+ * values (like a Deferred)
935
+ *
936
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
937
+ *
938
+ * stopOnFalse: interrupt callings when a callback returns false
939
+ *
940
+ */
941
+ jQuery.Callbacks = function( options ) {
942
+
943
+ // Convert options from String-formatted to Object-formatted if needed
944
+ // (we check in cache first)
945
+ options = typeof options === "string" ?
946
+ ( optionsCache[ options ] || createOptions( options ) ) :
947
+ jQuery.extend( {}, options );
948
+
949
+ var // Last fire value (for non-forgettable lists)
950
+ memory,
951
+ // Flag to know if list was already fired
952
+ fired,
953
+ // Flag to know if list is currently firing
954
+ firing,
955
+ // First callback to fire (used internally by add and fireWith)
956
+ firingStart,
957
+ // End of the loop when firing
958
+ firingLength,
959
+ // Index of currently firing callback (modified by remove if needed)
960
+ firingIndex,
961
+ // Actual callback list
962
+ list = [],
963
+ // Stack of fire calls for repeatable lists
964
+ stack = !options.once && [],
965
+ // Fire callbacks
966
+ fire = function( data ) {
967
+ memory = options.memory && data;
968
+ fired = true;
969
+ firingIndex = firingStart || 0;
970
+ firingStart = 0;
971
+ firingLength = list.length;
972
+ firing = true;
973
+ for ( ; list && firingIndex < firingLength; firingIndex++ ) {
974
+ if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
975
+ memory = false; // To prevent further calls using add
976
+ break;
977
+ }
978
+ }
979
+ firing = false;
980
+ if ( list ) {
981
+ if ( stack ) {
982
+ if ( stack.length ) {
983
+ fire( stack.shift() );
984
+ }
985
+ } else if ( memory ) {
986
+ list = [];
987
+ } else {
988
+ self.disable();
989
+ }
990
+ }
991
+ },
992
+ // Actual Callbacks object
993
+ self = {
994
+ // Add a callback or a collection of callbacks to the list
995
+ add: function() {
996
+ if ( list ) {
997
+ // First, we save the current length
998
+ var start = list.length;
999
+ (function add( args ) {
1000
+ jQuery.each( args, function( _, arg ) {
1001
+ var type = jQuery.type( arg );
1002
+ if ( type === "function" && ( !options.unique || !self.has( arg ) ) ) {
1003
+ list.push( arg );
1004
+ } else if ( arg && arg.length && type !== "string" ) {
1005
+ // Inspect recursively
1006
+ add( arg );
1007
+ }
1008
+ });
1009
+ })( arguments );
1010
+ // Do we need to add the callbacks to the
1011
+ // current firing batch?
1012
+ if ( firing ) {
1013
+ firingLength = list.length;
1014
+ // With memory, if we're not firing then
1015
+ // we should call right away
1016
+ } else if ( memory ) {
1017
+ firingStart = start;
1018
+ fire( memory );
1019
+ }
1020
+ }
1021
+ return this;
1022
+ },
1023
+ // Remove a callback from the list
1024
+ remove: function() {
1025
+ if ( list ) {
1026
+ jQuery.each( arguments, function( _, arg ) {
1027
+ var index;
1028
+ while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
1029
+ list.splice( index, 1 );
1030
+ // Handle firing indexes
1031
+ if ( firing ) {
1032
+ if ( index <= firingLength ) {
1033
+ firingLength--;
1034
+ }
1035
+ if ( index <= firingIndex ) {
1036
+ firingIndex--;
1037
+ }
1038
+ }
1039
+ }
1040
+ });
1041
+ }
1042
+ return this;
1043
+ },
1044
+ // Control if a given callback is in the list
1045
+ has: function( fn ) {
1046
+ return jQuery.inArray( fn, list ) > -1;
1047
+ },
1048
+ // Remove all callbacks from the list
1049
+ empty: function() {
1050
+ list = [];
1051
+ return this;
1052
+ },
1053
+ // Have the list do nothing anymore
1054
+ disable: function() {
1055
+ list = stack = memory = undefined;
1056
+ return this;
1057
+ },
1058
+ // Is it disabled?
1059
+ disabled: function() {
1060
+ return !list;
1061
+ },
1062
+ // Lock the list in its current state
1063
+ lock: function() {
1064
+ stack = undefined;
1065
+ if ( !memory ) {
1066
+ self.disable();
1067
+ }
1068
+ return this;
1069
+ },
1070
+ // Is it locked?
1071
+ locked: function() {
1072
+ return !stack;
1073
+ },
1074
+ // Call all callbacks with the given context and arguments
1075
+ fireWith: function( context, args ) {
1076
+ args = args || [];
1077
+ args = [ context, args.slice ? args.slice() : args ];
1078
+ if ( list && ( !fired || stack ) ) {
1079
+ if ( firing ) {
1080
+ stack.push( args );
1081
+ } else {
1082
+ fire( args );
1083
+ }
1084
+ }
1085
+ return this;
1086
+ },
1087
+ // Call all the callbacks with the given arguments
1088
+ fire: function() {
1089
+ self.fireWith( this, arguments );
1090
+ return this;
1091
+ },
1092
+ // To know if the callbacks have already been called at least once
1093
+ fired: function() {
1094
+ return !!fired;
1095
+ }
1096
+ };
1097
+
1098
+ return self;
1099
+ };
1100
+ jQuery.extend({
1101
+
1102
+ Deferred: function( func ) {
1103
+ var tuples = [
1104
+ // action, add listener, listener list, final state
1105
+ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
1106
+ [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
1107
+ [ "notify", "progress", jQuery.Callbacks("memory") ]
1108
+ ],
1109
+ state = "pending",
1110
+ promise = {
1111
+ state: function() {
1112
+ return state;
1113
+ },
1114
+ always: function() {
1115
+ deferred.done( arguments ).fail( arguments );
1116
+ return this;
1117
+ },
1118
+ then: function( /* fnDone, fnFail, fnProgress */ ) {
1119
+ var fns = arguments;
1120
+ return jQuery.Deferred(function( newDefer ) {
1121
+ jQuery.each( tuples, function( i, tuple ) {
1122
+ var action = tuple[ 0 ],
1123
+ fn = fns[ i ];
1124
+ // deferred[ done | fail | progress ] for forwarding actions to newDefer
1125
+ deferred[ tuple[1] ]( jQuery.isFunction( fn ) ?
1126
+ function() {
1127
+ var returned = fn.apply( this, arguments );
1128
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
1129
+ returned.promise()
1130
+ .done( newDefer.resolve )
1131
+ .fail( newDefer.reject )
1132
+ .progress( newDefer.notify );
1133
+ } else {
1134
+ newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1135
+ }
1136
+ } :
1137
+ newDefer[ action ]
1138
+ );
1139
+ });
1140
+ fns = null;
1141
+ }).promise();
1142
+ },
1143
+ // Get a promise for this deferred
1144
+ // If obj is provided, the promise aspect is added to the object
1145
+ promise: function( obj ) {
1146
+ return obj != null ? jQuery.extend( obj, promise ) : promise;
1147
+ }
1148
+ },
1149
+ deferred = {};
1150
+
1151
+ // Keep pipe for back-compat
1152
+ promise.pipe = promise.then;
1153
+
1154
+ // Add list-specific methods
1155
+ jQuery.each( tuples, function( i, tuple ) {
1156
+ var list = tuple[ 2 ],
1157
+ stateString = tuple[ 3 ];
1158
+
1159
+ // promise[ done | fail | progress ] = list.add
1160
+ promise[ tuple[1] ] = list.add;
1161
+
1162
+ // Handle state
1163
+ if ( stateString ) {
1164
+ list.add(function() {
1165
+ // state = [ resolved | rejected ]
1166
+ state = stateString;
1167
+
1168
+ // [ reject_list | resolve_list ].disable; progress_list.lock
1169
+ }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
1170
+ }
1171
+
1172
+ // deferred[ resolve | reject | notify ] = list.fire
1173
+ deferred[ tuple[0] ] = list.fire;
1174
+ deferred[ tuple[0] + "With" ] = list.fireWith;
1175
+ });
1176
+
1177
+ // Make the deferred a promise
1178
+ promise.promise( deferred );
1179
+
1180
+ // Call given func if any
1181
+ if ( func ) {
1182
+ func.call( deferred, deferred );
1183
+ }
1184
+
1185
+ // All done!
1186
+ return deferred;
1187
+ },
1188
+
1189
+ // Deferred helper
1190
+ when: function( subordinate /* , ..., subordinateN */ ) {
1191
+ var i = 0,
1192
+ resolveValues = core_slice.call( arguments ),
1193
+ length = resolveValues.length,
1194
+
1195
+ // the count of uncompleted subordinates
1196
+ remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
1197
+
1198
+ // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
1199
+ deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
1200
+
1201
+ // Update function for both resolve and progress values
1202
+ updateFunc = function( i, contexts, values ) {
1203
+ return function( value ) {
1204
+ contexts[ i ] = this;
1205
+ values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
1206
+ if( values === progressValues ) {
1207
+ deferred.notifyWith( contexts, values );
1208
+ } else if ( !( --remaining ) ) {
1209
+ deferred.resolveWith( contexts, values );
1210
+ }
1211
+ };
1212
+ },
1213
+
1214
+ progressValues, progressContexts, resolveContexts;
1215
+
1216
+ // add listeners to Deferred subordinates; treat others as resolved
1217
+ if ( length > 1 ) {
1218
+ progressValues = new Array( length );
1219
+ progressContexts = new Array( length );
1220
+ resolveContexts = new Array( length );
1221
+ for ( ; i < length; i++ ) {
1222
+ if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
1223
+ resolveValues[ i ].promise()
1224
+ .done( updateFunc( i, resolveContexts, resolveValues ) )
1225
+ .fail( deferred.reject )
1226
+ .progress( updateFunc( i, progressContexts, progressValues ) );
1227
+ } else {
1228
+ --remaining;
1229
+ }
1230
+ }
1231
+ }
1232
+
1233
+ // if we're not waiting on anything, resolve the master
1234
+ if ( !remaining ) {
1235
+ deferred.resolveWith( resolveContexts, resolveValues );
1236
+ }
1237
+
1238
+ return deferred.promise();
1239
+ }
1240
+ });
1241
+ jQuery.support = (function() {
1242
+
1243
+ var support,
1244
+ all,
1245
+ a,
1246
+ select,
1247
+ opt,
1248
+ input,
1249
+ fragment,
1250
+ eventName,
1251
+ i,
1252
+ isSupported,
1253
+ clickFn,
1254
+ div = document.createElement("div");
1255
+
1256
+ // Preliminary tests
1257
+ div.setAttribute( "className", "t" );
1258
+ div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
1259
+
1260
+ all = div.getElementsByTagName("*");
1261
+ a = div.getElementsByTagName("a")[ 0 ];
1262
+ a.style.cssText = "top:1px;float:left;opacity:.5";
1263
+
1264
+ // Can't get basic test support
1265
+ if ( !all || !all.length ) {
1266
+ return {};
1267
+ }
1268
+
1269
+ // First batch of supports tests
1270
+ select = document.createElement("select");
1271
+ opt = select.appendChild( document.createElement("option") );
1272
+ input = div.getElementsByTagName("input")[ 0 ];
1273
+
1274
+ support = {
1275
+ // IE strips leading whitespace when .innerHTML is used
1276
+ leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1277
+
1278
+ // Make sure that tbody elements aren't automatically inserted
1279
+ // IE will insert them into empty tables
1280
+ tbody: !div.getElementsByTagName("tbody").length,
1281
+
1282
+ // Make sure that link elements get serialized correctly by innerHTML
1283
+ // This requires a wrapper element in IE
1284
+ htmlSerialize: !!div.getElementsByTagName("link").length,
1285
+
1286
+ // Get the style information from getAttribute
1287
+ // (IE uses .cssText instead)
1288
+ style: /top/.test( a.getAttribute("style") ),
1289
+
1290
+ // Make sure that URLs aren't manipulated
1291
+ // (IE normalizes it by default)
1292
+ hrefNormalized: ( a.getAttribute("href") === "/a" ),
1293
+
1294
+ // Make sure that element opacity exists
1295
+ // (IE uses filter instead)
1296
+ // Use a regex to work around a WebKit issue. See #5145
1297
+ opacity: /^0.5/.test( a.style.opacity ),
1298
+
1299
+ // Verify style float existence
1300
+ // (IE uses styleFloat instead of cssFloat)
1301
+ cssFloat: !!a.style.cssFloat,
1302
+
1303
+ // Make sure that if no value is specified for a checkbox
1304
+ // that it defaults to "on".
1305
+ // (WebKit defaults to "" instead)
1306
+ checkOn: ( input.value === "on" ),
1307
+
1308
+ // Make sure that a selected-by-default option has a working selected property.
1309
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1310
+ optSelected: opt.selected,
1311
+
1312
+ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1313
+ getSetAttribute: div.className !== "t",
1314
+
1315
+ // Tests for enctype support on a form(#6743)
1316
+ enctype: !!document.createElement("form").enctype,
1317
+
1318
+ // Makes sure cloning an html5 element does not cause problems
1319
+ // Where outerHTML is undefined, this still works
1320
+ html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
1321
+
1322
+ // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
1323
+ boxModel: ( document.compatMode === "CSS1Compat" ),
1324
+
1325
+ // Will be defined later
1326
+ submitBubbles: true,
1327
+ changeBubbles: true,
1328
+ focusinBubbles: false,
1329
+ deleteExpando: true,
1330
+ noCloneEvent: true,
1331
+ inlineBlockNeedsLayout: false,
1332
+ shrinkWrapBlocks: false,
1333
+ reliableMarginRight: true,
1334
+ boxSizingReliable: true,
1335
+ pixelPosition: false
1336
+ };
1337
+
1338
+ // Make sure checked status is properly cloned
1339
+ input.checked = true;
1340
+ support.noCloneChecked = input.cloneNode( true ).checked;
1341
+
1342
+ // Make sure that the options inside disabled selects aren't marked as disabled
1343
+ // (WebKit marks them as disabled)
1344
+ select.disabled = true;
1345
+ support.optDisabled = !opt.disabled;
1346
+
1347
+ // Test to see if it's possible to delete an expando from an element
1348
+ // Fails in Internet Explorer
1349
+ try {
1350
+ delete div.test;
1351
+ } catch( e ) {
1352
+ support.deleteExpando = false;
1353
+ }
1354
+
1355
+ if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1356
+ div.attachEvent( "onclick", clickFn = function() {
1357
+ // Cloning a node shouldn't copy over any
1358
+ // bound event handlers (IE does this)
1359
+ support.noCloneEvent = false;
1360
+ });
1361
+ div.cloneNode( true ).fireEvent("onclick");
1362
+ div.detachEvent( "onclick", clickFn );
1363
+ }
1364
+
1365
+ // Check if a radio maintains its value
1366
+ // after being appended to the DOM
1367
+ input = document.createElement("input");
1368
+ input.value = "t";
1369
+ input.setAttribute( "type", "radio" );
1370
+ support.radioValue = input.value === "t";
1371
+
1372
+ input.setAttribute( "checked", "checked" );
1373
+
1374
+ // #11217 - WebKit loses check when the name is after the checked attribute
1375
+ input.setAttribute( "name", "t" );
1376
+
1377
+ div.appendChild( input );
1378
+ fragment = document.createDocumentFragment();
1379
+ fragment.appendChild( div.lastChild );
1380
+
1381
+ // WebKit doesn't clone checked state correctly in fragments
1382
+ support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1383
+
1384
+ // Check if a disconnected checkbox will retain its checked
1385
+ // value of true after appended to the DOM (IE6/7)
1386
+ support.appendChecked = input.checked;
1387
+
1388
+ fragment.removeChild( input );
1389
+ fragment.appendChild( div );
1390
+
1391
+ // Technique from Juriy Zaytsev
1392
+ // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
1393
+ // We only care about the case where non-standard event systems
1394
+ // are used, namely in IE. Short-circuiting here helps us to
1395
+ // avoid an eval call (in setAttribute) which can cause CSP
1396
+ // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1397
+ if ( div.attachEvent ) {
1398
+ for ( i in {
1399
+ submit: true,
1400
+ change: true,
1401
+ focusin: true
1402
+ }) {
1403
+ eventName = "on" + i;
1404
+ isSupported = ( eventName in div );
1405
+ if ( !isSupported ) {
1406
+ div.setAttribute( eventName, "return;" );
1407
+ isSupported = ( typeof div[ eventName ] === "function" );
1408
+ }
1409
+ support[ i + "Bubbles" ] = isSupported;
1410
+ }
1411
+ }
1412
+
1413
+ // Run tests that need a body at doc ready
1414
+ jQuery(function() {
1415
+ var container, div, tds, marginDiv,
1416
+ divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;",
1417
+ body = document.getElementsByTagName("body")[0];
1418
+
1419
+ if ( !body ) {
1420
+ // Return for frameset docs that don't have a body
1421
+ return;
1422
+ }
1423
+
1424
+ container = document.createElement("div");
1425
+ container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px";
1426
+ body.insertBefore( container, body.firstChild );
1427
+
1428
+ // Construct the test element
1429
+ div = document.createElement("div");
1430
+ container.appendChild( div );
1431
+
1432
+ // Check if table cells still have offsetWidth/Height when they are set
1433
+ // to display:none and there are still other visible table cells in a
1434
+ // table row; if so, offsetWidth/Height are not reliable for use when
1435
+ // determining if an element has been hidden directly using
1436
+ // display:none (it is still safe to use offsets if a parent element is
1437
+ // hidden; don safety goggles and see bug #4512 for more information).
1438
+ // (only IE 8 fails this test)
1439
+ div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
1440
+ tds = div.getElementsByTagName("td");
1441
+ tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
1442
+ isSupported = ( tds[ 0 ].offsetHeight === 0 );
1443
+
1444
+ tds[ 0 ].style.display = "";
1445
+ tds[ 1 ].style.display = "none";
1446
+
1447
+ // Check if empty table cells still have offsetWidth/Height
1448
+ // (IE <= 8 fail this test)
1449
+ support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1450
+
1451
+ // Check box-sizing and margin behavior
1452
+ div.innerHTML = "";
1453
+ div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
1454
+ support.boxSizing = ( div.offsetWidth === 4 );
1455
+ support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
1456
+
1457
+ // NOTE: To any future maintainer, we've window.getComputedStyle
1458
+ // because jsdom on node.js will break without it.
1459
+ if ( window.getComputedStyle ) {
1460
+ support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
1461
+ support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
1462
+
1463
+ // Check if div with explicit width and no margin-right incorrectly
1464
+ // gets computed margin-right based on width of container. For more
1465
+ // info see bug #3333
1466
+ // Fails in WebKit before Feb 2011 nightlies
1467
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1468
+ marginDiv = document.createElement("div");
1469
+ marginDiv.style.cssText = div.style.cssText = divReset;
1470
+ marginDiv.style.marginRight = marginDiv.style.width = "0";
1471
+ div.style.width = "1px";
1472
+ div.appendChild( marginDiv );
1473
+ support.reliableMarginRight =
1474
+ !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
1475
+ }
1476
+
1477
+ if ( typeof div.style.zoom !== "undefined" ) {
1478
+ // Check if natively block-level elements act like inline-block
1479
+ // elements when setting their display to 'inline' and giving
1480
+ // them layout
1481
+ // (IE < 8 does this)
1482
+ div.innerHTML = "";
1483
+ div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
1484
+ support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
1485
+
1486
+ // Check if elements with layout shrink-wrap their children
1487
+ // (IE 6 does this)
1488
+ div.style.display = "block";
1489
+ div.style.overflow = "visible";
1490
+ div.innerHTML = "<div></div>";
1491
+ div.firstChild.style.width = "5px";
1492
+ support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
1493
+
1494
+ container.style.zoom = 1;
1495
+ }
1496
+
1497
+ // Null elements to avoid leaks in IE
1498
+ body.removeChild( container );
1499
+ container = div = tds = marginDiv = null;
1500
+ });
1501
+
1502
+ // Null elements to avoid leaks in IE
1503
+ fragment.removeChild( div );
1504
+ all = a = select = opt = input = fragment = div = null;
1505
+
1506
+ return support;
1507
+ })();
1508
+ var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
1509
+ rmultiDash = /([A-Z])/g;
1510
+
1511
+ jQuery.extend({
1512
+ cache: {},
1513
+
1514
+ deletedIds: [],
1515
+
1516
+ // Remove at next major release (1.9/2.0)
1517
+ uuid: 0,
1518
+
1519
+ // Unique for each copy of jQuery on the page
1520
+ // Non-digits removed to match rinlinejQuery
1521
+ expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1522
+
1523
+ // The following elements throw uncatchable exceptions if you
1524
+ // attempt to add expando properties to them.
1525
+ noData: {
1526
+ "embed": true,
1527
+ // Ban all objects except for Flash (which handle expandos)
1528
+ "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1529
+ "applet": true
1530
+ },
1531
+
1532
+ hasData: function( elem ) {
1533
+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1534
+ return !!elem && !isEmptyDataObject( elem );
1535
+ },
1536
+
1537
+ data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1538
+ if ( !jQuery.acceptData( elem ) ) {
1539
+ return;
1540
+ }
1541
+
1542
+ var thisCache, ret,
1543
+ internalKey = jQuery.expando,
1544
+ getByName = typeof name === "string",
1545
+
1546
+ // We have to handle DOM nodes and JS objects differently because IE6-7
1547
+ // can't GC object references properly across the DOM-JS boundary
1548
+ isNode = elem.nodeType,
1549
+
1550
+ // Only DOM nodes need the global jQuery cache; JS object data is
1551
+ // attached directly to the object so GC can occur automatically
1552
+ cache = isNode ? jQuery.cache : elem,
1553
+
1554
+ // Only defining an ID for JS objects if its cache already exists allows
1555
+ // the code to shortcut on the same path as a DOM node with no cache
1556
+ id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
1557
+
1558
+ // Avoid doing any more work than we need to when trying to get data on an
1559
+ // object that has no data at all
1560
+ if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {
1561
+ return;
1562
+ }
1563
+
1564
+ if ( !id ) {
1565
+ // Only DOM nodes need a new unique ID for each element since their data
1566
+ // ends up in the global cache
1567
+ if ( isNode ) {
1568
+ elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;
1569
+ } else {
1570
+ id = internalKey;
1571
+ }
1572
+ }
1573
+
1574
+ if ( !cache[ id ] ) {
1575
+ cache[ id ] = {};
1576
+
1577
+ // Avoids exposing jQuery metadata on plain JS objects when the object
1578
+ // is serialized using JSON.stringify
1579
+ if ( !isNode ) {
1580
+ cache[ id ].toJSON = jQuery.noop;
1581
+ }
1582
+ }
1583
+
1584
+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
1585
+ // shallow copied over onto the existing cache
1586
+ if ( typeof name === "object" || typeof name === "function" ) {
1587
+ if ( pvt ) {
1588
+ cache[ id ] = jQuery.extend( cache[ id ], name );
1589
+ } else {
1590
+ cache[ id ].data = jQuery.extend( cache[ id ].data, name );
1591
+ }
1592
+ }
1593
+
1594
+ thisCache = cache[ id ];
1595
+
1596
+ // jQuery data() is stored in a separate object inside the object's internal data
1597
+ // cache in order to avoid key collisions between internal data and user-defined
1598
+ // data.
1599
+ if ( !pvt ) {
1600
+ if ( !thisCache.data ) {
1601
+ thisCache.data = {};
1602
+ }
1603
+
1604
+ thisCache = thisCache.data;
1605
+ }
1606
+
1607
+ if ( data !== undefined ) {
1608
+ thisCache[ jQuery.camelCase( name ) ] = data;
1609
+ }
1610
+
1611
+ // Check for both converted-to-camel and non-converted data property names
1612
+ // If a data property was specified
1613
+ if ( getByName ) {
1614
+
1615
+ // First Try to find as-is property data
1616
+ ret = thisCache[ name ];
1617
+
1618
+ // Test for null|undefined property data
1619
+ if ( ret == null ) {
1620
+
1621
+ // Try to find the camelCased property
1622
+ ret = thisCache[ jQuery.camelCase( name ) ];
1623
+ }
1624
+ } else {
1625
+ ret = thisCache;
1626
+ }
1627
+
1628
+ return ret;
1629
+ },
1630
+
1631
+ removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1632
+ if ( !jQuery.acceptData( elem ) ) {
1633
+ return;
1634
+ }
1635
+
1636
+ var thisCache, i, l,
1637
+
1638
+ isNode = elem.nodeType,
1639
+
1640
+ // See jQuery.data for more information
1641
+ cache = isNode ? jQuery.cache : elem,
1642
+ id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1643
+
1644
+ // If there is already no cache entry for this object, there is no
1645
+ // purpose in continuing
1646
+ if ( !cache[ id ] ) {
1647
+ return;
1648
+ }
1649
+
1650
+ if ( name ) {
1651
+
1652
+ thisCache = pvt ? cache[ id ] : cache[ id ].data;
1653
+
1654
+ if ( thisCache ) {
1655
+
1656
+ // Support array or space separated string names for data keys
1657
+ if ( !jQuery.isArray( name ) ) {
1658
+
1659
+ // try the string as a key before any manipulation
1660
+ if ( name in thisCache ) {
1661
+ name = [ name ];
1662
+ } else {
1663
+
1664
+ // split the camel cased version by spaces unless a key with the spaces exists
1665
+ name = jQuery.camelCase( name );
1666
+ if ( name in thisCache ) {
1667
+ name = [ name ];
1668
+ } else {
1669
+ name = name.split(" ");
1670
+ }
1671
+ }
1672
+ }
1673
+
1674
+ for ( i = 0, l = name.length; i < l; i++ ) {
1675
+ delete thisCache[ name[i] ];
1676
+ }
1677
+
1678
+ // If there is no data left in the cache, we want to continue
1679
+ // and let the cache object itself get destroyed
1680
+ if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
1681
+ return;
1682
+ }
1683
+ }
1684
+ }
1685
+
1686
+ // See jQuery.data for more information
1687
+ if ( !pvt ) {
1688
+ delete cache[ id ].data;
1689
+
1690
+ // Don't destroy the parent cache unless the internal data object
1691
+ // had been the only thing left in it
1692
+ if ( !isEmptyDataObject( cache[ id ] ) ) {
1693
+ return;
1694
+ }
1695
+ }
1696
+
1697
+ // Destroy the cache
1698
+ if ( isNode ) {
1699
+ jQuery.cleanData( [ elem ], true );
1700
+
1701
+ // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
1702
+ } else if ( jQuery.support.deleteExpando || cache != cache.window ) {
1703
+ delete cache[ id ];
1704
+
1705
+ // When all else fails, null
1706
+ } else {
1707
+ cache[ id ] = null;
1708
+ }
1709
+ },
1710
+
1711
+ // For internal use only.
1712
+ _data: function( elem, name, data ) {
1713
+ return jQuery.data( elem, name, data, true );
1714
+ },
1715
+
1716
+ // A method for determining if a DOM node can handle the data expando
1717
+ acceptData: function( elem ) {
1718
+ var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
1719
+
1720
+ // nodes accept data unless otherwise specified; rejection can be conditional
1721
+ return !noData || noData !== true && elem.getAttribute("classid") === noData;
1722
+ }
1723
+ });
1724
+
1725
+ jQuery.fn.extend({
1726
+ data: function( key, value ) {
1727
+ var parts, part, attr, name, l,
1728
+ elem = this[0],
1729
+ i = 0,
1730
+ data = null;
1731
+
1732
+ // Gets all values
1733
+ if ( key === undefined ) {
1734
+ if ( this.length ) {
1735
+ data = jQuery.data( elem );
1736
+
1737
+ if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
1738
+ attr = elem.attributes;
1739
+ for ( l = attr.length; i < l; i++ ) {
1740
+ name = attr[i].name;
1741
+
1742
+ if ( !name.indexOf( "data-" ) ) {
1743
+ name = jQuery.camelCase( name.substring(5) );
1744
+
1745
+ dataAttr( elem, name, data[ name ] );
1746
+ }
1747
+ }
1748
+ jQuery._data( elem, "parsedAttrs", true );
1749
+ }
1750
+ }
1751
+
1752
+ return data;
1753
+ }
1754
+
1755
+ // Sets multiple values
1756
+ if ( typeof key === "object" ) {
1757
+ return this.each(function() {
1758
+ jQuery.data( this, key );
1759
+ });
1760
+ }
1761
+
1762
+ parts = key.split( ".", 2 );
1763
+ parts[1] = parts[1] ? "." + parts[1] : "";
1764
+ part = parts[1] + "!";
1765
+
1766
+ return jQuery.access( this, function( value ) {
1767
+
1768
+ if ( value === undefined ) {
1769
+ data = this.triggerHandler( "getData" + part, [ parts[0] ] );
1770
+
1771
+ // Try to fetch any internally stored data first
1772
+ if ( data === undefined && elem ) {
1773
+ data = jQuery.data( elem, key );
1774
+ data = dataAttr( elem, key, data );
1775
+ }
1776
+
1777
+ return data === undefined && parts[1] ?
1778
+ this.data( parts[0] ) :
1779
+ data;
1780
+ }
1781
+
1782
+ parts[1] = value;
1783
+ this.each(function() {
1784
+ var self = jQuery( this );
1785
+
1786
+ self.triggerHandler( "setData" + part, parts );
1787
+ jQuery.data( this, key, value );
1788
+ self.triggerHandler( "changeData" + part, parts );
1789
+ });
1790
+ }, null, value, arguments.length > 1, null, false );
1791
+ },
1792
+
1793
+ removeData: function( key ) {
1794
+ return this.each(function() {
1795
+ jQuery.removeData( this, key );
1796
+ });
1797
+ }
1798
+ });
1799
+
1800
+ function dataAttr( elem, key, data ) {
1801
+ // If nothing was found internally, try to fetch any
1802
+ // data from the HTML5 data-* attribute
1803
+ if ( data === undefined && elem.nodeType === 1 ) {
1804
+
1805
+ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
1806
+
1807
+ data = elem.getAttribute( name );
1808
+
1809
+ if ( typeof data === "string" ) {
1810
+ try {
1811
+ data = data === "true" ? true :
1812
+ data === "false" ? false :
1813
+ data === "null" ? null :
1814
+ // Only convert to a number if it doesn't change the string
1815
+ +data + "" === data ? +data :
1816
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
1817
+ data;
1818
+ } catch( e ) {}
1819
+
1820
+ // Make sure we set the data so it isn't changed later
1821
+ jQuery.data( elem, key, data );
1822
+
1823
+ } else {
1824
+ data = undefined;
1825
+ }
1826
+ }
1827
+
1828
+ return data;
1829
+ }
1830
+
1831
+ // checks a cache object for emptiness
1832
+ function isEmptyDataObject( obj ) {
1833
+ var name;
1834
+ for ( name in obj ) {
1835
+
1836
+ // if the public data object is empty, the private is still empty
1837
+ if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
1838
+ continue;
1839
+ }
1840
+ if ( name !== "toJSON" ) {
1841
+ return false;
1842
+ }
1843
+ }
1844
+
1845
+ return true;
1846
+ }
1847
+ jQuery.extend({
1848
+ queue: function( elem, type, data ) {
1849
+ var queue;
1850
+
1851
+ if ( elem ) {
1852
+ type = ( type || "fx" ) + "queue";
1853
+ queue = jQuery._data( elem, type );
1854
+
1855
+ // Speed up dequeue by getting out quickly if this is just a lookup
1856
+ if ( data ) {
1857
+ if ( !queue || jQuery.isArray(data) ) {
1858
+ queue = jQuery._data( elem, type, jQuery.makeArray(data) );
1859
+ } else {
1860
+ queue.push( data );
1861
+ }
1862
+ }
1863
+ return queue || [];
1864
+ }
1865
+ },
1866
+
1867
+ dequeue: function( elem, type ) {
1868
+ type = type || "fx";
1869
+
1870
+ var queue = jQuery.queue( elem, type ),
1871
+ startLength = queue.length,
1872
+ fn = queue.shift(),
1873
+ hooks = jQuery._queueHooks( elem, type ),
1874
+ next = function() {
1875
+ jQuery.dequeue( elem, type );
1876
+ };
1877
+
1878
+ // If the fx queue is dequeued, always remove the progress sentinel
1879
+ if ( fn === "inprogress" ) {
1880
+ fn = queue.shift();
1881
+ startLength--;
1882
+ }
1883
+
1884
+ if ( fn ) {
1885
+
1886
+ // Add a progress sentinel to prevent the fx queue from being
1887
+ // automatically dequeued
1888
+ if ( type === "fx" ) {
1889
+ queue.unshift( "inprogress" );
1890
+ }
1891
+
1892
+ // clear up the last queue stop function
1893
+ delete hooks.stop;
1894
+ fn.call( elem, next, hooks );
1895
+ }
1896
+
1897
+ if ( !startLength && hooks ) {
1898
+ hooks.empty.fire();
1899
+ }
1900
+ },
1901
+
1902
+ // not intended for public consumption - generates a queueHooks object, or returns the current one
1903
+ _queueHooks: function( elem, type ) {
1904
+ var key = type + "queueHooks";
1905
+ return jQuery._data( elem, key ) || jQuery._data( elem, key, {
1906
+ empty: jQuery.Callbacks("once memory").add(function() {
1907
+ jQuery.removeData( elem, type + "queue", true );
1908
+ jQuery.removeData( elem, key, true );
1909
+ })
1910
+ });
1911
+ }
1912
+ });
1913
+
1914
+ jQuery.fn.extend({
1915
+ queue: function( type, data ) {
1916
+ var setter = 2;
1917
+
1918
+ if ( typeof type !== "string" ) {
1919
+ data = type;
1920
+ type = "fx";
1921
+ setter--;
1922
+ }
1923
+
1924
+ if ( arguments.length < setter ) {
1925
+ return jQuery.queue( this[0], type );
1926
+ }
1927
+
1928
+ return data === undefined ?
1929
+ this :
1930
+ this.each(function() {
1931
+ var queue = jQuery.queue( this, type, data );
1932
+
1933
+ // ensure a hooks for this queue
1934
+ jQuery._queueHooks( this, type );
1935
+
1936
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
1937
+ jQuery.dequeue( this, type );
1938
+ }
1939
+ });
1940
+ },
1941
+ dequeue: function( type ) {
1942
+ return this.each(function() {
1943
+ jQuery.dequeue( this, type );
1944
+ });
1945
+ },
1946
+ // Based off of the plugin by Clint Helfers, with permission.
1947
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
1948
+ delay: function( time, type ) {
1949
+ time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
1950
+ type = type || "fx";
1951
+
1952
+ return this.queue( type, function( next, hooks ) {
1953
+ var timeout = setTimeout( next, time );
1954
+ hooks.stop = function() {
1955
+ clearTimeout( timeout );
1956
+ };
1957
+ });
1958
+ },
1959
+ clearQueue: function( type ) {
1960
+ return this.queue( type || "fx", [] );
1961
+ },
1962
+ // Get a promise resolved when queues of a certain type
1963
+ // are emptied (fx is the type by default)
1964
+ promise: function( type, obj ) {
1965
+ var tmp,
1966
+ count = 1,
1967
+ defer = jQuery.Deferred(),
1968
+ elements = this,
1969
+ i = this.length,
1970
+ resolve = function() {
1971
+ if ( !( --count ) ) {
1972
+ defer.resolveWith( elements, [ elements ] );
1973
+ }
1974
+ };
1975
+
1976
+ if ( typeof type !== "string" ) {
1977
+ obj = type;
1978
+ type = undefined;
1979
+ }
1980
+ type = type || "fx";
1981
+
1982
+ while( i-- ) {
1983
+ tmp = jQuery._data( elements[ i ], type + "queueHooks" );
1984
+ if ( tmp && tmp.empty ) {
1985
+ count++;
1986
+ tmp.empty.add( resolve );
1987
+ }
1988
+ }
1989
+ resolve();
1990
+ return defer.promise( obj );
1991
+ }
1992
+ });
1993
+ var nodeHook, boolHook, fixSpecified,
1994
+ rclass = /[\t\r\n]/g,
1995
+ rreturn = /\r/g,
1996
+ rtype = /^(?:button|input)$/i,
1997
+ rfocusable = /^(?:button|input|object|select|textarea)$/i,
1998
+ rclickable = /^a(?:rea|)$/i,
1999
+ rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
2000
+ getSetAttribute = jQuery.support.getSetAttribute;
2001
+
2002
+ jQuery.fn.extend({
2003
+ attr: function( name, value ) {
2004
+ return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
2005
+ },
2006
+
2007
+ removeAttr: function( name ) {
2008
+ return this.each(function() {
2009
+ jQuery.removeAttr( this, name );
2010
+ });
2011
+ },
2012
+
2013
+ prop: function( name, value ) {
2014
+ return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
2015
+ },
2016
+
2017
+ removeProp: function( name ) {
2018
+ name = jQuery.propFix[ name ] || name;
2019
+ return this.each(function() {
2020
+ // try/catch handles cases where IE balks (such as removing a property on window)
2021
+ try {
2022
+ this[ name ] = undefined;
2023
+ delete this[ name ];
2024
+ } catch( e ) {}
2025
+ });
2026
+ },
2027
+
2028
+ addClass: function( value ) {
2029
+ var classNames, i, l, elem,
2030
+ setClass, c, cl;
2031
+
2032
+ if ( jQuery.isFunction( value ) ) {
2033
+ return this.each(function( j ) {
2034
+ jQuery( this ).addClass( value.call(this, j, this.className) );
2035
+ });
2036
+ }
2037
+
2038
+ if ( value && typeof value === "string" ) {
2039
+ classNames = value.split( core_rspace );
2040
+
2041
+ for ( i = 0, l = this.length; i < l; i++ ) {
2042
+ elem = this[ i ];
2043
+
2044
+ if ( elem.nodeType === 1 ) {
2045
+ if ( !elem.className && classNames.length === 1 ) {
2046
+ elem.className = value;
2047
+
2048
+ } else {
2049
+ setClass = " " + elem.className + " ";
2050
+
2051
+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2052
+ if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) {
2053
+ setClass += classNames[ c ] + " ";
2054
+ }
2055
+ }
2056
+ elem.className = jQuery.trim( setClass );
2057
+ }
2058
+ }
2059
+ }
2060
+ }
2061
+
2062
+ return this;
2063
+ },
2064
+
2065
+ removeClass: function( value ) {
2066
+ var removes, className, elem, c, cl, i, l;
2067
+
2068
+ if ( jQuery.isFunction( value ) ) {
2069
+ return this.each(function( j ) {
2070
+ jQuery( this ).removeClass( value.call(this, j, this.className) );
2071
+ });
2072
+ }
2073
+ if ( (value && typeof value === "string") || value === undefined ) {
2074
+ removes = ( value || "" ).split( core_rspace );
2075
+
2076
+ for ( i = 0, l = this.length; i < l; i++ ) {
2077
+ elem = this[ i ];
2078
+ if ( elem.nodeType === 1 && elem.className ) {
2079
+
2080
+ className = (" " + elem.className + " ").replace( rclass, " " );
2081
+
2082
+ // loop over each item in the removal list
2083
+ for ( c = 0, cl = removes.length; c < cl; c++ ) {
2084
+ // Remove until there is nothing to remove,
2085
+ while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) {
2086
+ className = className.replace( " " + removes[ c ] + " " , " " );
2087
+ }
2088
+ }
2089
+ elem.className = value ? jQuery.trim( className ) : "";
2090
+ }
2091
+ }
2092
+ }
2093
+
2094
+ return this;
2095
+ },
2096
+
2097
+ toggleClass: function( value, stateVal ) {
2098
+ var type = typeof value,
2099
+ isBool = typeof stateVal === "boolean";
2100
+
2101
+ if ( jQuery.isFunction( value ) ) {
2102
+ return this.each(function( i ) {
2103
+ jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2104
+ });
2105
+ }
2106
+
2107
+ return this.each(function() {
2108
+ if ( type === "string" ) {
2109
+ // toggle individual class names
2110
+ var className,
2111
+ i = 0,
2112
+ self = jQuery( this ),
2113
+ state = stateVal,
2114
+ classNames = value.split( core_rspace );
2115
+
2116
+ while ( (className = classNames[ i++ ]) ) {
2117
+ // check each className given, space separated list
2118
+ state = isBool ? state : !self.hasClass( className );
2119
+ self[ state ? "addClass" : "removeClass" ]( className );
2120
+ }
2121
+
2122
+ } else if ( type === "undefined" || type === "boolean" ) {
2123
+ if ( this.className ) {
2124
+ // store className if set
2125
+ jQuery._data( this, "__className__", this.className );
2126
+ }
2127
+
2128
+ // toggle whole className
2129
+ this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2130
+ }
2131
+ });
2132
+ },
2133
+
2134
+ hasClass: function( selector ) {
2135
+ var className = " " + selector + " ",
2136
+ i = 0,
2137
+ l = this.length;
2138
+ for ( ; i < l; i++ ) {
2139
+ if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
2140
+ return true;
2141
+ }
2142
+ }
2143
+
2144
+ return false;
2145
+ },
2146
+
2147
+ val: function( value ) {
2148
+ var hooks, ret, isFunction,
2149
+ elem = this[0];
2150
+
2151
+ if ( !arguments.length ) {
2152
+ if ( elem ) {
2153
+ hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
2154
+
2155
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2156
+ return ret;
2157
+ }
2158
+
2159
+ ret = elem.value;
2160
+
2161
+ return typeof ret === "string" ?
2162
+ // handle most common string cases
2163
+ ret.replace(rreturn, "") :
2164
+ // handle cases where value is null/undef or number
2165
+ ret == null ? "" : ret;
2166
+ }
2167
+
2168
+ return;
2169
+ }
2170
+
2171
+ isFunction = jQuery.isFunction( value );
2172
+
2173
+ return this.each(function( i ) {
2174
+ var val,
2175
+ self = jQuery(this);
2176
+
2177
+ if ( this.nodeType !== 1 ) {
2178
+ return;
2179
+ }
2180
+
2181
+ if ( isFunction ) {
2182
+ val = value.call( this, i, self.val() );
2183
+ } else {
2184
+ val = value;
2185
+ }
2186
+
2187
+ // Treat null/undefined as ""; convert numbers to string
2188
+ if ( val == null ) {
2189
+ val = "";
2190
+ } else if ( typeof val === "number" ) {
2191
+ val += "";
2192
+ } else if ( jQuery.isArray( val ) ) {
2193
+ val = jQuery.map(val, function ( value ) {
2194
+ return value == null ? "" : value + "";
2195
+ });
2196
+ }
2197
+
2198
+ hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
2199
+
2200
+ // If set returns undefined, fall back to normal setting
2201
+ if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2202
+ this.value = val;
2203
+ }
2204
+ });
2205
+ }
2206
+ });
2207
+
2208
+ jQuery.extend({
2209
+ valHooks: {
2210
+ option: {
2211
+ get: function( elem ) {
2212
+ // attributes.value is undefined in Blackberry 4.7 but
2213
+ // uses .value. See #6932
2214
+ var val = elem.attributes.value;
2215
+ return !val || val.specified ? elem.value : elem.text;
2216
+ }
2217
+ },
2218
+ select: {
2219
+ get: function( elem ) {
2220
+ var value, i, max, option,
2221
+ index = elem.selectedIndex,
2222
+ values = [],
2223
+ options = elem.options,
2224
+ one = elem.type === "select-one";
2225
+
2226
+ // Nothing was selected
2227
+ if ( index < 0 ) {
2228
+ return null;
2229
+ }
2230
+
2231
+ // Loop through all the selected options
2232
+ i = one ? index : 0;
2233
+ max = one ? index + 1 : options.length;
2234
+ for ( ; i < max; i++ ) {
2235
+ option = options[ i ];
2236
+
2237
+ // Don't return options that are disabled or in a disabled optgroup
2238
+ if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2239
+ (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2240
+
2241
+ // Get the specific value for the option
2242
+ value = jQuery( option ).val();
2243
+
2244
+ // We don't need an array for one selects
2245
+ if ( one ) {
2246
+ return value;
2247
+ }
2248
+
2249
+ // Multi-Selects return an array
2250
+ values.push( value );
2251
+ }
2252
+ }
2253
+
2254
+ // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2255
+ if ( one && !values.length && options.length ) {
2256
+ return jQuery( options[ index ] ).val();
2257
+ }
2258
+
2259
+ return values;
2260
+ },
2261
+
2262
+ set: function( elem, value ) {
2263
+ var values = jQuery.makeArray( value );
2264
+
2265
+ jQuery(elem).find("option").each(function() {
2266
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2267
+ });
2268
+
2269
+ if ( !values.length ) {
2270
+ elem.selectedIndex = -1;
2271
+ }
2272
+ return values;
2273
+ }
2274
+ }
2275
+ },
2276
+
2277
+ // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9
2278
+ attrFn: {},
2279
+
2280
+ attr: function( elem, name, value, pass ) {
2281
+ var ret, hooks, notxml,
2282
+ nType = elem.nodeType;
2283
+
2284
+ // don't get/set attributes on text, comment and attribute nodes
2285
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2286
+ return;
2287
+ }
2288
+
2289
+ if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {
2290
+ return jQuery( elem )[ name ]( value );
2291
+ }
2292
+
2293
+ // Fallback to prop when attributes are not supported
2294
+ if ( typeof elem.getAttribute === "undefined" ) {
2295
+ return jQuery.prop( elem, name, value );
2296
+ }
2297
+
2298
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2299
+
2300
+ // All attributes are lowercase
2301
+ // Grab necessary hook if one is defined
2302
+ if ( notxml ) {
2303
+ name = name.toLowerCase();
2304
+ hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
2305
+ }
2306
+
2307
+ if ( value !== undefined ) {
2308
+
2309
+ if ( value === null ) {
2310
+ jQuery.removeAttr( elem, name );
2311
+ return;
2312
+
2313
+ } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2314
+ return ret;
2315
+
2316
+ } else {
2317
+ elem.setAttribute( name, value + "" );
2318
+ return value;
2319
+ }
2320
+
2321
+ } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2322
+ return ret;
2323
+
2324
+ } else {
2325
+
2326
+ ret = elem.getAttribute( name );
2327
+
2328
+ // Non-existent attributes return null, we normalize to undefined
2329
+ return ret === null ?
2330
+ undefined :
2331
+ ret;
2332
+ }
2333
+ },
2334
+
2335
+ removeAttr: function( elem, value ) {
2336
+ var propName, attrNames, name, isBool,
2337
+ i = 0;
2338
+
2339
+ if ( value && elem.nodeType === 1 ) {
2340
+
2341
+ attrNames = value.split( core_rspace );
2342
+
2343
+ for ( ; i < attrNames.length; i++ ) {
2344
+ name = attrNames[ i ];
2345
+
2346
+ if ( name ) {
2347
+ propName = jQuery.propFix[ name ] || name;
2348
+ isBool = rboolean.test( name );
2349
+
2350
+ // See #9699 for explanation of this approach (setting first, then removal)
2351
+ // Do not do this for boolean attributes (see #10870)
2352
+ if ( !isBool ) {
2353
+ jQuery.attr( elem, name, "" );
2354
+ }
2355
+ elem.removeAttribute( getSetAttribute ? name : propName );
2356
+
2357
+ // Set corresponding property to false for boolean attributes
2358
+ if ( isBool && propName in elem ) {
2359
+ elem[ propName ] = false;
2360
+ }
2361
+ }
2362
+ }
2363
+ }
2364
+ },
2365
+
2366
+ attrHooks: {
2367
+ type: {
2368
+ set: function( elem, value ) {
2369
+ // We can't allow the type property to be changed (since it causes problems in IE)
2370
+ if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2371
+ jQuery.error( "type property can't be changed" );
2372
+ } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2373
+ // Setting the type on a radio button after the value resets the value in IE6-9
2374
+ // Reset value to it's default in case type is set after value
2375
+ // This is for element creation
2376
+ var val = elem.value;
2377
+ elem.setAttribute( "type", value );
2378
+ if ( val ) {
2379
+ elem.value = val;
2380
+ }
2381
+ return value;
2382
+ }
2383
+ }
2384
+ },
2385
+ // Use the value property for back compat
2386
+ // Use the nodeHook for button elements in IE6/7 (#1954)
2387
+ value: {
2388
+ get: function( elem, name ) {
2389
+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2390
+ return nodeHook.get( elem, name );
2391
+ }
2392
+ return name in elem ?
2393
+ elem.value :
2394
+ null;
2395
+ },
2396
+ set: function( elem, value, name ) {
2397
+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2398
+ return nodeHook.set( elem, value, name );
2399
+ }
2400
+ // Does not return so that setAttribute is also used
2401
+ elem.value = value;
2402
+ }
2403
+ }
2404
+ },
2405
+
2406
+ propFix: {
2407
+ tabindex: "tabIndex",
2408
+ readonly: "readOnly",
2409
+ "for": "htmlFor",
2410
+ "class": "className",
2411
+ maxlength: "maxLength",
2412
+ cellspacing: "cellSpacing",
2413
+ cellpadding: "cellPadding",
2414
+ rowspan: "rowSpan",
2415
+ colspan: "colSpan",
2416
+ usemap: "useMap",
2417
+ frameborder: "frameBorder",
2418
+ contenteditable: "contentEditable"
2419
+ },
2420
+
2421
+ prop: function( elem, name, value ) {
2422
+ var ret, hooks, notxml,
2423
+ nType = elem.nodeType;
2424
+
2425
+ // don't get/set properties on text, comment and attribute nodes
2426
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2427
+ return;
2428
+ }
2429
+
2430
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2431
+
2432
+ if ( notxml ) {
2433
+ // Fix name and attach hooks
2434
+ name = jQuery.propFix[ name ] || name;
2435
+ hooks = jQuery.propHooks[ name ];
2436
+ }
2437
+
2438
+ if ( value !== undefined ) {
2439
+ if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2440
+ return ret;
2441
+
2442
+ } else {
2443
+ return ( elem[ name ] = value );
2444
+ }
2445
+
2446
+ } else {
2447
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2448
+ return ret;
2449
+
2450
+ } else {
2451
+ return elem[ name ];
2452
+ }
2453
+ }
2454
+ },
2455
+
2456
+ propHooks: {
2457
+ tabIndex: {
2458
+ get: function( elem ) {
2459
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2460
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2461
+ var attributeNode = elem.getAttributeNode("tabindex");
2462
+
2463
+ return attributeNode && attributeNode.specified ?
2464
+ parseInt( attributeNode.value, 10 ) :
2465
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2466
+ 0 :
2467
+ undefined;
2468
+ }
2469
+ }
2470
+ }
2471
+ });
2472
+
2473
+ // Hook for boolean attributes
2474
+ boolHook = {
2475
+ get: function( elem, name ) {
2476
+ // Align boolean attributes with corresponding properties
2477
+ // Fall back to attribute presence where some booleans are not supported
2478
+ var attrNode,
2479
+ property = jQuery.prop( elem, name );
2480
+ return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
2481
+ name.toLowerCase() :
2482
+ undefined;
2483
+ },
2484
+ set: function( elem, value, name ) {
2485
+ var propName;
2486
+ if ( value === false ) {
2487
+ // Remove boolean attributes when set to false
2488
+ jQuery.removeAttr( elem, name );
2489
+ } else {
2490
+ // value is true since we know at this point it's type boolean and not false
2491
+ // Set boolean attributes to the same name and set the DOM property
2492
+ propName = jQuery.propFix[ name ] || name;
2493
+ if ( propName in elem ) {
2494
+ // Only set the IDL specifically if it already exists on the element
2495
+ elem[ propName ] = true;
2496
+ }
2497
+
2498
+ elem.setAttribute( name, name.toLowerCase() );
2499
+ }
2500
+ return name;
2501
+ }
2502
+ };
2503
+
2504
+ // IE6/7 do not support getting/setting some attributes with get/setAttribute
2505
+ if ( !getSetAttribute ) {
2506
+
2507
+ fixSpecified = {
2508
+ name: true,
2509
+ id: true,
2510
+ coords: true
2511
+ };
2512
+
2513
+ // Use this for any attribute in IE6/7
2514
+ // This fixes almost every IE6/7 issue
2515
+ nodeHook = jQuery.valHooks.button = {
2516
+ get: function( elem, name ) {
2517
+ var ret;
2518
+ ret = elem.getAttributeNode( name );
2519
+ return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ?
2520
+ ret.value :
2521
+ undefined;
2522
+ },
2523
+ set: function( elem, value, name ) {
2524
+ // Set the existing or create a new attribute node
2525
+ var ret = elem.getAttributeNode( name );
2526
+ if ( !ret ) {
2527
+ ret = document.createAttribute( name );
2528
+ elem.setAttributeNode( ret );
2529
+ }
2530
+ return ( ret.value = value + "" );
2531
+ }
2532
+ };
2533
+
2534
+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2535
+ // This is for removals
2536
+ jQuery.each([ "width", "height" ], function( i, name ) {
2537
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2538
+ set: function( elem, value ) {
2539
+ if ( value === "" ) {
2540
+ elem.setAttribute( name, "auto" );
2541
+ return value;
2542
+ }
2543
+ }
2544
+ });
2545
+ });
2546
+
2547
+ // Set contenteditable to false on removals(#10429)
2548
+ // Setting to empty string throws an error as an invalid value
2549
+ jQuery.attrHooks.contenteditable = {
2550
+ get: nodeHook.get,
2551
+ set: function( elem, value, name ) {
2552
+ if ( value === "" ) {
2553
+ value = "false";
2554
+ }
2555
+ nodeHook.set( elem, value, name );
2556
+ }
2557
+ };
2558
+ }
2559
+
2560
+
2561
+ // Some attributes require a special call on IE
2562
+ if ( !jQuery.support.hrefNormalized ) {
2563
+ jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2564
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2565
+ get: function( elem ) {
2566
+ var ret = elem.getAttribute( name, 2 );
2567
+ return ret === null ? undefined : ret;
2568
+ }
2569
+ });
2570
+ });
2571
+ }
2572
+
2573
+ if ( !jQuery.support.style ) {
2574
+ jQuery.attrHooks.style = {
2575
+ get: function( elem ) {
2576
+ // Return undefined in the case of empty string
2577
+ // Normalize to lowercase since IE uppercases css property names
2578
+ return elem.style.cssText.toLowerCase() || undefined;
2579
+ },
2580
+ set: function( elem, value ) {
2581
+ return ( elem.style.cssText = value + "" );
2582
+ }
2583
+ };
2584
+ }
2585
+
2586
+ // Safari mis-reports the default selected property of an option
2587
+ // Accessing the parent's selectedIndex property fixes it
2588
+ if ( !jQuery.support.optSelected ) {
2589
+ jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2590
+ get: function( elem ) {
2591
+ var parent = elem.parentNode;
2592
+
2593
+ if ( parent ) {
2594
+ parent.selectedIndex;
2595
+
2596
+ // Make sure that it also works with optgroups, see #5701
2597
+ if ( parent.parentNode ) {
2598
+ parent.parentNode.selectedIndex;
2599
+ }
2600
+ }
2601
+ return null;
2602
+ }
2603
+ });
2604
+ }
2605
+
2606
+ // IE6/7 call enctype encoding
2607
+ if ( !jQuery.support.enctype ) {
2608
+ jQuery.propFix.enctype = "encoding";
2609
+ }
2610
+
2611
+ // Radios and checkboxes getter/setter
2612
+ if ( !jQuery.support.checkOn ) {
2613
+ jQuery.each([ "radio", "checkbox" ], function() {
2614
+ jQuery.valHooks[ this ] = {
2615
+ get: function( elem ) {
2616
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2617
+ return elem.getAttribute("value") === null ? "on" : elem.value;
2618
+ }
2619
+ };
2620
+ });
2621
+ }
2622
+ jQuery.each([ "radio", "checkbox" ], function() {
2623
+ jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2624
+ set: function( elem, value ) {
2625
+ if ( jQuery.isArray( value ) ) {
2626
+ return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
2627
+ }
2628
+ }
2629
+ });
2630
+ });
2631
+ var rformElems = /^(?:textarea|input|select)$/i,
2632
+ rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/,
2633
+ rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
2634
+ rkeyEvent = /^key/,
2635
+ rmouseEvent = /^(?:mouse|contextmenu)|click/,
2636
+ rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
2637
+ hoverHack = function( events ) {
2638
+ return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
2639
+ };
2640
+
2641
+ /*
2642
+ * Helper functions for managing events -- not part of the public interface.
2643
+ * Props to Dean Edwards' addEvent library for many of the ideas.
2644
+ */
2645
+ jQuery.event = {
2646
+
2647
+ add: function( elem, types, handler, data, selector ) {
2648
+
2649
+ var elemData, eventHandle, events,
2650
+ t, tns, type, namespaces, handleObj,
2651
+ handleObjIn, handlers, special;
2652
+
2653
+ // Don't attach events to noData or text/comment nodes (allow plain objects tho)
2654
+ if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
2655
+ return;
2656
+ }
2657
+
2658
+ // Caller can pass in an object of custom data in lieu of the handler
2659
+ if ( handler.handler ) {
2660
+ handleObjIn = handler;
2661
+ handler = handleObjIn.handler;
2662
+ selector = handleObjIn.selector;
2663
+ }
2664
+
2665
+ // Make sure that the handler has a unique ID, used to find/remove it later
2666
+ if ( !handler.guid ) {
2667
+ handler.guid = jQuery.guid++;
2668
+ }
2669
+
2670
+ // Init the element's event structure and main handler, if this is the first
2671
+ events = elemData.events;
2672
+ if ( !events ) {
2673
+ elemData.events = events = {};
2674
+ }
2675
+ eventHandle = elemData.handle;
2676
+ if ( !eventHandle ) {
2677
+ elemData.handle = eventHandle = function( e ) {
2678
+ // Discard the second event of a jQuery.event.trigger() and
2679
+ // when an event is called after a page has unloaded
2680
+ return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2681
+ jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
2682
+ undefined;
2683
+ };
2684
+ // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
2685
+ eventHandle.elem = elem;
2686
+ }
2687
+
2688
+ // Handle multiple events separated by a space
2689
+ // jQuery(...).bind("mouseover mouseout", fn);
2690
+ types = jQuery.trim( hoverHack(types) ).split( " " );
2691
+ for ( t = 0; t < types.length; t++ ) {
2692
+
2693
+ tns = rtypenamespace.exec( types[t] ) || [];
2694
+ type = tns[1];
2695
+ namespaces = ( tns[2] || "" ).split( "." ).sort();
2696
+
2697
+ // If event changes its type, use the special event handlers for the changed type
2698
+ special = jQuery.event.special[ type ] || {};
2699
+
2700
+ // If selector defined, determine special event api type, otherwise given type
2701
+ type = ( selector ? special.delegateType : special.bindType ) || type;
2702
+
2703
+ // Update special based on newly reset type
2704
+ special = jQuery.event.special[ type ] || {};
2705
+
2706
+ // handleObj is passed to all event handlers
2707
+ handleObj = jQuery.extend({
2708
+ type: type,
2709
+ origType: tns[1],
2710
+ data: data,
2711
+ handler: handler,
2712
+ guid: handler.guid,
2713
+ selector: selector,
2714
+ needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
2715
+ namespace: namespaces.join(".")
2716
+ }, handleObjIn );
2717
+
2718
+ // Init the event handler queue if we're the first
2719
+ handlers = events[ type ];
2720
+ if ( !handlers ) {
2721
+ handlers = events[ type ] = [];
2722
+ handlers.delegateCount = 0;
2723
+
2724
+ // Only use addEventListener/attachEvent if the special events handler returns false
2725
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2726
+ // Bind the global event handler to the element
2727
+ if ( elem.addEventListener ) {
2728
+ elem.addEventListener( type, eventHandle, false );
2729
+
2730
+ } else if ( elem.attachEvent ) {
2731
+ elem.attachEvent( "on" + type, eventHandle );
2732
+ }
2733
+ }
2734
+ }
2735
+
2736
+ if ( special.add ) {
2737
+ special.add.call( elem, handleObj );
2738
+
2739
+ if ( !handleObj.handler.guid ) {
2740
+ handleObj.handler.guid = handler.guid;
2741
+ }
2742
+ }
2743
+
2744
+ // Add to the element's handler list, delegates in front
2745
+ if ( selector ) {
2746
+ handlers.splice( handlers.delegateCount++, 0, handleObj );
2747
+ } else {
2748
+ handlers.push( handleObj );
2749
+ }
2750
+
2751
+ // Keep track of which events have ever been used, for event optimization
2752
+ jQuery.event.global[ type ] = true;
2753
+ }
2754
+
2755
+ // Nullify elem to prevent memory leaks in IE
2756
+ elem = null;
2757
+ },
2758
+
2759
+ global: {},
2760
+
2761
+ // Detach an event or set of events from an element
2762
+ remove: function( elem, types, handler, selector, mappedTypes ) {
2763
+
2764
+ var t, tns, type, origType, namespaces, origCount,
2765
+ j, events, special, eventType, handleObj,
2766
+ elemData = jQuery.hasData( elem ) && jQuery._data( elem );
2767
+
2768
+ if ( !elemData || !(events = elemData.events) ) {
2769
+ return;
2770
+ }
2771
+
2772
+ // Once for each type.namespace in types; type may be omitted
2773
+ types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
2774
+ for ( t = 0; t < types.length; t++ ) {
2775
+ tns = rtypenamespace.exec( types[t] ) || [];
2776
+ type = origType = tns[1];
2777
+ namespaces = tns[2];
2778
+
2779
+ // Unbind all events (on this namespace, if provided) for the element
2780
+ if ( !type ) {
2781
+ for ( type in events ) {
2782
+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
2783
+ }
2784
+ continue;
2785
+ }
2786
+
2787
+ special = jQuery.event.special[ type ] || {};
2788
+ type = ( selector? special.delegateType : special.bindType ) || type;
2789
+ eventType = events[ type ] || [];
2790
+ origCount = eventType.length;
2791
+ namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
2792
+
2793
+ // Remove matching events
2794
+ for ( j = 0; j < eventType.length; j++ ) {
2795
+ handleObj = eventType[ j ];
2796
+
2797
+ if ( ( mappedTypes || origType === handleObj.origType ) &&
2798
+ ( !handler || handler.guid === handleObj.guid ) &&
2799
+ ( !namespaces || namespaces.test( handleObj.namespace ) ) &&
2800
+ ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
2801
+ eventType.splice( j--, 1 );
2802
+
2803
+ if ( handleObj.selector ) {
2804
+ eventType.delegateCount--;
2805
+ }
2806
+ if ( special.remove ) {
2807
+ special.remove.call( elem, handleObj );
2808
+ }
2809
+ }
2810
+ }
2811
+
2812
+ // Remove generic event handler if we removed something and no more handlers exist
2813
+ // (avoids potential for endless recursion during removal of special event handlers)
2814
+ if ( eventType.length === 0 && origCount !== eventType.length ) {
2815
+ if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
2816
+ jQuery.removeEvent( elem, type, elemData.handle );
2817
+ }
2818
+
2819
+ delete events[ type ];
2820
+ }
2821
+ }
2822
+
2823
+ // Remove the expando if it's no longer used
2824
+ if ( jQuery.isEmptyObject( events ) ) {
2825
+ delete elemData.handle;
2826
+
2827
+ // removeData also checks for emptiness and clears the expando if empty
2828
+ // so use it instead of delete
2829
+ jQuery.removeData( elem, "events", true );
2830
+ }
2831
+ },
2832
+
2833
+ // Events that are safe to short-circuit if no handlers are attached.
2834
+ // Native DOM events should not be added, they may have inline handlers.
2835
+ customEvent: {
2836
+ "getData": true,
2837
+ "setData": true,
2838
+ "changeData": true
2839
+ },
2840
+
2841
+ trigger: function( event, data, elem, onlyHandlers ) {
2842
+ // Don't do events on text and comment nodes
2843
+ if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
2844
+ return;
2845
+ }
2846
+
2847
+ // Event object or event type
2848
+ var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,
2849
+ type = event.type || event,
2850
+ namespaces = [];
2851
+
2852
+ // focus/blur morphs to focusin/out; ensure we're not firing them right now
2853
+ if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
2854
+ return;
2855
+ }
2856
+
2857
+ if ( type.indexOf( "!" ) >= 0 ) {
2858
+ // Exclusive events trigger only for the exact event (no namespaces)
2859
+ type = type.slice(0, -1);
2860
+ exclusive = true;
2861
+ }
2862
+
2863
+ if ( type.indexOf( "." ) >= 0 ) {
2864
+ // Namespaced trigger; create a regexp to match event type in handle()
2865
+ namespaces = type.split(".");
2866
+ type = namespaces.shift();
2867
+ namespaces.sort();
2868
+ }
2869
+
2870
+ if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2871
+ // No jQuery handlers for this event type, and it can't have inline handlers
2872
+ return;
2873
+ }
2874
+
2875
+ // Caller can pass in an Event, Object, or just an event type string
2876
+ event = typeof event === "object" ?
2877
+ // jQuery.Event object
2878
+ event[ jQuery.expando ] ? event :
2879
+ // Object literal
2880
+ new jQuery.Event( type, event ) :
2881
+ // Just the event type (string)
2882
+ new jQuery.Event( type );
2883
+
2884
+ event.type = type;
2885
+ event.isTrigger = true;
2886
+ event.exclusive = exclusive;
2887
+ event.namespace = namespaces.join( "." );
2888
+ event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
2889
+ ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
2890
+
2891
+ // Handle a global trigger
2892
+ if ( !elem ) {
2893
+
2894
+ // TODO: Stop taunting the data cache; remove global events and always attach to document
2895
+ cache = jQuery.cache;
2896
+ for ( i in cache ) {
2897
+ if ( cache[ i ].events && cache[ i ].events[ type ] ) {
2898
+ jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
2899
+ }
2900
+ }
2901
+ return;
2902
+ }
2903
+
2904
+ // Clean up the event in case it is being reused
2905
+ event.result = undefined;
2906
+ if ( !event.target ) {
2907
+ event.target = elem;
2908
+ }
2909
+
2910
+ // Clone any incoming data and prepend the event, creating the handler arg list
2911
+ data = data != null ? jQuery.makeArray( data ) : [];
2912
+ data.unshift( event );
2913
+
2914
+ // Allow special events to draw outside the lines
2915
+ special = jQuery.event.special[ type ] || {};
2916
+ if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
2917
+ return;
2918
+ }
2919
+
2920
+ // Determine event propagation path in advance, per W3C events spec (#9951)
2921
+ // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
2922
+ eventPath = [[ elem, special.bindType || type ]];
2923
+ if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
2924
+
2925
+ bubbleType = special.delegateType || type;
2926
+ cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
2927
+ for ( old = elem; cur; cur = cur.parentNode ) {
2928
+ eventPath.push([ cur, bubbleType ]);
2929
+ old = cur;
2930
+ }
2931
+
2932
+ // Only add window if we got to document (e.g., not plain obj or detached DOM)
2933
+ if ( old === (elem.ownerDocument || document) ) {
2934
+ eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
2935
+ }
2936
+ }
2937
+
2938
+ // Fire handlers on the event path
2939
+ for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {
2940
+
2941
+ cur = eventPath[i][0];
2942
+ event.type = eventPath[i][1];
2943
+
2944
+ handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
2945
+ if ( handle ) {
2946
+ handle.apply( cur, data );
2947
+ }
2948
+ // Note that this is a bare JS function and not a jQuery handler
2949
+ handle = ontype && cur[ ontype ];
2950
+ if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
2951
+ event.preventDefault();
2952
+ }
2953
+ }
2954
+ event.type = type;
2955
+
2956
+ // If nobody prevented the default action, do it now
2957
+ if ( !onlyHandlers && !event.isDefaultPrevented() ) {
2958
+
2959
+ if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
2960
+ !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2961
+
2962
+ // Call a native DOM method on the target with the same name name as the event.
2963
+ // Can't use an .isFunction() check here because IE6/7 fails that test.
2964
+ // Don't do default actions on window, that's where global variables be (#6170)
2965
+ // IE<9 dies on focus/blur to hidden element (#1486)
2966
+ if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
2967
+
2968
+ // Don't re-trigger an onFOO event when we call its FOO() method
2969
+ old = elem[ ontype ];
2970
+
2971
+ if ( old ) {
2972
+ elem[ ontype ] = null;
2973
+ }
2974
+
2975
+ // Prevent re-triggering of the same event, since we already bubbled it above
2976
+ jQuery.event.triggered = type;
2977
+ elem[ type ]();
2978
+ jQuery.event.triggered = undefined;
2979
+
2980
+ if ( old ) {
2981
+ elem[ ontype ] = old;
2982
+ }
2983
+ }
2984
+ }
2985
+ }
2986
+
2987
+ return event.result;
2988
+ },
2989
+
2990
+ dispatch: function( event ) {
2991
+
2992
+ // Make a writable jQuery.Event from the native event object
2993
+ event = jQuery.event.fix( event || window.event );
2994
+
2995
+ var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,
2996
+ handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
2997
+ delegateCount = handlers.delegateCount,
2998
+ args = core_slice.call( arguments ),
2999
+ run_all = !event.exclusive && !event.namespace,
3000
+ special = jQuery.event.special[ event.type ] || {},
3001
+ handlerQueue = [];
3002
+
3003
+ // Use the fix-ed jQuery.Event rather than the (read-only) native event
3004
+ args[0] = event;
3005
+ event.delegateTarget = this;
3006
+
3007
+ // Call the preDispatch hook for the mapped type, and let it bail if desired
3008
+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
3009
+ return;
3010
+ }
3011
+
3012
+ // Determine handlers that should run if there are delegated events
3013
+ // Avoid non-left-click bubbling in Firefox (#3861)
3014
+ if ( delegateCount && !(event.button && event.type === "click") ) {
3015
+
3016
+ for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
3017
+
3018
+ // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)
3019
+ if ( cur.disabled !== true || event.type !== "click" ) {
3020
+ selMatch = {};
3021
+ matches = [];
3022
+ for ( i = 0; i < delegateCount; i++ ) {
3023
+ handleObj = handlers[ i ];
3024
+ sel = handleObj.selector;
3025
+
3026
+ if ( selMatch[ sel ] === undefined ) {
3027
+ selMatch[ sel ] = handleObj.needsContext ?
3028
+ jQuery( sel, this ).index( cur ) >= 0 :
3029
+ jQuery.find( sel, this, null, [ cur ] ).length;
3030
+ }
3031
+ if ( selMatch[ sel ] ) {
3032
+ matches.push( handleObj );
3033
+ }
3034
+ }
3035
+ if ( matches.length ) {
3036
+ handlerQueue.push({ elem: cur, matches: matches });
3037
+ }
3038
+ }
3039
+ }
3040
+ }
3041
+
3042
+ // Add the remaining (directly-bound) handlers
3043
+ if ( handlers.length > delegateCount ) {
3044
+ handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
3045
+ }
3046
+
3047
+ // Run delegates first; they may want to stop propagation beneath us
3048
+ for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
3049
+ matched = handlerQueue[ i ];
3050
+ event.currentTarget = matched.elem;
3051
+
3052
+ for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
3053
+ handleObj = matched.matches[ j ];
3054
+
3055
+ // Triggered event must either 1) be non-exclusive and have no namespace, or
3056
+ // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
3057
+ if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
3058
+
3059
+ event.data = handleObj.data;
3060
+ event.handleObj = handleObj;
3061
+
3062
+ ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
3063
+ .apply( matched.elem, args );
3064
+
3065
+ if ( ret !== undefined ) {
3066
+ event.result = ret;
3067
+ if ( ret === false ) {
3068
+ event.preventDefault();
3069
+ event.stopPropagation();
3070
+ }
3071
+ }
3072
+ }
3073
+ }
3074
+ }
3075
+
3076
+ // Call the postDispatch hook for the mapped type
3077
+ if ( special.postDispatch ) {
3078
+ special.postDispatch.call( this, event );
3079
+ }
3080
+
3081
+ return event.result;
3082
+ },
3083
+
3084
+ // Includes some event props shared by KeyEvent and MouseEvent
3085
+ // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
3086
+ props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
3087
+
3088
+ fixHooks: {},
3089
+
3090
+ keyHooks: {
3091
+ props: "char charCode key keyCode".split(" "),
3092
+ filter: function( event, original ) {
3093
+
3094
+ // Add which for key events
3095
+ if ( event.which == null ) {
3096
+ event.which = original.charCode != null ? original.charCode : original.keyCode;
3097
+ }
3098
+
3099
+ return event;
3100
+ }
3101
+ },
3102
+
3103
+ mouseHooks: {
3104
+ props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
3105
+ filter: function( event, original ) {
3106
+ var eventDoc, doc, body,
3107
+ button = original.button,
3108
+ fromElement = original.fromElement;
3109
+
3110
+ // Calculate pageX/Y if missing and clientX/Y available
3111
+ if ( event.pageX == null && original.clientX != null ) {
3112
+ eventDoc = event.target.ownerDocument || document;
3113
+ doc = eventDoc.documentElement;
3114
+ body = eventDoc.body;
3115
+
3116
+ event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
3117
+ event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
3118
+ }
3119
+
3120
+ // Add relatedTarget, if necessary
3121
+ if ( !event.relatedTarget && fromElement ) {
3122
+ event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
3123
+ }
3124
+
3125
+ // Add which for click: 1 === left; 2 === middle; 3 === right
3126
+ // Note: button is not normalized, so don't use it
3127
+ if ( !event.which && button !== undefined ) {
3128
+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
3129
+ }
3130
+
3131
+ return event;
3132
+ }
3133
+ },
3134
+
3135
+ fix: function( event ) {
3136
+ if ( event[ jQuery.expando ] ) {
3137
+ return event;
3138
+ }
3139
+
3140
+ // Create a writable copy of the event object and normalize some properties
3141
+ var i, prop,
3142
+ originalEvent = event,
3143
+ fixHook = jQuery.event.fixHooks[ event.type ] || {},
3144
+ copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
3145
+
3146
+ event = jQuery.Event( originalEvent );
3147
+
3148
+ for ( i = copy.length; i; ) {
3149
+ prop = copy[ --i ];
3150
+ event[ prop ] = originalEvent[ prop ];
3151
+ }
3152
+
3153
+ // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
3154
+ if ( !event.target ) {
3155
+ event.target = originalEvent.srcElement || document;
3156
+ }
3157
+
3158
+ // Target should not be a text node (#504, Safari)
3159
+ if ( event.target.nodeType === 3 ) {
3160
+ event.target = event.target.parentNode;
3161
+ }
3162
+
3163
+ // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8)
3164
+ event.metaKey = !!event.metaKey;
3165
+
3166
+ return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
3167
+ },
3168
+
3169
+ special: {
3170
+ load: {
3171
+ // Prevent triggered image.load events from bubbling to window.load
3172
+ noBubble: true
3173
+ },
3174
+
3175
+ focus: {
3176
+ delegateType: "focusin"
3177
+ },
3178
+ blur: {
3179
+ delegateType: "focusout"
3180
+ },
3181
+
3182
+ beforeunload: {
3183
+ setup: function( data, namespaces, eventHandle ) {
3184
+ // We only want to do this special case on windows
3185
+ if ( jQuery.isWindow( this ) ) {
3186
+ this.onbeforeunload = eventHandle;
3187
+ }
3188
+ },
3189
+
3190
+ teardown: function( namespaces, eventHandle ) {
3191
+ if ( this.onbeforeunload === eventHandle ) {
3192
+ this.onbeforeunload = null;
3193
+ }
3194
+ }
3195
+ }
3196
+ },
3197
+
3198
+ simulate: function( type, elem, event, bubble ) {
3199
+ // Piggyback on a donor event to simulate a different one.
3200
+ // Fake originalEvent to avoid donor's stopPropagation, but if the
3201
+ // simulated event prevents default then we do the same on the donor.
3202
+ var e = jQuery.extend(
3203
+ new jQuery.Event(),
3204
+ event,
3205
+ { type: type,
3206
+ isSimulated: true,
3207
+ originalEvent: {}
3208
+ }
3209
+ );
3210
+ if ( bubble ) {
3211
+ jQuery.event.trigger( e, null, elem );
3212
+ } else {
3213
+ jQuery.event.dispatch.call( elem, e );
3214
+ }
3215
+ if ( e.isDefaultPrevented() ) {
3216
+ event.preventDefault();
3217
+ }
3218
+ }
3219
+ };
3220
+
3221
+ // Some plugins are using, but it's undocumented/deprecated and will be removed.
3222
+ // The 1.7 special event interface should provide all the hooks needed now.
3223
+ jQuery.event.handle = jQuery.event.dispatch;
3224
+
3225
+ jQuery.removeEvent = document.removeEventListener ?
3226
+ function( elem, type, handle ) {
3227
+ if ( elem.removeEventListener ) {
3228
+ elem.removeEventListener( type, handle, false );
3229
+ }
3230
+ } :
3231
+ function( elem, type, handle ) {
3232
+ var name = "on" + type;
3233
+
3234
+ if ( elem.detachEvent ) {
3235
+
3236
+ // #8545, #7054, preventing memory leaks for custom events in IE6-8 –
3237
+ // detachEvent needed property on element, by name of that event, to properly expose it to GC
3238
+ if ( typeof elem[ name ] === "undefined" ) {
3239
+ elem[ name ] = null;
3240
+ }
3241
+
3242
+ elem.detachEvent( name, handle );
3243
+ }
3244
+ };
3245
+
3246
+ jQuery.Event = function( src, props ) {
3247
+ // Allow instantiation without the 'new' keyword
3248
+ if ( !(this instanceof jQuery.Event) ) {
3249
+ return new jQuery.Event( src, props );
3250
+ }
3251
+
3252
+ // Event object
3253
+ if ( src && src.type ) {
3254
+ this.originalEvent = src;
3255
+ this.type = src.type;
3256
+
3257
+ // Events bubbling up the document may have been marked as prevented
3258
+ // by a handler lower down the tree; reflect the correct value.
3259
+ this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
3260
+ src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
3261
+
3262
+ // Event type
3263
+ } else {
3264
+ this.type = src;
3265
+ }
3266
+
3267
+ // Put explicitly provided properties onto the event object
3268
+ if ( props ) {
3269
+ jQuery.extend( this, props );
3270
+ }
3271
+
3272
+ // Create a timestamp if incoming event doesn't have one
3273
+ this.timeStamp = src && src.timeStamp || jQuery.now();
3274
+
3275
+ // Mark it as fixed
3276
+ this[ jQuery.expando ] = true;
3277
+ };
3278
+
3279
+ function returnFalse() {
3280
+ return false;
3281
+ }
3282
+ function returnTrue() {
3283
+ return true;
3284
+ }
3285
+
3286
+ // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3287
+ // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3288
+ jQuery.Event.prototype = {
3289
+ preventDefault: function() {
3290
+ this.isDefaultPrevented = returnTrue;
3291
+
3292
+ var e = this.originalEvent;
3293
+ if ( !e ) {
3294
+ return;
3295
+ }
3296
+
3297
+ // if preventDefault exists run it on the original event
3298
+ if ( e.preventDefault ) {
3299
+ e.preventDefault();
3300
+
3301
+ // otherwise set the returnValue property of the original event to false (IE)
3302
+ } else {
3303
+ e.returnValue = false;
3304
+ }
3305
+ },
3306
+ stopPropagation: function() {
3307
+ this.isPropagationStopped = returnTrue;
3308
+
3309
+ var e = this.originalEvent;
3310
+ if ( !e ) {
3311
+ return;
3312
+ }
3313
+ // if stopPropagation exists run it on the original event
3314
+ if ( e.stopPropagation ) {
3315
+ e.stopPropagation();
3316
+ }
3317
+ // otherwise set the cancelBubble property of the original event to true (IE)
3318
+ e.cancelBubble = true;
3319
+ },
3320
+ stopImmediatePropagation: function() {
3321
+ this.isImmediatePropagationStopped = returnTrue;
3322
+ this.stopPropagation();
3323
+ },
3324
+ isDefaultPrevented: returnFalse,
3325
+ isPropagationStopped: returnFalse,
3326
+ isImmediatePropagationStopped: returnFalse
3327
+ };
3328
+
3329
+ // Create mouseenter/leave events using mouseover/out and event-time checks
3330
+ jQuery.each({
3331
+ mouseenter: "mouseover",
3332
+ mouseleave: "mouseout"
3333
+ }, function( orig, fix ) {
3334
+ jQuery.event.special[ orig ] = {
3335
+ delegateType: fix,
3336
+ bindType: fix,
3337
+
3338
+ handle: function( event ) {
3339
+ var ret,
3340
+ target = this,
3341
+ related = event.relatedTarget,
3342
+ handleObj = event.handleObj,
3343
+ selector = handleObj.selector;
3344
+
3345
+ // For mousenter/leave call the handler if related is outside the target.
3346
+ // NB: No relatedTarget if the mouse left/entered the browser window
3347
+ if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
3348
+ event.type = handleObj.origType;
3349
+ ret = handleObj.handler.apply( this, arguments );
3350
+ event.type = fix;
3351
+ }
3352
+ return ret;
3353
+ }
3354
+ };
3355
+ });
3356
+
3357
+ // IE submit delegation
3358
+ if ( !jQuery.support.submitBubbles ) {
3359
+
3360
+ jQuery.event.special.submit = {
3361
+ setup: function() {
3362
+ // Only need this for delegated form submit events
3363
+ if ( jQuery.nodeName( this, "form" ) ) {
3364
+ return false;
3365
+ }
3366
+
3367
+ // Lazy-add a submit handler when a descendant form may potentially be submitted
3368
+ jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
3369
+ // Node name check avoids a VML-related crash in IE (#9807)
3370
+ var elem = e.target,
3371
+ form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
3372
+ if ( form && !jQuery._data( form, "_submit_attached" ) ) {
3373
+ jQuery.event.add( form, "submit._submit", function( event ) {
3374
+ event._submit_bubble = true;
3375
+ });
3376
+ jQuery._data( form, "_submit_attached", true );
3377
+ }
3378
+ });
3379
+ // return undefined since we don't need an event listener
3380
+ },
3381
+
3382
+ postDispatch: function( event ) {
3383
+ // If form was submitted by the user, bubble the event up the tree
3384
+ if ( event._submit_bubble ) {
3385
+ delete event._submit_bubble;
3386
+ if ( this.parentNode && !event.isTrigger ) {
3387
+ jQuery.event.simulate( "submit", this.parentNode, event, true );
3388
+ }
3389
+ }
3390
+ },
3391
+
3392
+ teardown: function() {
3393
+ // Only need this for delegated form submit events
3394
+ if ( jQuery.nodeName( this, "form" ) ) {
3395
+ return false;
3396
+ }
3397
+
3398
+ // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
3399
+ jQuery.event.remove( this, "._submit" );
3400
+ }
3401
+ };
3402
+ }
3403
+
3404
+ // IE change delegation and checkbox/radio fix
3405
+ if ( !jQuery.support.changeBubbles ) {
3406
+
3407
+ jQuery.event.special.change = {
3408
+
3409
+ setup: function() {
3410
+
3411
+ if ( rformElems.test( this.nodeName ) ) {
3412
+ // IE doesn't fire change on a check/radio until blur; trigger it on click
3413
+ // after a propertychange. Eat the blur-change in special.change.handle.
3414
+ // This still fires onchange a second time for check/radio after blur.
3415
+ if ( this.type === "checkbox" || this.type === "radio" ) {
3416
+ jQuery.event.add( this, "propertychange._change", function( event ) {
3417
+ if ( event.originalEvent.propertyName === "checked" ) {
3418
+ this._just_changed = true;
3419
+ }
3420
+ });
3421
+ jQuery.event.add( this, "click._change", function( event ) {
3422
+ if ( this._just_changed && !event.isTrigger ) {
3423
+ this._just_changed = false;
3424
+ }
3425
+ // Allow triggered, simulated change events (#11500)
3426
+ jQuery.event.simulate( "change", this, event, true );
3427
+ });
3428
+ }
3429
+ return false;
3430
+ }
3431
+ // Delegated event; lazy-add a change handler on descendant inputs
3432
+ jQuery.event.add( this, "beforeactivate._change", function( e ) {
3433
+ var elem = e.target;
3434
+
3435
+ if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) {
3436
+ jQuery.event.add( elem, "change._change", function( event ) {
3437
+ if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
3438
+ jQuery.event.simulate( "change", this.parentNode, event, true );
3439
+ }
3440
+ });
3441
+ jQuery._data( elem, "_change_attached", true );
3442
+ }
3443
+ });
3444
+ },
3445
+
3446
+ handle: function( event ) {
3447
+ var elem = event.target;
3448
+
3449
+ // Swallow native change events from checkbox/radio, we already triggered them above
3450
+ if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
3451
+ return event.handleObj.handler.apply( this, arguments );
3452
+ }
3453
+ },
3454
+
3455
+ teardown: function() {
3456
+ jQuery.event.remove( this, "._change" );
3457
+
3458
+ return !rformElems.test( this.nodeName );
3459
+ }
3460
+ };
3461
+ }
3462
+
3463
+ // Create "bubbling" focus and blur events
3464
+ if ( !jQuery.support.focusinBubbles ) {
3465
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3466
+
3467
+ // Attach a single capturing handler while someone wants focusin/focusout
3468
+ var attaches = 0,
3469
+ handler = function( event ) {
3470
+ jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
3471
+ };
3472
+
3473
+ jQuery.event.special[ fix ] = {
3474
+ setup: function() {
3475
+ if ( attaches++ === 0 ) {
3476
+ document.addEventListener( orig, handler, true );
3477
+ }
3478
+ },
3479
+ teardown: function() {
3480
+ if ( --attaches === 0 ) {
3481
+ document.removeEventListener( orig, handler, true );
3482
+ }
3483
+ }
3484
+ };
3485
+ });
3486
+ }
3487
+
3488
+ jQuery.fn.extend({
3489
+
3490
+ on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
3491
+ var origFn, type;
3492
+
3493
+ // Types can be a map of types/handlers
3494
+ if ( typeof types === "object" ) {
3495
+ // ( types-Object, selector, data )
3496
+ if ( typeof selector !== "string" ) { // && selector != null
3497
+ // ( types-Object, data )
3498
+ data = data || selector;
3499
+ selector = undefined;
3500
+ }
3501
+ for ( type in types ) {
3502
+ this.on( type, selector, data, types[ type ], one );
3503
+ }
3504
+ return this;
3505
+ }
3506
+
3507
+ if ( data == null && fn == null ) {
3508
+ // ( types, fn )
3509
+ fn = selector;
3510
+ data = selector = undefined;
3511
+ } else if ( fn == null ) {
3512
+ if ( typeof selector === "string" ) {
3513
+ // ( types, selector, fn )
3514
+ fn = data;
3515
+ data = undefined;
3516
+ } else {
3517
+ // ( types, data, fn )
3518
+ fn = data;
3519
+ data = selector;
3520
+ selector = undefined;
3521
+ }
3522
+ }
3523
+ if ( fn === false ) {
3524
+ fn = returnFalse;
3525
+ } else if ( !fn ) {
3526
+ return this;
3527
+ }
3528
+
3529
+ if ( one === 1 ) {
3530
+ origFn = fn;
3531
+ fn = function( event ) {
3532
+ // Can use an empty set, since event contains the info
3533
+ jQuery().off( event );
3534
+ return origFn.apply( this, arguments );
3535
+ };
3536
+ // Use same guid so caller can remove using origFn
3537
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
3538
+ }
3539
+ return this.each( function() {
3540
+ jQuery.event.add( this, types, fn, data, selector );
3541
+ });
3542
+ },
3543
+ one: function( types, selector, data, fn ) {
3544
+ return this.on( types, selector, data, fn, 1 );
3545
+ },
3546
+ off: function( types, selector, fn ) {
3547
+ var handleObj, type;
3548
+ if ( types && types.preventDefault && types.handleObj ) {
3549
+ // ( event ) dispatched jQuery.Event
3550
+ handleObj = types.handleObj;
3551
+ jQuery( types.delegateTarget ).off(
3552
+ handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
3553
+ handleObj.selector,
3554
+ handleObj.handler
3555
+ );
3556
+ return this;
3557
+ }
3558
+ if ( typeof types === "object" ) {
3559
+ // ( types-object [, selector] )
3560
+ for ( type in types ) {
3561
+ this.off( type, selector, types[ type ] );
3562
+ }
3563
+ return this;
3564
+ }
3565
+ if ( selector === false || typeof selector === "function" ) {
3566
+ // ( types [, fn] )
3567
+ fn = selector;
3568
+ selector = undefined;
3569
+ }
3570
+ if ( fn === false ) {
3571
+ fn = returnFalse;
3572
+ }
3573
+ return this.each(function() {
3574
+ jQuery.event.remove( this, types, fn, selector );
3575
+ });
3576
+ },
3577
+
3578
+ bind: function( types, data, fn ) {
3579
+ return this.on( types, null, data, fn );
3580
+ },
3581
+ unbind: function( types, fn ) {
3582
+ return this.off( types, null, fn );
3583
+ },
3584
+
3585
+ live: function( types, data, fn ) {
3586
+ jQuery( this.context ).on( types, this.selector, data, fn );
3587
+ return this;
3588
+ },
3589
+ die: function( types, fn ) {
3590
+ jQuery( this.context ).off( types, this.selector || "**", fn );
3591
+ return this;
3592
+ },
3593
+
3594
+ delegate: function( selector, types, data, fn ) {
3595
+ return this.on( types, selector, data, fn );
3596
+ },
3597
+ undelegate: function( selector, types, fn ) {
3598
+ // ( namespace ) or ( selector, types [, fn] )
3599
+ return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
3600
+ },
3601
+
3602
+ trigger: function( type, data ) {
3603
+ return this.each(function() {
3604
+ jQuery.event.trigger( type, data, this );
3605
+ });
3606
+ },
3607
+ triggerHandler: function( type, data ) {
3608
+ if ( this[0] ) {
3609
+ return jQuery.event.trigger( type, data, this[0], true );
3610
+ }
3611
+ },
3612
+
3613
+ toggle: function( fn ) {
3614
+ // Save reference to arguments for access in closure
3615
+ var args = arguments,
3616
+ guid = fn.guid || jQuery.guid++,
3617
+ i = 0,
3618
+ toggler = function( event ) {
3619
+ // Figure out which function to execute
3620
+ var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3621
+ jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3622
+
3623
+ // Make sure that clicks stop
3624
+ event.preventDefault();
3625
+
3626
+ // and execute the function
3627
+ return args[ lastToggle ].apply( this, arguments ) || false;
3628
+ };
3629
+
3630
+ // link all the functions, so any of them can unbind this click handler
3631
+ toggler.guid = guid;
3632
+ while ( i < args.length ) {
3633
+ args[ i++ ].guid = guid;
3634
+ }
3635
+
3636
+ return this.click( toggler );
3637
+ },
3638
+
3639
+ hover: function( fnOver, fnOut ) {
3640
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3641
+ }
3642
+ });
3643
+
3644
+ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3645
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3646
+ "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
3647
+
3648
+ // Handle event binding
3649
+ jQuery.fn[ name ] = function( data, fn ) {
3650
+ if ( fn == null ) {
3651
+ fn = data;
3652
+ data = null;
3653
+ }
3654
+
3655
+ return arguments.length > 0 ?
3656
+ this.on( name, null, data, fn ) :
3657
+ this.trigger( name );
3658
+ };
3659
+
3660
+ if ( rkeyEvent.test( name ) ) {
3661
+ jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
3662
+ }
3663
+
3664
+ if ( rmouseEvent.test( name ) ) {
3665
+ jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
3666
+ }
3667
+ });
3668
+ /*!
3669
+ * Sizzle CSS Selector Engine
3670
+ * Copyright 2012 jQuery Foundation and other contributors
3671
+ * Released under the MIT license
3672
+ * http://sizzlejs.com/
3673
+ */
3674
+ (function( window, undefined ) {
3675
+
3676
+ var cachedruns,
3677
+ assertGetIdNotName,
3678
+ Expr,
3679
+ getText,
3680
+ isXML,
3681
+ contains,
3682
+ compile,
3683
+ sortOrder,
3684
+ hasDuplicate,
3685
+ outermostContext,
3686
+
3687
+ baseHasDuplicate = true,
3688
+ strundefined = "undefined",
3689
+
3690
+ expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
3691
+
3692
+ Token = String,
3693
+ document = window.document,
3694
+ docElem = document.documentElement,
3695
+ dirruns = 0,
3696
+ done = 0,
3697
+ pop = [].pop,
3698
+ push = [].push,
3699
+ slice = [].slice,
3700
+ // Use a stripped-down indexOf if a native one is unavailable
3701
+ indexOf = [].indexOf || function( elem ) {
3702
+ var i = 0,
3703
+ len = this.length;
3704
+ for ( ; i < len; i++ ) {
3705
+ if ( this[i] === elem ) {
3706
+ return i;
3707
+ }
3708
+ }
3709
+ return -1;
3710
+ },
3711
+
3712
+ // Augment a function for special use by Sizzle
3713
+ markFunction = function( fn, value ) {
3714
+ fn[ expando ] = value == null || value;
3715
+ return fn;
3716
+ },
3717
+
3718
+ createCache = function() {
3719
+ var cache = {},
3720
+ keys = [];
3721
+
3722
+ return markFunction(function( key, value ) {
3723
+ // Only keep the most recent entries
3724
+ if ( keys.push( key ) > Expr.cacheLength ) {
3725
+ delete cache[ keys.shift() ];
3726
+ }
3727
+
3728
+ return (cache[ key ] = value);
3729
+ }, cache );
3730
+ },
3731
+
3732
+ classCache = createCache(),
3733
+ tokenCache = createCache(),
3734
+ compilerCache = createCache(),
3735
+
3736
+ // Regex
3737
+
3738
+ // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
3739
+ whitespace = "[\\x20\\t\\r\\n\\f]",
3740
+ // http://www.w3.org/TR/css3-syntax/#characters
3741
+ characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
3742
+
3743
+ // Loosely modeled on CSS identifier characters
3744
+ // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
3745
+ // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
3746
+ identifier = characterEncoding.replace( "w", "w#" ),
3747
+
3748
+ // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
3749
+ operators = "([*^$|!~]?=)",
3750
+ attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
3751
+ "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
3752
+
3753
+ // Prefer arguments not in parens/brackets,
3754
+ // then attribute selectors and non-pseudos (denoted by :),
3755
+ // then anything else
3756
+ // These preferences are here to reduce the number of selectors
3757
+ // needing tokenize in the PSEUDO preFilter
3758
+ pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
3759
+
3760
+ // For matchExpr.POS and matchExpr.needsContext
3761
+ pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
3762
+ "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",
3763
+
3764
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
3765
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
3766
+
3767
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
3768
+ rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
3769
+ rpseudo = new RegExp( pseudos ),
3770
+
3771
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
3772
+ rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
3773
+
3774
+ rnot = /^:not/,
3775
+ rsibling = /[\x20\t\r\n\f]*[+~]/,
3776
+ rendsWithNot = /:not\($/,
3777
+
3778
+ rheader = /h\d/i,
3779
+ rinputs = /input|select|textarea|button/i,
3780
+
3781
+ rbackslash = /\\(?!\\)/g,
3782
+
3783
+ matchExpr = {
3784
+ "ID": new RegExp( "^#(" + characterEncoding + ")" ),
3785
+ "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
3786
+ "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
3787
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
3788
+ "ATTR": new RegExp( "^" + attributes ),
3789
+ "PSEUDO": new RegExp( "^" + pseudos ),
3790
+ "POS": new RegExp( pos, "i" ),
3791
+ "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +
3792
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
3793
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
3794
+ // For use in libraries implementing .is()
3795
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
3796
+ },
3797
+
3798
+ // Support
3799
+
3800
+ // Used for testing something on an element
3801
+ assert = function( fn ) {
3802
+ var div = document.createElement("div");
3803
+
3804
+ try {
3805
+ return fn( div );
3806
+ } catch (e) {
3807
+ return false;
3808
+ } finally {
3809
+ // release memory in IE
3810
+ div = null;
3811
+ }
3812
+ },
3813
+
3814
+ // Check if getElementsByTagName("*") returns only elements
3815
+ assertTagNameNoComments = assert(function( div ) {
3816
+ div.appendChild( document.createComment("") );
3817
+ return !div.getElementsByTagName("*").length;
3818
+ }),
3819
+
3820
+ // Check if getAttribute returns normalized href attributes
3821
+ assertHrefNotNormalized = assert(function( div ) {
3822
+ div.innerHTML = "<a href='#'></a>";
3823
+ return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
3824
+ div.firstChild.getAttribute("href") === "#";
3825
+ }),
3826
+
3827
+ // Check if attributes should be retrieved by attribute nodes
3828
+ assertAttributes = assert(function( div ) {
3829
+ div.innerHTML = "<select></select>";
3830
+ var type = typeof div.lastChild.getAttribute("multiple");
3831
+ // IE8 returns a string for some attributes even when not present
3832
+ return type !== "boolean" && type !== "string";
3833
+ }),
3834
+
3835
+ // Check if getElementsByClassName can be trusted
3836
+ assertUsableClassName = assert(function( div ) {
3837
+ // Opera can't find a second classname (in 9.6)
3838
+ div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
3839
+ if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
3840
+ return false;
3841
+ }
3842
+
3843
+ // Safari 3.2 caches class attributes and doesn't catch changes
3844
+ div.lastChild.className = "e";
3845
+ return div.getElementsByClassName("e").length === 2;
3846
+ }),
3847
+
3848
+ // Check if getElementById returns elements by name
3849
+ // Check if getElementsByName privileges form controls or returns elements by ID
3850
+ assertUsableName = assert(function( div ) {
3851
+ // Inject content
3852
+ div.id = expando + 0;
3853
+ div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
3854
+ docElem.insertBefore( div, docElem.firstChild );
3855
+
3856
+ // Test
3857
+ var pass = document.getElementsByName &&
3858
+ // buggy browsers will return fewer than the correct 2
3859
+ document.getElementsByName( expando ).length === 2 +
3860
+ // buggy browsers will return more than the correct 0
3861
+ document.getElementsByName( expando + 0 ).length;
3862
+ assertGetIdNotName = !document.getElementById( expando );
3863
+
3864
+ // Cleanup
3865
+ docElem.removeChild( div );
3866
+
3867
+ return pass;
3868
+ });
3869
+
3870
+ // If slice is not available, provide a backup
3871
+ try {
3872
+ slice.call( docElem.childNodes, 0 )[0].nodeType;
3873
+ } catch ( e ) {
3874
+ slice = function( i ) {
3875
+ var elem,
3876
+ results = [];
3877
+ for ( ; (elem = this[i]); i++ ) {
3878
+ results.push( elem );
3879
+ }
3880
+ return results;
3881
+ };
3882
+ }
3883
+
3884
+ function Sizzle( selector, context, results, seed ) {
3885
+ results = results || [];
3886
+ context = context || document;
3887
+ var match, elem, xml, m,
3888
+ nodeType = context.nodeType;
3889
+
3890
+ if ( !selector || typeof selector !== "string" ) {
3891
+ return results;
3892
+ }
3893
+
3894
+ if ( nodeType !== 1 && nodeType !== 9 ) {
3895
+ return [];
3896
+ }
3897
+
3898
+ xml = isXML( context );
3899
+
3900
+ if ( !xml && !seed ) {
3901
+ if ( (match = rquickExpr.exec( selector )) ) {
3902
+ // Speed-up: Sizzle("#ID")
3903
+ if ( (m = match[1]) ) {
3904
+ if ( nodeType === 9 ) {
3905
+ elem = context.getElementById( m );
3906
+ // Check parentNode to catch when Blackberry 4.6 returns
3907
+ // nodes that are no longer in the document #6963
3908
+ if ( elem && elem.parentNode ) {
3909
+ // Handle the case where IE, Opera, and Webkit return items
3910
+ // by name instead of ID
3911
+ if ( elem.id === m ) {
3912
+ results.push( elem );
3913
+ return results;
3914
+ }
3915
+ } else {
3916
+ return results;
3917
+ }
3918
+ } else {
3919
+ // Context is not a document
3920
+ if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
3921
+ contains( context, elem ) && elem.id === m ) {
3922
+ results.push( elem );
3923
+ return results;
3924
+ }
3925
+ }
3926
+
3927
+ // Speed-up: Sizzle("TAG")
3928
+ } else if ( match[2] ) {
3929
+ push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
3930
+ return results;
3931
+
3932
+ // Speed-up: Sizzle(".CLASS")
3933
+ } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
3934
+ push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
3935
+ return results;
3936
+ }
3937
+ }
3938
+ }
3939
+
3940
+ // All others
3941
+ return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );
3942
+ }
3943
+
3944
+ Sizzle.matches = function( expr, elements ) {
3945
+ return Sizzle( expr, null, null, elements );
3946
+ };
3947
+
3948
+ Sizzle.matchesSelector = function( elem, expr ) {
3949
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;
3950
+ };
3951
+
3952
+ // Returns a function to use in pseudos for input types
3953
+ function createInputPseudo( type ) {
3954
+ return function( elem ) {
3955
+ var name = elem.nodeName.toLowerCase();
3956
+ return name === "input" && elem.type === type;
3957
+ };
3958
+ }
3959
+
3960
+ // Returns a function to use in pseudos for buttons
3961
+ function createButtonPseudo( type ) {
3962
+ return function( elem ) {
3963
+ var name = elem.nodeName.toLowerCase();
3964
+ return (name === "input" || name === "button") && elem.type === type;
3965
+ };
3966
+ }
3967
+
3968
+ // Returns a function to use in pseudos for positionals
3969
+ function createPositionalPseudo( fn ) {
3970
+ return markFunction(function( argument ) {
3971
+ argument = +argument;
3972
+ return markFunction(function( seed, matches ) {
3973
+ var j,
3974
+ matchIndexes = fn( [], seed.length, argument ),
3975
+ i = matchIndexes.length;
3976
+
3977
+ // Match elements found at the specified indexes
3978
+ while ( i-- ) {
3979
+ if ( seed[ (j = matchIndexes[i]) ] ) {
3980
+ seed[j] = !(matches[j] = seed[j]);
3981
+ }
3982
+ }
3983
+ });
3984
+ });
3985
+ }
3986
+
3987
+ /**
3988
+ * Utility function for retrieving the text value of an array of DOM nodes
3989
+ * @param {Array|Element} elem
3990
+ */
3991
+ getText = Sizzle.getText = function( elem ) {
3992
+ var node,
3993
+ ret = "",
3994
+ i = 0,
3995
+ nodeType = elem.nodeType;
3996
+
3997
+ if ( nodeType ) {
3998
+ if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
3999
+ // Use textContent for elements
4000
+ // innerText usage removed for consistency of new lines (see #11153)
4001
+ if ( typeof elem.textContent === "string" ) {
4002
+ return elem.textContent;
4003
+ } else {
4004
+ // Traverse its children
4005
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
4006
+ ret += getText( elem );
4007
+ }
4008
+ }
4009
+ } else if ( nodeType === 3 || nodeType === 4 ) {
4010
+ return elem.nodeValue;
4011
+ }
4012
+ // Do not include comment or processing instruction nodes
4013
+ } else {
4014
+
4015
+ // If no nodeType, this is expected to be an array
4016
+ for ( ; (node = elem[i]); i++ ) {
4017
+ // Do not traverse comment nodes
4018
+ ret += getText( node );
4019
+ }
4020
+ }
4021
+ return ret;
4022
+ };
4023
+
4024
+ isXML = Sizzle.isXML = function( elem ) {
4025
+ // documentElement is verified for cases where it doesn't yet exist
4026
+ // (such as loading iframes in IE - #4833)
4027
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
4028
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
4029
+ };
4030
+
4031
+ // Element contains another
4032
+ contains = Sizzle.contains = docElem.contains ?
4033
+ function( a, b ) {
4034
+ var adown = a.nodeType === 9 ? a.documentElement : a,
4035
+ bup = b && b.parentNode;
4036
+ return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
4037
+ } :
4038
+ docElem.compareDocumentPosition ?
4039
+ function( a, b ) {
4040
+ return b && !!( a.compareDocumentPosition( b ) & 16 );
4041
+ } :
4042
+ function( a, b ) {
4043
+ while ( (b = b.parentNode) ) {
4044
+ if ( b === a ) {
4045
+ return true;
4046
+ }
4047
+ }
4048
+ return false;
4049
+ };
4050
+
4051
+ Sizzle.attr = function( elem, name ) {
4052
+ var val,
4053
+ xml = isXML( elem );
4054
+
4055
+ if ( !xml ) {
4056
+ name = name.toLowerCase();
4057
+ }
4058
+ if ( (val = Expr.attrHandle[ name ]) ) {
4059
+ return val( elem );
4060
+ }
4061
+ if ( xml || assertAttributes ) {
4062
+ return elem.getAttribute( name );
4063
+ }
4064
+ val = elem.getAttributeNode( name );
4065
+ return val ?
4066
+ typeof elem[ name ] === "boolean" ?
4067
+ elem[ name ] ? name : null :
4068
+ val.specified ? val.value : null :
4069
+ null;
4070
+ };
4071
+
4072
+ Expr = Sizzle.selectors = {
4073
+
4074
+ // Can be adjusted by the user
4075
+ cacheLength: 50,
4076
+
4077
+ createPseudo: markFunction,
4078
+
4079
+ match: matchExpr,
4080
+
4081
+ // IE6/7 return a modified href
4082
+ attrHandle: assertHrefNotNormalized ?
4083
+ {} :
4084
+ {
4085
+ "href": function( elem ) {
4086
+ return elem.getAttribute( "href", 2 );
4087
+ },
4088
+ "type": function( elem ) {
4089
+ return elem.getAttribute("type");
4090
+ }
4091
+ },
4092
+
4093
+ find: {
4094
+ "ID": assertGetIdNotName ?
4095
+ function( id, context, xml ) {
4096
+ if ( typeof context.getElementById !== strundefined && !xml ) {
4097
+ var m = context.getElementById( id );
4098
+ // Check parentNode to catch when Blackberry 4.6 returns
4099
+ // nodes that are no longer in the document #6963
4100
+ return m && m.parentNode ? [m] : [];
4101
+ }
4102
+ } :
4103
+ function( id, context, xml ) {
4104
+ if ( typeof context.getElementById !== strundefined && !xml ) {
4105
+ var m = context.getElementById( id );
4106
+
4107
+ return m ?
4108
+ m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
4109
+ [m] :
4110
+ undefined :
4111
+ [];
4112
+ }
4113
+ },
4114
+
4115
+ "TAG": assertTagNameNoComments ?
4116
+ function( tag, context ) {
4117
+ if ( typeof context.getElementsByTagName !== strundefined ) {
4118
+ return context.getElementsByTagName( tag );
4119
+ }
4120
+ } :
4121
+ function( tag, context ) {
4122
+ var results = context.getElementsByTagName( tag );
4123
+
4124
+ // Filter out possible comments
4125
+ if ( tag === "*" ) {
4126
+ var elem,
4127
+ tmp = [],
4128
+ i = 0;
4129
+
4130
+ for ( ; (elem = results[i]); i++ ) {
4131
+ if ( elem.nodeType === 1 ) {
4132
+ tmp.push( elem );
4133
+ }
4134
+ }
4135
+
4136
+ return tmp;
4137
+ }
4138
+ return results;
4139
+ },
4140
+
4141
+ "NAME": assertUsableName && function( tag, context ) {
4142
+ if ( typeof context.getElementsByName !== strundefined ) {
4143
+ return context.getElementsByName( name );
4144
+ }
4145
+ },
4146
+
4147
+ "CLASS": assertUsableClassName && function( className, context, xml ) {
4148
+ if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
4149
+ return context.getElementsByClassName( className );
4150
+ }
4151
+ }
4152
+ },
4153
+
4154
+ relative: {
4155
+ ">": { dir: "parentNode", first: true },
4156
+ " ": { dir: "parentNode" },
4157
+ "+": { dir: "previousSibling", first: true },
4158
+ "~": { dir: "previousSibling" }
4159
+ },
4160
+
4161
+ preFilter: {
4162
+ "ATTR": function( match ) {
4163
+ match[1] = match[1].replace( rbackslash, "" );
4164
+
4165
+ // Move the given value to match[3] whether quoted or unquoted
4166
+ match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
4167
+
4168
+ if ( match[2] === "~=" ) {
4169
+ match[3] = " " + match[3] + " ";
4170
+ }
4171
+
4172
+ return match.slice( 0, 4 );
4173
+ },
4174
+
4175
+ "CHILD": function( match ) {
4176
+ /* matches from matchExpr["CHILD"]
4177
+ 1 type (only|nth|...)
4178
+ 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
4179
+ 3 xn-component of xn+y argument ([+-]?\d*n|)
4180
+ 4 sign of xn-component
4181
+ 5 x of xn-component
4182
+ 6 sign of y-component
4183
+ 7 y of y-component
4184
+ */
4185
+ match[1] = match[1].toLowerCase();
4186
+
4187
+ if ( match[1] === "nth" ) {
4188
+ // nth-child requires argument
4189
+ if ( !match[2] ) {
4190
+ Sizzle.error( match[0] );
4191
+ }
4192
+
4193
+ // numeric x and y parameters for Expr.filter.CHILD
4194
+ // remember that false/true cast respectively to 0/1
4195
+ match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
4196
+ match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
4197
+
4198
+ // other types prohibit arguments
4199
+ } else if ( match[2] ) {
4200
+ Sizzle.error( match[0] );
4201
+ }
4202
+
4203
+ return match;
4204
+ },
4205
+
4206
+ "PSEUDO": function( match ) {
4207
+ var unquoted, excess;
4208
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
4209
+ return null;
4210
+ }
4211
+
4212
+ if ( match[3] ) {
4213
+ match[2] = match[3];
4214
+ } else if ( (unquoted = match[4]) ) {
4215
+ // Only check arguments that contain a pseudo
4216
+ if ( rpseudo.test(unquoted) &&
4217
+ // Get excess from tokenize (recursively)
4218
+ (excess = tokenize( unquoted, true )) &&
4219
+ // advance to the next closing parenthesis
4220
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
4221
+
4222
+ // excess is a negative index
4223
+ unquoted = unquoted.slice( 0, excess );
4224
+ match[0] = match[0].slice( 0, excess );
4225
+ }
4226
+ match[2] = unquoted;
4227
+ }
4228
+
4229
+ // Return only captures needed by the pseudo filter method (type and argument)
4230
+ return match.slice( 0, 3 );
4231
+ }
4232
+ },
4233
+
4234
+ filter: {
4235
+ "ID": assertGetIdNotName ?
4236
+ function( id ) {
4237
+ id = id.replace( rbackslash, "" );
4238
+ return function( elem ) {
4239
+ return elem.getAttribute("id") === id;
4240
+ };
4241
+ } :
4242
+ function( id ) {
4243
+ id = id.replace( rbackslash, "" );
4244
+ return function( elem ) {
4245
+ var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
4246
+ return node && node.value === id;
4247
+ };
4248
+ },
4249
+
4250
+ "TAG": function( nodeName ) {
4251
+ if ( nodeName === "*" ) {
4252
+ return function() { return true; };
4253
+ }
4254
+ nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
4255
+
4256
+ return function( elem ) {
4257
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
4258
+ };
4259
+ },
4260
+
4261
+ "CLASS": function( className ) {
4262
+ var pattern = classCache[ expando ][ className ];
4263
+ if ( !pattern ) {
4264
+ pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") );
4265
+ }
4266
+ return function( elem ) {
4267
+ return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
4268
+ };
4269
+ },
4270
+
4271
+ "ATTR": function( name, operator, check ) {
4272
+ return function( elem, context ) {
4273
+ var result = Sizzle.attr( elem, name );
4274
+
4275
+ if ( result == null ) {
4276
+ return operator === "!=";
4277
+ }
4278
+ if ( !operator ) {
4279
+ return true;
4280
+ }
4281
+
4282
+ result += "";
4283
+
4284
+ return operator === "=" ? result === check :
4285
+ operator === "!=" ? result !== check :
4286
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
4287
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
4288
+ operator === "$=" ? check && result.substr( result.length - check.length ) === check :
4289
+ operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
4290
+ operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :
4291
+ false;
4292
+ };
4293
+ },
4294
+
4295
+ "CHILD": function( type, argument, first, last ) {
4296
+
4297
+ if ( type === "nth" ) {
4298
+ return function( elem ) {
4299
+ var node, diff,
4300
+ parent = elem.parentNode;
4301
+
4302
+ if ( first === 1 && last === 0 ) {
4303
+ return true;
4304
+ }
4305
+
4306
+ if ( parent ) {
4307
+ diff = 0;
4308
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
4309
+ if ( node.nodeType === 1 ) {
4310
+ diff++;
4311
+ if ( elem === node ) {
4312
+ break;
4313
+ }
4314
+ }
4315
+ }
4316
+ }
4317
+
4318
+ // Incorporate the offset (or cast to NaN), then check against cycle size
4319
+ diff -= last;
4320
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
4321
+ };
4322
+ }
4323
+
4324
+ return function( elem ) {
4325
+ var node = elem;
4326
+
4327
+ switch ( type ) {
4328
+ case "only":
4329
+ case "first":
4330
+ while ( (node = node.previousSibling) ) {
4331
+ if ( node.nodeType === 1 ) {
4332
+ return false;
4333
+ }
4334
+ }
4335
+
4336
+ if ( type === "first" ) {
4337
+ return true;
4338
+ }
4339
+
4340
+ node = elem;
4341
+
4342
+ /* falls through */
4343
+ case "last":
4344
+ while ( (node = node.nextSibling) ) {
4345
+ if ( node.nodeType === 1 ) {
4346
+ return false;
4347
+ }
4348
+ }
4349
+
4350
+ return true;
4351
+ }
4352
+ };
4353
+ },
4354
+
4355
+ "PSEUDO": function( pseudo, argument ) {
4356
+ // pseudo-class names are case-insensitive
4357
+ // http://www.w3.org/TR/selectors/#pseudo-classes
4358
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
4359
+ // Remember that setFilters inherits from pseudos
4360
+ var args,
4361
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
4362
+ Sizzle.error( "unsupported pseudo: " + pseudo );
4363
+
4364
+ // The user may use createPseudo to indicate that
4365
+ // arguments are needed to create the filter function
4366
+ // just as Sizzle does
4367
+ if ( fn[ expando ] ) {
4368
+ return fn( argument );
4369
+ }
4370
+
4371
+ // But maintain support for old signatures
4372
+ if ( fn.length > 1 ) {
4373
+ args = [ pseudo, pseudo, "", argument ];
4374
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
4375
+ markFunction(function( seed, matches ) {
4376
+ var idx,
4377
+ matched = fn( seed, argument ),
4378
+ i = matched.length;
4379
+ while ( i-- ) {
4380
+ idx = indexOf.call( seed, matched[i] );
4381
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
4382
+ }
4383
+ }) :
4384
+ function( elem ) {
4385
+ return fn( elem, 0, args );
4386
+ };
4387
+ }
4388
+
4389
+ return fn;
4390
+ }
4391
+ },
4392
+
4393
+ pseudos: {
4394
+ "not": markFunction(function( selector ) {
4395
+ // Trim the selector passed to compile
4396
+ // to avoid treating leading and trailing
4397
+ // spaces as combinators
4398
+ var input = [],
4399
+ results = [],
4400
+ matcher = compile( selector.replace( rtrim, "$1" ) );
4401
+
4402
+ return matcher[ expando ] ?
4403
+ markFunction(function( seed, matches, context, xml ) {
4404
+ var elem,
4405
+ unmatched = matcher( seed, null, xml, [] ),
4406
+ i = seed.length;
4407
+
4408
+ // Match elements unmatched by `matcher`
4409
+ while ( i-- ) {
4410
+ if ( (elem = unmatched[i]) ) {
4411
+ seed[i] = !(matches[i] = elem);
4412
+ }
4413
+ }
4414
+ }) :
4415
+ function( elem, context, xml ) {
4416
+ input[0] = elem;
4417
+ matcher( input, null, xml, results );
4418
+ return !results.pop();
4419
+ };
4420
+ }),
4421
+
4422
+ "has": markFunction(function( selector ) {
4423
+ return function( elem ) {
4424
+ return Sizzle( selector, elem ).length > 0;
4425
+ };
4426
+ }),
4427
+
4428
+ "contains": markFunction(function( text ) {
4429
+ return function( elem ) {
4430
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
4431
+ };
4432
+ }),
4433
+
4434
+ "enabled": function( elem ) {
4435
+ return elem.disabled === false;
4436
+ },
4437
+
4438
+ "disabled": function( elem ) {
4439
+ return elem.disabled === true;
4440
+ },
4441
+
4442
+ "checked": function( elem ) {
4443
+ // In CSS3, :checked should return both checked and selected elements
4444
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
4445
+ var nodeName = elem.nodeName.toLowerCase();
4446
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
4447
+ },
4448
+
4449
+ "selected": function( elem ) {
4450
+ // Accessing this property makes selected-by-default
4451
+ // options in Safari work properly
4452
+ if ( elem.parentNode ) {
4453
+ elem.parentNode.selectedIndex;
4454
+ }
4455
+
4456
+ return elem.selected === true;
4457
+ },
4458
+
4459
+ "parent": function( elem ) {
4460
+ return !Expr.pseudos["empty"]( elem );
4461
+ },
4462
+
4463
+ "empty": function( elem ) {
4464
+ // http://www.w3.org/TR/selectors/#empty-pseudo
4465
+ // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
4466
+ // not comment, processing instructions, or others
4467
+ // Thanks to Diego Perini for the nodeName shortcut
4468
+ // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
4469
+ var nodeType;
4470
+ elem = elem.firstChild;
4471
+ while ( elem ) {
4472
+ if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
4473
+ return false;
4474
+ }
4475
+ elem = elem.nextSibling;
4476
+ }
4477
+ return true;
4478
+ },
4479
+
4480
+ "header": function( elem ) {
4481
+ return rheader.test( elem.nodeName );
4482
+ },
4483
+
4484
+ "text": function( elem ) {
4485
+ var type, attr;
4486
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4487
+ // use getAttribute instead to test this case
4488
+ return elem.nodeName.toLowerCase() === "input" &&
4489
+ (type = elem.type) === "text" &&
4490
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
4491
+ },
4492
+
4493
+ // Input types
4494
+ "radio": createInputPseudo("radio"),
4495
+ "checkbox": createInputPseudo("checkbox"),
4496
+ "file": createInputPseudo("file"),
4497
+ "password": createInputPseudo("password"),
4498
+ "image": createInputPseudo("image"),
4499
+
4500
+ "submit": createButtonPseudo("submit"),
4501
+ "reset": createButtonPseudo("reset"),
4502
+
4503
+ "button": function( elem ) {
4504
+ var name = elem.nodeName.toLowerCase();
4505
+ return name === "input" && elem.type === "button" || name === "button";
4506
+ },
4507
+
4508
+ "input": function( elem ) {
4509
+ return rinputs.test( elem.nodeName );
4510
+ },
4511
+
4512
+ "focus": function( elem ) {
4513
+ var doc = elem.ownerDocument;
4514
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);
4515
+ },
4516
+
4517
+ "active": function( elem ) {
4518
+ return elem === elem.ownerDocument.activeElement;
4519
+ },
4520
+
4521
+ // Positional types
4522
+ "first": createPositionalPseudo(function( matchIndexes, length, argument ) {
4523
+ return [ 0 ];
4524
+ }),
4525
+
4526
+ "last": createPositionalPseudo(function( matchIndexes, length, argument ) {
4527
+ return [ length - 1 ];
4528
+ }),
4529
+
4530
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
4531
+ return [ argument < 0 ? argument + length : argument ];
4532
+ }),
4533
+
4534
+ "even": createPositionalPseudo(function( matchIndexes, length, argument ) {
4535
+ for ( var i = 0; i < length; i += 2 ) {
4536
+ matchIndexes.push( i );
4537
+ }
4538
+ return matchIndexes;
4539
+ }),
4540
+
4541
+ "odd": createPositionalPseudo(function( matchIndexes, length, argument ) {
4542
+ for ( var i = 1; i < length; i += 2 ) {
4543
+ matchIndexes.push( i );
4544
+ }
4545
+ return matchIndexes;
4546
+ }),
4547
+
4548
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
4549
+ for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {
4550
+ matchIndexes.push( i );
4551
+ }
4552
+ return matchIndexes;
4553
+ }),
4554
+
4555
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
4556
+ for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {
4557
+ matchIndexes.push( i );
4558
+ }
4559
+ return matchIndexes;
4560
+ })
4561
+ }
4562
+ };
4563
+
4564
+ function siblingCheck( a, b, ret ) {
4565
+ if ( a === b ) {
4566
+ return ret;
4567
+ }
4568
+
4569
+ var cur = a.nextSibling;
4570
+
4571
+ while ( cur ) {
4572
+ if ( cur === b ) {
4573
+ return -1;
4574
+ }
4575
+
4576
+ cur = cur.nextSibling;
4577
+ }
4578
+
4579
+ return 1;
4580
+ }
4581
+
4582
+ sortOrder = docElem.compareDocumentPosition ?
4583
+ function( a, b ) {
4584
+ if ( a === b ) {
4585
+ hasDuplicate = true;
4586
+ return 0;
4587
+ }
4588
+
4589
+ return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
4590
+ a.compareDocumentPosition :
4591
+ a.compareDocumentPosition(b) & 4
4592
+ ) ? -1 : 1;
4593
+ } :
4594
+ function( a, b ) {
4595
+ // The nodes are identical, we can exit early
4596
+ if ( a === b ) {
4597
+ hasDuplicate = true;
4598
+ return 0;
4599
+
4600
+ // Fallback to using sourceIndex (in IE) if it's available on both nodes
4601
+ } else if ( a.sourceIndex && b.sourceIndex ) {
4602
+ return a.sourceIndex - b.sourceIndex;
4603
+ }
4604
+
4605
+ var al, bl,
4606
+ ap = [],
4607
+ bp = [],
4608
+ aup = a.parentNode,
4609
+ bup = b.parentNode,
4610
+ cur = aup;
4611
+
4612
+ // If the nodes are siblings (or identical) we can do a quick check
4613
+ if ( aup === bup ) {
4614
+ return siblingCheck( a, b );
4615
+
4616
+ // If no parents were found then the nodes are disconnected
4617
+ } else if ( !aup ) {
4618
+ return -1;
4619
+
4620
+ } else if ( !bup ) {
4621
+ return 1;
4622
+ }
4623
+
4624
+ // Otherwise they're somewhere else in the tree so we need
4625
+ // to build up a full list of the parentNodes for comparison
4626
+ while ( cur ) {
4627
+ ap.unshift( cur );
4628
+ cur = cur.parentNode;
4629
+ }
4630
+
4631
+ cur = bup;
4632
+
4633
+ while ( cur ) {
4634
+ bp.unshift( cur );
4635
+ cur = cur.parentNode;
4636
+ }
4637
+
4638
+ al = ap.length;
4639
+ bl = bp.length;
4640
+
4641
+ // Start walking down the tree looking for a discrepancy
4642
+ for ( var i = 0; i < al && i < bl; i++ ) {
4643
+ if ( ap[i] !== bp[i] ) {
4644
+ return siblingCheck( ap[i], bp[i] );
4645
+ }
4646
+ }
4647
+
4648
+ // We ended someplace up the tree so do a sibling check
4649
+ return i === al ?
4650
+ siblingCheck( a, bp[i], -1 ) :
4651
+ siblingCheck( ap[i], b, 1 );
4652
+ };
4653
+
4654
+ // Always assume the presence of duplicates if sort doesn't
4655
+ // pass them to our comparison function (as in Google Chrome).
4656
+ [0, 0].sort( sortOrder );
4657
+ baseHasDuplicate = !hasDuplicate;
4658
+
4659
+ // Document sorting and removing duplicates
4660
+ Sizzle.uniqueSort = function( results ) {
4661
+ var elem,
4662
+ i = 1;
4663
+
4664
+ hasDuplicate = baseHasDuplicate;
4665
+ results.sort( sortOrder );
4666
+
4667
+ if ( hasDuplicate ) {
4668
+ for ( ; (elem = results[i]); i++ ) {
4669
+ if ( elem === results[ i - 1 ] ) {
4670
+ results.splice( i--, 1 );
4671
+ }
4672
+ }
4673
+ }
4674
+
4675
+ return results;
4676
+ };
4677
+
4678
+ Sizzle.error = function( msg ) {
4679
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
4680
+ };
4681
+
4682
+ function tokenize( selector, parseOnly ) {
4683
+ var matched, match, tokens, type, soFar, groups, preFilters,
4684
+ cached = tokenCache[ expando ][ selector ];
4685
+
4686
+ if ( cached ) {
4687
+ return parseOnly ? 0 : cached.slice( 0 );
4688
+ }
4689
+
4690
+ soFar = selector;
4691
+ groups = [];
4692
+ preFilters = Expr.preFilter;
4693
+
4694
+ while ( soFar ) {
4695
+
4696
+ // Comma and first run
4697
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
4698
+ if ( match ) {
4699
+ soFar = soFar.slice( match[0].length );
4700
+ }
4701
+ groups.push( tokens = [] );
4702
+ }
4703
+
4704
+ matched = false;
4705
+
4706
+ // Combinators
4707
+ if ( (match = rcombinators.exec( soFar )) ) {
4708
+ tokens.push( matched = new Token( match.shift() ) );
4709
+ soFar = soFar.slice( matched.length );
4710
+
4711
+ // Cast descendant combinators to space
4712
+ matched.type = match[0].replace( rtrim, " " );
4713
+ }
4714
+
4715
+ // Filters
4716
+ for ( type in Expr.filter ) {
4717
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
4718
+ // The last two arguments here are (context, xml) for backCompat
4719
+ (match = preFilters[ type ]( match, document, true ))) ) {
4720
+
4721
+ tokens.push( matched = new Token( match.shift() ) );
4722
+ soFar = soFar.slice( matched.length );
4723
+ matched.type = type;
4724
+ matched.matches = match;
4725
+ }
4726
+ }
4727
+
4728
+ if ( !matched ) {
4729
+ break;
4730
+ }
4731
+ }
4732
+
4733
+ // Return the length of the invalid excess
4734
+ // if we're just parsing
4735
+ // Otherwise, throw an error or return tokens
4736
+ return parseOnly ?
4737
+ soFar.length :
4738
+ soFar ?
4739
+ Sizzle.error( selector ) :
4740
+ // Cache the tokens
4741
+ tokenCache( selector, groups ).slice( 0 );
4742
+ }
4743
+
4744
+ function addCombinator( matcher, combinator, base ) {
4745
+ var dir = combinator.dir,
4746
+ checkNonElements = base && combinator.dir === "parentNode",
4747
+ doneName = done++;
4748
+
4749
+ return combinator.first ?
4750
+ // Check against closest ancestor/preceding element
4751
+ function( elem, context, xml ) {
4752
+ while ( (elem = elem[ dir ]) ) {
4753
+ if ( checkNonElements || elem.nodeType === 1 ) {
4754
+ return matcher( elem, context, xml );
4755
+ }
4756
+ }
4757
+ } :
4758
+
4759
+ // Check against all ancestor/preceding elements
4760
+ function( elem, context, xml ) {
4761
+ // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
4762
+ if ( !xml ) {
4763
+ var cache,
4764
+ dirkey = dirruns + " " + doneName + " ",
4765
+ cachedkey = dirkey + cachedruns;
4766
+ while ( (elem = elem[ dir ]) ) {
4767
+ if ( checkNonElements || elem.nodeType === 1 ) {
4768
+ if ( (cache = elem[ expando ]) === cachedkey ) {
4769
+ return elem.sizset;
4770
+ } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
4771
+ if ( elem.sizset ) {
4772
+ return elem;
4773
+ }
4774
+ } else {
4775
+ elem[ expando ] = cachedkey;
4776
+ if ( matcher( elem, context, xml ) ) {
4777
+ elem.sizset = true;
4778
+ return elem;
4779
+ }
4780
+ elem.sizset = false;
4781
+ }
4782
+ }
4783
+ }
4784
+ } else {
4785
+ while ( (elem = elem[ dir ]) ) {
4786
+ if ( checkNonElements || elem.nodeType === 1 ) {
4787
+ if ( matcher( elem, context, xml ) ) {
4788
+ return elem;
4789
+ }
4790
+ }
4791
+ }
4792
+ }
4793
+ };
4794
+ }
4795
+
4796
+ function elementMatcher( matchers ) {
4797
+ return matchers.length > 1 ?
4798
+ function( elem, context, xml ) {
4799
+ var i = matchers.length;
4800
+ while ( i-- ) {
4801
+ if ( !matchers[i]( elem, context, xml ) ) {
4802
+ return false;
4803
+ }
4804
+ }
4805
+ return true;
4806
+ } :
4807
+ matchers[0];
4808
+ }
4809
+
4810
+ function condense( unmatched, map, filter, context, xml ) {
4811
+ var elem,
4812
+ newUnmatched = [],
4813
+ i = 0,
4814
+ len = unmatched.length,
4815
+ mapped = map != null;
4816
+
4817
+ for ( ; i < len; i++ ) {
4818
+ if ( (elem = unmatched[i]) ) {
4819
+ if ( !filter || filter( elem, context, xml ) ) {
4820
+ newUnmatched.push( elem );
4821
+ if ( mapped ) {
4822
+ map.push( i );
4823
+ }
4824
+ }
4825
+ }
4826
+ }
4827
+
4828
+ return newUnmatched;
4829
+ }
4830
+
4831
+ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
4832
+ if ( postFilter && !postFilter[ expando ] ) {
4833
+ postFilter = setMatcher( postFilter );
4834
+ }
4835
+ if ( postFinder && !postFinder[ expando ] ) {
4836
+ postFinder = setMatcher( postFinder, postSelector );
4837
+ }
4838
+ return markFunction(function( seed, results, context, xml ) {
4839
+ // Positional selectors apply to seed elements, so it is invalid to follow them with relative ones
4840
+ if ( seed && postFinder ) {
4841
+ return;
4842
+ }
4843
+
4844
+ var i, elem, postFilterIn,
4845
+ preMap = [],
4846
+ postMap = [],
4847
+ preexisting = results.length,
4848
+
4849
+ // Get initial elements from seed or context
4850
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [], seed ),
4851
+
4852
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
4853
+ matcherIn = preFilter && ( seed || !selector ) ?
4854
+ condense( elems, preMap, preFilter, context, xml ) :
4855
+ elems,
4856
+
4857
+ matcherOut = matcher ?
4858
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
4859
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
4860
+
4861
+ // ...intermediate processing is necessary
4862
+ [] :
4863
+
4864
+ // ...otherwise use results directly
4865
+ results :
4866
+ matcherIn;
4867
+
4868
+ // Find primary matches
4869
+ if ( matcher ) {
4870
+ matcher( matcherIn, matcherOut, context, xml );
4871
+ }
4872
+
4873
+ // Apply postFilter
4874
+ if ( postFilter ) {
4875
+ postFilterIn = condense( matcherOut, postMap );
4876
+ postFilter( postFilterIn, [], context, xml );
4877
+
4878
+ // Un-match failing elements by moving them back to matcherIn
4879
+ i = postFilterIn.length;
4880
+ while ( i-- ) {
4881
+ if ( (elem = postFilterIn[i]) ) {
4882
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
4883
+ }
4884
+ }
4885
+ }
4886
+
4887
+ // Keep seed and results synchronized
4888
+ if ( seed ) {
4889
+ // Ignore postFinder because it can't coexist with seed
4890
+ i = preFilter && matcherOut.length;
4891
+ while ( i-- ) {
4892
+ if ( (elem = matcherOut[i]) ) {
4893
+ seed[ preMap[i] ] = !(results[ preMap[i] ] = elem);
4894
+ }
4895
+ }
4896
+ } else {
4897
+ matcherOut = condense(
4898
+ matcherOut === results ?
4899
+ matcherOut.splice( preexisting, matcherOut.length ) :
4900
+ matcherOut
4901
+ );
4902
+ if ( postFinder ) {
4903
+ postFinder( null, results, matcherOut, xml );
4904
+ } else {
4905
+ push.apply( results, matcherOut );
4906
+ }
4907
+ }
4908
+ });
4909
+ }
4910
+
4911
+ function matcherFromTokens( tokens ) {
4912
+ var checkContext, matcher, j,
4913
+ len = tokens.length,
4914
+ leadingRelative = Expr.relative[ tokens[0].type ],
4915
+ implicitRelative = leadingRelative || Expr.relative[" "],
4916
+ i = leadingRelative ? 1 : 0,
4917
+
4918
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
4919
+ matchContext = addCombinator( function( elem ) {
4920
+ return elem === checkContext;
4921
+ }, implicitRelative, true ),
4922
+ matchAnyContext = addCombinator( function( elem ) {
4923
+ return indexOf.call( checkContext, elem ) > -1;
4924
+ }, implicitRelative, true ),
4925
+ matchers = [ function( elem, context, xml ) {
4926
+ return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
4927
+ (checkContext = context).nodeType ?
4928
+ matchContext( elem, context, xml ) :
4929
+ matchAnyContext( elem, context, xml ) );
4930
+ } ];
4931
+
4932
+ for ( ; i < len; i++ ) {
4933
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
4934
+ matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
4935
+ } else {
4936
+ // The concatenated values are (context, xml) for backCompat
4937
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
4938
+
4939
+ // Return special upon seeing a positional matcher
4940
+ if ( matcher[ expando ] ) {
4941
+ // Find the next relative operator (if any) for proper handling
4942
+ j = ++i;
4943
+ for ( ; j < len; j++ ) {
4944
+ if ( Expr.relative[ tokens[j].type ] ) {
4945
+ break;
4946
+ }
4947
+ }
4948
+ return setMatcher(
4949
+ i > 1 && elementMatcher( matchers ),
4950
+ i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),
4951
+ matcher,
4952
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
4953
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
4954
+ j < len && tokens.join("")
4955
+ );
4956
+ }
4957
+ matchers.push( matcher );
4958
+ }
4959
+ }
4960
+
4961
+ return elementMatcher( matchers );
4962
+ }
4963
+
4964
+ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
4965
+ var bySet = setMatchers.length > 0,
4966
+ byElement = elementMatchers.length > 0,
4967
+ superMatcher = function( seed, context, xml, results, expandContext ) {
4968
+ var elem, j, matcher,
4969
+ setMatched = [],
4970
+ matchedCount = 0,
4971
+ i = "0",
4972
+ unmatched = seed && [],
4973
+ outermost = expandContext != null,
4974
+ contextBackup = outermostContext,
4975
+ // We must always have either seed elements or context
4976
+ elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
4977
+ // Nested matchers should use non-integer dirruns
4978
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);
4979
+
4980
+ if ( outermost ) {
4981
+ outermostContext = context !== document && context;
4982
+ cachedruns = superMatcher.el;
4983
+ }
4984
+
4985
+ // Add elements passing elementMatchers directly to results
4986
+ for ( ; (elem = elems[i]) != null; i++ ) {
4987
+ if ( byElement && elem ) {
4988
+ for ( j = 0; (matcher = elementMatchers[j]); j++ ) {
4989
+ if ( matcher( elem, context, xml ) ) {
4990
+ results.push( elem );
4991
+ break;
4992
+ }
4993
+ }
4994
+ if ( outermost ) {
4995
+ dirruns = dirrunsUnique;
4996
+ cachedruns = ++superMatcher.el;
4997
+ }
4998
+ }
4999
+
5000
+ // Track unmatched elements for set filters
5001
+ if ( bySet ) {
5002
+ // They will have gone through all possible matchers
5003
+ if ( (elem = !matcher && elem) ) {
5004
+ matchedCount--;
5005
+ }
5006
+
5007
+ // Lengthen the array for every element, matched or not
5008
+ if ( seed ) {
5009
+ unmatched.push( elem );
5010
+ }
5011
+ }
5012
+ }
5013
+
5014
+ // Apply set filters to unmatched elements
5015
+ matchedCount += i;
5016
+ if ( bySet && i !== matchedCount ) {
5017
+ for ( j = 0; (matcher = setMatchers[j]); j++ ) {
5018
+ matcher( unmatched, setMatched, context, xml );
5019
+ }
5020
+
5021
+ if ( seed ) {
5022
+ // Reintegrate element matches to eliminate the need for sorting
5023
+ if ( matchedCount > 0 ) {
5024
+ while ( i-- ) {
5025
+ if ( !(unmatched[i] || setMatched[i]) ) {
5026
+ setMatched[i] = pop.call( results );
5027
+ }
5028
+ }
5029
+ }
5030
+
5031
+ // Discard index placeholder values to get only actual matches
5032
+ setMatched = condense( setMatched );
5033
+ }
5034
+
5035
+ // Add matches to results
5036
+ push.apply( results, setMatched );
5037
+
5038
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
5039
+ if ( outermost && !seed && setMatched.length > 0 &&
5040
+ ( matchedCount + setMatchers.length ) > 1 ) {
5041
+
5042
+ Sizzle.uniqueSort( results );
5043
+ }
5044
+ }
5045
+
5046
+ // Override manipulation of globals by nested matchers
5047
+ if ( outermost ) {
5048
+ dirruns = dirrunsUnique;
5049
+ outermostContext = contextBackup;
5050
+ }
5051
+
5052
+ return unmatched;
5053
+ };
5054
+
5055
+ superMatcher.el = 0;
5056
+ return bySet ?
5057
+ markFunction( superMatcher ) :
5058
+ superMatcher;
5059
+ }
5060
+
5061
+ compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
5062
+ var i,
5063
+ setMatchers = [],
5064
+ elementMatchers = [],
5065
+ cached = compilerCache[ expando ][ selector ];
5066
+
5067
+ if ( !cached ) {
5068
+ // Generate a function of recursive functions that can be used to check each element
5069
+ if ( !group ) {
5070
+ group = tokenize( selector );
5071
+ }
5072
+ i = group.length;
5073
+ while ( i-- ) {
5074
+ cached = matcherFromTokens( group[i] );
5075
+ if ( cached[ expando ] ) {
5076
+ setMatchers.push( cached );
5077
+ } else {
5078
+ elementMatchers.push( cached );
5079
+ }
5080
+ }
5081
+
5082
+ // Cache the compiled function
5083
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
5084
+ }
5085
+ return cached;
5086
+ };
5087
+
5088
+ function multipleContexts( selector, contexts, results, seed ) {
5089
+ var i = 0,
5090
+ len = contexts.length;
5091
+ for ( ; i < len; i++ ) {
5092
+ Sizzle( selector, contexts[i], results, seed );
5093
+ }
5094
+ return results;
5095
+ }
5096
+
5097
+ function select( selector, context, results, seed, xml ) {
5098
+ var i, tokens, token, type, find,
5099
+ match = tokenize( selector ),
5100
+ j = match.length;
5101
+
5102
+ if ( !seed ) {
5103
+ // Try to minimize operations if there is only one group
5104
+ if ( match.length === 1 ) {
5105
+
5106
+ // Take a shortcut and set the context if the root selector is an ID
5107
+ tokens = match[0] = match[0].slice( 0 );
5108
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
5109
+ context.nodeType === 9 && !xml &&
5110
+ Expr.relative[ tokens[1].type ] ) {
5111
+
5112
+ context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];
5113
+ if ( !context ) {
5114
+ return results;
5115
+ }
5116
+
5117
+ selector = selector.slice( tokens.shift().length );
5118
+ }
5119
+
5120
+ // Fetch a seed set for right-to-left matching
5121
+ for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {
5122
+ token = tokens[i];
5123
+
5124
+ // Abort if we hit a combinator
5125
+ if ( Expr.relative[ (type = token.type) ] ) {
5126
+ break;
5127
+ }
5128
+ if ( (find = Expr.find[ type ]) ) {
5129
+ // Search, expanding context for leading sibling combinators
5130
+ if ( (seed = find(
5131
+ token.matches[0].replace( rbackslash, "" ),
5132
+ rsibling.test( tokens[0].type ) && context.parentNode || context,
5133
+ xml
5134
+ )) ) {
5135
+
5136
+ // If seed is empty or no tokens remain, we can return early
5137
+ tokens.splice( i, 1 );
5138
+ selector = seed.length && tokens.join("");
5139
+ if ( !selector ) {
5140
+ push.apply( results, slice.call( seed, 0 ) );
5141
+ return results;
5142
+ }
5143
+
5144
+ break;
5145
+ }
5146
+ }
5147
+ }
5148
+ }
5149
+ }
5150
+
5151
+ // Compile and execute a filtering function
5152
+ // Provide `match` to avoid retokenization if we modified the selector above
5153
+ compile( selector, match )(
5154
+ seed,
5155
+ context,
5156
+ xml,
5157
+ results,
5158
+ rsibling.test( selector )
5159
+ );
5160
+ return results;
5161
+ }
5162
+
5163
+ if ( document.querySelectorAll ) {
5164
+ (function() {
5165
+ var disconnectedMatch,
5166
+ oldSelect = select,
5167
+ rescape = /'|\\/g,
5168
+ rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
5169
+
5170
+ // qSa(:focus) reports false when true (Chrome 21),
5171
+ // A support test would require too much code (would include document ready)
5172
+ rbuggyQSA = [":focus"],
5173
+
5174
+ // matchesSelector(:focus) reports false when true (Chrome 21),
5175
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
5176
+ // A support test would require too much code (would include document ready)
5177
+ // just skip matchesSelector for :active
5178
+ rbuggyMatches = [ ":active", ":focus" ],
5179
+ matches = docElem.matchesSelector ||
5180
+ docElem.mozMatchesSelector ||
5181
+ docElem.webkitMatchesSelector ||
5182
+ docElem.oMatchesSelector ||
5183
+ docElem.msMatchesSelector;
5184
+
5185
+ // Build QSA regex
5186
+ // Regex strategy adopted from Diego Perini
5187
+ assert(function( div ) {
5188
+ // Select is set to empty string on purpose
5189
+ // This is to test IE's treatment of not explictly
5190
+ // setting a boolean content attribute,
5191
+ // since its presence should be enough
5192
+ // http://bugs.jquery.com/ticket/12359
5193
+ div.innerHTML = "<select><option selected=''></option></select>";
5194
+
5195
+ // IE8 - Some boolean attributes are not treated correctly
5196
+ if ( !div.querySelectorAll("[selected]").length ) {
5197
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
5198
+ }
5199
+
5200
+ // Webkit/Opera - :checked should return selected option elements
5201
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
5202
+ // IE8 throws error here (do not put tests after this one)
5203
+ if ( !div.querySelectorAll(":checked").length ) {
5204
+ rbuggyQSA.push(":checked");
5205
+ }
5206
+ });
5207
+
5208
+ assert(function( div ) {
5209
+
5210
+ // Opera 10-12/IE9 - ^= $= *= and empty values
5211
+ // Should not select anything
5212
+ div.innerHTML = "<p test=''></p>";
5213
+ if ( div.querySelectorAll("[test^='']").length ) {
5214
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
5215
+ }
5216
+
5217
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
5218
+ // IE8 throws error here (do not put tests after this one)
5219
+ div.innerHTML = "<input type='hidden'/>";
5220
+ if ( !div.querySelectorAll(":enabled").length ) {
5221
+ rbuggyQSA.push(":enabled", ":disabled");
5222
+ }
5223
+ });
5224
+
5225
+ // rbuggyQSA always contains :focus, so no need for a length check
5226
+ rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );
5227
+
5228
+ select = function( selector, context, results, seed, xml ) {
5229
+ // Only use querySelectorAll when not filtering,
5230
+ // when this is not xml,
5231
+ // and when no QSA bugs apply
5232
+ if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
5233
+ var groups, i,
5234
+ old = true,
5235
+ nid = expando,
5236
+ newContext = context,
5237
+ newSelector = context.nodeType === 9 && selector;
5238
+
5239
+ // qSA works strangely on Element-rooted queries
5240
+ // We can work around this by specifying an extra ID on the root
5241
+ // and working up from there (Thanks to Andrew Dupont for the technique)
5242
+ // IE 8 doesn't work on object elements
5243
+ if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5244
+ groups = tokenize( selector );
5245
+
5246
+ if ( (old = context.getAttribute("id")) ) {
5247
+ nid = old.replace( rescape, "\\$&" );
5248
+ } else {
5249
+ context.setAttribute( "id", nid );
5250
+ }
5251
+ nid = "[id='" + nid + "'] ";
5252
+
5253
+ i = groups.length;
5254
+ while ( i-- ) {
5255
+ groups[i] = nid + groups[i].join("");
5256
+ }
5257
+ newContext = rsibling.test( selector ) && context.parentNode || context;
5258
+ newSelector = groups.join(",");
5259
+ }
5260
+
5261
+ if ( newSelector ) {
5262
+ try {
5263
+ push.apply( results, slice.call( newContext.querySelectorAll(
5264
+ newSelector
5265
+ ), 0 ) );
5266
+ return results;
5267
+ } catch(qsaError) {
5268
+ } finally {
5269
+ if ( !old ) {
5270
+ context.removeAttribute("id");
5271
+ }
5272
+ }
5273
+ }
5274
+ }
5275
+
5276
+ return oldSelect( selector, context, results, seed, xml );
5277
+ };
5278
+
5279
+ if ( matches ) {
5280
+ assert(function( div ) {
5281
+ // Check to see if it's possible to do matchesSelector
5282
+ // on a disconnected node (IE 9)
5283
+ disconnectedMatch = matches.call( div, "div" );
5284
+
5285
+ // This should fail with an exception
5286
+ // Gecko does not error, returns false instead
5287
+ try {
5288
+ matches.call( div, "[test!='']:sizzle" );
5289
+ rbuggyMatches.push( "!=", pseudos );
5290
+ } catch ( e ) {}
5291
+ });
5292
+
5293
+ // rbuggyMatches always contains :active and :focus, so no need for a length check
5294
+ rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
5295
+
5296
+ Sizzle.matchesSelector = function( elem, expr ) {
5297
+ // Make sure that attribute selectors are quoted
5298
+ expr = expr.replace( rattributeQuotes, "='$1']" );
5299
+
5300
+ // rbuggyMatches always contains :active, so no need for an existence check
5301
+ if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) {
5302
+ try {
5303
+ var ret = matches.call( elem, expr );
5304
+
5305
+ // IE 9's matchesSelector returns false on disconnected nodes
5306
+ if ( ret || disconnectedMatch ||
5307
+ // As well, disconnected nodes are said to be in a document
5308
+ // fragment in IE 9
5309
+ elem.document && elem.document.nodeType !== 11 ) {
5310
+ return ret;
5311
+ }
5312
+ } catch(e) {}
5313
+ }
5314
+
5315
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;
5316
+ };
5317
+ }
5318
+ })();
5319
+ }
5320
+
5321
+ // Deprecated
5322
+ Expr.pseudos["nth"] = Expr.pseudos["eq"];
5323
+
5324
+ // Back-compat
5325
+ function setFilters() {}
5326
+ Expr.filters = setFilters.prototype = Expr.pseudos;
5327
+ Expr.setFilters = new setFilters();
5328
+
5329
+ // Override sizzle attribute retrieval
5330
+ Sizzle.attr = jQuery.attr;
5331
+ jQuery.find = Sizzle;
5332
+ jQuery.expr = Sizzle.selectors;
5333
+ jQuery.expr[":"] = jQuery.expr.pseudos;
5334
+ jQuery.unique = Sizzle.uniqueSort;
5335
+ jQuery.text = Sizzle.getText;
5336
+ jQuery.isXMLDoc = Sizzle.isXML;
5337
+ jQuery.contains = Sizzle.contains;
5338
+
5339
+
5340
+ })( window );
5341
+ var runtil = /Until$/,
5342
+ rparentsprev = /^(?:parents|prev(?:Until|All))/,
5343
+ isSimple = /^.[^:#\[\.,]*$/,
5344
+ rneedsContext = jQuery.expr.match.needsContext,
5345
+ // methods guaranteed to produce a unique set when starting from a unique set
5346
+ guaranteedUnique = {
5347
+ children: true,
5348
+ contents: true,
5349
+ next: true,
5350
+ prev: true
5351
+ };
5352
+
5353
+ jQuery.fn.extend({
5354
+ find: function( selector ) {
5355
+ var i, l, length, n, r, ret,
5356
+ self = this;
5357
+
5358
+ if ( typeof selector !== "string" ) {
5359
+ return jQuery( selector ).filter(function() {
5360
+ for ( i = 0, l = self.length; i < l; i++ ) {
5361
+ if ( jQuery.contains( self[ i ], this ) ) {
5362
+ return true;
5363
+ }
5364
+ }
5365
+ });
5366
+ }
5367
+
5368
+ ret = this.pushStack( "", "find", selector );
5369
+
5370
+ for ( i = 0, l = this.length; i < l; i++ ) {
5371
+ length = ret.length;
5372
+ jQuery.find( selector, this[i], ret );
5373
+
5374
+ if ( i > 0 ) {
5375
+ // Make sure that the results are unique
5376
+ for ( n = length; n < ret.length; n++ ) {
5377
+ for ( r = 0; r < length; r++ ) {
5378
+ if ( ret[r] === ret[n] ) {
5379
+ ret.splice(n--, 1);
5380
+ break;
5381
+ }
5382
+ }
5383
+ }
5384
+ }
5385
+ }
5386
+
5387
+ return ret;
5388
+ },
5389
+
5390
+ has: function( target ) {
5391
+ var i,
5392
+ targets = jQuery( target, this ),
5393
+ len = targets.length;
5394
+
5395
+ return this.filter(function() {
5396
+ for ( i = 0; i < len; i++ ) {
5397
+ if ( jQuery.contains( this, targets[i] ) ) {
5398
+ return true;
5399
+ }
5400
+ }
5401
+ });
5402
+ },
5403
+
5404
+ not: function( selector ) {
5405
+ return this.pushStack( winnow(this, selector, false), "not", selector);
5406
+ },
5407
+
5408
+ filter: function( selector ) {
5409
+ return this.pushStack( winnow(this, selector, true), "filter", selector );
5410
+ },
5411
+
5412
+ is: function( selector ) {
5413
+ return !!selector && (
5414
+ typeof selector === "string" ?
5415
+ // If this is a positional/relative selector, check membership in the returned set
5416
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
5417
+ rneedsContext.test( selector ) ?
5418
+ jQuery( selector, this.context ).index( this[0] ) >= 0 :
5419
+ jQuery.filter( selector, this ).length > 0 :
5420
+ this.filter( selector ).length > 0 );
5421
+ },
5422
+
5423
+ closest: function( selectors, context ) {
5424
+ var cur,
5425
+ i = 0,
5426
+ l = this.length,
5427
+ ret = [],
5428
+ pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
5429
+ jQuery( selectors, context || this.context ) :
5430
+ 0;
5431
+
5432
+ for ( ; i < l; i++ ) {
5433
+ cur = this[i];
5434
+
5435
+ while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {
5436
+ if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5437
+ ret.push( cur );
5438
+ break;
5439
+ }
5440
+ cur = cur.parentNode;
5441
+ }
5442
+ }
5443
+
5444
+ ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5445
+
5446
+ return this.pushStack( ret, "closest", selectors );
5447
+ },
5448
+
5449
+ // Determine the position of an element within
5450
+ // the matched set of elements
5451
+ index: function( elem ) {
5452
+
5453
+ // No argument, return index in parent
5454
+ if ( !elem ) {
5455
+ return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
5456
+ }
5457
+
5458
+ // index in selector
5459
+ if ( typeof elem === "string" ) {
5460
+ return jQuery.inArray( this[0], jQuery( elem ) );
5461
+ }
5462
+
5463
+ // Locate the position of the desired element
5464
+ return jQuery.inArray(
5465
+ // If it receives a jQuery object, the first element is used
5466
+ elem.jquery ? elem[0] : elem, this );
5467
+ },
5468
+
5469
+ add: function( selector, context ) {
5470
+ var set = typeof selector === "string" ?
5471
+ jQuery( selector, context ) :
5472
+ jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5473
+ all = jQuery.merge( this.get(), set );
5474
+
5475
+ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5476
+ all :
5477
+ jQuery.unique( all ) );
5478
+ },
5479
+
5480
+ addBack: function( selector ) {
5481
+ return this.add( selector == null ?
5482
+ this.prevObject : this.prevObject.filter(selector)
5483
+ );
5484
+ }
5485
+ });
5486
+
5487
+ jQuery.fn.andSelf = jQuery.fn.addBack;
5488
+
5489
+ // A painfully simple check to see if an element is disconnected
5490
+ // from a document (should be improved, where feasible).
5491
+ function isDisconnected( node ) {
5492
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
5493
+ }
5494
+
5495
+ function sibling( cur, dir ) {
5496
+ do {
5497
+ cur = cur[ dir ];
5498
+ } while ( cur && cur.nodeType !== 1 );
5499
+
5500
+ return cur;
5501
+ }
5502
+
5503
+ jQuery.each({
5504
+ parent: function( elem ) {
5505
+ var parent = elem.parentNode;
5506
+ return parent && parent.nodeType !== 11 ? parent : null;
5507
+ },
5508
+ parents: function( elem ) {
5509
+ return jQuery.dir( elem, "parentNode" );
5510
+ },
5511
+ parentsUntil: function( elem, i, until ) {
5512
+ return jQuery.dir( elem, "parentNode", until );
5513
+ },
5514
+ next: function( elem ) {
5515
+ return sibling( elem, "nextSibling" );
5516
+ },
5517
+ prev: function( elem ) {
5518
+ return sibling( elem, "previousSibling" );
5519
+ },
5520
+ nextAll: function( elem ) {
5521
+ return jQuery.dir( elem, "nextSibling" );
5522
+ },
5523
+ prevAll: function( elem ) {
5524
+ return jQuery.dir( elem, "previousSibling" );
5525
+ },
5526
+ nextUntil: function( elem, i, until ) {
5527
+ return jQuery.dir( elem, "nextSibling", until );
5528
+ },
5529
+ prevUntil: function( elem, i, until ) {
5530
+ return jQuery.dir( elem, "previousSibling", until );
5531
+ },
5532
+ siblings: function( elem ) {
5533
+ return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
5534
+ },
5535
+ children: function( elem ) {
5536
+ return jQuery.sibling( elem.firstChild );
5537
+ },
5538
+ contents: function( elem ) {
5539
+ return jQuery.nodeName( elem, "iframe" ) ?
5540
+ elem.contentDocument || elem.contentWindow.document :
5541
+ jQuery.merge( [], elem.childNodes );
5542
+ }
5543
+ }, function( name, fn ) {
5544
+ jQuery.fn[ name ] = function( until, selector ) {
5545
+ var ret = jQuery.map( this, fn, until );
5546
+
5547
+ if ( !runtil.test( name ) ) {
5548
+ selector = until;
5549
+ }
5550
+
5551
+ if ( selector && typeof selector === "string" ) {
5552
+ ret = jQuery.filter( selector, ret );
5553
+ }
5554
+
5555
+ ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5556
+
5557
+ if ( this.length > 1 && rparentsprev.test( name ) ) {
5558
+ ret = ret.reverse();
5559
+ }
5560
+
5561
+ return this.pushStack( ret, name, core_slice.call( arguments ).join(",") );
5562
+ };
5563
+ });
5564
+
5565
+ jQuery.extend({
5566
+ filter: function( expr, elems, not ) {
5567
+ if ( not ) {
5568
+ expr = ":not(" + expr + ")";
5569
+ }
5570
+
5571
+ return elems.length === 1 ?
5572
+ jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5573
+ jQuery.find.matches(expr, elems);
5574
+ },
5575
+
5576
+ dir: function( elem, dir, until ) {
5577
+ var matched = [],
5578
+ cur = elem[ dir ];
5579
+
5580
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5581
+ if ( cur.nodeType === 1 ) {
5582
+ matched.push( cur );
5583
+ }
5584
+ cur = cur[dir];
5585
+ }
5586
+ return matched;
5587
+ },
5588
+
5589
+ sibling: function( n, elem ) {
5590
+ var r = [];
5591
+
5592
+ for ( ; n; n = n.nextSibling ) {
5593
+ if ( n.nodeType === 1 && n !== elem ) {
5594
+ r.push( n );
5595
+ }
5596
+ }
5597
+
5598
+ return r;
5599
+ }
5600
+ });
5601
+
5602
+ // Implement the identical functionality for filter and not
5603
+ function winnow( elements, qualifier, keep ) {
5604
+
5605
+ // Can't pass null or undefined to indexOf in Firefox 4
5606
+ // Set to 0 to skip string check
5607
+ qualifier = qualifier || 0;
5608
+
5609
+ if ( jQuery.isFunction( qualifier ) ) {
5610
+ return jQuery.grep(elements, function( elem, i ) {
5611
+ var retVal = !!qualifier.call( elem, i, elem );
5612
+ return retVal === keep;
5613
+ });
5614
+
5615
+ } else if ( qualifier.nodeType ) {
5616
+ return jQuery.grep(elements, function( elem, i ) {
5617
+ return ( elem === qualifier ) === keep;
5618
+ });
5619
+
5620
+ } else if ( typeof qualifier === "string" ) {
5621
+ var filtered = jQuery.grep(elements, function( elem ) {
5622
+ return elem.nodeType === 1;
5623
+ });
5624
+
5625
+ if ( isSimple.test( qualifier ) ) {
5626
+ return jQuery.filter(qualifier, filtered, !keep);
5627
+ } else {
5628
+ qualifier = jQuery.filter( qualifier, filtered );
5629
+ }
5630
+ }
5631
+
5632
+ return jQuery.grep(elements, function( elem, i ) {
5633
+ return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
5634
+ });
5635
+ }
5636
+ function createSafeFragment( document ) {
5637
+ var list = nodeNames.split( "|" ),
5638
+ safeFrag = document.createDocumentFragment();
5639
+
5640
+ if ( safeFrag.createElement ) {
5641
+ while ( list.length ) {
5642
+ safeFrag.createElement(
5643
+ list.pop()
5644
+ );
5645
+ }
5646
+ }
5647
+ return safeFrag;
5648
+ }
5649
+
5650
+ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
5651
+ "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
5652
+ rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5653
+ rleadingWhitespace = /^\s+/,
5654
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
5655
+ rtagName = /<([\w:]+)/,
5656
+ rtbody = /<tbody/i,
5657
+ rhtml = /<|&#?\w+;/,
5658
+ rnoInnerhtml = /<(?:script|style|link)/i,
5659
+ rnocache = /<(?:script|object|embed|option|style)/i,
5660
+ rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
5661
+ rcheckableType = /^(?:checkbox|radio)$/,
5662
+ // checked="checked" or checked
5663
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5664
+ rscriptType = /\/(java|ecma)script/i,
5665
+ rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,
5666
+ wrapMap = {
5667
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
5668
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
5669
+ thead: [ 1, "<table>", "</table>" ],
5670
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5671
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5672
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5673
+ area: [ 1, "<map>", "</map>" ],
5674
+ _default: [ 0, "", "" ]
5675
+ },
5676
+ safeFragment = createSafeFragment( document ),
5677
+ fragmentDiv = safeFragment.appendChild( document.createElement("div") );
5678
+
5679
+ wrapMap.optgroup = wrapMap.option;
5680
+ wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5681
+ wrapMap.th = wrapMap.td;
5682
+
5683
+ // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
5684
+ // unless wrapped in a div with non-breaking characters in front of it.
5685
+ if ( !jQuery.support.htmlSerialize ) {
5686
+ wrapMap._default = [ 1, "X<div>", "</div>" ];
5687
+ }
5688
+
5689
+ jQuery.fn.extend({
5690
+ text: function( value ) {
5691
+ return jQuery.access( this, function( value ) {
5692
+ return value === undefined ?
5693
+ jQuery.text( this ) :
5694
+ this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
5695
+ }, null, value, arguments.length );
5696
+ },
5697
+
5698
+ wrapAll: function( html ) {
5699
+ if ( jQuery.isFunction( html ) ) {
5700
+ return this.each(function(i) {
5701
+ jQuery(this).wrapAll( html.call(this, i) );
5702
+ });
5703
+ }
5704
+
5705
+ if ( this[0] ) {
5706
+ // The elements to wrap the target around
5707
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5708
+
5709
+ if ( this[0].parentNode ) {
5710
+ wrap.insertBefore( this[0] );
5711
+ }
5712
+
5713
+ wrap.map(function() {
5714
+ var elem = this;
5715
+
5716
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5717
+ elem = elem.firstChild;
5718
+ }
5719
+
5720
+ return elem;
5721
+ }).append( this );
5722
+ }
5723
+
5724
+ return this;
5725
+ },
5726
+
5727
+ wrapInner: function( html ) {
5728
+ if ( jQuery.isFunction( html ) ) {
5729
+ return this.each(function(i) {
5730
+ jQuery(this).wrapInner( html.call(this, i) );
5731
+ });
5732
+ }
5733
+
5734
+ return this.each(function() {
5735
+ var self = jQuery( this ),
5736
+ contents = self.contents();
5737
+
5738
+ if ( contents.length ) {
5739
+ contents.wrapAll( html );
5740
+
5741
+ } else {
5742
+ self.append( html );
5743
+ }
5744
+ });
5745
+ },
5746
+
5747
+ wrap: function( html ) {
5748
+ var isFunction = jQuery.isFunction( html );
5749
+
5750
+ return this.each(function(i) {
5751
+ jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
5752
+ });
5753
+ },
5754
+
5755
+ unwrap: function() {
5756
+ return this.parent().each(function() {
5757
+ if ( !jQuery.nodeName( this, "body" ) ) {
5758
+ jQuery( this ).replaceWith( this.childNodes );
5759
+ }
5760
+ }).end();
5761
+ },
5762
+
5763
+ append: function() {
5764
+ return this.domManip(arguments, true, function( elem ) {
5765
+ if ( this.nodeType === 1 || this.nodeType === 11 ) {
5766
+ this.appendChild( elem );
5767
+ }
5768
+ });
5769
+ },
5770
+
5771
+ prepend: function() {
5772
+ return this.domManip(arguments, true, function( elem ) {
5773
+ if ( this.nodeType === 1 || this.nodeType === 11 ) {
5774
+ this.insertBefore( elem, this.firstChild );
5775
+ }
5776
+ });
5777
+ },
5778
+
5779
+ before: function() {
5780
+ if ( !isDisconnected( this[0] ) ) {
5781
+ return this.domManip(arguments, false, function( elem ) {
5782
+ this.parentNode.insertBefore( elem, this );
5783
+ });
5784
+ }
5785
+
5786
+ if ( arguments.length ) {
5787
+ var set = jQuery.clean( arguments );
5788
+ return this.pushStack( jQuery.merge( set, this ), "before", this.selector );
5789
+ }
5790
+ },
5791
+
5792
+ after: function() {
5793
+ if ( !isDisconnected( this[0] ) ) {
5794
+ return this.domManip(arguments, false, function( elem ) {
5795
+ this.parentNode.insertBefore( elem, this.nextSibling );
5796
+ });
5797
+ }
5798
+
5799
+ if ( arguments.length ) {
5800
+ var set = jQuery.clean( arguments );
5801
+ return this.pushStack( jQuery.merge( this, set ), "after", this.selector );
5802
+ }
5803
+ },
5804
+
5805
+ // keepData is for internal use only--do not document
5806
+ remove: function( selector, keepData ) {
5807
+ var elem,
5808
+ i = 0;
5809
+
5810
+ for ( ; (elem = this[i]) != null; i++ ) {
5811
+ if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5812
+ if ( !keepData && elem.nodeType === 1 ) {
5813
+ jQuery.cleanData( elem.getElementsByTagName("*") );
5814
+ jQuery.cleanData( [ elem ] );
5815
+ }
5816
+
5817
+ if ( elem.parentNode ) {
5818
+ elem.parentNode.removeChild( elem );
5819
+ }
5820
+ }
5821
+ }
5822
+
5823
+ return this;
5824
+ },
5825
+
5826
+ empty: function() {
5827
+ var elem,
5828
+ i = 0;
5829
+
5830
+ for ( ; (elem = this[i]) != null; i++ ) {
5831
+ // Remove element nodes and prevent memory leaks
5832
+ if ( elem.nodeType === 1 ) {
5833
+ jQuery.cleanData( elem.getElementsByTagName("*") );
5834
+ }
5835
+
5836
+ // Remove any remaining nodes
5837
+ while ( elem.firstChild ) {
5838
+ elem.removeChild( elem.firstChild );
5839
+ }
5840
+ }
5841
+
5842
+ return this;
5843
+ },
5844
+
5845
+ clone: function( dataAndEvents, deepDataAndEvents ) {
5846
+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5847
+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5848
+
5849
+ return this.map( function () {
5850
+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5851
+ });
5852
+ },
5853
+
5854
+ html: function( value ) {
5855
+ return jQuery.access( this, function( value ) {
5856
+ var elem = this[0] || {},
5857
+ i = 0,
5858
+ l = this.length;
5859
+
5860
+ if ( value === undefined ) {
5861
+ return elem.nodeType === 1 ?
5862
+ elem.innerHTML.replace( rinlinejQuery, "" ) :
5863
+ undefined;
5864
+ }
5865
+
5866
+ // See if we can take a shortcut and just use innerHTML
5867
+ if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5868
+ ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) &&
5869
+ ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
5870
+ !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
5871
+
5872
+ value = value.replace( rxhtmlTag, "<$1></$2>" );
5873
+
5874
+ try {
5875
+ for (; i < l; i++ ) {
5876
+ // Remove element nodes and prevent memory leaks
5877
+ elem = this[i] || {};
5878
+ if ( elem.nodeType === 1 ) {
5879
+ jQuery.cleanData( elem.getElementsByTagName( "*" ) );
5880
+ elem.innerHTML = value;
5881
+ }
5882
+ }
5883
+
5884
+ elem = 0;
5885
+
5886
+ // If using innerHTML throws an exception, use the fallback method
5887
+ } catch(e) {}
5888
+ }
5889
+
5890
+ if ( elem ) {
5891
+ this.empty().append( value );
5892
+ }
5893
+ }, null, value, arguments.length );
5894
+ },
5895
+
5896
+ replaceWith: function( value ) {
5897
+ if ( !isDisconnected( this[0] ) ) {
5898
+ // Make sure that the elements are removed from the DOM before they are inserted
5899
+ // this can help fix replacing a parent with child elements
5900
+ if ( jQuery.isFunction( value ) ) {
5901
+ return this.each(function(i) {
5902
+ var self = jQuery(this), old = self.html();
5903
+ self.replaceWith( value.call( this, i, old ) );
5904
+ });
5905
+ }
5906
+
5907
+ if ( typeof value !== "string" ) {
5908
+ value = jQuery( value ).detach();
5909
+ }
5910
+
5911
+ return this.each(function() {
5912
+ var next = this.nextSibling,
5913
+ parent = this.parentNode;
5914
+
5915
+ jQuery( this ).remove();
5916
+
5917
+ if ( next ) {
5918
+ jQuery(next).before( value );
5919
+ } else {
5920
+ jQuery(parent).append( value );
5921
+ }
5922
+ });
5923
+ }
5924
+
5925
+ return this.length ?
5926
+ this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5927
+ this;
5928
+ },
5929
+
5930
+ detach: function( selector ) {
5931
+ return this.remove( selector, true );
5932
+ },
5933
+
5934
+ domManip: function( args, table, callback ) {
5935
+
5936
+ // Flatten any nested arrays
5937
+ args = [].concat.apply( [], args );
5938
+
5939
+ var results, first, fragment, iNoClone,
5940
+ i = 0,
5941
+ value = args[0],
5942
+ scripts = [],
5943
+ l = this.length;
5944
+
5945
+ // We can't cloneNode fragments that contain checked, in WebKit
5946
+ if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) {
5947
+ return this.each(function() {
5948
+ jQuery(this).domManip( args, table, callback );
5949
+ });
5950
+ }
5951
+
5952
+ if ( jQuery.isFunction(value) ) {
5953
+ return this.each(function(i) {
5954
+ var self = jQuery(this);
5955
+ args[0] = value.call( this, i, table ? self.html() : undefined );
5956
+ self.domManip( args, table, callback );
5957
+ });
5958
+ }
5959
+
5960
+ if ( this[0] ) {
5961
+ results = jQuery.buildFragment( args, this, scripts );
5962
+ fragment = results.fragment;
5963
+ first = fragment.firstChild;
5964
+
5965
+ if ( fragment.childNodes.length === 1 ) {
5966
+ fragment = first;
5967
+ }
5968
+
5969
+ if ( first ) {
5970
+ table = table && jQuery.nodeName( first, "tr" );
5971
+
5972
+ // Use the original fragment for the last item instead of the first because it can end up
5973
+ // being emptied incorrectly in certain situations (#8070).
5974
+ // Fragments from the fragment cache must always be cloned and never used in place.
5975
+ for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) {
5976
+ callback.call(
5977
+ table && jQuery.nodeName( this[i], "table" ) ?
5978
+ findOrAppend( this[i], "tbody" ) :
5979
+ this[i],
5980
+ i === iNoClone ?
5981
+ fragment :
5982
+ jQuery.clone( fragment, true, true )
5983
+ );
5984
+ }
5985
+ }
5986
+
5987
+ // Fix #11809: Avoid leaking memory
5988
+ fragment = first = null;
5989
+
5990
+ if ( scripts.length ) {
5991
+ jQuery.each( scripts, function( i, elem ) {
5992
+ if ( elem.src ) {
5993
+ if ( jQuery.ajax ) {
5994
+ jQuery.ajax({
5995
+ url: elem.src,
5996
+ type: "GET",
5997
+ dataType: "script",
5998
+ async: false,
5999
+ global: false,
6000
+ "throws": true
6001
+ });
6002
+ } else {
6003
+ jQuery.error("no ajax");
6004
+ }
6005
+ } else {
6006
+ jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) );
6007
+ }
6008
+
6009
+ if ( elem.parentNode ) {
6010
+ elem.parentNode.removeChild( elem );
6011
+ }
6012
+ });
6013
+ }
6014
+ }
6015
+
6016
+ return this;
6017
+ }
6018
+ });
6019
+
6020
+ function findOrAppend( elem, tag ) {
6021
+ return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );
6022
+ }
6023
+
6024
+ function cloneCopyEvent( src, dest ) {
6025
+
6026
+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
6027
+ return;
6028
+ }
6029
+
6030
+ var type, i, l,
6031
+ oldData = jQuery._data( src ),
6032
+ curData = jQuery._data( dest, oldData ),
6033
+ events = oldData.events;
6034
+
6035
+ if ( events ) {
6036
+ delete curData.handle;
6037
+ curData.events = {};
6038
+
6039
+ for ( type in events ) {
6040
+ for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6041
+ jQuery.event.add( dest, type, events[ type ][ i ] );
6042
+ }
6043
+ }
6044
+ }
6045
+
6046
+ // make the cloned public data object a copy from the original
6047
+ if ( curData.data ) {
6048
+ curData.data = jQuery.extend( {}, curData.data );
6049
+ }
6050
+ }
6051
+
6052
+ function cloneFixAttributes( src, dest ) {
6053
+ var nodeName;
6054
+
6055
+ // We do not need to do anything for non-Elements
6056
+ if ( dest.nodeType !== 1 ) {
6057
+ return;
6058
+ }
6059
+
6060
+ // clearAttributes removes the attributes, which we don't want,
6061
+ // but also removes the attachEvent events, which we *do* want
6062
+ if ( dest.clearAttributes ) {
6063
+ dest.clearAttributes();
6064
+ }
6065
+
6066
+ // mergeAttributes, in contrast, only merges back on the
6067
+ // original attributes, not the events
6068
+ if ( dest.mergeAttributes ) {
6069
+ dest.mergeAttributes( src );
6070
+ }
6071
+
6072
+ nodeName = dest.nodeName.toLowerCase();
6073
+
6074
+ if ( nodeName === "object" ) {
6075
+ // IE6-10 improperly clones children of object elements using classid.
6076
+ // IE10 throws NoModificationAllowedError if parent is null, #12132.
6077
+ if ( dest.parentNode ) {
6078
+ dest.outerHTML = src.outerHTML;
6079
+ }
6080
+
6081
+ // This path appears unavoidable for IE9. When cloning an object
6082
+ // element in IE9, the outerHTML strategy above is not sufficient.
6083
+ // If the src has innerHTML and the destination does not,
6084
+ // copy the src.innerHTML into the dest.innerHTML. #10324
6085
+ if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) {
6086
+ dest.innerHTML = src.innerHTML;
6087
+ }
6088
+
6089
+ } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
6090
+ // IE6-8 fails to persist the checked state of a cloned checkbox
6091
+ // or radio button. Worse, IE6-7 fail to give the cloned element
6092
+ // a checked appearance if the defaultChecked value isn't also set
6093
+
6094
+ dest.defaultChecked = dest.checked = src.checked;
6095
+
6096
+ // IE6-7 get confused and end up setting the value of a cloned
6097
+ // checkbox/radio button to an empty string instead of "on"
6098
+ if ( dest.value !== src.value ) {
6099
+ dest.value = src.value;
6100
+ }
6101
+
6102
+ // IE6-8 fails to return the selected option to the default selected
6103
+ // state when cloning options
6104
+ } else if ( nodeName === "option" ) {
6105
+ dest.selected = src.defaultSelected;
6106
+
6107
+ // IE6-8 fails to set the defaultValue to the correct value when
6108
+ // cloning other types of input fields
6109
+ } else if ( nodeName === "input" || nodeName === "textarea" ) {
6110
+ dest.defaultValue = src.defaultValue;
6111
+
6112
+ // IE blanks contents when cloning scripts
6113
+ } else if ( nodeName === "script" && dest.text !== src.text ) {
6114
+ dest.text = src.text;
6115
+ }
6116
+
6117
+ // Event data gets referenced instead of copied if the expando
6118
+ // gets copied too
6119
+ dest.removeAttribute( jQuery.expando );
6120
+ }
6121
+
6122
+ jQuery.buildFragment = function( args, context, scripts ) {
6123
+ var fragment, cacheable, cachehit,
6124
+ first = args[ 0 ];
6125
+
6126
+ // Set context from what may come in as undefined or a jQuery collection or a node
6127
+ // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &
6128
+ // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception
6129
+ context = context || document;
6130
+ context = !context.nodeType && context[0] || context;
6131
+ context = context.ownerDocument || context;
6132
+
6133
+ // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
6134
+ // Cloning options loses the selected state, so don't cache them
6135
+ // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6136
+ // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6137
+ // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
6138
+ if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document &&
6139
+ first.charAt(0) === "<" && !rnocache.test( first ) &&
6140
+ (jQuery.support.checkClone || !rchecked.test( first )) &&
6141
+ (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
6142
+
6143
+ // Mark cacheable and look for a hit
6144
+ cacheable = true;
6145
+ fragment = jQuery.fragments[ first ];
6146
+ cachehit = fragment !== undefined;
6147
+ }
6148
+
6149
+ if ( !fragment ) {
6150
+ fragment = context.createDocumentFragment();
6151
+ jQuery.clean( args, context, fragment, scripts );
6152
+
6153
+ // Update the cache, but only store false
6154
+ // unless this is a second parsing of the same content
6155
+ if ( cacheable ) {
6156
+ jQuery.fragments[ first ] = cachehit && fragment;
6157
+ }
6158
+ }
6159
+
6160
+ return { fragment: fragment, cacheable: cacheable };
6161
+ };
6162
+
6163
+ jQuery.fragments = {};
6164
+
6165
+ jQuery.each({
6166
+ appendTo: "append",
6167
+ prependTo: "prepend",
6168
+ insertBefore: "before",
6169
+ insertAfter: "after",
6170
+ replaceAll: "replaceWith"
6171
+ }, function( name, original ) {
6172
+ jQuery.fn[ name ] = function( selector ) {
6173
+ var elems,
6174
+ i = 0,
6175
+ ret = [],
6176
+ insert = jQuery( selector ),
6177
+ l = insert.length,
6178
+ parent = this.length === 1 && this[0].parentNode;
6179
+
6180
+ if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) {
6181
+ insert[ original ]( this[0] );
6182
+ return this;
6183
+ } else {
6184
+ for ( ; i < l; i++ ) {
6185
+ elems = ( i > 0 ? this.clone(true) : this ).get();
6186
+ jQuery( insert[i] )[ original ]( elems );
6187
+ ret = ret.concat( elems );
6188
+ }
6189
+
6190
+ return this.pushStack( ret, name, insert.selector );
6191
+ }
6192
+ };
6193
+ });
6194
+
6195
+ function getAll( elem ) {
6196
+ if ( typeof elem.getElementsByTagName !== "undefined" ) {
6197
+ return elem.getElementsByTagName( "*" );
6198
+
6199
+ } else if ( typeof elem.querySelectorAll !== "undefined" ) {
6200
+ return elem.querySelectorAll( "*" );
6201
+
6202
+ } else {
6203
+ return [];
6204
+ }
6205
+ }
6206
+
6207
+ // Used in clean, fixes the defaultChecked property
6208
+ function fixDefaultChecked( elem ) {
6209
+ if ( rcheckableType.test( elem.type ) ) {
6210
+ elem.defaultChecked = elem.checked;
6211
+ }
6212
+ }
6213
+
6214
+ jQuery.extend({
6215
+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6216
+ var srcElements,
6217
+ destElements,
6218
+ i,
6219
+ clone;
6220
+
6221
+ if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
6222
+ clone = elem.cloneNode( true );
6223
+
6224
+ // IE<=8 does not properly clone detached, unknown element nodes
6225
+ } else {
6226
+ fragmentDiv.innerHTML = elem.outerHTML;
6227
+ fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
6228
+ }
6229
+
6230
+ if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6231
+ (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6232
+ // IE copies events bound via attachEvent when using cloneNode.
6233
+ // Calling detachEvent on the clone will also remove the events
6234
+ // from the original. In order to get around this, we use some
6235
+ // proprietary methods to clear the events. Thanks to MooTools
6236
+ // guys for this hotness.
6237
+
6238
+ cloneFixAttributes( elem, clone );
6239
+
6240
+ // Using Sizzle here is crazy slow, so we use getElementsByTagName instead
6241
+ srcElements = getAll( elem );
6242
+ destElements = getAll( clone );
6243
+
6244
+ // Weird iteration because IE will replace the length property
6245
+ // with an element if you are cloning the body and one of the
6246
+ // elements on the page has a name or id of "length"
6247
+ for ( i = 0; srcElements[i]; ++i ) {
6248
+ // Ensure that the destination node is not null; Fixes #9587
6249
+ if ( destElements[i] ) {
6250
+ cloneFixAttributes( srcElements[i], destElements[i] );
6251
+ }
6252
+ }
6253
+ }
6254
+
6255
+ // Copy the events from the original to the clone
6256
+ if ( dataAndEvents ) {
6257
+ cloneCopyEvent( elem, clone );
6258
+
6259
+ if ( deepDataAndEvents ) {
6260
+ srcElements = getAll( elem );
6261
+ destElements = getAll( clone );
6262
+
6263
+ for ( i = 0; srcElements[i]; ++i ) {
6264
+ cloneCopyEvent( srcElements[i], destElements[i] );
6265
+ }
6266
+ }
6267
+ }
6268
+
6269
+ srcElements = destElements = null;
6270
+
6271
+ // Return the cloned set
6272
+ return clone;
6273
+ },
6274
+
6275
+ clean: function( elems, context, fragment, scripts ) {
6276
+ var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,
6277
+ safe = context === document && safeFragment,
6278
+ ret = [];
6279
+
6280
+ // Ensure that context is a document
6281
+ if ( !context || typeof context.createDocumentFragment === "undefined" ) {
6282
+ context = document;
6283
+ }
6284
+
6285
+ // Use the already-created safe fragment if context permits
6286
+ for ( i = 0; (elem = elems[i]) != null; i++ ) {
6287
+ if ( typeof elem === "number" ) {
6288
+ elem += "";
6289
+ }
6290
+
6291
+ if ( !elem ) {
6292
+ continue;
6293
+ }
6294
+
6295
+ // Convert html string into DOM nodes
6296
+ if ( typeof elem === "string" ) {
6297
+ if ( !rhtml.test( elem ) ) {
6298
+ elem = context.createTextNode( elem );
6299
+ } else {
6300
+ // Ensure a safe container in which to render the html
6301
+ safe = safe || createSafeFragment( context );
6302
+ div = context.createElement("div");
6303
+ safe.appendChild( div );
6304
+
6305
+ // Fix "XHTML"-style tags in all browsers
6306
+ elem = elem.replace(rxhtmlTag, "<$1></$2>");
6307
+
6308
+ // Go to html and back, then peel off extra wrappers
6309
+ tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
6310
+ wrap = wrapMap[ tag ] || wrapMap._default;
6311
+ depth = wrap[0];
6312
+ div.innerHTML = wrap[1] + elem + wrap[2];
6313
+
6314
+ // Move to the right depth
6315
+ while ( depth-- ) {
6316
+ div = div.lastChild;
6317
+ }
6318
+
6319
+ // Remove IE's autoinserted <tbody> from table fragments
6320
+ if ( !jQuery.support.tbody ) {
6321
+
6322
+ // String was a <table>, *may* have spurious <tbody>
6323
+ hasBody = rtbody.test(elem);
6324
+ tbody = tag === "table" && !hasBody ?
6325
+ div.firstChild && div.firstChild.childNodes :
6326
+
6327
+ // String was a bare <thead> or <tfoot>
6328
+ wrap[1] === "<table>" && !hasBody ?
6329
+ div.childNodes :
6330
+ [];
6331
+
6332
+ for ( j = tbody.length - 1; j >= 0 ; --j ) {
6333
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6334
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
6335
+ }
6336
+ }
6337
+ }
6338
+
6339
+ // IE completely kills leading whitespace when innerHTML is used
6340
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6341
+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6342
+ }
6343
+
6344
+ elem = div.childNodes;
6345
+
6346
+ // Take out of fragment container (we need a fresh div each time)
6347
+ div.parentNode.removeChild( div );
6348
+ }
6349
+ }
6350
+
6351
+ if ( elem.nodeType ) {
6352
+ ret.push( elem );
6353
+ } else {
6354
+ jQuery.merge( ret, elem );
6355
+ }
6356
+ }
6357
+
6358
+ // Fix #11356: Clear elements from safeFragment
6359
+ if ( div ) {
6360
+ elem = div = safe = null;
6361
+ }
6362
+
6363
+ // Reset defaultChecked for any radios and checkboxes
6364
+ // about to be appended to the DOM in IE 6/7 (#8060)
6365
+ if ( !jQuery.support.appendChecked ) {
6366
+ for ( i = 0; (elem = ret[i]) != null; i++ ) {
6367
+ if ( jQuery.nodeName( elem, "input" ) ) {
6368
+ fixDefaultChecked( elem );
6369
+ } else if ( typeof elem.getElementsByTagName !== "undefined" ) {
6370
+ jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6371
+ }
6372
+ }
6373
+ }
6374
+
6375
+ // Append elements to a provided document fragment
6376
+ if ( fragment ) {
6377
+ // Special handling of each script element
6378
+ handleScript = function( elem ) {
6379
+ // Check if we consider it executable
6380
+ if ( !elem.type || rscriptType.test( elem.type ) ) {
6381
+ // Detach the script and store it in the scripts array (if provided) or the fragment
6382
+ // Return truthy to indicate that it has been handled
6383
+ return scripts ?
6384
+ scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
6385
+ fragment.appendChild( elem );
6386
+ }
6387
+ };
6388
+
6389
+ for ( i = 0; (elem = ret[i]) != null; i++ ) {
6390
+ // Check if we're done after handling an executable script
6391
+ if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
6392
+ // Append to fragment and handle embedded scripts
6393
+ fragment.appendChild( elem );
6394
+ if ( typeof elem.getElementsByTagName !== "undefined" ) {
6395
+ // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
6396
+ jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
6397
+
6398
+ // Splice the scripts into ret after their former ancestor and advance our index beyond them
6399
+ ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6400
+ i += jsTags.length;
6401
+ }
6402
+ }
6403
+ }
6404
+ }
6405
+
6406
+ return ret;
6407
+ },
6408
+
6409
+ cleanData: function( elems, /* internal */ acceptData ) {
6410
+ var data, id, elem, type,
6411
+ i = 0,
6412
+ internalKey = jQuery.expando,
6413
+ cache = jQuery.cache,
6414
+ deleteExpando = jQuery.support.deleteExpando,
6415
+ special = jQuery.event.special;
6416
+
6417
+ for ( ; (elem = elems[i]) != null; i++ ) {
6418
+
6419
+ if ( acceptData || jQuery.acceptData( elem ) ) {
6420
+
6421
+ id = elem[ internalKey ];
6422
+ data = id && cache[ id ];
6423
+
6424
+ if ( data ) {
6425
+ if ( data.events ) {
6426
+ for ( type in data.events ) {
6427
+ if ( special[ type ] ) {
6428
+ jQuery.event.remove( elem, type );
6429
+
6430
+ // This is a shortcut to avoid jQuery.event.remove's overhead
6431
+ } else {
6432
+ jQuery.removeEvent( elem, type, data.handle );
6433
+ }
6434
+ }
6435
+ }
6436
+
6437
+ // Remove cache only if it was not already removed by jQuery.event.remove
6438
+ if ( cache[ id ] ) {
6439
+
6440
+ delete cache[ id ];
6441
+
6442
+ // IE does not allow us to delete expando properties from nodes,
6443
+ // nor does it have a removeAttribute function on Document nodes;
6444
+ // we must handle all of these cases
6445
+ if ( deleteExpando ) {
6446
+ delete elem[ internalKey ];
6447
+
6448
+ } else if ( elem.removeAttribute ) {
6449
+ elem.removeAttribute( internalKey );
6450
+
6451
+ } else {
6452
+ elem[ internalKey ] = null;
6453
+ }
6454
+
6455
+ jQuery.deletedIds.push( id );
6456
+ }
6457
+ }
6458
+ }
6459
+ }
6460
+ }
6461
+ });
6462
+ // Limit scope pollution from any deprecated API
6463
+ (function() {
6464
+
6465
+ var matched, browser;
6466
+
6467
+ // Use of jQuery.browser is frowned upon.
6468
+ // More details: http://api.jquery.com/jQuery.browser
6469
+ // jQuery.uaMatch maintained for back-compat
6470
+ jQuery.uaMatch = function( ua ) {
6471
+ ua = ua.toLowerCase();
6472
+
6473
+ var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
6474
+ /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
6475
+ /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
6476
+ /(msie) ([\w.]+)/.exec( ua ) ||
6477
+ ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
6478
+ [];
6479
+
6480
+ return {
6481
+ browser: match[ 1 ] || "",
6482
+ version: match[ 2 ] || "0"
6483
+ };
6484
+ };
6485
+
6486
+ matched = jQuery.uaMatch( navigator.userAgent );
6487
+ browser = {};
6488
+
6489
+ if ( matched.browser ) {
6490
+ browser[ matched.browser ] = true;
6491
+ browser.version = matched.version;
6492
+ }
6493
+
6494
+ // Chrome is Webkit, but Webkit is also Safari.
6495
+ if ( browser.chrome ) {
6496
+ browser.webkit = true;
6497
+ } else if ( browser.webkit ) {
6498
+ browser.safari = true;
6499
+ }
6500
+
6501
+ jQuery.browser = browser;
6502
+
6503
+ jQuery.sub = function() {
6504
+ function jQuerySub( selector, context ) {
6505
+ return new jQuerySub.fn.init( selector, context );
6506
+ }
6507
+ jQuery.extend( true, jQuerySub, this );
6508
+ jQuerySub.superclass = this;
6509
+ jQuerySub.fn = jQuerySub.prototype = this();
6510
+ jQuerySub.fn.constructor = jQuerySub;
6511
+ jQuerySub.sub = this.sub;
6512
+ jQuerySub.fn.init = function init( selector, context ) {
6513
+ if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
6514
+ context = jQuerySub( context );
6515
+ }
6516
+
6517
+ return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
6518
+ };
6519
+ jQuerySub.fn.init.prototype = jQuerySub.fn;
6520
+ var rootjQuerySub = jQuerySub(document);
6521
+ return jQuerySub;
6522
+ };
6523
+
6524
+ })();
6525
+ var curCSS, iframe, iframeDoc,
6526
+ ralpha = /alpha\([^)]*\)/i,
6527
+ ropacity = /opacity=([^)]*)/,
6528
+ rposition = /^(top|right|bottom|left)$/,
6529
+ // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
6530
+ // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6531
+ rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6532
+ rmargin = /^margin/,
6533
+ rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
6534
+ rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
6535
+ rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ),
6536
+ elemdisplay = {},
6537
+
6538
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6539
+ cssNormalTransform = {
6540
+ letterSpacing: 0,
6541
+ fontWeight: 400
6542
+ },
6543
+
6544
+ cssExpand = [ "Top", "Right", "Bottom", "Left" ],
6545
+ cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
6546
+
6547
+ eventsToggle = jQuery.fn.toggle;
6548
+
6549
+ // return a css property mapped to a potentially vendor prefixed property
6550
+ function vendorPropName( style, name ) {
6551
+
6552
+ // shortcut for names that are not vendor prefixed
6553
+ if ( name in style ) {
6554
+ return name;
6555
+ }
6556
+
6557
+ // check for vendor prefixed names
6558
+ var capName = name.charAt(0).toUpperCase() + name.slice(1),
6559
+ origName = name,
6560
+ i = cssPrefixes.length;
6561
+
6562
+ while ( i-- ) {
6563
+ name = cssPrefixes[ i ] + capName;
6564
+ if ( name in style ) {
6565
+ return name;
6566
+ }
6567
+ }
6568
+
6569
+ return origName;
6570
+ }
6571
+
6572
+ function isHidden( elem, el ) {
6573
+ elem = el || elem;
6574
+ return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
6575
+ }
6576
+
6577
+ function showHide( elements, show ) {
6578
+ var elem, display,
6579
+ values = [],
6580
+ index = 0,
6581
+ length = elements.length;
6582
+
6583
+ for ( ; index < length; index++ ) {
6584
+ elem = elements[ index ];
6585
+ if ( !elem.style ) {
6586
+ continue;
6587
+ }
6588
+ values[ index ] = jQuery._data( elem, "olddisplay" );
6589
+ if ( show ) {
6590
+ // Reset the inline display of this element to learn if it is
6591
+ // being hidden by cascaded rules or not
6592
+ if ( !values[ index ] && elem.style.display === "none" ) {
6593
+ elem.style.display = "";
6594
+ }
6595
+
6596
+ // Set elements which have been overridden with display: none
6597
+ // in a stylesheet to whatever the default browser style is
6598
+ // for such an element
6599
+ if ( elem.style.display === "" && isHidden( elem ) ) {
6600
+ values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
6601
+ }
6602
+ } else {
6603
+ display = curCSS( elem, "display" );
6604
+
6605
+ if ( !values[ index ] && display !== "none" ) {
6606
+ jQuery._data( elem, "olddisplay", display );
6607
+ }
6608
+ }
6609
+ }
6610
+
6611
+ // Set the display of most of the elements in a second loop
6612
+ // to avoid the constant reflow
6613
+ for ( index = 0; index < length; index++ ) {
6614
+ elem = elements[ index ];
6615
+ if ( !elem.style ) {
6616
+ continue;
6617
+ }
6618
+ if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6619
+ elem.style.display = show ? values[ index ] || "" : "none";
6620
+ }
6621
+ }
6622
+
6623
+ return elements;
6624
+ }
6625
+
6626
+ jQuery.fn.extend({
6627
+ css: function( name, value ) {
6628
+ return jQuery.access( this, function( elem, name, value ) {
6629
+ return value !== undefined ?
6630
+ jQuery.style( elem, name, value ) :
6631
+ jQuery.css( elem, name );
6632
+ }, name, value, arguments.length > 1 );
6633
+ },
6634
+ show: function() {
6635
+ return showHide( this, true );
6636
+ },
6637
+ hide: function() {
6638
+ return showHide( this );
6639
+ },
6640
+ toggle: function( state, fn2 ) {
6641
+ var bool = typeof state === "boolean";
6642
+
6643
+ if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) {
6644
+ return eventsToggle.apply( this, arguments );
6645
+ }
6646
+
6647
+ return this.each(function() {
6648
+ if ( bool ? state : isHidden( this ) ) {
6649
+ jQuery( this ).show();
6650
+ } else {
6651
+ jQuery( this ).hide();
6652
+ }
6653
+ });
6654
+ }
6655
+ });
6656
+
6657
+ jQuery.extend({
6658
+ // Add in style property hooks for overriding the default
6659
+ // behavior of getting and setting a style property
6660
+ cssHooks: {
6661
+ opacity: {
6662
+ get: function( elem, computed ) {
6663
+ if ( computed ) {
6664
+ // We should always get a number back from opacity
6665
+ var ret = curCSS( elem, "opacity" );
6666
+ return ret === "" ? "1" : ret;
6667
+
6668
+ }
6669
+ }
6670
+ }
6671
+ },
6672
+
6673
+ // Exclude the following css properties to add px
6674
+ cssNumber: {
6675
+ "fillOpacity": true,
6676
+ "fontWeight": true,
6677
+ "lineHeight": true,
6678
+ "opacity": true,
6679
+ "orphans": true,
6680
+ "widows": true,
6681
+ "zIndex": true,
6682
+ "zoom": true
6683
+ },
6684
+
6685
+ // Add in properties whose names you wish to fix before
6686
+ // setting or getting the value
6687
+ cssProps: {
6688
+ // normalize float css property
6689
+ "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6690
+ },
6691
+
6692
+ // Get and set the style property on a DOM Node
6693
+ style: function( elem, name, value, extra ) {
6694
+ // Don't set styles on text and comment nodes
6695
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6696
+ return;
6697
+ }
6698
+
6699
+ // Make sure that we're working with the right name
6700
+ var ret, type, hooks,
6701
+ origName = jQuery.camelCase( name ),
6702
+ style = elem.style;
6703
+
6704
+ name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
6705
+
6706
+ // gets hook for the prefixed version
6707
+ // followed by the unprefixed version
6708
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6709
+
6710
+ // Check if we're setting a value
6711
+ if ( value !== undefined ) {
6712
+ type = typeof value;
6713
+
6714
+ // convert relative number strings (+= or -=) to relative numbers. #7345
6715
+ if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6716
+ value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
6717
+ // Fixes bug #9237
6718
+ type = "number";
6719
+ }
6720
+
6721
+ // Make sure that NaN and null values aren't set. See: #7116
6722
+ if ( value == null || type === "number" && isNaN( value ) ) {
6723
+ return;
6724
+ }
6725
+
6726
+ // If a number was passed in, add 'px' to the (except for certain CSS properties)
6727
+ if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6728
+ value += "px";
6729
+ }
6730
+
6731
+ // If a hook was provided, use that value, otherwise just set the specified value
6732
+ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
6733
+ // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6734
+ // Fixes bug #5509
6735
+ try {
6736
+ style[ name ] = value;
6737
+ } catch(e) {}
6738
+ }
6739
+
6740
+ } else {
6741
+ // If a hook was provided get the non-computed value from there
6742
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6743
+ return ret;
6744
+ }
6745
+
6746
+ // Otherwise just get the value from the style object
6747
+ return style[ name ];
6748
+ }
6749
+ },
6750
+
6751
+ css: function( elem, name, numeric, extra ) {
6752
+ var val, num, hooks,
6753
+ origName = jQuery.camelCase( name );
6754
+
6755
+ // Make sure that we're working with the right name
6756
+ name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6757
+
6758
+ // gets hook for the prefixed version
6759
+ // followed by the unprefixed version
6760
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6761
+
6762
+ // If a hook was provided get the computed value from there
6763
+ if ( hooks && "get" in hooks ) {
6764
+ val = hooks.get( elem, true, extra );
6765
+ }
6766
+
6767
+ // Otherwise, if a way to get the computed value exists, use that
6768
+ if ( val === undefined ) {
6769
+ val = curCSS( elem, name );
6770
+ }
6771
+
6772
+ //convert "normal" to computed value
6773
+ if ( val === "normal" && name in cssNormalTransform ) {
6774
+ val = cssNormalTransform[ name ];
6775
+ }
6776
+
6777
+ // Return, converting to number if forced or a qualifier was provided and val looks numeric
6778
+ if ( numeric || extra !== undefined ) {
6779
+ num = parseFloat( val );
6780
+ return numeric || jQuery.isNumeric( num ) ? num || 0 : val;
6781
+ }
6782
+ return val;
6783
+ },
6784
+
6785
+ // A method for quickly swapping in/out CSS properties to get correct calculations
6786
+ swap: function( elem, options, callback ) {
6787
+ var ret, name,
6788
+ old = {};
6789
+
6790
+ // Remember the old values, and insert the new ones
6791
+ for ( name in options ) {
6792
+ old[ name ] = elem.style[ name ];
6793
+ elem.style[ name ] = options[ name ];
6794
+ }
6795
+
6796
+ ret = callback.call( elem );
6797
+
6798
+ // Revert the old values
6799
+ for ( name in options ) {
6800
+ elem.style[ name ] = old[ name ];
6801
+ }
6802
+
6803
+ return ret;
6804
+ }
6805
+ });
6806
+
6807
+ // NOTE: To any future maintainer, we've window.getComputedStyle
6808
+ // because jsdom on node.js will break without it.
6809
+ if ( window.getComputedStyle ) {
6810
+ curCSS = function( elem, name ) {
6811
+ var ret, width, minWidth, maxWidth,
6812
+ computed = window.getComputedStyle( elem, null ),
6813
+ style = elem.style;
6814
+
6815
+ if ( computed ) {
6816
+
6817
+ ret = computed[ name ];
6818
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6819
+ ret = jQuery.style( elem, name );
6820
+ }
6821
+
6822
+ // A tribute to the "awesome hack by Dean Edwards"
6823
+ // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
6824
+ // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
6825
+ // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
6826
+ if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6827
+ width = style.width;
6828
+ minWidth = style.minWidth;
6829
+ maxWidth = style.maxWidth;
6830
+
6831
+ style.minWidth = style.maxWidth = style.width = ret;
6832
+ ret = computed.width;
6833
+
6834
+ style.width = width;
6835
+ style.minWidth = minWidth;
6836
+ style.maxWidth = maxWidth;
6837
+ }
6838
+ }
6839
+
6840
+ return ret;
6841
+ };
6842
+ } else if ( document.documentElement.currentStyle ) {
6843
+ curCSS = function( elem, name ) {
6844
+ var left, rsLeft,
6845
+ ret = elem.currentStyle && elem.currentStyle[ name ],
6846
+ style = elem.style;
6847
+
6848
+ // Avoid setting ret to empty string here
6849
+ // so we don't default to auto
6850
+ if ( ret == null && style && style[ name ] ) {
6851
+ ret = style[ name ];
6852
+ }
6853
+
6854
+ // From the awesome hack by Dean Edwards
6855
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6856
+
6857
+ // If we're not dealing with a regular pixel number
6858
+ // but a number that has a weird ending, we need to convert it to pixels
6859
+ // but not position css attributes, as those are proportional to the parent element instead
6860
+ // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
6861
+ if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6862
+
6863
+ // Remember the original values
6864
+ left = style.left;
6865
+ rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
6866
+
6867
+ // Put in the new values to get a computed value out
6868
+ if ( rsLeft ) {
6869
+ elem.runtimeStyle.left = elem.currentStyle.left;
6870
+ }
6871
+ style.left = name === "fontSize" ? "1em" : ret;
6872
+ ret = style.pixelLeft + "px";
6873
+
6874
+ // Revert the changed values
6875
+ style.left = left;
6876
+ if ( rsLeft ) {
6877
+ elem.runtimeStyle.left = rsLeft;
6878
+ }
6879
+ }
6880
+
6881
+ return ret === "" ? "auto" : ret;
6882
+ };
6883
+ }
6884
+
6885
+ function setPositiveNumber( elem, value, subtract ) {
6886
+ var matches = rnumsplit.exec( value );
6887
+ return matches ?
6888
+ Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6889
+ value;
6890
+ }
6891
+
6892
+ function augmentWidthOrHeight( elem, name, extra, isBorderBox ) {
6893
+ var i = extra === ( isBorderBox ? "border" : "content" ) ?
6894
+ // If we already have the right measurement, avoid augmentation
6895
+ 4 :
6896
+ // Otherwise initialize for horizontal or vertical properties
6897
+ name === "width" ? 1 : 0,
6898
+
6899
+ val = 0;
6900
+
6901
+ for ( ; i < 4; i += 2 ) {
6902
+ // both box models exclude margin, so add it if we want it
6903
+ if ( extra === "margin" ) {
6904
+ // we use jQuery.css instead of curCSS here
6905
+ // because of the reliableMarginRight CSS hook!
6906
+ val += jQuery.css( elem, extra + cssExpand[ i ], true );
6907
+ }
6908
+
6909
+ // From this point on we use curCSS for maximum performance (relevant in animations)
6910
+ if ( isBorderBox ) {
6911
+ // border-box includes padding, so remove it if we want content
6912
+ if ( extra === "content" ) {
6913
+ val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
6914
+ }
6915
+
6916
+ // at this point, extra isn't border nor margin, so remove border
6917
+ if ( extra !== "margin" ) {
6918
+ val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6919
+ }
6920
+ } else {
6921
+ // at this point, extra isn't content, so add padding
6922
+ val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
6923
+
6924
+ // at this point, extra isn't content nor padding, so add border
6925
+ if ( extra !== "padding" ) {
6926
+ val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6927
+ }
6928
+ }
6929
+ }
6930
+
6931
+ return val;
6932
+ }
6933
+
6934
+ function getWidthOrHeight( elem, name, extra ) {
6935
+
6936
+ // Start with offset property, which is equivalent to the border-box value
6937
+ var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6938
+ valueIsBorderBox = true,
6939
+ isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box";
6940
+
6941
+ // some non-html elements return undefined for offsetWidth, so check for null/undefined
6942
+ // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6943
+ // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6944
+ if ( val <= 0 || val == null ) {
6945
+ // Fall back to computed then uncomputed css if necessary
6946
+ val = curCSS( elem, name );
6947
+ if ( val < 0 || val == null ) {
6948
+ val = elem.style[ name ];
6949
+ }
6950
+
6951
+ // Computed unit is not pixels. Stop here and return.
6952
+ if ( rnumnonpx.test(val) ) {
6953
+ return val;
6954
+ }
6955
+
6956
+ // we need the check for style in case a browser which returns unreliable values
6957
+ // for getComputedStyle silently falls back to the reliable elem.style
6958
+ valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
6959
+
6960
+ // Normalize "", auto, and prepare for extra
6961
+ val = parseFloat( val ) || 0;
6962
+ }
6963
+
6964
+ // use the active box-sizing model to add/subtract irrelevant styles
6965
+ return ( val +
6966
+ augmentWidthOrHeight(
6967
+ elem,
6968
+ name,
6969
+ extra || ( isBorderBox ? "border" : "content" ),
6970
+ valueIsBorderBox
6971
+ )
6972
+ ) + "px";
6973
+ }
6974
+
6975
+
6976
+ // Try to determine the default display value of an element
6977
+ function css_defaultDisplay( nodeName ) {
6978
+ if ( elemdisplay[ nodeName ] ) {
6979
+ return elemdisplay[ nodeName ];
6980
+ }
6981
+
6982
+ var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ),
6983
+ display = elem.css("display");
6984
+ elem.remove();
6985
+
6986
+ // If the simple way fails,
6987
+ // get element's real default display by attaching it to a temp iframe
6988
+ if ( display === "none" || display === "" ) {
6989
+ // Use the already-created iframe if possible
6990
+ iframe = document.body.appendChild(
6991
+ iframe || jQuery.extend( document.createElement("iframe"), {
6992
+ frameBorder: 0,
6993
+ width: 0,
6994
+ height: 0
6995
+ })
6996
+ );
6997
+
6998
+ // Create a cacheable copy of the iframe document on first call.
6999
+ // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
7000
+ // document to it; WebKit & Firefox won't allow reusing the iframe document.
7001
+ if ( !iframeDoc || !iframe.createElement ) {
7002
+ iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
7003
+ iframeDoc.write("<!doctype html><html><body>");
7004
+ iframeDoc.close();
7005
+ }
7006
+
7007
+ elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );
7008
+
7009
+ display = curCSS( elem, "display" );
7010
+ document.body.removeChild( iframe );
7011
+ }
7012
+
7013
+ // Store the correct default display
7014
+ elemdisplay[ nodeName ] = display;
7015
+
7016
+ return display;
7017
+ }
7018
+
7019
+ jQuery.each([ "height", "width" ], function( i, name ) {
7020
+ jQuery.cssHooks[ name ] = {
7021
+ get: function( elem, computed, extra ) {
7022
+ if ( computed ) {
7023
+ // certain elements can have dimension info if we invisibly show them
7024
+ // however, it must have a current display style that would benefit from this
7025
+ if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) {
7026
+ return jQuery.swap( elem, cssShow, function() {
7027
+ return getWidthOrHeight( elem, name, extra );
7028
+ });
7029
+ } else {
7030
+ return getWidthOrHeight( elem, name, extra );
7031
+ }
7032
+ }
7033
+ },
7034
+
7035
+ set: function( elem, value, extra ) {
7036
+ return setPositiveNumber( elem, value, extra ?
7037
+ augmentWidthOrHeight(
7038
+ elem,
7039
+ name,
7040
+ extra,
7041
+ jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"
7042
+ ) : 0
7043
+ );
7044
+ }
7045
+ };
7046
+ });
7047
+
7048
+ if ( !jQuery.support.opacity ) {
7049
+ jQuery.cssHooks.opacity = {
7050
+ get: function( elem, computed ) {
7051
+ // IE uses filters for opacity
7052
+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
7053
+ ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
7054
+ computed ? "1" : "";
7055
+ },
7056
+
7057
+ set: function( elem, value ) {
7058
+ var style = elem.style,
7059
+ currentStyle = elem.currentStyle,
7060
+ opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
7061
+ filter = currentStyle && currentStyle.filter || style.filter || "";
7062
+
7063
+ // IE has trouble with opacity if it does not have layout
7064
+ // Force it by setting the zoom level
7065
+ style.zoom = 1;
7066
+
7067
+ // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
7068
+ if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
7069
+ style.removeAttribute ) {
7070
+
7071
+ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
7072
+ // if "filter:" is present at all, clearType is disabled, we want to avoid this
7073
+ // style.removeAttribute is IE Only, but so apparently is this code path...
7074
+ style.removeAttribute( "filter" );
7075
+
7076
+ // if there there is no filter style applied in a css rule, we are done
7077
+ if ( currentStyle && !currentStyle.filter ) {
7078
+ return;
7079
+ }
7080
+ }
7081
+
7082
+ // otherwise, set new filter values
7083
+ style.filter = ralpha.test( filter ) ?
7084
+ filter.replace( ralpha, opacity ) :
7085
+ filter + " " + opacity;
7086
+ }
7087
+ };
7088
+ }
7089
+
7090
+ // These hooks cannot be added until DOM ready because the support test
7091
+ // for it is not run until after DOM ready
7092
+ jQuery(function() {
7093
+ if ( !jQuery.support.reliableMarginRight ) {
7094
+ jQuery.cssHooks.marginRight = {
7095
+ get: function( elem, computed ) {
7096
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
7097
+ // Work around by temporarily setting element display to inline-block
7098
+ return jQuery.swap( elem, { "display": "inline-block" }, function() {
7099
+ if ( computed ) {
7100
+ return curCSS( elem, "marginRight" );
7101
+ }
7102
+ });
7103
+ }
7104
+ };
7105
+ }
7106
+
7107
+ // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
7108
+ // getComputedStyle returns percent when specified for top/left/bottom/right
7109
+ // rather than make the css module depend on the offset module, we just check for it here
7110
+ if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
7111
+ jQuery.each( [ "top", "left" ], function( i, prop ) {
7112
+ jQuery.cssHooks[ prop ] = {
7113
+ get: function( elem, computed ) {
7114
+ if ( computed ) {
7115
+ var ret = curCSS( elem, prop );
7116
+ // if curCSS returns percentage, fallback to offset
7117
+ return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret;
7118
+ }
7119
+ }
7120
+ };
7121
+ });
7122
+ }
7123
+
7124
+ });
7125
+
7126
+ if ( jQuery.expr && jQuery.expr.filters ) {
7127
+ jQuery.expr.filters.hidden = function( elem ) {
7128
+ return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none");
7129
+ };
7130
+
7131
+ jQuery.expr.filters.visible = function( elem ) {
7132
+ return !jQuery.expr.filters.hidden( elem );
7133
+ };
7134
+ }
7135
+
7136
+ // These hooks are used by animate to expand properties
7137
+ jQuery.each({
7138
+ margin: "",
7139
+ padding: "",
7140
+ border: "Width"
7141
+ }, function( prefix, suffix ) {
7142
+ jQuery.cssHooks[ prefix + suffix ] = {
7143
+ expand: function( value ) {
7144
+ var i,
7145
+
7146
+ // assumes a single number if not a string
7147
+ parts = typeof value === "string" ? value.split(" ") : [ value ],
7148
+ expanded = {};
7149
+
7150
+ for ( i = 0; i < 4; i++ ) {
7151
+ expanded[ prefix + cssExpand[ i ] + suffix ] =
7152
+ parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7153
+ }
7154
+
7155
+ return expanded;
7156
+ }
7157
+ };
7158
+
7159
+ if ( !rmargin.test( prefix ) ) {
7160
+ jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7161
+ }
7162
+ });
7163
+ var r20 = /%20/g,
7164
+ rbracket = /\[\]$/,
7165
+ rCRLF = /\r?\n/g,
7166
+ rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
7167
+ rselectTextarea = /^(?:select|textarea)/i;
7168
+
7169
+ jQuery.fn.extend({
7170
+ serialize: function() {
7171
+ return jQuery.param( this.serializeArray() );
7172
+ },
7173
+ serializeArray: function() {
7174
+ return this.map(function(){
7175
+ return this.elements ? jQuery.makeArray( this.elements ) : this;
7176
+ })
7177
+ .filter(function(){
7178
+ return this.name && !this.disabled &&
7179
+ ( this.checked || rselectTextarea.test( this.nodeName ) ||
7180
+ rinput.test( this.type ) );
7181
+ })
7182
+ .map(function( i, elem ){
7183
+ var val = jQuery( this ).val();
7184
+
7185
+ return val == null ?
7186
+ null :
7187
+ jQuery.isArray( val ) ?
7188
+ jQuery.map( val, function( val, i ){
7189
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7190
+ }) :
7191
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7192
+ }).get();
7193
+ }
7194
+ });
7195
+
7196
+ //Serialize an array of form elements or a set of
7197
+ //key/values into a query string
7198
+ jQuery.param = function( a, traditional ) {
7199
+ var prefix,
7200
+ s = [],
7201
+ add = function( key, value ) {
7202
+ // If value is a function, invoke it and return its value
7203
+ value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
7204
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7205
+ };
7206
+
7207
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
7208
+ if ( traditional === undefined ) {
7209
+ traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
7210
+ }
7211
+
7212
+ // If an array was passed in, assume that it is an array of form elements.
7213
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7214
+ // Serialize the form elements
7215
+ jQuery.each( a, function() {
7216
+ add( this.name, this.value );
7217
+ });
7218
+
7219
+ } else {
7220
+ // If traditional, encode the "old" way (the way 1.3.2 or older
7221
+ // did it), otherwise encode params recursively.
7222
+ for ( prefix in a ) {
7223
+ buildParams( prefix, a[ prefix ], traditional, add );
7224
+ }
7225
+ }
7226
+
7227
+ // Return the resulting serialization
7228
+ return s.join( "&" ).replace( r20, "+" );
7229
+ };
7230
+
7231
+ function buildParams( prefix, obj, traditional, add ) {
7232
+ var name;
7233
+
7234
+ if ( jQuery.isArray( obj ) ) {
7235
+ // Serialize array item.
7236
+ jQuery.each( obj, function( i, v ) {
7237
+ if ( traditional || rbracket.test( prefix ) ) {
7238
+ // Treat each array item as a scalar.
7239
+ add( prefix, v );
7240
+
7241
+ } else {
7242
+ // If array item is non-scalar (array or object), encode its
7243
+ // numeric index to resolve deserialization ambiguity issues.
7244
+ // Note that rack (as of 1.0.0) can't currently deserialize
7245
+ // nested arrays properly, and attempting to do so may cause
7246
+ // a server error. Possible fixes are to modify rack's
7247
+ // deserialization algorithm or to provide an option or flag
7248
+ // to force array serialization to be shallow.
7249
+ buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
7250
+ }
7251
+ });
7252
+
7253
+ } else if ( !traditional && jQuery.type( obj ) === "object" ) {
7254
+ // Serialize object item.
7255
+ for ( name in obj ) {
7256
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7257
+ }
7258
+
7259
+ } else {
7260
+ // Serialize scalar item.
7261
+ add( prefix, obj );
7262
+ }
7263
+ }
7264
+ var
7265
+ // Document location
7266
+ ajaxLocParts,
7267
+ ajaxLocation,
7268
+
7269
+ rhash = /#.*$/,
7270
+ rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
7271
+ // #7653, #8125, #8152: local protocol detection
7272
+ rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
7273
+ rnoContent = /^(?:GET|HEAD)$/,
7274
+ rprotocol = /^\/\//,
7275
+ rquery = /\?/,
7276
+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
7277
+ rts = /([?&])_=[^&]*/,
7278
+ rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
7279
+
7280
+ // Keep a copy of the old load method
7281
+ _load = jQuery.fn.load,
7282
+
7283
+ /* Prefilters
7284
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
7285
+ * 2) These are called:
7286
+ * - BEFORE asking for a transport
7287
+ * - AFTER param serialization (s.data is a string if s.processData is true)
7288
+ * 3) key is the dataType
7289
+ * 4) the catchall symbol "*" can be used
7290
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
7291
+ */
7292
+ prefilters = {},
7293
+
7294
+ /* Transports bindings
7295
+ * 1) key is the dataType
7296
+ * 2) the catchall symbol "*" can be used
7297
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
7298
+ */
7299
+ transports = {},
7300
+
7301
+ // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
7302
+ allTypes = ["*/"] + ["*"];
7303
+
7304
+ // #8138, IE may throw an exception when accessing
7305
+ // a field from window.location if document.domain has been set
7306
+ try {
7307
+ ajaxLocation = location.href;
7308
+ } catch( e ) {
7309
+ // Use the href attribute of an A element
7310
+ // since IE will modify it given document.location
7311
+ ajaxLocation = document.createElement( "a" );
7312
+ ajaxLocation.href = "";
7313
+ ajaxLocation = ajaxLocation.href;
7314
+ }
7315
+
7316
+ // Segment location into parts
7317
+ ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7318
+
7319
+ // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7320
+ function addToPrefiltersOrTransports( structure ) {
7321
+
7322
+ // dataTypeExpression is optional and defaults to "*"
7323
+ return function( dataTypeExpression, func ) {
7324
+
7325
+ if ( typeof dataTypeExpression !== "string" ) {
7326
+ func = dataTypeExpression;
7327
+ dataTypeExpression = "*";
7328
+ }
7329
+
7330
+ var dataType, list, placeBefore,
7331
+ dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),
7332
+ i = 0,
7333
+ length = dataTypes.length;
7334
+
7335
+ if ( jQuery.isFunction( func ) ) {
7336
+ // For each dataType in the dataTypeExpression
7337
+ for ( ; i < length; i++ ) {
7338
+ dataType = dataTypes[ i ];
7339
+ // We control if we're asked to add before
7340
+ // any existing element
7341
+ placeBefore = /^\+/.test( dataType );
7342
+ if ( placeBefore ) {
7343
+ dataType = dataType.substr( 1 ) || "*";
7344
+ }
7345
+ list = structure[ dataType ] = structure[ dataType ] || [];
7346
+ // then we add to the structure accordingly
7347
+ list[ placeBefore ? "unshift" : "push" ]( func );
7348
+ }
7349
+ }
7350
+ };
7351
+ }
7352
+
7353
+ // Base inspection function for prefilters and transports
7354
+ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
7355
+ dataType /* internal */, inspected /* internal */ ) {
7356
+
7357
+ dataType = dataType || options.dataTypes[ 0 ];
7358
+ inspected = inspected || {};
7359
+
7360
+ inspected[ dataType ] = true;
7361
+
7362
+ var selection,
7363
+ list = structure[ dataType ],
7364
+ i = 0,
7365
+ length = list ? list.length : 0,
7366
+ executeOnly = ( structure === prefilters );
7367
+
7368
+ for ( ; i < length && ( executeOnly || !selection ); i++ ) {
7369
+ selection = list[ i ]( options, originalOptions, jqXHR );
7370
+ // If we got redirected to another dataType
7371
+ // we try there if executing only and not done already
7372
+ if ( typeof selection === "string" ) {
7373
+ if ( !executeOnly || inspected[ selection ] ) {
7374
+ selection = undefined;
7375
+ } else {
7376
+ options.dataTypes.unshift( selection );
7377
+ selection = inspectPrefiltersOrTransports(
7378
+ structure, options, originalOptions, jqXHR, selection, inspected );
7379
+ }
7380
+ }
7381
+ }
7382
+ // If we're only executing or nothing was selected
7383
+ // we try the catchall dataType if not done already
7384
+ if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
7385
+ selection = inspectPrefiltersOrTransports(
7386
+ structure, options, originalOptions, jqXHR, "*", inspected );
7387
+ }
7388
+ // unnecessary when only executing (prefilters)
7389
+ // but it'll be ignored by the caller in that case
7390
+ return selection;
7391
+ }
7392
+
7393
+ // A special extend for ajax options
7394
+ // that takes "flat" options (not to be deep extended)
7395
+ // Fixes #9887
7396
+ function ajaxExtend( target, src ) {
7397
+ var key, deep,
7398
+ flatOptions = jQuery.ajaxSettings.flatOptions || {};
7399
+ for ( key in src ) {
7400
+ if ( src[ key ] !== undefined ) {
7401
+ ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
7402
+ }
7403
+ }
7404
+ if ( deep ) {
7405
+ jQuery.extend( true, target, deep );
7406
+ }
7407
+ }
7408
+
7409
+ jQuery.fn.load = function( url, params, callback ) {
7410
+ if ( typeof url !== "string" && _load ) {
7411
+ return _load.apply( this, arguments );
7412
+ }
7413
+
7414
+ // Don't do a request if no elements are being requested
7415
+ if ( !this.length ) {
7416
+ return this;
7417
+ }
7418
+
7419
+ var selector, type, response,
7420
+ self = this,
7421
+ off = url.indexOf(" ");
7422
+
7423
+ if ( off >= 0 ) {
7424
+ selector = url.slice( off, url.length );
7425
+ url = url.slice( 0, off );
7426
+ }
7427
+
7428
+ // If it's a function
7429
+ if ( jQuery.isFunction( params ) ) {
7430
+
7431
+ // We assume that it's the callback
7432
+ callback = params;
7433
+ params = undefined;
7434
+
7435
+ // Otherwise, build a param string
7436
+ } else if ( params && typeof params === "object" ) {
7437
+ type = "POST";
7438
+ }
7439
+
7440
+ // Request the remote document
7441
+ jQuery.ajax({
7442
+ url: url,
7443
+
7444
+ // if "type" variable is undefined, then "GET" method will be used
7445
+ type: type,
7446
+ dataType: "html",
7447
+ data: params,
7448
+ complete: function( jqXHR, status ) {
7449
+ if ( callback ) {
7450
+ self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
7451
+ }
7452
+ }
7453
+ }).done(function( responseText ) {
7454
+
7455
+ // Save response for use in complete callback
7456
+ response = arguments;
7457
+
7458
+ // See if a selector was specified
7459
+ self.html( selector ?
7460
+
7461
+ // Create a dummy div to hold the results
7462
+ jQuery("<div>")
7463
+
7464
+ // inject the contents of the document in, removing the scripts
7465
+ // to avoid any 'Permission Denied' errors in IE
7466
+ .append( responseText.replace( rscript, "" ) )
7467
+
7468
+ // Locate the specified elements
7469
+ .find( selector ) :
7470
+
7471
+ // If not, just inject the full result
7472
+ responseText );
7473
+
7474
+ });
7475
+
7476
+ return this;
7477
+ };
7478
+
7479
+ // Attach a bunch of functions for handling common AJAX events
7480
+ jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
7481
+ jQuery.fn[ o ] = function( f ){
7482
+ return this.on( o, f );
7483
+ };
7484
+ });
7485
+
7486
+ jQuery.each( [ "get", "post" ], function( i, method ) {
7487
+ jQuery[ method ] = function( url, data, callback, type ) {
7488
+ // shift arguments if data argument was omitted
7489
+ if ( jQuery.isFunction( data ) ) {
7490
+ type = type || callback;
7491
+ callback = data;
7492
+ data = undefined;
7493
+ }
7494
+
7495
+ return jQuery.ajax({
7496
+ type: method,
7497
+ url: url,
7498
+ data: data,
7499
+ success: callback,
7500
+ dataType: type
7501
+ });
7502
+ };
7503
+ });
7504
+
7505
+ jQuery.extend({
7506
+
7507
+ getScript: function( url, callback ) {
7508
+ return jQuery.get( url, undefined, callback, "script" );
7509
+ },
7510
+
7511
+ getJSON: function( url, data, callback ) {
7512
+ return jQuery.get( url, data, callback, "json" );
7513
+ },
7514
+
7515
+ // Creates a full fledged settings object into target
7516
+ // with both ajaxSettings and settings fields.
7517
+ // If target is omitted, writes into ajaxSettings.
7518
+ ajaxSetup: function( target, settings ) {
7519
+ if ( settings ) {
7520
+ // Building a settings object
7521
+ ajaxExtend( target, jQuery.ajaxSettings );
7522
+ } else {
7523
+ // Extending ajaxSettings
7524
+ settings = target;
7525
+ target = jQuery.ajaxSettings;
7526
+ }
7527
+ ajaxExtend( target, settings );
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; charset=UTF-8",
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
+ throws: false,
7547
+ traditional: false,
7548
+ headers: {},
7549
+ */
7550
+
7551
+ accepts: {
7552
+ xml: "application/xml, text/xml",
7553
+ html: "text/html",
7554
+ text: "text/plain",
7555
+ json: "application/json, text/javascript",
7556
+ "*": allTypes
7557
+ },
7558
+
7559
+ contents: {
7560
+ xml: /xml/,
7561
+ html: /html/,
7562
+ json: /json/
7563
+ },
7564
+
7565
+ responseFields: {
7566
+ xml: "responseXML",
7567
+ text: "responseText"
7568
+ },
7569
+
7570
+ // List of data converters
7571
+ // 1) key format is "source_type destination_type" (a single space in-between)
7572
+ // 2) the catchall symbol "*" can be used for source_type
7573
+ converters: {
7574
+
7575
+ // Convert anything to text
7576
+ "* text": window.String,
7577
+
7578
+ // Text to html (true = no transformation)
7579
+ "text html": true,
7580
+
7581
+ // Evaluate text as a json expression
7582
+ "text json": jQuery.parseJSON,
7583
+
7584
+ // Parse text as xml
7585
+ "text xml": jQuery.parseXML
7586
+ },
7587
+
7588
+ // For options that shouldn't be deep extended:
7589
+ // you can add your own custom options here if
7590
+ // and when you create one that shouldn't be
7591
+ // deep extended (see ajaxExtend)
7592
+ flatOptions: {
7593
+ context: true,
7594
+ url: true
7595
+ }
7596
+ },
7597
+
7598
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7599
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
7600
+
7601
+ // Main method
7602
+ ajax: function( url, options ) {
7603
+
7604
+ // If url is an object, simulate pre-1.5 signature
7605
+ if ( typeof url === "object" ) {
7606
+ options = url;
7607
+ url = undefined;
7608
+ }
7609
+
7610
+ // Force options to be an object
7611
+ options = options || {};
7612
+
7613
+ var // ifModified key
7614
+ ifModifiedKey,
7615
+ // Response headers
7616
+ responseHeadersString,
7617
+ responseHeaders,
7618
+ // transport
7619
+ transport,
7620
+ // timeout handle
7621
+ timeoutTimer,
7622
+ // Cross-domain detection vars
7623
+ parts,
7624
+ // To know if global events are to be dispatched
7625
+ fireGlobals,
7626
+ // Loop variable
7627
+ i,
7628
+ // Create the final options object
7629
+ s = jQuery.ajaxSetup( {}, options ),
7630
+ // Callbacks context
7631
+ callbackContext = s.context || s,
7632
+ // Context for global events
7633
+ // It's the callbackContext if one was provided in the options
7634
+ // and if it's a DOM node or a jQuery collection
7635
+ globalEventContext = callbackContext !== s &&
7636
+ ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7637
+ jQuery( callbackContext ) : jQuery.event,
7638
+ // Deferreds
7639
+ deferred = jQuery.Deferred(),
7640
+ completeDeferred = jQuery.Callbacks( "once memory" ),
7641
+ // Status-dependent callbacks
7642
+ statusCode = s.statusCode || {},
7643
+ // Headers (they are sent all at once)
7644
+ requestHeaders = {},
7645
+ requestHeadersNames = {},
7646
+ // The jqXHR state
7647
+ state = 0,
7648
+ // Default abort message
7649
+ strAbort = "canceled",
7650
+ // Fake xhr
7651
+ jqXHR = {
7652
+
7653
+ readyState: 0,
7654
+
7655
+ // Caches the header
7656
+ setRequestHeader: function( name, value ) {
7657
+ if ( !state ) {
7658
+ var lname = name.toLowerCase();
7659
+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7660
+ requestHeaders[ name ] = value;
7661
+ }
7662
+ return this;
7663
+ },
7664
+
7665
+ // Raw string
7666
+ getAllResponseHeaders: function() {
7667
+ return state === 2 ? responseHeadersString : null;
7668
+ },
7669
+
7670
+ // Builds headers hashtable if needed
7671
+ getResponseHeader: function( key ) {
7672
+ var match;
7673
+ if ( state === 2 ) {
7674
+ if ( !responseHeaders ) {
7675
+ responseHeaders = {};
7676
+ while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7677
+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7678
+ }
7679
+ }
7680
+ match = responseHeaders[ key.toLowerCase() ];
7681
+ }
7682
+ return match === undefined ? null : match;
7683
+ },
7684
+
7685
+ // Overrides response content-type header
7686
+ overrideMimeType: function( type ) {
7687
+ if ( !state ) {
7688
+ s.mimeType = type;
7689
+ }
7690
+ return this;
7691
+ },
7692
+
7693
+ // Cancel the request
7694
+ abort: function( statusText ) {
7695
+ statusText = statusText || strAbort;
7696
+ if ( transport ) {
7697
+ transport.abort( statusText );
7698
+ }
7699
+ done( 0, statusText );
7700
+ return this;
7701
+ }
7702
+ };
7703
+
7704
+ // Callback for when everything is done
7705
+ // It is defined here because jslint complains if it is declared
7706
+ // at the end of the function (which would be more logical and readable)
7707
+ function done( status, nativeStatusText, responses, headers ) {
7708
+ var isSuccess, success, error, response, modified,
7709
+ statusText = nativeStatusText;
7710
+
7711
+ // Called once
7712
+ if ( state === 2 ) {
7713
+ return;
7714
+ }
7715
+
7716
+ // State is "done" now
7717
+ state = 2;
7718
+
7719
+ // Clear timeout if it exists
7720
+ if ( timeoutTimer ) {
7721
+ clearTimeout( timeoutTimer );
7722
+ }
7723
+
7724
+ // Dereference transport for early garbage collection
7725
+ // (no matter how long the jqXHR object will be used)
7726
+ transport = undefined;
7727
+
7728
+ // Cache response headers
7729
+ responseHeadersString = headers || "";
7730
+
7731
+ // Set readyState
7732
+ jqXHR.readyState = status > 0 ? 4 : 0;
7733
+
7734
+ // Get response data
7735
+ if ( responses ) {
7736
+ response = ajaxHandleResponses( s, jqXHR, responses );
7737
+ }
7738
+
7739
+ // If successful, handle type chaining
7740
+ if ( status >= 200 && status < 300 || status === 304 ) {
7741
+
7742
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7743
+ if ( s.ifModified ) {
7744
+
7745
+ modified = jqXHR.getResponseHeader("Last-Modified");
7746
+ if ( modified ) {
7747
+ jQuery.lastModified[ ifModifiedKey ] = modified;
7748
+ }
7749
+ modified = jqXHR.getResponseHeader("Etag");
7750
+ if ( modified ) {
7751
+ jQuery.etag[ ifModifiedKey ] = modified;
7752
+ }
7753
+ }
7754
+
7755
+ // If not modified
7756
+ if ( status === 304 ) {
7757
+
7758
+ statusText = "notmodified";
7759
+ isSuccess = true;
7760
+
7761
+ // If we have data
7762
+ } else {
7763
+
7764
+ isSuccess = ajaxConvert( s, response );
7765
+ statusText = isSuccess.state;
7766
+ success = isSuccess.data;
7767
+ error = isSuccess.error;
7768
+ isSuccess = !error;
7769
+ }
7770
+ } else {
7771
+ // We extract error from statusText
7772
+ // then normalize statusText and status for non-aborts
7773
+ error = statusText;
7774
+ if ( !statusText || status ) {
7775
+ statusText = "error";
7776
+ if ( status < 0 ) {
7777
+ status = 0;
7778
+ }
7779
+ }
7780
+ }
7781
+
7782
+ // Set data for the fake xhr object
7783
+ jqXHR.status = status;
7784
+ jqXHR.statusText = ( nativeStatusText || statusText ) + "";
7785
+
7786
+ // Success/Error
7787
+ if ( isSuccess ) {
7788
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7789
+ } else {
7790
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7791
+ }
7792
+
7793
+ // Status-dependent callbacks
7794
+ jqXHR.statusCode( statusCode );
7795
+ statusCode = undefined;
7796
+
7797
+ if ( fireGlobals ) {
7798
+ globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7799
+ [ jqXHR, s, isSuccess ? success : error ] );
7800
+ }
7801
+
7802
+ // Complete
7803
+ completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
7804
+
7805
+ if ( fireGlobals ) {
7806
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7807
+ // Handle the global AJAX counter
7808
+ if ( !( --jQuery.active ) ) {
7809
+ jQuery.event.trigger( "ajaxStop" );
7810
+ }
7811
+ }
7812
+ }
7813
+
7814
+ // Attach deferreds
7815
+ deferred.promise( jqXHR );
7816
+ jqXHR.success = jqXHR.done;
7817
+ jqXHR.error = jqXHR.fail;
7818
+ jqXHR.complete = completeDeferred.add;
7819
+
7820
+ // Status-dependent callbacks
7821
+ jqXHR.statusCode = function( map ) {
7822
+ if ( map ) {
7823
+ var tmp;
7824
+ if ( state < 2 ) {
7825
+ for ( tmp in map ) {
7826
+ statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7827
+ }
7828
+ } else {
7829
+ tmp = map[ jqXHR.status ];
7830
+ jqXHR.always( tmp );
7831
+ }
7832
+ }
7833
+ return this;
7834
+ };
7835
+
7836
+ // Remove hash character (#7531: and string promotion)
7837
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7838
+ // We also use the url parameter if available
7839
+ s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7840
+
7841
+ // Extract dataTypes list
7842
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace );
7843
+
7844
+ // A cross-domain request is in order when we have a protocol:host:port mismatch
7845
+ if ( s.crossDomain == null ) {
7846
+ parts = rurl.exec( s.url.toLowerCase() ) || false;
7847
+ s.crossDomain = parts && ( parts.join(":") + ( parts[ 3 ] ? "" : parts[ 1 ] === "http:" ? 80 : 443 ) ) !==
7848
+ ( ajaxLocParts.join(":") + ( ajaxLocParts[ 3 ] ? "" : ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) );
7849
+ }
7850
+
7851
+ // Convert data if not already a string
7852
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
7853
+ s.data = jQuery.param( s.data, s.traditional );
7854
+ }
7855
+
7856
+ // Apply prefilters
7857
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7858
+
7859
+ // If request was aborted inside a prefilter, stop there
7860
+ if ( state === 2 ) {
7861
+ return jqXHR;
7862
+ }
7863
+
7864
+ // We can fire global events as of now if asked to
7865
+ fireGlobals = s.global;
7866
+
7867
+ // Uppercase the type
7868
+ s.type = s.type.toUpperCase();
7869
+
7870
+ // Determine if request has content
7871
+ s.hasContent = !rnoContent.test( s.type );
7872
+
7873
+ // Watch for a new set of requests
7874
+ if ( fireGlobals && jQuery.active++ === 0 ) {
7875
+ jQuery.event.trigger( "ajaxStart" );
7876
+ }
7877
+
7878
+ // More options handling for requests with no content
7879
+ if ( !s.hasContent ) {
7880
+
7881
+ // If data is available, append data to url
7882
+ if ( s.data ) {
7883
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7884
+ // #9682: remove data so that it's not used in an eventual retry
7885
+ delete s.data;
7886
+ }
7887
+
7888
+ // Get ifModifiedKey before adding the anti-cache parameter
7889
+ ifModifiedKey = s.url;
7890
+
7891
+ // Add anti-cache in url if needed
7892
+ if ( s.cache === false ) {
7893
+
7894
+ var ts = jQuery.now(),
7895
+ // try replacing _= if it is there
7896
+ ret = s.url.replace( rts, "$1_=" + ts );
7897
+
7898
+ // if nothing was replaced, add timestamp to the end
7899
+ s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7900
+ }
7901
+ }
7902
+
7903
+ // Set the correct header, if data is being sent
7904
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7905
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
7906
+ }
7907
+
7908
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7909
+ if ( s.ifModified ) {
7910
+ ifModifiedKey = ifModifiedKey || s.url;
7911
+ if ( jQuery.lastModified[ ifModifiedKey ] ) {
7912
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7913
+ }
7914
+ if ( jQuery.etag[ ifModifiedKey ] ) {
7915
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7916
+ }
7917
+ }
7918
+
7919
+ // Set the Accepts header for the server, depending on the dataType
7920
+ jqXHR.setRequestHeader(
7921
+ "Accept",
7922
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7923
+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7924
+ s.accepts[ "*" ]
7925
+ );
7926
+
7927
+ // Check for headers option
7928
+ for ( i in s.headers ) {
7929
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
7930
+ }
7931
+
7932
+ // Allow custom headers/mimetypes and early abort
7933
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7934
+ // Abort if not done already and return
7935
+ return jqXHR.abort();
7936
+
7937
+ }
7938
+
7939
+ // aborting is no longer a cancellation
7940
+ strAbort = "abort";
7941
+
7942
+ // Install callbacks on deferreds
7943
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
7944
+ jqXHR[ i ]( s[ i ] );
7945
+ }
7946
+
7947
+ // Get transport
7948
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7949
+
7950
+ // If no transport, we auto-abort
7951
+ if ( !transport ) {
7952
+ done( -1, "No Transport" );
7953
+ } else {
7954
+ jqXHR.readyState = 1;
7955
+ // Send global event
7956
+ if ( fireGlobals ) {
7957
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7958
+ }
7959
+ // Timeout
7960
+ if ( s.async && s.timeout > 0 ) {
7961
+ timeoutTimer = setTimeout( function(){
7962
+ jqXHR.abort( "timeout" );
7963
+ }, s.timeout );
7964
+ }
7965
+
7966
+ try {
7967
+ state = 1;
7968
+ transport.send( requestHeaders, done );
7969
+ } catch (e) {
7970
+ // Propagate exception as error if not done
7971
+ if ( state < 2 ) {
7972
+ done( -1, e );
7973
+ // Simply rethrow otherwise
7974
+ } else {
7975
+ throw e;
7976
+ }
7977
+ }
7978
+ }
7979
+
7980
+ return jqXHR;
7981
+ },
7982
+
7983
+ // Counter for holding the number of active queries
7984
+ active: 0,
7985
+
7986
+ // Last-Modified header cache for next request
7987
+ lastModified: {},
7988
+ etag: {}
7989
+
7990
+ });
7991
+
7992
+ /* Handles responses to an ajax request:
7993
+ * - sets all responseXXX fields accordingly
7994
+ * - finds the right dataType (mediates between content-type and expected dataType)
7995
+ * - returns the corresponding response
7996
+ */
7997
+ function ajaxHandleResponses( s, jqXHR, responses ) {
7998
+
7999
+ var ct, type, finalDataType, firstDataType,
8000
+ contents = s.contents,
8001
+ dataTypes = s.dataTypes,
8002
+ responseFields = s.responseFields;
8003
+
8004
+ // Fill responseXXX fields
8005
+ for ( type in responseFields ) {
8006
+ if ( type in responses ) {
8007
+ jqXHR[ responseFields[type] ] = responses[ type ];
8008
+ }
8009
+ }
8010
+
8011
+ // Remove auto dataType and get content-type in the process
8012
+ while( dataTypes[ 0 ] === "*" ) {
8013
+ dataTypes.shift();
8014
+ if ( ct === undefined ) {
8015
+ ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
8016
+ }
8017
+ }
8018
+
8019
+ // Check if we're dealing with a known content-type
8020
+ if ( ct ) {
8021
+ for ( type in contents ) {
8022
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
8023
+ dataTypes.unshift( type );
8024
+ break;
8025
+ }
8026
+ }
8027
+ }
8028
+
8029
+ // Check to see if we have a response for the expected dataType
8030
+ if ( dataTypes[ 0 ] in responses ) {
8031
+ finalDataType = dataTypes[ 0 ];
8032
+ } else {
8033
+ // Try convertible dataTypes
8034
+ for ( type in responses ) {
8035
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
8036
+ finalDataType = type;
8037
+ break;
8038
+ }
8039
+ if ( !firstDataType ) {
8040
+ firstDataType = type;
8041
+ }
8042
+ }
8043
+ // Or just use first one
8044
+ finalDataType = finalDataType || firstDataType;
8045
+ }
8046
+
8047
+ // If we found a dataType
8048
+ // We add the dataType to the list if needed
8049
+ // and return the corresponding response
8050
+ if ( finalDataType ) {
8051
+ if ( finalDataType !== dataTypes[ 0 ] ) {
8052
+ dataTypes.unshift( finalDataType );
8053
+ }
8054
+ return responses[ finalDataType ];
8055
+ }
8056
+ }
8057
+
8058
+ // Chain conversions given the request and the original response
8059
+ function ajaxConvert( s, response ) {
8060
+
8061
+ var conv, conv2, current, tmp,
8062
+ // Work with a copy of dataTypes in case we need to modify it for conversion
8063
+ dataTypes = s.dataTypes.slice(),
8064
+ prev = dataTypes[ 0 ],
8065
+ converters = {},
8066
+ i = 0;
8067
+
8068
+ // Apply the dataFilter if provided
8069
+ if ( s.dataFilter ) {
8070
+ response = s.dataFilter( response, s.dataType );
8071
+ }
8072
+
8073
+ // Create converters map with lowercased keys
8074
+ if ( dataTypes[ 1 ] ) {
8075
+ for ( conv in s.converters ) {
8076
+ converters[ conv.toLowerCase() ] = s.converters[ conv ];
8077
+ }
8078
+ }
8079
+
8080
+ // Convert to each sequential dataType, tolerating list modification
8081
+ for ( ; (current = dataTypes[++i]); ) {
8082
+
8083
+ // There's only work to do if current dataType is non-auto
8084
+ if ( current !== "*" ) {
8085
+
8086
+ // Convert response if prev dataType is non-auto and differs from current
8087
+ if ( prev !== "*" && prev !== current ) {
8088
+
8089
+ // Seek a direct converter
8090
+ conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8091
+
8092
+ // If none found, seek a pair
8093
+ if ( !conv ) {
8094
+ for ( conv2 in converters ) {
8095
+
8096
+ // If conv2 outputs current
8097
+ tmp = conv2.split(" ");
8098
+ if ( tmp[ 1 ] === current ) {
8099
+
8100
+ // If prev can be converted to accepted input
8101
+ conv = converters[ prev + " " + tmp[ 0 ] ] ||
8102
+ converters[ "* " + tmp[ 0 ] ];
8103
+ if ( conv ) {
8104
+ // Condense equivalence converters
8105
+ if ( conv === true ) {
8106
+ conv = converters[ conv2 ];
8107
+
8108
+ // Otherwise, insert the intermediate dataType
8109
+ } else if ( converters[ conv2 ] !== true ) {
8110
+ current = tmp[ 0 ];
8111
+ dataTypes.splice( i--, 0, current );
8112
+ }
8113
+
8114
+ break;
8115
+ }
8116
+ }
8117
+ }
8118
+ }
8119
+
8120
+ // Apply converter (if not an equivalence)
8121
+ if ( conv !== true ) {
8122
+
8123
+ // Unless errors are allowed to bubble, catch and return them
8124
+ if ( conv && s["throws"] ) {
8125
+ response = conv( response );
8126
+ } else {
8127
+ try {
8128
+ response = conv( response );
8129
+ } catch ( e ) {
8130
+ return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
8131
+ }
8132
+ }
8133
+ }
8134
+ }
8135
+
8136
+ // Update prev for next iteration
8137
+ prev = current;
8138
+ }
8139
+ }
8140
+
8141
+ return { state: "success", data: response };
8142
+ }
8143
+ var oldCallbacks = [],
8144
+ rquestion = /\?/,
8145
+ rjsonp = /(=)\?(?=&|$)|\?\?/,
8146
+ nonce = jQuery.now();
8147
+
8148
+ // Default jsonp settings
8149
+ jQuery.ajaxSetup({
8150
+ jsonp: "callback",
8151
+ jsonpCallback: function() {
8152
+ var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
8153
+ this[ callback ] = true;
8154
+ return callback;
8155
+ }
8156
+ });
8157
+
8158
+ // Detect, normalize options and install callbacks for jsonp requests
8159
+ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
8160
+
8161
+ var callbackName, overwritten, responseContainer,
8162
+ data = s.data,
8163
+ url = s.url,
8164
+ hasCallback = s.jsonp !== false,
8165
+ replaceInUrl = hasCallback && rjsonp.test( url ),
8166
+ replaceInData = hasCallback && !replaceInUrl && typeof data === "string" &&
8167
+ !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") &&
8168
+ rjsonp.test( data );
8169
+
8170
+ // Handle iff the expected data type is "jsonp" or we have a parameter to set
8171
+ if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) {
8172
+
8173
+ // Get callback name, remembering preexisting value associated with it
8174
+ callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
8175
+ s.jsonpCallback() :
8176
+ s.jsonpCallback;
8177
+ overwritten = window[ callbackName ];
8178
+
8179
+ // Insert callback into url or form data
8180
+ if ( replaceInUrl ) {
8181
+ s.url = url.replace( rjsonp, "$1" + callbackName );
8182
+ } else if ( replaceInData ) {
8183
+ s.data = data.replace( rjsonp, "$1" + callbackName );
8184
+ } else if ( hasCallback ) {
8185
+ s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
8186
+ }
8187
+
8188
+ // Use data converter to retrieve json after script execution
8189
+ s.converters["script json"] = function() {
8190
+ if ( !responseContainer ) {
8191
+ jQuery.error( callbackName + " was not called" );
8192
+ }
8193
+ return responseContainer[ 0 ];
8194
+ };
8195
+
8196
+ // force json dataType
8197
+ s.dataTypes[ 0 ] = "json";
8198
+
8199
+ // Install callback
8200
+ window[ callbackName ] = function() {
8201
+ responseContainer = arguments;
8202
+ };
8203
+
8204
+ // Clean-up function (fires after converters)
8205
+ jqXHR.always(function() {
8206
+ // Restore preexisting value
8207
+ window[ callbackName ] = overwritten;
8208
+
8209
+ // Save back as free
8210
+ if ( s[ callbackName ] ) {
8211
+ // make sure that re-using the options doesn't screw things around
8212
+ s.jsonpCallback = originalSettings.jsonpCallback;
8213
+
8214
+ // save the callback name for future use
8215
+ oldCallbacks.push( callbackName );
8216
+ }
8217
+
8218
+ // Call if it was a function and we have a response
8219
+ if ( responseContainer && jQuery.isFunction( overwritten ) ) {
8220
+ overwritten( responseContainer[ 0 ] );
8221
+ }
8222
+
8223
+ responseContainer = overwritten = undefined;
8224
+ });
8225
+
8226
+ // Delegate to script
8227
+ return "script";
8228
+ }
8229
+ });
8230
+ // Install script dataType
8231
+ jQuery.ajaxSetup({
8232
+ accepts: {
8233
+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8234
+ },
8235
+ contents: {
8236
+ script: /javascript|ecmascript/
8237
+ },
8238
+ converters: {
8239
+ "text script": function( text ) {
8240
+ jQuery.globalEval( text );
8241
+ return text;
8242
+ }
8243
+ }
8244
+ });
8245
+
8246
+ // Handle cache's special case and global
8247
+ jQuery.ajaxPrefilter( "script", function( s ) {
8248
+ if ( s.cache === undefined ) {
8249
+ s.cache = false;
8250
+ }
8251
+ if ( s.crossDomain ) {
8252
+ s.type = "GET";
8253
+ s.global = false;
8254
+ }
8255
+ });
8256
+
8257
+ // Bind script tag hack transport
8258
+ jQuery.ajaxTransport( "script", function(s) {
8259
+
8260
+ // This transport only deals with cross domain requests
8261
+ if ( s.crossDomain ) {
8262
+
8263
+ var script,
8264
+ head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
8265
+
8266
+ return {
8267
+
8268
+ send: function( _, callback ) {
8269
+
8270
+ script = document.createElement( "script" );
8271
+
8272
+ script.async = "async";
8273
+
8274
+ if ( s.scriptCharset ) {
8275
+ script.charset = s.scriptCharset;
8276
+ }
8277
+
8278
+ script.src = s.url;
8279
+
8280
+ // Attach handlers for all browsers
8281
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
8282
+
8283
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
8284
+
8285
+ // Handle memory leak in IE
8286
+ script.onload = script.onreadystatechange = null;
8287
+
8288
+ // Remove the script
8289
+ if ( head && script.parentNode ) {
8290
+ head.removeChild( script );
8291
+ }
8292
+
8293
+ // Dereference the script
8294
+ script = undefined;
8295
+
8296
+ // Callback if not abort
8297
+ if ( !isAbort ) {
8298
+ callback( 200, "success" );
8299
+ }
8300
+ }
8301
+ };
8302
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
8303
+ // This arises when a base node is used (#2709 and #4378).
8304
+ head.insertBefore( script, head.firstChild );
8305
+ },
8306
+
8307
+ abort: function() {
8308
+ if ( script ) {
8309
+ script.onload( 0, 1 );
8310
+ }
8311
+ }
8312
+ };
8313
+ }
8314
+ });
8315
+ var xhrCallbacks,
8316
+ // #5280: Internet Explorer will keep connections alive if we don't abort on unload
8317
+ xhrOnUnloadAbort = window.ActiveXObject ? function() {
8318
+ // Abort all pending requests
8319
+ for ( var key in xhrCallbacks ) {
8320
+ xhrCallbacks[ key ]( 0, 1 );
8321
+ }
8322
+ } : false,
8323
+ xhrId = 0;
8324
+
8325
+ // Functions to create xhrs
8326
+ function createStandardXHR() {
8327
+ try {
8328
+ return new window.XMLHttpRequest();
8329
+ } catch( e ) {}
8330
+ }
8331
+
8332
+ function createActiveXHR() {
8333
+ try {
8334
+ return new window.ActiveXObject( "Microsoft.XMLHTTP" );
8335
+ } catch( e ) {}
8336
+ }
8337
+
8338
+ // Create the request object
8339
+ // (This is still attached to ajaxSettings for backward compatibility)
8340
+ jQuery.ajaxSettings.xhr = window.ActiveXObject ?
8341
+ /* Microsoft failed to properly
8342
+ * implement the XMLHttpRequest in IE7 (can't request local files),
8343
+ * so we use the ActiveXObject when it is available
8344
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
8345
+ * we need a fallback.
8346
+ */
8347
+ function() {
8348
+ return !this.isLocal && createStandardXHR() || createActiveXHR();
8349
+ } :
8350
+ // For all other browsers, use the standard XMLHttpRequest object
8351
+ createStandardXHR;
8352
+
8353
+ // Determine support properties
8354
+ (function( xhr ) {
8355
+ jQuery.extend( jQuery.support, {
8356
+ ajax: !!xhr,
8357
+ cors: !!xhr && ( "withCredentials" in xhr )
8358
+ });
8359
+ })( jQuery.ajaxSettings.xhr() );
8360
+
8361
+ // Create transport if the browser can provide an xhr
8362
+ if ( jQuery.support.ajax ) {
8363
+
8364
+ jQuery.ajaxTransport(function( s ) {
8365
+ // Cross domain only allowed if supported through XMLHttpRequest
8366
+ if ( !s.crossDomain || jQuery.support.cors ) {
8367
+
8368
+ var callback;
8369
+
8370
+ return {
8371
+ send: function( headers, complete ) {
8372
+
8373
+ // Get a new xhr
8374
+ var handle, i,
8375
+ xhr = s.xhr();
8376
+
8377
+ // Open the socket
8378
+ // Passing null username, generates a login popup on Opera (#2865)
8379
+ if ( s.username ) {
8380
+ xhr.open( s.type, s.url, s.async, s.username, s.password );
8381
+ } else {
8382
+ xhr.open( s.type, s.url, s.async );
8383
+ }
8384
+
8385
+ // Apply custom fields if provided
8386
+ if ( s.xhrFields ) {
8387
+ for ( i in s.xhrFields ) {
8388
+ xhr[ i ] = s.xhrFields[ i ];
8389
+ }
8390
+ }
8391
+
8392
+ // Override mime type if needed
8393
+ if ( s.mimeType && xhr.overrideMimeType ) {
8394
+ xhr.overrideMimeType( s.mimeType );
8395
+ }
8396
+
8397
+ // X-Requested-With header
8398
+ // For cross-domain requests, seeing as conditions for a preflight are
8399
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
8400
+ // (it can always be set on a per-request basis or even using ajaxSetup)
8401
+ // For same-domain requests, won't change header if already provided.
8402
+ if ( !s.crossDomain && !headers["X-Requested-With"] ) {
8403
+ headers[ "X-Requested-With" ] = "XMLHttpRequest";
8404
+ }
8405
+
8406
+ // Need an extra try/catch for cross domain requests in Firefox 3
8407
+ try {
8408
+ for ( i in headers ) {
8409
+ xhr.setRequestHeader( i, headers[ i ] );
8410
+ }
8411
+ } catch( _ ) {}
8412
+
8413
+ // Do send the request
8414
+ // This may raise an exception which is actually
8415
+ // handled in jQuery.ajax (so no try/catch here)
8416
+ xhr.send( ( s.hasContent && s.data ) || null );
8417
+
8418
+ // Listener
8419
+ callback = function( _, isAbort ) {
8420
+
8421
+ var status,
8422
+ statusText,
8423
+ responseHeaders,
8424
+ responses,
8425
+ xml;
8426
+
8427
+ // Firefox throws exceptions when accessing properties
8428
+ // of an xhr when a network error occurred
8429
+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
8430
+ try {
8431
+
8432
+ // Was never called and is aborted or complete
8433
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8434
+
8435
+ // Only called once
8436
+ callback = undefined;
8437
+
8438
+ // Do not keep as active anymore
8439
+ if ( handle ) {
8440
+ xhr.onreadystatechange = jQuery.noop;
8441
+ if ( xhrOnUnloadAbort ) {
8442
+ delete xhrCallbacks[ handle ];
8443
+ }
8444
+ }
8445
+
8446
+ // If it's an abort
8447
+ if ( isAbort ) {
8448
+ // Abort it manually if needed
8449
+ if ( xhr.readyState !== 4 ) {
8450
+ xhr.abort();
8451
+ }
8452
+ } else {
8453
+ status = xhr.status;
8454
+ responseHeaders = xhr.getAllResponseHeaders();
8455
+ responses = {};
8456
+ xml = xhr.responseXML;
8457
+
8458
+ // Construct response list
8459
+ if ( xml && xml.documentElement /* #4958 */ ) {
8460
+ responses.xml = xml;
8461
+ }
8462
+
8463
+ // When requesting binary data, IE6-9 will throw an exception
8464
+ // on any attempt to access responseText (#11426)
8465
+ try {
8466
+ responses.text = xhr.responseText;
8467
+ } catch( _ ) {
8468
+ }
8469
+
8470
+ // Firefox throws an exception when accessing
8471
+ // statusText for faulty cross-domain requests
8472
+ try {
8473
+ statusText = xhr.statusText;
8474
+ } catch( e ) {
8475
+ // We normalize with Webkit giving an empty statusText
8476
+ statusText = "";
8477
+ }
8478
+
8479
+ // Filter status for non standard behaviors
8480
+
8481
+ // If the request is local and we have data: assume a success
8482
+ // (success with no data won't get notified, that's the best we
8483
+ // can do given current implementations)
8484
+ if ( !status && s.isLocal && !s.crossDomain ) {
8485
+ status = responses.text ? 200 : 404;
8486
+ // IE - #1450: sometimes returns 1223 when it should be 204
8487
+ } else if ( status === 1223 ) {
8488
+ status = 204;
8489
+ }
8490
+ }
8491
+ }
8492
+ } catch( firefoxAccessException ) {
8493
+ if ( !isAbort ) {
8494
+ complete( -1, firefoxAccessException );
8495
+ }
8496
+ }
8497
+
8498
+ // Call complete if needed
8499
+ if ( responses ) {
8500
+ complete( status, statusText, responses, responseHeaders );
8501
+ }
8502
+ };
8503
+
8504
+ if ( !s.async ) {
8505
+ // if we're in sync mode we fire the callback
8506
+ callback();
8507
+ } else if ( xhr.readyState === 4 ) {
8508
+ // (IE6 & IE7) if it's in cache and has been
8509
+ // retrieved directly we need to fire the callback
8510
+ setTimeout( callback, 0 );
8511
+ } else {
8512
+ handle = ++xhrId;
8513
+ if ( xhrOnUnloadAbort ) {
8514
+ // Create the active xhrs callbacks list if needed
8515
+ // and attach the unload handler
8516
+ if ( !xhrCallbacks ) {
8517
+ xhrCallbacks = {};
8518
+ jQuery( window ).unload( xhrOnUnloadAbort );
8519
+ }
8520
+ // Add to list of active xhrs callbacks
8521
+ xhrCallbacks[ handle ] = callback;
8522
+ }
8523
+ xhr.onreadystatechange = callback;
8524
+ }
8525
+ },
8526
+
8527
+ abort: function() {
8528
+ if ( callback ) {
8529
+ callback(0,1);
8530
+ }
8531
+ }
8532
+ };
8533
+ }
8534
+ });
8535
+ }
8536
+ var fxNow, timerId,
8537
+ rfxtypes = /^(?:toggle|show|hide)$/,
8538
+ rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
8539
+ rrun = /queueHooks$/,
8540
+ animationPrefilters = [ defaultPrefilter ],
8541
+ tweeners = {
8542
+ "*": [function( prop, value ) {
8543
+ var end, unit,
8544
+ tween = this.createTween( prop, value ),
8545
+ parts = rfxnum.exec( value ),
8546
+ target = tween.cur(),
8547
+ start = +target || 0,
8548
+ scale = 1,
8549
+ maxIterations = 20;
8550
+
8551
+ if ( parts ) {
8552
+ end = +parts[2];
8553
+ unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" );
8554
+
8555
+ // We need to compute starting value
8556
+ if ( unit !== "px" && start ) {
8557
+ // Iteratively approximate from a nonzero starting point
8558
+ // Prefer the current property, because this process will be trivial if it uses the same units
8559
+ // Fallback to end or a simple constant
8560
+ start = jQuery.css( tween.elem, prop, true ) || end || 1;
8561
+
8562
+ do {
8563
+ // If previous iteration zeroed out, double until we get *something*
8564
+ // Use a string for doubling factor so we don't accidentally see scale as unchanged below
8565
+ scale = scale || ".5";
8566
+
8567
+ // Adjust and apply
8568
+ start = start / scale;
8569
+ jQuery.style( tween.elem, prop, start + unit );
8570
+
8571
+ // Update scale, tolerating zero or NaN from tween.cur()
8572
+ // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
8573
+ } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
8574
+ }
8575
+
8576
+ tween.unit = unit;
8577
+ tween.start = start;
8578
+ // If a +=/-= token was provided, we're doing a relative animation
8579
+ tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;
8580
+ }
8581
+ return tween;
8582
+ }]
8583
+ };
8584
+
8585
+ // Animations created synchronously will run synchronously
8586
+ function createFxNow() {
8587
+ setTimeout(function() {
8588
+ fxNow = undefined;
8589
+ }, 0 );
8590
+ return ( fxNow = jQuery.now() );
8591
+ }
8592
+
8593
+ function createTweens( animation, props ) {
8594
+ jQuery.each( props, function( prop, value ) {
8595
+ var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
8596
+ index = 0,
8597
+ length = collection.length;
8598
+ for ( ; index < length; index++ ) {
8599
+ if ( collection[ index ].call( animation, prop, value ) ) {
8600
+
8601
+ // we're done with this property
8602
+ return;
8603
+ }
8604
+ }
8605
+ });
8606
+ }
8607
+
8608
+ function Animation( elem, properties, options ) {
8609
+ var result,
8610
+ index = 0,
8611
+ tweenerIndex = 0,
8612
+ length = animationPrefilters.length,
8613
+ deferred = jQuery.Deferred().always( function() {
8614
+ // don't match elem in the :animated selector
8615
+ delete tick.elem;
8616
+ }),
8617
+ tick = function() {
8618
+ var currentTime = fxNow || createFxNow(),
8619
+ remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
8620
+ percent = 1 - ( remaining / animation.duration || 0 ),
8621
+ index = 0,
8622
+ length = animation.tweens.length;
8623
+
8624
+ for ( ; index < length ; index++ ) {
8625
+ animation.tweens[ index ].run( percent );
8626
+ }
8627
+
8628
+ deferred.notifyWith( elem, [ animation, percent, remaining ]);
8629
+
8630
+ if ( percent < 1 && length ) {
8631
+ return remaining;
8632
+ } else {
8633
+ deferred.resolveWith( elem, [ animation ] );
8634
+ return false;
8635
+ }
8636
+ },
8637
+ animation = deferred.promise({
8638
+ elem: elem,
8639
+ props: jQuery.extend( {}, properties ),
8640
+ opts: jQuery.extend( true, { specialEasing: {} }, options ),
8641
+ originalProperties: properties,
8642
+ originalOptions: options,
8643
+ startTime: fxNow || createFxNow(),
8644
+ duration: options.duration,
8645
+ tweens: [],
8646
+ createTween: function( prop, end, easing ) {
8647
+ var tween = jQuery.Tween( elem, animation.opts, prop, end,
8648
+ animation.opts.specialEasing[ prop ] || animation.opts.easing );
8649
+ animation.tweens.push( tween );
8650
+ return tween;
8651
+ },
8652
+ stop: function( gotoEnd ) {
8653
+ var index = 0,
8654
+ // if we are going to the end, we want to run all the tweens
8655
+ // otherwise we skip this part
8656
+ length = gotoEnd ? animation.tweens.length : 0;
8657
+
8658
+ for ( ; index < length ; index++ ) {
8659
+ animation.tweens[ index ].run( 1 );
8660
+ }
8661
+
8662
+ // resolve when we played the last frame
8663
+ // otherwise, reject
8664
+ if ( gotoEnd ) {
8665
+ deferred.resolveWith( elem, [ animation, gotoEnd ] );
8666
+ } else {
8667
+ deferred.rejectWith( elem, [ animation, gotoEnd ] );
8668
+ }
8669
+ return this;
8670
+ }
8671
+ }),
8672
+ props = animation.props;
8673
+
8674
+ propFilter( props, animation.opts.specialEasing );
8675
+
8676
+ for ( ; index < length ; index++ ) {
8677
+ result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
8678
+ if ( result ) {
8679
+ return result;
8680
+ }
8681
+ }
8682
+
8683
+ createTweens( animation, props );
8684
+
8685
+ if ( jQuery.isFunction( animation.opts.start ) ) {
8686
+ animation.opts.start.call( elem, animation );
8687
+ }
8688
+
8689
+ jQuery.fx.timer(
8690
+ jQuery.extend( tick, {
8691
+ anim: animation,
8692
+ queue: animation.opts.queue,
8693
+ elem: elem
8694
+ })
8695
+ );
8696
+
8697
+ // attach callbacks from options
8698
+ return animation.progress( animation.opts.progress )
8699
+ .done( animation.opts.done, animation.opts.complete )
8700
+ .fail( animation.opts.fail )
8701
+ .always( animation.opts.always );
8702
+ }
8703
+
8704
+ function propFilter( props, specialEasing ) {
8705
+ var index, name, easing, value, hooks;
8706
+
8707
+ // camelCase, specialEasing and expand cssHook pass
8708
+ for ( index in props ) {
8709
+ name = jQuery.camelCase( index );
8710
+ easing = specialEasing[ name ];
8711
+ value = props[ index ];
8712
+ if ( jQuery.isArray( value ) ) {
8713
+ easing = value[ 1 ];
8714
+ value = props[ index ] = value[ 0 ];
8715
+ }
8716
+
8717
+ if ( index !== name ) {
8718
+ props[ name ] = value;
8719
+ delete props[ index ];
8720
+ }
8721
+
8722
+ hooks = jQuery.cssHooks[ name ];
8723
+ if ( hooks && "expand" in hooks ) {
8724
+ value = hooks.expand( value );
8725
+ delete props[ name ];
8726
+
8727
+ // not quite $.extend, this wont overwrite keys already present.
8728
+ // also - reusing 'index' from above because we have the correct "name"
8729
+ for ( index in value ) {
8730
+ if ( !( index in props ) ) {
8731
+ props[ index ] = value[ index ];
8732
+ specialEasing[ index ] = easing;
8733
+ }
8734
+ }
8735
+ } else {
8736
+ specialEasing[ name ] = easing;
8737
+ }
8738
+ }
8739
+ }
8740
+
8741
+ jQuery.Animation = jQuery.extend( Animation, {
8742
+
8743
+ tweener: function( props, callback ) {
8744
+ if ( jQuery.isFunction( props ) ) {
8745
+ callback = props;
8746
+ props = [ "*" ];
8747
+ } else {
8748
+ props = props.split(" ");
8749
+ }
8750
+
8751
+ var prop,
8752
+ index = 0,
8753
+ length = props.length;
8754
+
8755
+ for ( ; index < length ; index++ ) {
8756
+ prop = props[ index ];
8757
+ tweeners[ prop ] = tweeners[ prop ] || [];
8758
+ tweeners[ prop ].unshift( callback );
8759
+ }
8760
+ },
8761
+
8762
+ prefilter: function( callback, prepend ) {
8763
+ if ( prepend ) {
8764
+ animationPrefilters.unshift( callback );
8765
+ } else {
8766
+ animationPrefilters.push( callback );
8767
+ }
8768
+ }
8769
+ });
8770
+
8771
+ function defaultPrefilter( elem, props, opts ) {
8772
+ var index, prop, value, length, dataShow, tween, hooks, oldfire,
8773
+ anim = this,
8774
+ style = elem.style,
8775
+ orig = {},
8776
+ handled = [],
8777
+ hidden = elem.nodeType && isHidden( elem );
8778
+
8779
+ // handle queue: false promises
8780
+ if ( !opts.queue ) {
8781
+ hooks = jQuery._queueHooks( elem, "fx" );
8782
+ if ( hooks.unqueued == null ) {
8783
+ hooks.unqueued = 0;
8784
+ oldfire = hooks.empty.fire;
8785
+ hooks.empty.fire = function() {
8786
+ if ( !hooks.unqueued ) {
8787
+ oldfire();
8788
+ }
8789
+ };
8790
+ }
8791
+ hooks.unqueued++;
8792
+
8793
+ anim.always(function() {
8794
+ // doing this makes sure that the complete handler will be called
8795
+ // before this completes
8796
+ anim.always(function() {
8797
+ hooks.unqueued--;
8798
+ if ( !jQuery.queue( elem, "fx" ).length ) {
8799
+ hooks.empty.fire();
8800
+ }
8801
+ });
8802
+ });
8803
+ }
8804
+
8805
+ // height/width overflow pass
8806
+ if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
8807
+ // Make sure that nothing sneaks out
8808
+ // Record all 3 overflow attributes because IE does not
8809
+ // change the overflow attribute when overflowX and
8810
+ // overflowY are set to the same value
8811
+ opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
8812
+
8813
+ // Set display property to inline-block for height/width
8814
+ // animations on inline elements that are having width/height animated
8815
+ if ( jQuery.css( elem, "display" ) === "inline" &&
8816
+ jQuery.css( elem, "float" ) === "none" ) {
8817
+
8818
+ // inline-level elements accept inline-block;
8819
+ // block-level elements need to be inline with layout
8820
+ if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
8821
+ style.display = "inline-block";
8822
+
8823
+ } else {
8824
+ style.zoom = 1;
8825
+ }
8826
+ }
8827
+ }
8828
+
8829
+ if ( opts.overflow ) {
8830
+ style.overflow = "hidden";
8831
+ if ( !jQuery.support.shrinkWrapBlocks ) {
8832
+ anim.done(function() {
8833
+ style.overflow = opts.overflow[ 0 ];
8834
+ style.overflowX = opts.overflow[ 1 ];
8835
+ style.overflowY = opts.overflow[ 2 ];
8836
+ });
8837
+ }
8838
+ }
8839
+
8840
+
8841
+ // show/hide pass
8842
+ for ( index in props ) {
8843
+ value = props[ index ];
8844
+ if ( rfxtypes.exec( value ) ) {
8845
+ delete props[ index ];
8846
+ if ( value === ( hidden ? "hide" : "show" ) ) {
8847
+ continue;
8848
+ }
8849
+ handled.push( index );
8850
+ }
8851
+ }
8852
+
8853
+ length = handled.length;
8854
+ if ( length ) {
8855
+ dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} );
8856
+ if ( hidden ) {
8857
+ jQuery( elem ).show();
8858
+ } else {
8859
+ anim.done(function() {
8860
+ jQuery( elem ).hide();
8861
+ });
8862
+ }
8863
+ anim.done(function() {
8864
+ var prop;
8865
+ jQuery.removeData( elem, "fxshow", true );
8866
+ for ( prop in orig ) {
8867
+ jQuery.style( elem, prop, orig[ prop ] );
8868
+ }
8869
+ });
8870
+ for ( index = 0 ; index < length ; index++ ) {
8871
+ prop = handled[ index ];
8872
+ tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );
8873
+ orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );
8874
+
8875
+ if ( !( prop in dataShow ) ) {
8876
+ dataShow[ prop ] = tween.start;
8877
+ if ( hidden ) {
8878
+ tween.end = tween.start;
8879
+ tween.start = prop === "width" || prop === "height" ? 1 : 0;
8880
+ }
8881
+ }
8882
+ }
8883
+ }
8884
+ }
8885
+
8886
+ function Tween( elem, options, prop, end, easing ) {
8887
+ return new Tween.prototype.init( elem, options, prop, end, easing );
8888
+ }
8889
+ jQuery.Tween = Tween;
8890
+
8891
+ Tween.prototype = {
8892
+ constructor: Tween,
8893
+ init: function( elem, options, prop, end, easing, unit ) {
8894
+ this.elem = elem;
8895
+ this.prop = prop;
8896
+ this.easing = easing || "swing";
8897
+ this.options = options;
8898
+ this.start = this.now = this.cur();
8899
+ this.end = end;
8900
+ this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
8901
+ },
8902
+ cur: function() {
8903
+ var hooks = Tween.propHooks[ this.prop ];
8904
+
8905
+ return hooks && hooks.get ?
8906
+ hooks.get( this ) :
8907
+ Tween.propHooks._default.get( this );
8908
+ },
8909
+ run: function( percent ) {
8910
+ var eased,
8911
+ hooks = Tween.propHooks[ this.prop ];
8912
+
8913
+ if ( this.options.duration ) {
8914
+ this.pos = eased = jQuery.easing[ this.easing ](
8915
+ percent, this.options.duration * percent, 0, 1, this.options.duration
8916
+ );
8917
+ } else {
8918
+ this.pos = eased = percent;
8919
+ }
8920
+ this.now = ( this.end - this.start ) * eased + this.start;
8921
+
8922
+ if ( this.options.step ) {
8923
+ this.options.step.call( this.elem, this.now, this );
8924
+ }
8925
+
8926
+ if ( hooks && hooks.set ) {
8927
+ hooks.set( this );
8928
+ } else {
8929
+ Tween.propHooks._default.set( this );
8930
+ }
8931
+ return this;
8932
+ }
8933
+ };
8934
+
8935
+ Tween.prototype.init.prototype = Tween.prototype;
8936
+
8937
+ Tween.propHooks = {
8938
+ _default: {
8939
+ get: function( tween ) {
8940
+ var result;
8941
+
8942
+ if ( tween.elem[ tween.prop ] != null &&
8943
+ (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
8944
+ return tween.elem[ tween.prop ];
8945
+ }
8946
+
8947
+ // passing any value as a 4th parameter to .css will automatically
8948
+ // attempt a parseFloat and fallback to a string if the parse fails
8949
+ // so, simple values such as "10px" are parsed to Float.
8950
+ // complex values such as "rotate(1rad)" are returned as is.
8951
+ result = jQuery.css( tween.elem, tween.prop, false, "" );
8952
+ // Empty strings, null, undefined and "auto" are converted to 0.
8953
+ return !result || result === "auto" ? 0 : result;
8954
+ },
8955
+ set: function( tween ) {
8956
+ // use step hook for back compat - use cssHook if its there - use .style if its
8957
+ // available and use plain properties where available
8958
+ if ( jQuery.fx.step[ tween.prop ] ) {
8959
+ jQuery.fx.step[ tween.prop ]( tween );
8960
+ } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
8961
+ jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
8962
+ } else {
8963
+ tween.elem[ tween.prop ] = tween.now;
8964
+ }
8965
+ }
8966
+ }
8967
+ };
8968
+
8969
+ // Remove in 2.0 - this supports IE8's panic based approach
8970
+ // to setting things on disconnected nodes
8971
+
8972
+ Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
8973
+ set: function( tween ) {
8974
+ if ( tween.elem.nodeType && tween.elem.parentNode ) {
8975
+ tween.elem[ tween.prop ] = tween.now;
8976
+ }
8977
+ }
8978
+ };
8979
+
8980
+ jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
8981
+ var cssFn = jQuery.fn[ name ];
8982
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
8983
+ return speed == null || typeof speed === "boolean" ||
8984
+ // special check for .toggle( handler, handler, ... )
8985
+ ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ?
8986
+ cssFn.apply( this, arguments ) :
8987
+ this.animate( genFx( name, true ), speed, easing, callback );
8988
+ };
8989
+ });
8990
+
8991
+ jQuery.fn.extend({
8992
+ fadeTo: function( speed, to, easing, callback ) {
8993
+
8994
+ // show any hidden elements after setting opacity to 0
8995
+ return this.filter( isHidden ).css( "opacity", 0 ).show()
8996
+
8997
+ // animate to the value specified
8998
+ .end().animate({ opacity: to }, speed, easing, callback );
8999
+ },
9000
+ animate: function( prop, speed, easing, callback ) {
9001
+ var empty = jQuery.isEmptyObject( prop ),
9002
+ optall = jQuery.speed( speed, easing, callback ),
9003
+ doAnimation = function() {
9004
+ // Operate on a copy of prop so per-property easing won't be lost
9005
+ var anim = Animation( this, jQuery.extend( {}, prop ), optall );
9006
+
9007
+ // Empty animations resolve immediately
9008
+ if ( empty ) {
9009
+ anim.stop( true );
9010
+ }
9011
+ };
9012
+
9013
+ return empty || optall.queue === false ?
9014
+ this.each( doAnimation ) :
9015
+ this.queue( optall.queue, doAnimation );
9016
+ },
9017
+ stop: function( type, clearQueue, gotoEnd ) {
9018
+ var stopQueue = function( hooks ) {
9019
+ var stop = hooks.stop;
9020
+ delete hooks.stop;
9021
+ stop( gotoEnd );
9022
+ };
9023
+
9024
+ if ( typeof type !== "string" ) {
9025
+ gotoEnd = clearQueue;
9026
+ clearQueue = type;
9027
+ type = undefined;
9028
+ }
9029
+ if ( clearQueue && type !== false ) {
9030
+ this.queue( type || "fx", [] );
9031
+ }
9032
+
9033
+ return this.each(function() {
9034
+ var dequeue = true,
9035
+ index = type != null && type + "queueHooks",
9036
+ timers = jQuery.timers,
9037
+ data = jQuery._data( this );
9038
+
9039
+ if ( index ) {
9040
+ if ( data[ index ] && data[ index ].stop ) {
9041
+ stopQueue( data[ index ] );
9042
+ }
9043
+ } else {
9044
+ for ( index in data ) {
9045
+ if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
9046
+ stopQueue( data[ index ] );
9047
+ }
9048
+ }
9049
+ }
9050
+
9051
+ for ( index = timers.length; index--; ) {
9052
+ if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
9053
+ timers[ index ].anim.stop( gotoEnd );
9054
+ dequeue = false;
9055
+ timers.splice( index, 1 );
9056
+ }
9057
+ }
9058
+
9059
+ // start the next in the queue if the last step wasn't forced
9060
+ // timers currently will call their complete callbacks, which will dequeue
9061
+ // but only if they were gotoEnd
9062
+ if ( dequeue || !gotoEnd ) {
9063
+ jQuery.dequeue( this, type );
9064
+ }
9065
+ });
9066
+ }
9067
+ });
9068
+
9069
+ // Generate parameters to create a standard animation
9070
+ function genFx( type, includeWidth ) {
9071
+ var which,
9072
+ attrs = { height: type },
9073
+ i = 0;
9074
+
9075
+ // if we include width, step value is 1 to do all cssExpand values,
9076
+ // if we don't include width, step value is 2 to skip over Left and Right
9077
+ includeWidth = includeWidth? 1 : 0;
9078
+ for( ; i < 4 ; i += 2 - includeWidth ) {
9079
+ which = cssExpand[ i ];
9080
+ attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
9081
+ }
9082
+
9083
+ if ( includeWidth ) {
9084
+ attrs.opacity = attrs.width = type;
9085
+ }
9086
+
9087
+ return attrs;
9088
+ }
9089
+
9090
+ // Generate shortcuts for custom animations
9091
+ jQuery.each({
9092
+ slideDown: genFx("show"),
9093
+ slideUp: genFx("hide"),
9094
+ slideToggle: genFx("toggle"),
9095
+ fadeIn: { opacity: "show" },
9096
+ fadeOut: { opacity: "hide" },
9097
+ fadeToggle: { opacity: "toggle" }
9098
+ }, function( name, props ) {
9099
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
9100
+ return this.animate( props, speed, easing, callback );
9101
+ };
9102
+ });
9103
+
9104
+ jQuery.speed = function( speed, easing, fn ) {
9105
+ var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
9106
+ complete: fn || !fn && easing ||
9107
+ jQuery.isFunction( speed ) && speed,
9108
+ duration: speed,
9109
+ easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
9110
+ };
9111
+
9112
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
9113
+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
9114
+
9115
+ // normalize opt.queue - true/undefined/null -> "fx"
9116
+ if ( opt.queue == null || opt.queue === true ) {
9117
+ opt.queue = "fx";
9118
+ }
9119
+
9120
+ // Queueing
9121
+ opt.old = opt.complete;
9122
+
9123
+ opt.complete = function() {
9124
+ if ( jQuery.isFunction( opt.old ) ) {
9125
+ opt.old.call( this );
9126
+ }
9127
+
9128
+ if ( opt.queue ) {
9129
+ jQuery.dequeue( this, opt.queue );
9130
+ }
9131
+ };
9132
+
9133
+ return opt;
9134
+ };
9135
+
9136
+ jQuery.easing = {
9137
+ linear: function( p ) {
9138
+ return p;
9139
+ },
9140
+ swing: function( p ) {
9141
+ return 0.5 - Math.cos( p*Math.PI ) / 2;
9142
+ }
9143
+ };
9144
+
9145
+ jQuery.timers = [];
9146
+ jQuery.fx = Tween.prototype.init;
9147
+ jQuery.fx.tick = function() {
9148
+ var timer,
9149
+ timers = jQuery.timers,
9150
+ i = 0;
9151
+
9152
+ for ( ; i < timers.length; i++ ) {
9153
+ timer = timers[ i ];
9154
+ // Checks the timer has not already been removed
9155
+ if ( !timer() && timers[ i ] === timer ) {
9156
+ timers.splice( i--, 1 );
9157
+ }
9158
+ }
9159
+
9160
+ if ( !timers.length ) {
9161
+ jQuery.fx.stop();
9162
+ }
9163
+ };
9164
+
9165
+ jQuery.fx.timer = function( timer ) {
9166
+ if ( timer() && jQuery.timers.push( timer ) && !timerId ) {
9167
+ timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
9168
+ }
9169
+ };
9170
+
9171
+ jQuery.fx.interval = 13;
9172
+
9173
+ jQuery.fx.stop = function() {
9174
+ clearInterval( timerId );
9175
+ timerId = null;
9176
+ };
9177
+
9178
+ jQuery.fx.speeds = {
9179
+ slow: 600,
9180
+ fast: 200,
9181
+ // Default speed
9182
+ _default: 400
9183
+ };
9184
+
9185
+ // Back Compat <1.8 extension point
9186
+ jQuery.fx.step = {};
9187
+
9188
+ if ( jQuery.expr && jQuery.expr.filters ) {
9189
+ jQuery.expr.filters.animated = function( elem ) {
9190
+ return jQuery.grep(jQuery.timers, function( fn ) {
9191
+ return elem === fn.elem;
9192
+ }).length;
9193
+ };
9194
+ }
9195
+ var rroot = /^(?:body|html)$/i;
9196
+
9197
+ jQuery.fn.offset = function( options ) {
9198
+ if ( arguments.length ) {
9199
+ return options === undefined ?
9200
+ this :
9201
+ this.each(function( i ) {
9202
+ jQuery.offset.setOffset( this, options, i );
9203
+ });
9204
+ }
9205
+
9206
+ var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,
9207
+ box = { top: 0, left: 0 },
9208
+ elem = this[ 0 ],
9209
+ doc = elem && elem.ownerDocument;
9210
+
9211
+ if ( !doc ) {
9212
+ return;
9213
+ }
9214
+
9215
+ if ( (body = doc.body) === elem ) {
9216
+ return jQuery.offset.bodyOffset( elem );
9217
+ }
9218
+
9219
+ docElem = doc.documentElement;
9220
+
9221
+ // Make sure it's not a disconnected DOM node
9222
+ if ( !jQuery.contains( docElem, elem ) ) {
9223
+ return box;
9224
+ }
9225
+
9226
+ // If we don't have gBCR, just use 0,0 rather than error
9227
+ // BlackBerry 5, iOS 3 (original iPhone)
9228
+ if ( typeof elem.getBoundingClientRect !== "undefined" ) {
9229
+ box = elem.getBoundingClientRect();
9230
+ }
9231
+ win = getWindow( doc );
9232
+ clientTop = docElem.clientTop || body.clientTop || 0;
9233
+ clientLeft = docElem.clientLeft || body.clientLeft || 0;
9234
+ scrollTop = win.pageYOffset || docElem.scrollTop;
9235
+ scrollLeft = win.pageXOffset || docElem.scrollLeft;
9236
+ return {
9237
+ top: box.top + scrollTop - clientTop,
9238
+ left: box.left + scrollLeft - clientLeft
9239
+ };
9240
+ };
9241
+
9242
+ jQuery.offset = {
9243
+
9244
+ bodyOffset: function( body ) {
9245
+ var top = body.offsetTop,
9246
+ left = body.offsetLeft;
9247
+
9248
+ if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
9249
+ top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
9250
+ left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
9251
+ }
9252
+
9253
+ return { top: top, left: left };
9254
+ },
9255
+
9256
+ setOffset: function( elem, options, i ) {
9257
+ var position = jQuery.css( elem, "position" );
9258
+
9259
+ // set position first, in-case top/left are set even on static elem
9260
+ if ( position === "static" ) {
9261
+ elem.style.position = "relative";
9262
+ }
9263
+
9264
+ var curElem = jQuery( elem ),
9265
+ curOffset = curElem.offset(),
9266
+ curCSSTop = jQuery.css( elem, "top" ),
9267
+ curCSSLeft = jQuery.css( elem, "left" ),
9268
+ calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
9269
+ props = {}, curPosition = {}, curTop, curLeft;
9270
+
9271
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
9272
+ if ( calculatePosition ) {
9273
+ curPosition = curElem.position();
9274
+ curTop = curPosition.top;
9275
+ curLeft = curPosition.left;
9276
+ } else {
9277
+ curTop = parseFloat( curCSSTop ) || 0;
9278
+ curLeft = parseFloat( curCSSLeft ) || 0;
9279
+ }
9280
+
9281
+ if ( jQuery.isFunction( options ) ) {
9282
+ options = options.call( elem, i, curOffset );
9283
+ }
9284
+
9285
+ if ( options.top != null ) {
9286
+ props.top = ( options.top - curOffset.top ) + curTop;
9287
+ }
9288
+ if ( options.left != null ) {
9289
+ props.left = ( options.left - curOffset.left ) + curLeft;
9290
+ }
9291
+
9292
+ if ( "using" in options ) {
9293
+ options.using.call( elem, props );
9294
+ } else {
9295
+ curElem.css( props );
9296
+ }
9297
+ }
9298
+ };
9299
+
9300
+
9301
+ jQuery.fn.extend({
9302
+
9303
+ position: function() {
9304
+ if ( !this[0] ) {
9305
+ return;
9306
+ }
9307
+
9308
+ var elem = this[0],
9309
+
9310
+ // Get *real* offsetParent
9311
+ offsetParent = this.offsetParent(),
9312
+
9313
+ // Get correct offsets
9314
+ offset = this.offset(),
9315
+ parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
9316
+
9317
+ // Subtract element margins
9318
+ // note: when an element has margin: auto the offsetLeft and marginLeft
9319
+ // are the same in Safari causing offset.left to incorrectly be 0
9320
+ offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
9321
+ offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
9322
+
9323
+ // Add offsetParent borders
9324
+ parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
9325
+ parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
9326
+
9327
+ // Subtract the two offsets
9328
+ return {
9329
+ top: offset.top - parentOffset.top,
9330
+ left: offset.left - parentOffset.left
9331
+ };
9332
+ },
9333
+
9334
+ offsetParent: function() {
9335
+ return this.map(function() {
9336
+ var offsetParent = this.offsetParent || document.body;
9337
+ while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
9338
+ offsetParent = offsetParent.offsetParent;
9339
+ }
9340
+ return offsetParent || document.body;
9341
+ });
9342
+ }
9343
+ });
9344
+
9345
+
9346
+ // Create scrollLeft and scrollTop methods
9347
+ jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
9348
+ var top = /Y/.test( prop );
9349
+
9350
+ jQuery.fn[ method ] = function( val ) {
9351
+ return jQuery.access( this, function( elem, method, val ) {
9352
+ var win = getWindow( elem );
9353
+
9354
+ if ( val === undefined ) {
9355
+ return win ? (prop in win) ? win[ prop ] :
9356
+ win.document.documentElement[ method ] :
9357
+ elem[ method ];
9358
+ }
9359
+
9360
+ if ( win ) {
9361
+ win.scrollTo(
9362
+ !top ? val : jQuery( win ).scrollLeft(),
9363
+ top ? val : jQuery( win ).scrollTop()
9364
+ );
9365
+
9366
+ } else {
9367
+ elem[ method ] = val;
9368
+ }
9369
+ }, method, val, arguments.length, null );
9370
+ };
9371
+ });
9372
+
9373
+ function getWindow( elem ) {
9374
+ return jQuery.isWindow( elem ) ?
9375
+ elem :
9376
+ elem.nodeType === 9 ?
9377
+ elem.defaultView || elem.parentWindow :
9378
+ false;
9379
+ }
9380
+ // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9381
+ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9382
+ jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
9383
+ // margin is only for outerHeight, outerWidth
9384
+ jQuery.fn[ funcName ] = function( margin, value ) {
9385
+ var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9386
+ extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9387
+
9388
+ return jQuery.access( this, function( elem, type, value ) {
9389
+ var doc;
9390
+
9391
+ if ( jQuery.isWindow( elem ) ) {
9392
+ // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9393
+ // isn't a whole lot we can do. See pull request at this URL for discussion:
9394
+ // https://github.com/jquery/jquery/pull/764
9395
+ return elem.document.documentElement[ "client" + name ];
9396
+ }
9397
+
9398
+ // Get document width or height
9399
+ if ( elem.nodeType === 9 ) {
9400
+ doc = elem.documentElement;
9401
+
9402
+ // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
9403
+ // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
9404
+ return Math.max(
9405
+ elem.body[ "scroll" + name ], doc[ "scroll" + name ],
9406
+ elem.body[ "offset" + name ], doc[ "offset" + name ],
9407
+ doc[ "client" + name ]
9408
+ );
9409
+ }
9410
+
9411
+ return value === undefined ?
9412
+ // Get width or height on the element, requesting but not forcing parseFloat
9413
+ jQuery.css( elem, type, value, extra ) :
9414
+
9415
+ // Set width or height on the element
9416
+ jQuery.style( elem, type, value, extra );
9417
+ }, type, chainable ? margin : undefined, chainable, null );
9418
+ };
9419
+ });
9420
+ });
9421
+ // Expose jQuery to the global object
9422
+ window.jQuery = window.$ = jQuery;
9423
+
9424
+ // Expose jQuery as an AMD module, but only for AMD loaders that
9425
+ // understand the issues with loading multiple versions of jQuery
9426
+ // in a page that all might call define(). The loader will indicate
9427
+ // they have special allowances for multiple jQuery versions by
9428
+ // specifying define.amd.jQuery = true. Register as a named module,
9429
+ // since jQuery can be concatenated with other files that may use define,
9430
+ // but not use a proper concatenation script that understands anonymous
9431
+ // AMD modules. A named AMD is safest and most robust way to register.
9432
+ // Lowercase jquery is used because AMD module names are derived from
9433
+ // file names, and jQuery is normally delivered in a lowercase file name.
9434
+ // Do this after creating the global so that if an AMD module wants to call
9435
+ // noConflict to hide this version of jQuery, it will work.
9436
+ if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
9437
+ define( "jquery", [], function () { return jQuery; } );
9438
+ }
9439
+
9440
+ })( window );
9441
+ jQuery.noConflict();
js/tryon/jquery-ui.min.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ /*! jQuery UI - v1.8.23 - 2012-08-15
2
+ * https://github.com/jquery/jquery-ui
3
+ * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.effects.core.js, jquery.effects.blind.js, jquery.effects.bounce.js, jquery.effects.clip.js, jquery.effects.drop.js, jquery.effects.explode.js, jquery.effects.fade.js, jquery.effects.fold.js, jquery.effects.highlight.js, jquery.effects.pulsate.js, jquery.effects.scale.js, jquery.effects.shake.js, jquery.effects.slide.js, jquery.effects.transfer.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.tabs.js
4
+ * Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
5
+ (function(a,b){function c(b,c){var e=b.nodeName.toLowerCase();if("area"===e){var f=b.parentNode,g=f.name,h;return!b.href||!g||f.nodeName.toLowerCase()!=="map"?!1:(h=a("img[usemap=#"+g+"]")[0],!!h&&d(h))}return(/input|select|textarea|button|object/.test(e)?!b.disabled:"a"==e?b.href||c:c)&&d(b)}function d(b){return!a(b).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.ui=a.ui||{};if(a.ui.version)return;a.extend(a.ui,{version:"1.8.23",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(b,c){return typeof b=="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus(),c&&c.call(d)},b)}):this._focus.apply(this,arguments)},scrollParent:function(){var b;return a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?b=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):b=this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0),/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length){var d=a(this[0]),e,f;while(d.length&&d[0]!==document){e=d.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){f=parseInt(d.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}d=d.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a("<a>").outerWidth(1).jquery||a.each(["Width","Height"],function(c,d){function h(b,c,d,f){return a.each(e,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0,d&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0),f&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)}),c}var e=d==="Width"?["Left","Right"]:["Top","Bottom"],f=d.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){return c===b?g["inner"+d].call(this):this.each(function(){a(this).css(f,h(this,c)+"px")})},a.fn["outer"+d]=function(b,c){return typeof b!="number"?g["outer"+d].call(this,b):this.each(function(){a(this).css(f,h(this,b,!0,c)+"px")})}}),a.extend(a.expr[":"],{data:a.expr.createPseudo?a.expr.createPseudo(function(b){return function(c){return!!a.data(c,b)}}):function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));c.offsetHeight,a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.curCSS||(a.curCSS=a.css),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!d||!a.element[0].parentNode)return;for(var e=0;e<d.length;e++)a.options[d[e][0]]&&d[e][1].apply(a.element,c)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(b,c){if(a(b).css("overflow")==="hidden")return!1;var d=c&&c==="left"?"scrollLeft":"scrollTop",e=!1;return b[d]>0?!0:(b[d]=1,e=b[d]>0,b[d]=0,e)},isOverAxis:function(a,b,c){return a>b&&a<b+c},isOver:function(b,c,d,e,f,g){return a.ui.isOverAxis(b,d,f)&&a.ui.isOverAxis(c,e,g)}})})(jQuery),function(a,b){if(a.cleanData){var c=a.cleanData;a.cleanData=function(b){for(var d=0,e;(e=b[d])!=null;d++)try{a(e).triggerHandler("remove")}catch(f){}c(b)}}else{var d=a.fn.remove;a.fn.remove=function(b,c){return this.each(function(){return c||(!b||a.filter(b,[this]).length)&&a("*",this).add([this]).each(function(){try{a(this).triggerHandler("remove")}catch(b){}}),d.call(a(this),b,c)})}}a.widget=function(b,c,d){var e=b.split(".")[0],f;b=b.split(".")[1],f=e+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][f]=function(c){return!!a.data(c,b)},a[e]=a[e]||{},a[e][b]=function(a,b){arguments.length&&this._createWidget(a,b)};var g=new c;g.options=a.extend(!0,{},g.options),a[e][b].prototype=a.extend(!0,g,{namespace:e,widgetName:b,widgetEventPrefix:a[e][b].prototype.widgetEventPrefix||b,widgetBaseClass:f},d),a.widget.bridge(b,a[e][b])},a.widget.bridge=function(c,d){a.fn[c]=function(e){var f=typeof e=="string",g=Array.prototype.slice.call(arguments,1),h=this;return e=!f&&g.length?a.extend.apply(null,[!0,e].concat(g)):e,f&&e.charAt(0)==="_"?h:(f?this.each(function(){var d=a.data(this,c),f=d&&a.isFunction(d[e])?d[e].apply(d,g):d;if(f!==d&&f!==b)return h=f,!1}):this.each(function(){var b=a.data(this,c);b?b.option(e||{})._init():a.data(this,c,new d(e,this))}),h)}},a.Widget=function(a,b){arguments.length&&this._createWidget(a,b)},a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:!1},_createWidget:function(b,c){a.data(c,this.widgetName,this),this.element=a(c),this.options=a.extend(!0,{},this.options,this._getCreateOptions(),b);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()}),this._create(),this._trigger("create"),this._init()},_getCreateOptions:function(){return a.metadata&&a.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName),this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled "+"ui-state-disabled")},widget:function(){return this.element},option:function(c,d){var e=c;if(arguments.length===0)return a.extend({},this.options);if(typeof c=="string"){if(d===b)return this.options[c];e={},e[c]=d}return this._setOptions(e),this},_setOptions:function(b){var c=this;return a.each(b,function(a,b){c._setOption(a,b)}),this},_setOption:function(a,b){return this.options[a]=b,a==="disabled"&&this.widget()[b?"addClass":"removeClass"](this.widgetBaseClass+"-disabled"+" "+"ui-state-disabled").attr("aria-disabled",b),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_trigger:function(b,c,d){var e,f,g=this.options[b];d=d||{},c=a.Event(c),c.type=(b===this.widgetEventPrefix?b:this.widgetEventPrefix+b).toLowerCase(),c.target=this.element[0],f=c.originalEvent;if(f)for(e in f)e in c||(c[e]=f[e]);return this.element.trigger(c,d),!(a.isFunction(g)&&g.call(this.element[0],c,d)===!1||c.isDefaultPrevented())}}}(jQuery),function(a,b){var c=!1;a(document).mouseup(function(a){c=!1}),a.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var b=this;this.element.bind("mousedown."+this.widgetName,function(a){return b._mouseDown(a)}).bind("click."+this.widgetName,function(c){if(!0===a.data(c.target,b.widgetName+".preventClickEvent"))return a.removeData(c.target,b.widgetName+".preventClickEvent"),c.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(b){if(c)return;this._mouseStarted&&this._mouseUp(b),this._mouseDownEvent=b;var d=this,e=b.which==1,f=typeof this.options.cancel=="string"&&b.target.nodeName?a(b.target).closest(this.options.cancel).length:!1;if(!e||f||!this._mouseCapture(b))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){d.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)){this._mouseStarted=this._mouseStart(b)!==!1;if(!this._mouseStarted)return b.preventDefault(),!0}return!0===a.data(b.target,this.widgetName+".preventClickEvent")&&a.removeData(b.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(a){return d._mouseMove(a)},this._mouseUpDelegate=function(a){return d._mouseUp(a)},a(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),b.preventDefault(),c=!0,!0},_mouseMove:function(b){return!a.browser.msie||document.documentMode>=9||!!b.button?this._mouseStarted?(this._mouseDrag(b),b.preventDefault()):(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b)),!this._mouseStarted):this._mouseUp(b)},_mouseUp:function(b){return a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b)),!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})}(jQuery),function(a,b){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},destroy:function(){if(!this.element.data("draggable"))return;return this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy(),this},_mouseCapture:function(b){var c=this.options;return this.helper||c.disabled||a(b.target).is(".ui-resizable-handle")?!1:(this.handle=this._getHandle(b),this.handle?(c.iframeFix&&a(c.iframeFix===!0?"iframe":c.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(a(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(b){var c=this.options;return this.helper=this._createHelper(b),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),c.containment&&this._setContainment(),this._trigger("start",b)===!1?(this._clear(),!1):(this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b),!0)},_mouseDrag:function(b,c){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute");if(!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1)return this._mouseUp({}),!1;this.position=d.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";return a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),!1},_mouseStop:function(b){var c=!1;a.ui.ddmanager&&!this.options.dropBehaviour&&(c=a.ui.ddmanager.drop(this,b)),this.dropped&&(c=this.dropped,this.dropped=!1);var d=this.element[0],e=!1;while(d&&(d=d.parentNode))d==document&&(e=!0);if(!e&&this.options.helper==="original")return!1;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var f=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){f._trigger("stop",b)!==!1&&f._clear()})}else this._trigger("stop",b)!==!1&&this._clear();return!1},_mouseUp:function(b){return this.options.iframeFix===!0&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b),a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?!0:!1;return a(this.options.handle,this.element).find("*").andSelf().each(function(){this==b.target&&(c=!0)}),c},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;return d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo),d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&d.css("position","absolute"),d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[b.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,b.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(b.containment=="document"?0:a(window).scrollLeft())+a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(b.containment=="document"?0:a(window).scrollTop())+(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)&&b.containment.constructor!=Array){var c=a(b.containment),d=c[0];if(!d)return;var e=c.offset(),f=a(d).css("overflow")!="hidden";this.containment=[(parseInt(a(d).css("borderLeftWidth"),10)||0)+(parseInt(a(d).css("paddingLeft"),10)||0),(parseInt(a(d).css("borderTopWidth"),10)||0)+(parseInt(a(d).css("paddingTop"),10)||0),(f?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(a(d).css("borderLeftWidth"),10)||0)-(parseInt(a(d).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(f?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(a(d).css("borderTopWidth"),10)||0)-(parseInt(a(d).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=c}else b.containment.constructor==Array&&(this.containment=b.containment)},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName),f=b.pageX,g=b.pageY;if(this.originalPosition){var h;if(this.containment){if(this.relative_container){var i=this.relative_container.offset();h=[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]}else h=this.containment;b.pageX-this.offset.click.left<h[0]&&(f=h[0]+this.offset.click.left),b.pageY-this.offset.click.top<h[1]&&(g=h[1]+this.offset.click.top),b.pageX-this.offset.click.left>h[2]&&(f=h[2]+this.offset.click.left),b.pageY-this.offset.click.top>h[3]&&(g=h[3]+this.offset.click.top)}if(c.grid){var j=c.grid[1]?this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;g=h?j-this.offset.click.top<h[1]||j-this.offset.click.top>h[3]?j-this.offset.click.top<h[1]?j+c.grid[1]:j-c.grid[1]:j:j;var k=c.grid[0]?this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0]:this.originalPageX;f=h?k-this.offset.click.left<h[0]||k-this.offset.click.left>h[2]?k-this.offset.click.left<h[0]?k+c.grid[0]:k-c.grid[0]:k:k}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(b,c,d){return d=d||this._uiHash(),a.ui.plugin.call(this,b,[c,d]),b=="drag"&&(this.positionAbs=this._convertPositionTo("absolute")),a.Widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(a){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),a.extend(a.ui.draggable,{version:"1.8.23"}),a.ui.plugin.add("draggable","connectToSortable",{start:function(b,c){var d=a(this).data("draggable"),e=d.options,f=a.extend({},c,{item:d.element});d.sortables=[],a(e.connectToSortable).each(function(){var c=a.data(this,"sortable");c&&!c.options.disabled&&(d.sortables.push({instance:c,shouldRevert:c.options.revert}),c.refreshPositions(),c._trigger("activate",b,f))})},stop:function(b,c){var d=a(this).data("draggable"),e=a.extend({},c,{item:d.element});a.each(d.sortables,function(){this.instance.isOver?(this.instance.isOver=0,d.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(b),this.instance.options.helper=this.instance.options._helper,d.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",b,e))})},drag:function(b,c){var d=a(this).data("draggable"),e=this,f=function(b){var c=this.offset.click.top,d=this.offset.click.left,e=this.positionAbs.top,f=this.positionAbs.left,g=b.height,h=b.width,i=b.top,j=b.left;return a.ui.isOver(e+c,f+d,i,j,g,h)};a.each(d.sortables,function(f){this.instance.positionAbs=d.positionAbs,this.instance.helperProportions=d.helperProportions,this.instance.offset.click=d.offset.click,this.instance._intersectsWith(this.instance.containerCache)?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=a(e).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return c.helper[0]},b.target=this.instance.currentItem[0],this.instance._mouseCapture(b,!0),this.instance._mouseStart(b,!0,!0),this.instance.offset.click.top=d.offset.click.top,this.instance.offset.click.left=d.offset.click.left,this.instance.offset.parent.left-=d.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=d.offset.parent.top-this.instance.offset.parent.top,d._trigger("toSortable",b),d.dropped=this.instance.element,d.currentItem=d.element,this.instance.fromOutside=d),this.instance.currentItem&&this.instance._mouseDrag(b)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",b,this.instance._uiHash(this.instance)),this.instance._mouseStop(b,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),d._trigger("fromSortable",b),d.dropped=!1)})}}),a.ui.plugin.add("draggable","cursor",{start:function(b,c){var d=a("body"),e=a(this).data("draggable").options;d.css("cursor")&&(e._cursor=d.css("cursor")),d.css("cursor",e.cursor)},stop:function(b,c){var d=a(this).data("draggable").options;d._cursor&&a("body").css("cursor",d._cursor)}}),a.ui.plugin.add("draggable","opacity",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("opacity")&&(e._opacity=d.css("opacity")),d.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;d._opacity&&a(c.helper).css("opacity",d._opacity)}}),a.ui.plugin.add("draggable","scroll",{start:function(b,c){var d=a(this).data("draggable");d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"&&(d.overflowOffset=d.scrollParent.offset())},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=!1;if(d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"){if(!e.axis||e.axis!="x")d.overflowOffset.top+d.scrollParent[0].offsetHeight-b.pageY<e.scrollSensitivity?d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop+e.scrollSpeed:b.pageY-d.overflowOffset.top<e.scrollSensitivity&&(d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop-e.scrollSpeed);if(!e.axis||e.axis!="y")d.overflowOffset.left+d.scrollParent[0].offsetWidth-b.pageX<e.scrollSensitivity?d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft+e.scrollSpeed:b.pageX-d.overflowOffset.left<e.scrollSensitivity&&(d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft-e.scrollSpeed)}else{if(!e.axis||e.axis!="x")b.pageY-a(document).scrollTop()<e.scrollSensitivity?f=a(document).scrollTop(a(document).scrollTop()-e.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<e.scrollSensitivity&&(f=a(document).scrollTop(a(document).scrollTop()+e.scrollSpeed));if(!e.axis||e.axis!="y")b.pageX-a(document).scrollLeft()<e.scrollSensitivity?f=a(document).scrollLeft(a(document).scrollLeft()-e.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<e.scrollSensitivity&&(f=a(document).scrollLeft(a(document).scrollLeft()+e.scrollSpeed))}f!==!1&&a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(d,b)}}),a.ui.plugin.add("draggable","snap",{start:function(b,c){var d=a(this).data("draggable"),e=d.options;d.snapElements=[],a(e.snap.constructor!=String?e.snap.items||":data(draggable)":e.snap).each(function(){var b=a(this),c=b.offset();this!=d.element[0]&&d.snapElements.push({item:this,width:b.outerWidth(),height:b.outerHeight(),top:c.top,left:c.left})})},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=e.snapTolerance,g=c.offset.left,h=g+d.helperProportions.width,i=c.offset.top,j=i+d.helperProportions.height;for(var k=d.snapElements.length-1;k>=0;k--){var l=d.snapElements[k].left,m=l+d.snapElements[k].width,n=d.snapElements[k].top,o=n+d.snapElements[k].height;if(!(l-f<g&&g<m+f&&n-f<i&&i<o+f||l-f<g&&g<m+f&&n-f<j&&j<o+f||l-f<h&&h<m+f&&n-f<i&&i<o+f||l-f<h&&h<m+f&&n-f<j&&j<o+f)){d.snapElements[k].snapping&&d.options.snap.release&&d.options.snap.release.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=!1;continue}if(e.snapMode!="inner"){var p=Math.abs(n-j)<=f,q=Math.abs(o-i)<=f,r=Math.abs(l-h)<=f,s=Math.abs(m-g)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n-d.helperProportions.height,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l-d.helperProportions.width}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m}).left-d.margins.left)}var t=p||q||r||s;if(e.snapMode!="outer"){var p=Math.abs(n-i)<=f,q=Math.abs(o-j)<=f,r=Math.abs(l-g)<=f,s=Math.abs(m-h)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o-d.helperProportions.height,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m-d.helperProportions.width}).left-d.margins.left)}!d.snapElements[k].snapping&&(p||q||r||s||t)&&d.options.snap.snap&&d.options.snap.snap.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=p||q||r||s||t}}}),a.ui.plugin.add("draggable","stack",{start:function(b,c){var d=a(this).data("draggable").options,e=a.makeArray(a(d.stack)).sort(function(b,c){return(parseInt(a(b).css("zIndex"),10)||0)-(parseInt(a(c).css("zIndex"),10)||0)});if(!e.length)return;var f=parseInt(e[0].style.zIndex)||0;a(e).each(function(a){this.style.zIndex=f+a}),this[0].style.zIndex=f+e.length}}),a.ui.plugin.add("draggable","zIndex",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("zIndex")&&(e._zIndex=d.css("zIndex")),d.css("zIndex",e.zIndex)},stop:function(b,c){var d=a(this).data("draggable").options;d._zIndex&&a(c.helper).css("zIndex",d._zIndex)}})}(jQuery),function(a,b){a.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect"},_create:function(){var b=this.options,c=b.accept;this.isover=0,this.isout=1,this.accept=a.isFunction(c)?c:function(a){return a.is(c)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},a.ui.ddmanager.droppables[b.scope]=a.ui.ddmanager.droppables[b.scope]||[],a.ui.ddmanager.droppables[b.scope].push(this),b.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){var b=a.ui.ddmanager.droppables[this.options.scope];for(var c=0;c<b.length;c++)b[c]==this&&b.splice(c,1);return this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable"),this},_setOption:function(b,c){b=="accept"&&(this.accept=a.isFunction(c)?c:function(a){return a.is(c)}),a.Widget.prototype._setOption.apply(this,arguments)},_activate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),c&&this._trigger("activate",b,this.ui(c))},_deactivate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),c&&this._trigger("deactivate",b,this.ui(c))},_over:function(b){var c=a.ui.ddmanager.current;if(!c||(c.currentItem||c.element)[0]==this.element[0])return;this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",b,this.ui(c)))},_out:function(b){var c=a.ui.ddmanager.current;if(!c||(c.currentItem||c.element)[0]==this.element[0])return;this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",b,this.ui(c)))},_drop:function(b,c){var d=c||a.ui.ddmanager.current;if(!d||(d.currentItem||d.element)[0]==this.element[0])return!1;var e=!1;return this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var b=a.data(this,"droppable");if(b.options.greedy&&!b.options.disabled&&b.options.scope==d.options.scope&&b.accept.call(b.element[0],d.currentItem||d.element)&&a.ui.intersect(d,a.extend(b,{offset:b.element.offset()}),b.options.tolerance))return e=!0,!1}),e?!1:this.accept.call(this.element[0],d.currentItem||d.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",b,this.ui(d)),this.element):!1},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}}),a.extend(a.ui.droppable,{version:"1.8.23"}),a.ui.intersect=function(b,c,d){if(!c.offset)return!1;var e=(b.positionAbs||b.position.absolute).left,f=e+b.helperProportions.width,g=(b.positionAbs||b.position.absolute).top,h=g+b.helperProportions.height,i=c.offset.left,j=i+c.proportions.width,k=c.offset.top,l=k+c.proportions.height;switch(d){case"fit":return i<=e&&f<=j&&k<=g&&h<=l;case"intersect":return i<e+b.helperProportions.width/2&&f-b.helperProportions.width/2<j&&k<g+b.helperProportions.height/2&&h-b.helperProportions.height/2<l;case"pointer":var m=(b.positionAbs||b.position.absolute).left+(b.clickOffset||b.offset.click).left,n=(b.positionAbs||b.position.absolute).top+(b.clickOffset||b.offset.click).top,o=a.ui.isOver(n,m,k,i,c.proportions.height,c.proportions.width);return o;case"touch":return(g>=k&&g<=l||h>=k&&h<=l||g<k&&h>l)&&(e>=i&&e<=j||f>=i&&f<=j||e<i&&f>j);default:return!1}},a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(b,c){var d=a.ui.ddmanager.droppables[b.options.scope]||[],e=c?c.type:null,f=(b.currentItem||b.element).find(":data(droppable)").andSelf();g:for(var h=0;h<d.length;h++){if(d[h].options.disabled||b&&!d[h].accept.call(d[h].element[0],b.currentItem||b.element))continue;for(var i=0;i<f.length;i++)if(f[i]==d[h].element[0]){d[h].proportions.height=0;continue g}d[h].visible=d[h].element.css("display")!="none";if(!d[h].visible)continue;e=="mousedown"&&d[h]._activate.call(d[h],c),d[h].offset=d[h].element.offset(),d[h].proportions={width:d[h].element[0].offsetWidth,height:d[h].element[0].offsetHeight}}},drop:function(b,c){var d=!1;return a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){if(!this.options)return;!this.options.disabled&&this.visible&&a.ui.intersect(b,this,this.options.tolerance)&&(d=this._drop.call(this,c)||d),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],b.currentItem||b.element)&&(this.isout=1,this.isover=0,this._deactivate.call(this,c))}),d},dragStart:function(b,c){b.element.parents(":not(body,html)").bind("scroll.droppable",function(){b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)})},drag:function(b,c){b.options.refreshPositions&&a.ui.ddmanager.prepareOffsets(b,c),a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){if(this.options.disabled||this.greedyChild||!this.visible)return;var d=a.ui.intersect(b,this,this.options.tolerance),e=!d&&this.isover==1?"isout":d&&this.isover==0?"isover":null;if(!e)return;var f;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");g.length&&(f=a.data(g[0],"droppable"),f.greedyChild=e=="isover"?1:0)}f&&e=="isover"&&(f.isover=0,f.isout=1,f._out.call(f,c)),this[e]=1,this[e=="isout"?"isover":"isout"]=0,this[e=="isover"?"_over":"_out"].call(this,c),f&&e=="isout"&&(f.isout=0,f.isover=1,f._over.call(f,c))})},dragStop:function(b,c){b.element.parents(":not(body,html)").unbind("scroll.droppable"),b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)}}}(jQuery),function(a,b){a.widget("ui.resizable",a.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1e3},_create:function(){var b=this,c=this.options;this.element.addClass("ui-resizable"),a.extend(this,{_aspectRatio:!!c.aspectRatio,aspectRatio:c.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:c.helper||c.ghost||c.animate?c.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(a('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=c.handles||(a(".ui-resizable-handle",this.element).length?{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"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var d=this.handles.split(",");this.handles={};for(var e=0;e<d.length;e++){var f=a.trim(d[e]),g="ui-resizable-"+f,h=a('<div class="ui-resizable-handle '+g+'"></div>');h.css({zIndex:c.zIndex}),"se"==f&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[f]=".ui-resizable-"+f,this.element.append(h)}}this._renderAxis=function(b){b=b||this.element;for(var c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=a(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var d=a(this.handles[c],this.element),e=0;e=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth();var f=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");b.css(f,e),this._proportionallyResize()}if(!a(this.handles[c]).length)continue}},this._renderAxis(this.element),this._handles=a(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!b.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=a&&a[1]?a[1]:"se"}}),c.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").hover(function(){if(c.disabled)return;a(this).removeClass("ui-resizable-autohide"),b._handles.show()},function(){if(c.disabled)return;b.resizing||(a(this).addClass("ui-resizable-autohide"),b._handles.hide())})),this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var c=this.element;c.after(this.originalElement.css({position:c.css("position"),width:c.outerWidth(),height:c.outerHeight(),top:c.css("top"),left:c.css("left")})).remove()}return this.originalElement.css("resize",this.originalResizeStyle),b(this.originalElement),this},_mouseCapture:function(b){var c=!1;for(var d in this.handles)a(this.handles[d])[0]==b.target&&(c=!0);return!this.options.disabled&&c},_mouseStart:function(b){var d=this.options,e=this.element.position(),f=this.element;this.resizing=!0,this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()},(f.is(".ui-draggable")||/absolute/.test(f.css("position")))&&f.css({position:"absolute",top:e.top,left:e.left}),this._renderProxy();var g=c(this.helper.css("left")),h=c(this.helper.css("top"));d.containment&&(g+=a(d.containment).scrollLeft()||0,h+=a(d.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:g,top:h},this.size=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalSize=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalPosition={left:g,top:h},this.sizeDiff={width:f.outerWidth()-f.width(),height:f.outerHeight()-f.height()},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio=typeof d.aspectRatio=="number"?d.aspectRatio:this.originalSize.width/this.originalSize.height||1;var i=a(".ui-resizable-"+this.axis).css("cursor");return a("body").css("cursor",i=="auto"?this.axis+"-resize":i),f.addClass("ui-resizable-resizing"),this._propagate("start",b),!0},_mouseDrag:function(b){var c=this.helper,d=this.options,e={},f=this,g=this.originalMousePosition,h=this.axis,i=b.pageX-g.left||0,j=b.pageY-g.top||0,k=this._change[h];if(!k)return!1;var l=k.apply(this,[b,i,j]),m=a.browser.msie&&a.browser.version<7,n=this.sizeDiff;this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)l=this._updateRatio(l,b);return l=this._respectSize(l,b),this._propagate("resize",b),c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",b,this.ui()),!1},_mouseStop:function(b){this.resizing=!1;var c=this.options,d=this;if(this._helper){var e=this._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&a.ui.hasScroll(e[0],"left")?0:d.sizeDiff.height,h=f?0:d.sizeDiff.width,i={width:d.helper.width()-h,height:d.helper.height()-g},j=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,k=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;c.animate||this.element.css(a.extend(i,{top:k,left:j})),d.helper.height(d.size.height),d.helper.width(d.size.width),this._helper&&!c.animate&&this._proportionallyResize()}return a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(a){var b=this.options,c,e,f,g,h;h={minWidth:d(b.minWidth)?b.minWidth:0,maxWidth:d(b.maxWidth)?b.maxWidth:Infinity,minHeight:d(b.minHeight)?b.minHeight:0,maxHeight:d(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||a)c=h.minHeight*this.aspectRatio,f=h.minWidth/this.aspectRatio,e=h.maxHeight*this.aspectRatio,g=h.maxWidth/this.aspectRatio,c>h.minWidth&&(h.minWidth=c),f>h.minHeight&&(h.minHeight=f),e<h.maxWidth&&(h.maxWidth=e),g<h.maxHeight&&(h.maxHeight=g);this._vBoundaries=h},_updateCache:function(a){var b=this.options;this.offset=this.helper.offset(),d(a.left)&&(this.position.left=a.left),d(a.top)&&(this.position.top=a.top),d(a.height)&&(this.size.height=a.height),d(a.width)&&(this.size.width=a.width)},_updateRatio:function(a,b){var c=this.options,e=this.position,f=this.size,g=this.axis;return d(a.height)?a.width=a.height*this.aspectRatio:d(a.width)&&(a.height=a.width/this.aspectRatio),g=="sw"&&(a.left=e.left+(f.width-a.width),a.top=null),g=="nw"&&(a.top=e.top+(f.height-a.height),a.left=e.left+(f.width-a.width)),a},_respectSize:function(a,b){var c=this.helper,e=this._vBoundaries,f=this._aspectRatio||b.shiftKey,g=this.axis,h=d(a.width)&&e.maxWidth&&e.maxWidth<a.width,i=d(a.height)&&e.maxHeight&&e.maxHeight<a.height,j=d(a.width)&&e.minWidth&&e.minWidth>a.width,k=d(a.height)&&e.minHeight&&e.minHeight>a.height;j&&(a.width=e.minWidth),k&&(a.height=e.minHeight),h&&(a.width=e.maxWidth),i&&(a.height=e.maxHeight);var l=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height,n=/sw|nw|w/.test(g),o=/nw|ne|n/.test(g);j&&n&&(a.left=l-e.minWidth),h&&n&&(a.left=l-e.maxWidth),k&&o&&(a.top=m-e.minHeight),i&&o&&(a.top=m-e.maxHeight);var p=!a.width&&!a.height;return p&&!a.left&&a.top?a.top=null:p&&!a.top&&a.left&&(a.left=null),a},_proportionallyResize:function(){var b=this.options;if(!this._proportionallyResizeElements.length)return;var c=this.helper||this.element;for(var d=0;d<this._proportionallyResizeElements.length;d++){var e=this._proportionallyResizeElements[d];if(!this.borderDif){var f=[e.css("borderTopWidth"),e.css("borderRightWidth"),e.css("borderBottomWidth"),e.css("borderLeftWidth")],g=[e.css("paddingTop"),e.css("paddingRight"),e.css("paddingBottom"),e.css("paddingLeft")];this.borderDif=a.map(f,function(a,b){var c=parseInt(a,10)||0,d=parseInt(g[b],10)||0;return c+d})}if(!a.browser.msie||!a(c).is(":hidden")&&!a(c).parents(":hidden").length)e.css({height:c.height()-this.borderDif[0]-this.borderDif[2]||0,width:c.width()-this.borderDif[1]-this.borderDif[3]||0});else continue}},_renderProxy:function(){var b=this.element,c=this.options;this.elementOffset=b.offset();if(this._helper){this.helper=this.helper||a('<div style="overflow:hidden;"></div>');var d=a.browser.msie&&a.browser.version<7,e=d?1:0,f=d?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b,c){return{width:this.originalSize.width+b}},w:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{left:f.left+b,width:e.width-b}},n:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{top:f.top+c,height:e.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),b!="resize"&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.extend(a.ui.resizable,{version:"1.8.23"}),a.ui.plugin.add("resizable","alsoResize",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10)})})};typeof e.alsoResize=="object"&&!e.alsoResize.parentNode?e.alsoResize.length?(e.alsoResize=e.alsoResize[0],f(e.alsoResize)):a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0},i=function(b,d){a(b).each(function(){var b=a(this),e=a(this).data("resizable-alsoresize"),f={},g=d&&d.length?d:b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(g,function(a,b){var c=(e[b]||0)+(h[b]||0);c&&c>=0&&(f[b]=c||null)}),b.css(f)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a,b){i(a,b)}):i(e.alsoResize)},stop:function(b,c){a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","animate",{stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d._proportionallyResizeElements,g=f.length&&/textarea/i.test(f[0].nodeName),h=g&&a.ui.hasScroll(f[0],"left")?0:d.sizeDiff.height,i=g?0:d.sizeDiff.width,j={width:d.size.width-i,height:d.size.height-h},k=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,l=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;d.element.animate(a.extend(j,l&&k?{top:l,left:k}:{}),{duration:e.animateDuration,easing:e.animateEasing,step:function(){var c={width:parseInt(d.element.css("width"),10),height:parseInt(d.element.css("height"),10),top:parseInt(d.element.css("top"),10),left:parseInt(d.element.css("left"),10)};f&&f.length&&a(f[0]).css({width:c.width,height:c.height}),d._updateCache(c),d._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(b,d){var e=a(this).data("resizable"),f=e.options,g=e.element,h=f.containment,i=h instanceof a?h.get(0):/parent/.test(h)?g.parent().get(0):h;if(!i)return;e.containerElement=a(i);if(/document/.test(h)||h==document)e.containerOffset={left:0,top:0},e.containerPosition={left:0,top:0},e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var j=a(i),k=[];a(["Top","Right","Left","Bottom"]).each(function(a,b){k[a]=c(j.css("padding"+b))}),e.containerOffset=j.offset(),e.containerPosition=j.position(),e.containerSize={height:j.innerHeight()-k[3],width:j.innerWidth()-k[1]};var l=e.containerOffset,m=e.containerSize.height,n=e.containerSize.width,o=a.ui.hasScroll(i,"left")?i.scrollWidth:n,p=a.ui.hasScroll(i)?i.scrollHeight:m;e.parentData={element:i,left:l.left,top:l.top,width:o,height:p}}},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.containerSize,g=d.containerOffset,h=d.size,i=d.position,j=d._aspectRatio||b.shiftKey,k={top:0,left:0},l=d.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=g),i.left<(d._helper?g.left:0)&&(d.size.width=d.size.width+(d._helper?d.position.left-g.left:d.position.left-k.left),j&&(d.size.height=d.size.width/d.aspectRatio),d.position.left=e.helper?g.left:0),i.top<(d._helper?g.top:0)&&(d.size.height=d.size.height+(d._helper?d.position.top-g.top:d.position.top),j&&(d.size.width=d.size.height*d.aspectRatio),d.position.top=d._helper?g.top:0),d.offset.left=d.parentData.left+d.position.left,d.offset.top=d.parentData.top+d.position.top;var m=Math.abs((d._helper?d.offset.left-k.left:d.offset.left-k.left)+d.sizeDiff.width),n=Math.abs((d._helper?d.offset.top-k.top:d.offset.top-g.top)+d.sizeDiff.height),o=d.containerElement.get(0)==d.element.parent().get(0),p=/relative|absolute/.test(d.containerElement.css("position"));o&&p&&(m-=d.parentData.left),m+d.size.width>=d.parentData.width&&(d.size.width=d.parentData.width-m,j&&(d.size.height=d.size.width/d.aspectRatio)),n+d.size.height>=d.parentData.height&&(d.size.height=d.parentData.height-n,j&&(d.size.width=d.size.height*d.aspectRatio))},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.position,g=d.containerOffset,h=d.containerPosition,i=d.containerElement,j=a(d.helper),k=j.offset(),l=j.outerWidth()-d.sizeDiff.width,m=j.outerHeight()-d.sizeDiff.height;d._helper&&!e.animate&&/relative/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m}),d._helper&&!e.animate&&/static/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m})}}),a.ui.plugin.add("resizable","ghost",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size;d.ghost=d.originalElement.clone(),d.ghost.css({opacity:.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:""),d.ghost.appendTo(d.helper)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})},stop:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.helper&&d.helper.get(0).removeChild(d.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size,g=d.originalSize,h=d.originalPosition,i=d.axis,j=e._aspectRatio||b.shiftKey;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-g.width)/(e.grid[0]||1))*(e.grid[0]||1),l=Math.round((f.height-g.height)/(e.grid[1]||1))*(e.grid[1]||1);/^(se|s|e)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l):/^(ne)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l):/^(sw)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.left=h.left-k):(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l,d.position.left=h.left-k)}});var c=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}}(jQuery),function(a,b){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable"),this.dragged=!1;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]),c.addClass("ui-selectee"),c.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=c.addClass("ui-selectee"),this._mouseInit(),this.helper=a("<div class='ui-selectable-helper'></div>")},destroy:function(){return this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy(),this},_mouseStart:function(b){var c=this;this.opos=[b.pageX,b.pageY];if(this.options.disabled)return;var d=this.options;this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,!b.metaKey&&!b.ctrlKey&&(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().andSelf().each(function(){var d=a.data(this,"selectable-item");if(d){var e=!b.metaKey&&!b.ctrlKey||!d.$element.hasClass("ui-selected");return d.$element.removeClass(e?"ui-unselecting":"ui-selected").addClass(e?"ui-selecting":"ui-unselecting"),d.unselecting=!e,d.selecting=e,d.selected=e,e?c._trigger("selecting",b,{selecting:d.element}):c._trigger("unselecting",b,{unselecting:d.element}),!1}})},_mouseDrag:function(b){var c=this;this.dragged=!0;if(this.options.disabled)return;var d=this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g){var i=g;g=e,e=i}if(f>h){var i=h;h=f,f=i}return this.helper.css({left:e,top:f,width:g-e,height:h-f}),this.selectees.each(function(){var i=a.data(this,"selectable-item");if(!i||i.element==c.element[0])return;var j=!1;d.tolerance=="touch"?j=!(i.left>g||i.right<e||i.top>h||i.bottom<f):d.tolerance=="fit"&&(j=i.left>e&&i.right<g&&i.top>f&&i.bottom<h),j?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,c._trigger("selecting",b,{selecting:i.element}))):(i.selecting&&((b.metaKey||b.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),c._trigger("unselecting",b,{unselecting:i.element}))),i.selected&&!b.metaKey&&!b.ctrlKey&&!i.startselected&&(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,c._trigger("unselecting",b,{unselecting:i.element})))}),!1},_mouseStop:function(b){var c=this;this.dragged=!1;var d=this.options;return a(".ui-unselecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-unselecting"),d.unselecting=!1,d.startselected=!1,c._trigger("unselected",b,{unselected:d.element})}),a(".ui-selecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected"),d.selecting=!1,d.selected=!0,d.startselected=!0,c._trigger("selected",b,{selected:d.element})}),this._trigger("stop",b),this.helper.remove(),!1}}),a.extend(a.ui.selectable,{version:"1.8.23"})}(jQuery),function(a,b){a.widget("ui.sortable",a.ui.mouse,{widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},destroy:function(){a.Widget.prototype.destroy.call(this),this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--)this.items[b].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f)return e=a(this),!1});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}return this.currentItem=e,this._removeCurrentsFromItems(),!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));return a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b),!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY<c.scrollSensitivity?this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop+c.scrollSpeed:b.pageY-this.overflowOffset.top<c.scrollSensitivity&&(this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop-c.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-b.pageX<c.scrollSensitivity?this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft+c.scrollSpeed:b.pageX-this.overflowOffset.left<c.scrollSensitivity&&(this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft-c.scrollSpeed)):(b.pageY-a(document).scrollTop()<c.scrollSensitivity?d=a(document).scrollTop(a(document).scrollTop()-c.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<c.scrollSensitivity&&(d=a(document).scrollTop(a(document).scrollTop()+c.scrollSpeed)),b.pageX-a(document).scrollLeft()<c.scrollSensitivity?d=a(document).scrollLeft(a(document).scrollLeft()-c.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<c.scrollSensitivity&&(d=a(document).scrollLeft(a(document).scrollLeft()+c.scrollSpeed))),d!==!1&&a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(var e=this.items.length-1;e>=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}return this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(b,c){if(!b)return;a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"="),d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")}),d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+j<i&&b+k>f&&b+k<g;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?l:f<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<g&&h<d+this.helperProportions.height/2&&e-this.helperProportions.height/2<i},_intersectsWithPointer:function(b){var c=this.options.axis==="x"||a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top,b.height),d=this.options.axis==="y"||a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left,b.width),e=c&&d,f=this._getDragVerticalDirection(),g=this._getDragHorizontalDirection();return e?this.floating?g&&g=="right"||f=="down"?2:1:f&&(f=="down"?2:1):!1},_intersectsWithSides:function(b){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top+b.height/2,b.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left+b.width/2,b.width),e=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();return this.floating&&f?f=="right"&&d||f=="left"&&!d:e&&(e=="down"&&c||e=="up"&&!c)},_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){return this._refreshItems(a),this.refreshPositions(),this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(b){this.items=[],this.containers=[this];var c=this.items,d=this,e=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],b,{item:this.currentItem}):a(this.options.items,this.element),this]],f=this._connectWith();if(f&&this.ready)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i<m;i++){var n=a(l[i]);n.data(this.widgetName+"-item",k),c.push({item:n,instance:k,width:0,height:0,left:0,top:0})}}},refreshPositions:function(b){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());for(var c=this.items.length-1;c>=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return e||(b.style.visibility="hidden"),b},update:function(a,b){if(e&&!d.forcePlaceholderSize)return;b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!c)return;if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.containers[d].floating?this.items[i].item.offset().left:this.items[i].item.offset().top;Math.abs(j-h)<f&&(f=Math.abs(j-h),g=this.items[i],this.direction=j-h>0?"down":"up")}if(!g&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[d],g?this._rearrange(b,g,null,!0):this._rearrange(b,null,this.containers[d].element,!0),this._trigger("change",b,this._uiHash()),this.containers[d]._trigger("change",b,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1}},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b,this.currentItem])):c.helper=="clone"?this.currentItem.clone():this.currentItem;return d.parents("body").length||a(c.appendTo!="parent"?c.appendTo:this.currentItem[0].parentNode)[0].appendChild(d[0]),d[0]==this.currentItem[0]&&(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")}),(d[0].style.width==""||c.forceHelperSize)&&d.width(this.currentItem.width()),(d[0].style.height==""||c.forceHelperSize)&&d.height(this.currentItem.height()),d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)){var c=a(b.containment)[0],d=a(b.containment).offset(),e=a(c).css("overflow")!="hidden";this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var f=b.pageX,g=b.pageY;if(this.originalPosition){this.containment&&(b.pageX-this.offset.click.left<this.containment[0]&&(f=this.containment[0]+this.offset.click.left),b.pageY-this.offset.click.top<this.containment[1]&&(g=this.containment[1]+this.offset.click.top),b.pageX-this.offset.click.left>this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.top<this.containment[1]||h-this.offset.click.top>this.containment[3]?h-this.offset.click.top<this.containment[1]?h+c.grid[1]:h-c.grid[1]:h:h;var i=this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0];f=this.containment?i-this.offset.click.left<this.containment[0]||i-this.offset.click.left>this.containment[2]?i-this.offset.click.left<this.containment[0]?i+c.grid[0]:i-c.grid[0]:i:i}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_rearrange:function(a,b,c,d){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?b.item[0]:b.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var e=this,f=this.counter;window.setTimeout(function(){f==e.counter&&e.refreshPositions(!d)},0)},_clear:function(b,c){this.reverting=!1;var d=[],e=this;!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var f in this._storedCSS)if(this._storedCSS[f]=="auto"||this._storedCSS[f]=="static")this._storedCSS[f]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!c&&d.push(function(a){this._trigger("receive",a,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!c&&d.push(function(a){this._trigger("update",a,this._uiHash())});if(!a.ui.contains(this.element[0],this.currentItem[0])){c||d.push(function(a){this._trigger("remove",a,this._uiHash())});for(var f=this.containers.length-1;f>=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}return this.fromOutside=!1,!1}c||this._trigger("beforeStop",b,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!=this.currentItem[0]&&this.helper.remove(),this.helper=null;if(!c){for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){a.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(b){var c=b||this;return{helper:c.helper,placeholder:c.placeholder||a([]),position:c.position,originalPosition:c.originalPosition,offset:c.positionAbs,item:c.currentItem,sender:b?b.element:null}}}),a.extend(a.ui.sortable,{version:"1.8.23"})}(jQuery),jQuery.effects||function(a,b){function c(b){var c;return b&&b.constructor==Array&&b.length==3?b:(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b))?[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)]:(c=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b))?[parseFloat(c[1])*2.55,parseFloat(c[2])*2.55,parseFloat(c[3])*2.55]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))?[parseInt(c[1],16),parseInt(c[2],16),parseInt(c[3],16)]:(c=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))?[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)]:(c=/rgba\(0, 0, 0, 0\)/.exec(b))?e.transparent:e[a.trim(b).toLowerCase()]}function d(b,d){var e;do{e=(a.curCSS||a.css)(b,d);if(e!=""&&e!="transparent"||a.nodeName(b,"body"))break;d="backgroundColor"}while(b=b.parentNode);return c(e)}function h(){var a=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,b={},c,d;if(a&&a.length&&a[0]&&a[a[0]]){var e=a.length;while(e--)c=a[e],typeof a[c]=="string"&&(d=c.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),b[d]=a[c])}else for(c in a)typeof a[c]=="string"&&(b[c]=a[c]);return b}function i(b){var c,d;for(c in b)d=b[c],(d==null||a.isFunction(d)||c in g||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete b[c];return b}function j(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function k(b,c,d,e){typeof b=="object"&&(e=c,d=null,c=b,b=c.effect),a.isFunction(c)&&(e=c,d=null,c={});if(typeof c=="number"||a.fx.speeds[c])e=d,d=c,c={};return a.isFunction(d)&&(e=d,d=null),c=c||{},d=d||c.duration,d=a.fx.off?0:typeof d=="number"?d:d in a.fx.speeds?a.fx.speeds[d]:a.fx.speeds._default,e=e||c.complete,[b,c,d,e]}function l(b){return!b||typeof b=="number"||a.fx.speeds[b]?!0:typeof b=="string"&&!a.effects[b]?!0:!1}a.effects={},a.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(b,e){a.fx.step[e]=function(a){a.colorInit||(a.start=d(a.elem,e),a.end=c(a.end),a.colorInit=!0),a.elem.style[e]="rgb("+Math.max(Math.min(parseInt(a.pos*(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var e={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},f=["add","remove","toggle"],g={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(b,c,d,e){return a.isFunction(d)&&(e=d,d=null),this.queue(function(){var g=a(this),k=g.attr("style")||" ",l=i(h.call(this)),m,n=g.attr("class")||"";a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),m=i(h.call(this)),g.attr("class",n),g.animate(j(l,m),{queue:!1,duration:c,easing:d,complete:function(){a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),typeof g.attr("style")=="object"?(g.attr("style").cssText="",g.attr("style").cssText=k):g.attr("style",k),e&&e.apply(this,arguments),a.dequeue(this)}})})},a.fn.extend({_addClass:a.fn.addClass,addClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{add:b},c,d,e]):this._addClass(b)},_removeClass:a.fn.removeClass,removeClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{remove:b},c,d,e]):this._removeClass(b)},_toggleClass:a.fn.toggleClass,toggleClass:function(c,d,e,f,g){return typeof d=="boolean"||d===b?e?a.effects.animateClass.apply(this,[d?{add:c}:{remove:c},e,f,g]):this._toggleClass(c,d):a.effects.animateClass.apply(this,[{toggle:c},d,e,f])},switchClass:function(b,c,d,e,f){return a.effects.animateClass.apply(this,[{add:c,remove:b},d,e,f])}}),a.extend(a.effects,{version:"1.8.23",save:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.data("ec.storage."+b[c],a[0].style[b[c]])},restore:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.css(b[c],a.data("ec.storage."+b[c]))},setMode:function(a,b){return b=="toggle"&&(b=a.is(":hidden")?"show":"hide"),b},getBaseline:function(a,b){var c,d;switch(a[0]){case"top":c=0;break;case"middle":c=.5;break;case"bottom":c=1;break;default:c=a[0]/b.height}switch(a[1]){case"left":d=0;break;case"center":d=.5;break;case"right":d=1;break;default:d=a[1]/b.width}return{x:d,y:c}},createWrapper:function(b){if(b.parent().is(".ui-effects-wrapper"))return b.parent();var c={width:b.outerWidth(!0),height:b.outerHeight(!0),"float":b.css("float")},d=a("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e=document.activeElement;try{e.id}catch(f){e=document.body}return b.wrap(d),(b[0]===e||a.contains(b[0],e))&&a(e).focus(),d=b.parent(),b.css("position")=="static"?(d.css({position:"relative"}),b.css({position:"relative"})):(a.extend(c,{position:b.css("position"),zIndex:b.css("z-index")}),a.each(["top","left","bottom","right"],function(a,d){c[d]=b.css(d),isNaN(parseInt(c[d],10))&&(c[d]="auto")}),b.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),d.css(c).show()},removeWrapper:function(b){var c,d=document.activeElement;return b.parent().is(".ui-effects-wrapper")?(c=b.parent().replaceWith(b),(b[0]===d||a.contains(b[0],d))&&a(d).focus(),c):b},setTransition:function(b,c,d,e){return e=e||{},a.each(c,function(a,c){var f=b.cssUnit(c);f[0]>0&&(e[c]=f[0]*d+f[1])}),e}}),a.fn.extend({effect:function(b,c,d,e){var f=k.apply(this,arguments),g={options:f[1],duration:f[2],callback:f[3]},h=g.options.mode,i=a.effects[b];return a.fx.off||!i?h?this[h](g.duration,g.callback):this.each(function(){g.callback&&g.callback.call(this)}):i.call(this,g)},_show:a.fn.show,show:function(a){if(l(a))return this._show.apply(this,arguments);var b=k.apply(this,arguments);return b[1].mode="show",this.effect.apply(this,b)},_hide:a.fn.hide,hide:function(a){if(l(a))return this._hide.apply(this,arguments);var b=k.apply(this,arguments);return b[1].mode="hide",this.effect.apply(this,b)},__toggle:a.fn.toggle,toggle:function(b){if(l(b)||typeof b=="boolean"||a.isFunction(b))return this.__toggle.apply(this,arguments);var c=k.apply(this,arguments);return c[1].mode="toggle",this.effect.apply(this,c)},cssUnit:function(b){var c=this.css(b),d=[];return a.each(["em","px","%","pt"],function(a,b){c.indexOf(b)>0&&(d=[parseFloat(c),b])}),d}});var m={};a.each(["Quad","Cubic","Quart","Quint","Expo"],function(a,b){m[b]=function(b){return Math.pow(b,a+2)}}),a.extend(m,{Sine:function(a){return 1-Math.cos(a*Math.PI/2)},Circ:function(a){return 1-Math.sqrt(1-a*a)},Elastic:function(a){return a===0||a===1?a:-Math.pow(2,8*(a-1))*Math.sin(((a-1)*80-7.5)*Math.PI/15)},Back:function(a){return a*a*(3*a-2)},Bounce:function(a){var b,c=4;while(a<((b=Math.pow(2,--c))-1)/11);return 1/Math.pow(4,3-c)-7.5625*Math.pow((b*3-2)/22-a,2)}}),a.each(m,function(b,c){a.easing["easeIn"+b]=c,a.easing["easeOut"+b]=function(a){return 1-c(1-a)},a.easing["easeInOut"+b]=function(a){return a<.5?c(a*2)/2:c(a*-2+2)/-2+1}})}(jQuery),function(a,b){a.effects.blind=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=f=="vertical"?"height":"width",i=f=="vertical"?g.height():g.width();e=="show"&&g.css(h,0);var j={};j[h]=e=="show"?i:0,g.animate(j,b.duration,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}}(jQuery),function(a,b){a.effects.bounce=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"up",g=b.options.distance||20,h=b.options.times||5,i=b.duration||250;/show|hide/.test(e)&&d.push("opacity"),a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",g=b.options.distance||(j=="top"?c.outerHeight(!0)/3:c.outerWidth(!0)/3);e=="show"&&c.css("opacity",0).css(j,k=="pos"?-g:g),e=="hide"&&(g=g/(h*2)),e!="hide"&&h--;if(e=="show"){var l={opacity:1};l[j]=(k=="pos"?"+=":"-=")+g,c.animate(l,i/2,b.options.easing),g=g/2,h--}for(var m=0;m<h;m++){var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing),g=e=="hide"?g*2:g/2}if(e=="hide"){var l={opacity:0};l[j]=(k=="pos"?"-=":"+=")+g,c.animate(l,i/2,b.options.easing,function(){c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}else{var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}c.queue("fx",function(){c.dequeue()}),c.dequeue()})}}(jQuery),function(a,b){a.effects.clip=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","height","width"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=c[0].tagName=="IMG"?g:c,i={size:f=="vertical"?"height":"width",position:f=="vertical"?"top":"left"},j=f=="vertical"?h.height():h.width();e=="show"&&(h.css(i.size,0),h.css(i.position,j/2));var k={};k[i.size]=e=="show"?j:0,k[i.position]=e=="show"?0:j/2,h.animate(k,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.drop=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","opacity"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight(!0)/2:c.outerWidth(!0)/2);e=="show"&&c.css("opacity",0).css(g,h=="pos"?-i:i);var j={opacity:e=="show"?1:0};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.explode=function(b){return this.queue(function(){var c=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3,d=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;b.options.mode=b.options.mode=="toggle"?a(this).is(":visible")?"hide":"show":b.options.mode;var e=a(this).show().css("visibility","hidden"),f=e.offset();f.top-=parseInt(e.css("marginTop"),10)||0,f.left-=parseInt(e.css("marginLeft"),10)||0;var g=e.outerWidth(!0),h=e.outerHeight(!0);for(var i=0;i<c;i++)for(var j=0;j<d;j++)e.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-j*(g/d),top:-i*(h/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/d,height:h/c,left:f.left+j*(g/d)+(b.options.mode=="show"?(j-Math.floor(d/2))*(g/d):0),top:f.top+i*(h/c)+(b.options.mode=="show"?(i-Math.floor(c/2))*(h/c):0),opacity:b.options.mode=="show"?0:1}).animate({left:f.left+j*(g/d)+(b.options.mode=="show"?0:(j-Math.floor(d/2))*(g/d)),top:f.top+i*(h/c)+(b.options.mode=="show"?0:(i-Math.floor(c/2))*(h/c)),opacity:b.options.mode=="show"?1:0},b.duration||500);setTimeout(function(){b.options.mode=="show"?e.css({visibility:"visible"}):e.css({visibility:"visible"}).hide(),b.callback&&b.callback.apply(e[0]),e.dequeue(),a("div.ui-effects-explode").remove()},b.duration||500)})}}(jQuery),function(a,b){a.effects.fade=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide");c.animate({opacity:d},{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.fold=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.size||15,g=!!b.options.horizFirst,h=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(c,d),c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"}),j=e=="show"!=g,k=j?["width","height"]:["height","width"],l=j?[i.width(),i.height()]:[i.height(),i.width()],m=/([0-9]+)%/.exec(f);m&&(f=parseInt(m[1],10)/100*l[e=="hide"?0:1]),e=="show"&&i.css(g?{height:0,width:f}:{height:f,width:0});var n={},p={};n[k[0]]=e=="show"?l[0]:f,p[k[1]]=e=="show"?l[1]:0,i.animate(n,h,b.options.easing).animate(p,h,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}}(jQuery),function(a,b){a.effects.highlight=function(b){return this.queue(function(){var c=a(this),d=["backgroundImage","backgroundColor","opacity"],e=a.effects.setMode(c,b.options.mode||"show"),f={backgroundColor:c.css("backgroundColor")};e=="hide"&&(f.opacity=0),a.effects.save(c,d),c.show().css({backgroundImage:"none",backgroundColor:b.options.color||"#ffff99"}).animate(f,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),e=="show"&&!a.support.opacity&&this.style.removeAttribute("filter"),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.pulsate=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"show"),e=(b.options.times||5)*2-1,f=b.duration?b.duration/2:a.fx.speeds._default/2,g=c.is(":visible"),h=0;g||(c.css("opacity",0).show(),h=1),(d=="hide"&&g||d=="show"&&!g)&&e--;for(var i=0;i<e;i++)c.animate({opacity:h},f,b.options.easing),h=(h+1)%2;c.animate({opacity:h},f,b.options.easing,function(){h==0&&c.hide(),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}).dequeue()})}}(jQuery),function(a,b){a.effects.puff=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide"),e=parseInt(b.options.percent,10)||150,f=e/100,g={height:c.height(),width:c.width()};a.extend(b.options,{fade:!0,mode:d,percent:d=="hide"?e:100,from:d=="hide"?g:{height:g.height*f,width:g.width*f}}),c.effect("scale",b.options,b.duration,b.callback),c.dequeue()})},a.effects.scale=function(b){return this.queue(function(){var c=a(this),d=a.extend(!0,{},b.options),e=a.effects.setMode(c,b.options.mode||"effect"),f=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:e=="hide"?0:100),g=b.options.direction||"both",h=b.options.origin;e!="effect"&&(d.origin=h||["middle","center"],d.restore=!0);var i={height:c.height(),width:c.width()};c.from=b.options.from||(e=="show"?{height:0,width:0}:i);var j={y:g!="horizontal"?f/100:1,x:g!="vertical"?f/100:1};c.to={height:i.height*j.y,width:i.width*j.x},b.options.fade&&(e=="show"&&(c.from.opacity=0,c.to.opacity=1),e=="hide"&&(c.from.opacity=1,c.to.opacity=0)),d.from=c.from,d.to=c.to,d.mode=e,c.effect("size",d,b.duration,b.callback),c.dequeue()})},a.effects.size=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","width","height","overflow","opacity"],e=["position","top","bottom","left","right","overflow","opacity"],f=["width","height","overflow"],g=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],i=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],j=a.effects.setMode(c,b.options.mode||"effect"),k=b.options.restore||!1,l=b.options.scale||"both",m=b.options.origin,n={height:c.height(),width:c.width()};c.from=b.options.from||n,c.to=b.options.to||n;if(m){var p=a.effects.getBaseline(m,n);c.from.top=(n.height-c.from.height)*p.y,c.from.left=(n.width-c.from.width)*p.x,c.to.top=(n.height-c.to.height)*p.y,c.to.left=(n.width-c.to.width)*p.x}var q={from:{y:c.from.height/n.height,x:c.from.width/n.width},to:{y:c.to.height/n.height,x:c.to.width/n.width}};if(l=="box"||l=="both")q.from.y!=q.to.y&&(d=d.concat(h),c.from=a.effects.setTransition(c,h,q.from.y,c.from),c.to=a.effects.setTransition(c,h,q.to.y,c.to)),q.from.x!=q.to.x&&(d=d.concat(i),c.from=a.effects.setTransition(c,i,q.from.x,c.from),c.to=a.effects.setTransition(c,i,q.to.x,c.to));(l=="content"||l=="both")&&q.from.y!=q.to.y&&(d=d.concat(g),c.from=a.effects.setTransition(c,g,q.from.y,c.from),c.to=a.effects.setTransition(c,g,q.to.y,c.to)),a.effects.save(c,k?d:e),c.show(),a.effects.createWrapper(c),c.css("overflow","hidden").css(c.from);if(l=="content"||l=="both")h=h.concat(["marginTop","marginBottom"]).concat(g),i=i.concat(["marginLeft","marginRight"]),f=d.concat(h).concat(i),c.find("*[width]").each(function(){var c=a(this);k&&a.effects.save(c,f);var d={height:c.height(),width:c.width()};c.from={height:d.height*q.from.y,width:d.width*q.from.x},c.to={height:d.height*q.to.y,width:d.width*q.to.x},q.from.y!=q.to.y&&(c.from=a.effects.setTransition(c,h,q.from.y,c.from),c.to=a.effects.setTransition(c,h,q.to.y,c.to)),q.from.x!=q.to.x&&(c.from=a.effects.setTransition(c,i,q.from.x,c.from),c.to=a.effects.setTransition(c,i,q.to.x,c.to)),c.css(c.from),c.animate(c.to,b.duration,b.options.easing,function(){k&&a.effects.restore(c,f)})});c.animate(c.to,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){c.to.opacity===0&&c.css("opacity",c.from.opacity),j=="hide"&&c.hide(),a.effects.restore(c,k?d:e),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.shake=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"left",g=b.options.distance||20,h=b.options.times||3,i=b.duration||b.options.duration||140;a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",l={},m={},n={};l[j]=(k=="pos"?"-=":"+=")+g,m[j]=(k=="pos"?"+=":"-=")+g*2,n[j]=(k=="pos"?"-=":"+=")+g*2,c.animate(l,i,b.options.easing);for(var p=1;p<h;p++)c.animate(m,i,b.options.easing).animate(n,i,b.options.easing);c.animate(m,i,b.options.easing).animate(l,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}),c.dequeue()})}}(jQuery),function(a,b){a.effects.slide=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"show"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c).css({overflow:"hidden"});var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight(!0):c.outerWidth(!0));e=="show"&&c.css(g,h=="pos"?isNaN(i)?"-"+i:-i:i);var j={};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.transfer=function(b){return this.queue(function(){var c=a(this),d=a(b.options.to),e=d.offset(),f={top:e.top,left:e.left,height:d.innerHeight(),width:d.innerWidth()},g=c.offset(),h=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(f,b.duration,b.options.easing,function(){h.remove(),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}}(jQuery),function(a,b){a.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:!0,clearStyle:!1,collapsible:!1,event:"click",fillSpace:!1,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var b=this,c=b.options;b.running=0,b.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"),b.headers=b.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){if(c.disabled)return;a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){if(c.disabled)return;a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){if(c.disabled)return;a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){if(c.disabled)return;a(this).removeClass("ui-state-focus")}),b.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");if(c.navigation){var d=b.element.find("a").filter(c.navigationFilter).eq(0);if(d.length){var e=d.closest(".ui-accordion-header");e.length?b.active=e:b.active=d.closest(".ui-accordion-content").prev()}}b.active=b._findActive(b.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"),b.active.next().addClass("ui-accordion-content-active"),b._createIcons(),b.resize(),b.element.attr("role","tablist"),b.headers.attr("role","tab").bind("keydown.accordion",function(a){return b._keydown(a)}).next().attr("role","tabpanel"),b.headers.not(b.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide(),b.active.length?b.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):b.headers.eq(0).attr("tabIndex",0),a.browser.safari||b.headers.find("a").attr("tabIndex",-1),c.event&&b.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(a){b._clickHandler.call(b,a,this),a.preventDefault()})},_createIcons:function(){var b=this.options;b.icons&&(a("<span></span>").addClass("ui-icon "+b.icons.header).prependTo(this.headers),this.active.children(".ui-icon").toggleClass(b.icons.header).toggleClass(b.icons.headerSelected),this.element.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.children(".ui-icon").remove(),this.element.removeClass("ui-accordion-icons")},destroy:function(){var b=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.unbind(".accordion").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").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"),this.headers.find("a").removeAttr("tabIndex"),this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");return(b.autoHeight||b.fillHeight)&&c.css("height",""),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b=="active"&&this.activate(c),b=="icons"&&(this._destroyIcons(),c&&this._createIcons()),b=="disabled"&&this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(b){if(this.options.disabled||b.altKey||b.ctrlKey)return;var c=a.ui.keyCode,d=this.headers.length,e=this.headers.index(b.target),f=!1;switch(b.keyCode){case c.RIGHT:case c.DOWN:f=this.headers[(e+1)%d];break;case c.LEFT:case c.UP:f=this.headers[(e-1+d)%d];break;case c.SPACE:case c.ENTER:this._clickHandler({target:b.target},b.target),b.preventDefault()}return f?(a(b.target).attr("tabIndex",-1),a(f).attr("tabIndex",0),f.focus(),!1):!0},resize:function(){var b=this.options,c;if(b.fillSpace){if(a.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height(),a.browser.msie&&this.element.parent().css("overflow",d),this.headers.each(function(){c-=a(this).outerHeight(!0)}),this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")}else b.autoHeight&&(c=0,this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c));return this},activate:function(a){this.options.active=a;var b=this._findActive(a)[0];return this._clickHandler({target:b},b),this},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===!1?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,c){var d=this.options;if(d.disabled)return;if(!b.target){if(!d.collapsible)return;this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),this.active.next().addClass("ui-accordion-content-active");var e=this.active.next(),f={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:e},g=this.active=a([]);this._toggle(g,e,f);return}var h=a(b.currentTarget||c),i=h[0]===this.active[0];d.active=d.collapsible&&i?!1:this.headers.index(h);if(this.running||!d.collapsible&&i)return;var j=this.active,g=h.next(),e=this.active.next(),f={options:d,newHeader:i&&d.collapsible?a([]):h,oldHeader:this.active,newContent:i&&d.collapsible?a([]):g,oldContent:e},k=this.headers.index(this.active[0])>this.headers.index(h[0]);this.active=i?a([]):h,this._toggle(g,e,f,i,k),j.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),i||(h.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected),h.next().addClass("ui-accordion-content-active"));return},_toggle:function(b,c,d,e,f){var g=this,h=g.options;g.toShow=b,g.toHide=c,g.data=d;var i=function(){if(!g)return;return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data),g.running=c.size()===0?b.size():c.size();if(h.animated){var j={};h.collapsible&&e?j={toShow:a([]),toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace}:j={toShow:b,toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace},h.proxied||(h.proxied=h.animated),h.proxiedDuration||(h.proxiedDuration=h.duration),h.animated=a.isFunction(h.proxied)?h.proxied(j):h.proxied,h.duration=a.isFunction(h.proxiedDuration)?h.proxiedDuration(j):h.proxiedDuration;var k=a.ui.accordion.animations,l=h.duration,m=h.animated;m&&!k[m]&&!a.easing[m]&&(m="slide"),k[m]||(k[m]=function(a){this.slide(a,{easing:m,duration:l||700})}),k[m](j)}else h.collapsible&&e?b.toggle():(c.hide(),b.show()),i(!0);c.prev().attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).blur(),b.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(this.running)return;this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data)}}),a.extend(a.ui.accordion,{version:"1.8.23",animations:{slide:function(b,c){b=a.extend({easing:"swing",duration:300},b,c);if(!b.toHide.size()){b.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},b);return}if(!b.toShow.size()){b.toHide.animate({height:"hide",paddingTop:"hide",paddingBottom:"hide"},b);return}var d=b.toShow.css("overflow"),e=0,f={},g={},h=["height","paddingTop","paddingBottom"],i,j=b.toShow;i=j[0].style.width,j.width(j.parent().width()-parseFloat(j.css("paddingLeft"))-parseFloat(j.css("paddingRight"))-(parseFloat(j.css("borderLeftWidth"))||0)-(parseFloat(j.css("borderRightWidth"))||0)),a.each(h,function(c,d){g[d]="hide";var e=(""+a.css(b.toShow[0],d)).match(/^([\d+-.]+)(.*)$/);f[d]={value:e[1],unit:e[2]||"px"}}),b.toShow.css({height:0,overflow:"hidden"}).show(),b.toHide.filter(":hidden").each(b.complete).end().filter(":visible").animate(g,{step:function(a,c){c.prop=="height"&&(e=c.end-c.start===0?0:(c.now-c.start)/(c.end-c.start)),b.toShow[0].style[c.prop]=e*f[c.prop].value+f[c.prop].unit},duration:b.duration,easing:b.easing,complete:function(){b.autoHeight||b.toShow.css("height",""),b.toShow.css({width:i,overflow:d}),b.complete()}})},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1e3:200})}}})}(jQuery),function(a,b){var c=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var b=this,c=this.element[0].ownerDocument,d;this.isMultiLine=this.element.is("textarea"),this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(b.options.disabled||b.element.propAttr("readOnly"))return;d=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:b._move("previousPage",c);break;case e.PAGE_DOWN:b._move("nextPage",c);break;case e.UP:b._keyEvent("previous",c);break;case e.DOWN:b._keyEvent("next",c);break;case e.ENTER:case e.NUMPAD_ENTER:b.menu.active&&(d=!0,c.preventDefault());case e.TAB:if(!b.menu.active)return;b.menu.select(c);break;case e.ESCAPE:b.element.val(b.term),b.close(c);break;default:clearTimeout(b.searching),b.searching=setTimeout(function(){b.term!=b.element.val()&&(b.selectedItem=null,b.search(null,c))},b.options.delay)}}).bind("keypress.autocomplete",function(a){d&&(d=!1,a.preventDefault())}).bind("focus.autocomplete",function(){if(b.options.disabled)return;b.selectedItem=null,b.previous=b.element.val()}).bind("blur.autocomplete",function(a){if(b.options.disabled)return;clearTimeout(b.searching),b.closing=setTimeout(function(){b.close(a),b._change(a)},150)}),this._initSource(),this.menu=a("<ul></ul>").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",c)[0]).mousedown(function(c){var d=b.menu.element[0];a(c.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(c){c.target!==b.element[0]&&c.target!==d&&!a.ui.contains(d,c.target)&&b.close()})},1),setTimeout(function(){clearTimeout(b.closing)},13)}).menu({focus:function(a,c){var d=c.item.data("item.autocomplete");!1!==b._trigger("focus",a,{item:d})&&/^key/.test(a.originalEvent.type)&&b.element.val(d.value)},selected:function(a,d){var e=d.item.data("item.autocomplete"),f=b.previous;b.element[0]!==c.activeElement&&(b.element.focus(),b.previous=f,setTimeout(function(){b.previous=f,b.selectedItem=e},1)),!1!==b._trigger("select",a,{item:e})&&b.element.val(e.value),b.term=b.element.val(),b.close(a),b.selectedItem=e},blur:function(a,c){b.menu.element.is(":visible")&&b.element.val()!==b.term&&b.element.val(b.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"),a.fn.bgiframe&&this.menu.element.bgiframe(),b.beforeunloadHandler=function(){b.element.removeAttr("autocomplete")},a(window).bind("beforeunload",b.beforeunloadHandler)},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"),this.menu.element.remove(),a(window).unbind("beforeunload",this.beforeunloadHandler),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b==="source"&&this._initSource(),b==="appendTo"&&this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]),b==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var b=this,c,d;a.isArray(this.options.source)?(c=this.options.source,this.source=function(b,d){d(a.ui.autocomplete.filter(c,b.term))}):typeof this.options.source=="string"?(d=this.options.source,this.source=function(c,e){b.xhr&&b.xhr.abort(),b.xhr=a.ajax({url:d,data:c,dataType:"json",success:function(a,b){e(a)},error:function(){e([])}})}):this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val(),this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)===!1)return;return this._search(a)},_search:function(a){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.source({term:a},this._response())},_response:function(){var a=this,b=++c;return function(d){b===c&&a.__response(d),a.pending--,a.pending||a.element.removeClass("ui-autocomplete-loading")}},__response:function(a){!this.options.disabled&&a&&a.length?(a=this._normalize(a),this._suggest(a),this._trigger("open")):this.close()},close:function(a){clearTimeout(this.closing),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.deactivate(),this._trigger("close",a))},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(b){return b.length&&b[0].label&&b[0].value?b:a.map(b,function(b){return typeof b=="string"?{label:b,value:b}:a.extend({label:b.label||b.value,value:b.value||b.label},b)})},_suggest:function(b){var c=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(c,b),this.menu.deactivate(),this.menu.refresh(),c.show(),this._resizeMenu(),c.position(a.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(new a.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(b,c){var d=this;a.each(c,function(a,c){d._renderItem(b,c)})},_renderItem:function(b,c){return a("<li></li>").data("item.autocomplete",c).append(a("<a></a>").text(c.label)).appendTo(b)},_move:function(a,b){if(!this.menu.element.is(":visible")){this.search(null,b);return}if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term),this.menu.deactivate();return}this.menu[a](b)},widget:function(){return this.menu.element},_keyEvent:function(a,b){if(!this.isMultiLine||this.menu.element.is(":visible"))this._move(a,b),b.preventDefault()}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}})}(jQuery),function(a){a.widget("ui.menu",{_create:function(){var b=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){if(!a(c.target).closest(".ui-menu-item a").length)return;c.preventDefault(),b.select(c)}),this.refresh()},refresh:function(){var b=this,c=this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem");c.children("a").addClass("ui-corner-all").attr("tabindex",-1).mouseenter(function(c){b.activate(c,a(this).parent())}).mouseleave(function(){b.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.scrollTop(),e=this.element.height();c<0?this.element.scrollTop(d+c):c>=e&&this.element.scrollTop(d+c-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end(),this._trigger("focus",a,{item:b})},deactivate:function(){if(!this.active)return;this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(!this.active){this.activate(c,this.element.children(b));return}var d=this.active[a+"All"](".ui-menu-item").eq(0);d.length?this.activate(c,d):this.activate(c,this.element.children(b))},nextPage:function(b){if(this.hasScroll()){if(!this.active||this.last()){this.activate(b,this.element.children(".ui-menu-item:first"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c-d+a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:last")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(b){if(this.hasScroll()){if(!this.active||this.first()){this.activate(b,this.element.children(".ui-menu-item:last"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c+d-a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:first")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[a.fn.prop?"prop":"attr"]("scrollHeight")},select:function(a){this._trigger("selected",a,{item:this.active})}})}(jQuery),function(a,b){var c,d,e,f,g="ui-button ui-widget ui-state-default ui-corner-all",h="ui-state-hover ui-state-active ",i="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",j=function(){var b=a(this).find(":ui-button");setTimeout(function(){b.button("refresh")},1)},k=function(b){var c=b.name,d=b.form,e=a([]);return c&&(d?e=a(d).find("[name='"+c+"']"):e=a("[name='"+c+"']",b.ownerDocument).filter(function(){return!this.form})),e};a.widget("ui.button",{options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",j),typeof this.options.disabled!="boolean"?this.options.disabled=!!this.element.propAttr("disabled"):this.element.propAttr("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var b=this,h=this.options,i=this.type==="checkbox"||this.type==="radio",l="ui-state-hover"+(i?"":" ui-state-active"),m="ui-state-focus";h.label===null&&(h.label=this.buttonElement.html()),this.buttonElement.addClass(g).attr("role","button").bind("mouseenter.button",function(){if(h.disabled)return;a(this).addClass("ui-state-hover"),this===c&&a(this).addClass("ui-state-active")}).bind("mouseleave.button",function(){if(h.disabled)return;a(this).removeClass(l)}).bind("click.button",function(a){h.disabled&&(a.preventDefault(),a.stopImmediatePropagation())}),this.element.bind("focus.button",function(){b.buttonElement.addClass(m)}).bind("blur.button",function(){b.buttonElement.removeClass(m)}),i&&(this.element.bind("change.button",function(){if(f)return;b.refresh()}),this.buttonElement.bind("mousedown.button",function(a){if(h.disabled)return;f=!1,d=a.pageX,e=a.pageY}).bind("mouseup.button",function(a){if(h.disabled)return;if(d!==a.pageX||e!==a.pageY)f=!0})),this.type==="checkbox"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).toggleClass("ui-state-active"),b.buttonElement.attr("aria-pressed",b.element[0].checked)}):this.type==="radio"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).addClass("ui-state-active"),b.buttonElement.attr("aria-pressed","true");var c=b.element[0];k(c).not(c).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown.button",function(){if(h.disabled)return!1;a(this).addClass("ui-state-active"),c=this,a(document).one("mouseup",function(){c=null})}).bind("mouseup.button",function(){if(h.disabled)return!1;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(b){if(h.disabled)return!1;(b.keyCode==a.ui.keyCode.SPACE||b.keyCode==a.ui.keyCode.ENTER)&&a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(b){b.keyCode===a.ui.keyCode.SPACE&&a(this).click()})),this._setOption("disabled",h.disabled),this._resetButton()},_determineButtonType:function(){this.element.is(":checkbox")?this.type="checkbox":this.element.is(":radio")?this.type="radio":this.element.is("input")?this.type="input":this.type="button";if(this.type==="checkbox"||this.type==="radio"){var a=this.element.parents().filter(":last"),b="label[for='"+this.element.attr("id")+"']";this.buttonElement=a.find(b),this.buttonElement.length||(a=a.length?a.siblings():this.element.siblings(),this.buttonElement=a.filter(b),this.buttonElement.length||(this.buttonElement=a.find(b))),this.element.addClass("ui-helper-hidden-accessible");var c=this.element.is(":checked");c&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.attr("aria-pressed",c)}else this.buttonElement=this.element},widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(g+" "+h+" "+i).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title"),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments);if(b==="disabled"){c?this.element.propAttr("disabled",!0):this.element.propAttr("disabled",!1);return}this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b),this.type==="radio"?k(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):this.type==="checkbox"&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if(this.type==="input"){this.options.label&&this.element.val(this.options.label);return}var b=this.buttonElement.removeClass(i),c=a("<span></span>",this.element[0].ownerDocument).addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary,f=[];d.primary||d.secondary?(this.options.text&&f.push("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary")),d.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>"),d.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>"),this.options.text||(f.push(e?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||b.attr("title",c))):f.push("ui-button-text-only"),b.addClass(f.join(" "))}}),a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c),a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(b?"ui-corner-left":"ui-corner-right").end().end()},destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"),a.Widget.prototype.destroy.call(this)}})}(jQuery),function($,undefined){function Datepicker(){this.debug=!1,this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},$.extend(this._defaults,this.regional[""]),this.dpDiv=bindHover($('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function bindHover(a){var b="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return a.bind("mouseout",function(a){var c=$(a.target).closest(b);if(!c.length)return;c.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){var d=$(c.target).closest(b);if($.datepicker._isDisabledDatepicker(instActive.inline?a.parent()[0]:instActive.input[0])||!d.length)return;d.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),d.addClass("ui-state-hover"),d.hasClass("ui-datepicker-prev")&&d.addClass("ui-datepicker-prev-hover"),d.hasClass("ui-datepicker-next")&&d.addClass("ui-datepicker-next-hover")})}function extendRemove(a,b){$.extend(a,b);for(var c in b)if(b[c]==null||b[c]==undefined)a[c]=b[c];return a}function isArray(a){return a&&($.browser.safari&&typeof a=="object"&&a.length||a.constructor&&a.constructor.toString().match(/\Array\(\)/))}$.extend($.ui,{datepicker:{version:"1.8.23"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){return extendRemove(this._defaults,a||{}),this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(a,b){var c=a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:c,input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:b?bindHover($('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')):this.dpDiv}},_connectDatepicker:function(a,b){var c=$(a);b.append=$([]),b.trigger=$([]);if(c.hasClass(this.markerClassName))return;this._attachments(c,b),c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),this._autoSize(b),$.data(a,PROP_NAME,b),b.settings.disabled&&this._disableDatepicker(a)},_attachments:function(a,b){var c=this._get(b,"appendText"),d=this._get(b,"isRTL");b.append&&b.append.remove(),c&&(b.append=$('<span class="'+this._appendClass+'">'+c+"</span>"),a[d?"before":"after"](b.append)),a.unbind("focus",this._showDatepicker),b.trigger&&b.trigger.remove();var e=this._get(b,"showOn");(e=="focus"||e=="both")&&a.focus(this._showDatepicker);if(e=="button"||e=="both"){var f=this._get(b,"buttonText"),g=this._get(b,"buttonImage");b.trigger=$(this._get(b,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:g,alt:f,title:f}):$('<button type="button"></button>').addClass(this._triggerClass).html(g==""?f:$("<img/>").attr({src:g,alt:f,title:f}))),a[d?"before":"after"](b.trigger),b.trigger.click(function(){return $.datepicker._datepickerShowing&&$.datepicker._lastInput==a[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=a[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(a[0])):$.datepicker._showDatepicker(a[0]),!1})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var d=function(a){var b=0,c=0;for(var d=0;d<a.length;d++)a[d].length>b&&(b=a[d].length,c=d);return c};b.setMonth(d(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort"))),b.setDate(d(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=$(a);if(c.hasClass(this.markerClassName))return;c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),$.data(a,PROP_NAME,b),this._setDate(b,this._getDefaultDate(b),!0),this._updateDatepicker(b),this._updateAlternate(b),b.settings.disabled&&this._disableDatepicker(a),b.dpDiv.css("display","block")},_dialogDatepicker:function(a,b,c,d,e){var f=this._dialogInst;if(!f){this.uuid+=1;var g="dp"+this.uuid;this._dialogInput=$('<input type="text" id="'+g+'" style="position: absolute; top: -100px; width: 0px;"/>'),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),f=this._dialogInst=this._newInst(this._dialogInput,!1),f.settings={},$.data(this._dialogInput[0],PROP_NAME,f)}extendRemove(f.settings,d||{}),b=b&&b.constructor==Date?this._formatDate(f,b):b,this._dialogInput.val(b),this._pos=e?e.length?e:[e.pageX,e.pageY]:null;if(!this._pos){var h=document.documentElement.clientWidth,i=document.documentElement.clientHeight,j=document.documentElement.scrollLeft||document.body.scrollLeft,k=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[h/2-100+j,i/2-150+k]}return this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),f.settings.onSelect=c,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,f),this},_destroyDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!b.hasClass(this.markerClassName))return;var d=a.nodeName.toLowerCase();$.removeData(a,PROP_NAME),d=="input"?(c.append.remove(),c.trigger.remove(),b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(d=="div"||d=="span")&&b.removeClass(this.markerClassName).empty()},_enableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!b.hasClass(this.markerClassName))return;var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!1,c.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().removeClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b})},_disableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!b.hasClass(this.markerClassName))return;var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!0,c.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().addClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b}),this._disabledInputs[this._disabledInputs.length]=a},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return!0;return!1},_getInst:function(a){try{return $.data(a,PROP_NAME)}catch(b){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(a,b,c){var d=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?$.extend({},$.datepicker._defaults):d?b=="all"?$.extend({},d.settings):this._get(d,b):null;var e=b||{};typeof b=="string"&&(e={},e[b]=c);if(d){this._curInst==d&&this._hideDatepicker();var f=this._getDateDatepicker(a,!0),g=this._getMinMaxDate(d,"min"),h=this._getMinMaxDate(d,"max");extendRemove(d.settings,e),g!==null&&e.dateFormat!==undefined&&e.minDate===undefined&&(d.settings.minDate=this._formatDate(d,g)),h!==null&&e.dateFormat!==undefined&&e.maxDate===undefined&&(d.settings.maxDate=this._formatDate(d,h)),this._attachments($(a),d),this._autoSize(d),this._setDate(d,f),this._updateAlternate(d),this._updateDatepicker(d)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){var b=this._getInst(a);b&&this._updateDatepicker(b)},_setDateDatepicker:function(a,b){var c=this._getInst(a);c&&(this._setDate(c,b),this._updateDatepicker(c),this._updateAlternate(c))},_getDateDatepicker:function(a,b){var c=this._getInst(a);return c&&!c.inline&&this._setDateFromField(c,b),c?this._getDate(c):null},_doKeyDown:function(a){var b=$.datepicker._getInst(a.target),c=!0,d=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=!0;if($.datepicker._datepickerShowing)switch(a.keyCode){case 9:$.datepicker._hideDatepicker(),c=!1;break;case 13:var e=$("td."+$.datepicker._dayOverClass+":not(."+$.datepicker._currentClass+")",b.dpDiv);e[0]&&$.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,e[0]);var f=$.datepicker._get(b,"onSelect");if(f){var g=$.datepicker._formatDate(b);f.apply(b.input?b.input[0]:null,[g,b])}else $.datepicker._hideDatepicker();return!1;case 27:$.datepicker._hideDatepicker();break;case 33:$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 34:$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 35:(a.ctrlKey||a.metaKey)&&$.datepicker._clearDate(a.target),c=a.ctrlKey||a.metaKey;break;case 36:(a.ctrlKey||a.metaKey)&&$.datepicker._gotoToday(a.target),c=a.ctrlKey||a.metaKey;break;case 37:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?1:-1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 38:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,-7,"D"),c=a.ctrlKey||a.metaKey;break;case 39:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?-1:1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 40:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,7,"D"),c=a.ctrlKey||a.metaKey;break;default:c=!1}else a.keyCode==36&&a.ctrlKey?$.datepicker._showDatepicker(this):c=!1;c&&(a.preventDefault(),a.stopPropagation())},_doKeyPress:function(a){var b=$.datepicker._getInst(a.target);if($.datepicker._get(b,"constrainInput")){var c=$.datepicker._possibleChars($.datepicker._get(b,"dateFormat")),d=String.fromCharCode(a.charCode==undefined?a.keyCode:a.charCode);return a.ctrlKey||a.metaKey||d<" "||!c||c.indexOf(d)>-1}},_doKeyUp:function(a){var b=$.datepicker._getInst(a.target);if(b.input.val()!=b.lastVal)try{var c=$.datepicker.parseDate($.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,$.datepicker._getFormatConfig(b));c&&($.datepicker._setDateFromField(b),$.datepicker._updateAlternate(b),$.datepicker._updateDatepicker(b))}catch(d){$.datepicker.log(d)}return!0},_showDatepicker:function(a){a=a.target||a,a.nodeName.toLowerCase()!="input"&&(a=$("input",a.parentNode)[0]);if($.datepicker._isDisabledDatepicker(a)||$.datepicker._lastInput==a)return;var b=$.datepicker._getInst(a);$.datepicker._curInst&&$.datepicker._curInst!=b&&($.datepicker._curInst.dpDiv.stop(!0,!0),b&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var c=$.datepicker._get(b,"beforeShow"),d=c?c.apply(a,[a,b]):{};if(d===!1)return;extendRemove(b.settings,d),b.lastVal=null,$.datepicker._lastInput=a,$.datepicker._setDateFromField(b),$.datepicker._inDialog&&(a.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(a),$.datepicker._pos[1]+=a.offsetHeight);var e=!1;$(a).parents().each(function(){return e|=$(this).css("position")=="fixed",!e}),e&&$.browser.opera&&($.datepicker._pos[0]-=document.documentElement.scrollLeft,$.datepicker._pos[1]-=document.documentElement.scrollTop);var f={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,b.dpDiv.empty(),b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(b),f=$.datepicker._checkOffset(b,f,e),b.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":e?"fixed":"absolute",display:"none",left:f.left+"px",top:f.top+"px"});if(!b.inline){var g=$.datepicker._get(b,"showAnim"),h=$.datepicker._get(b,"duration"),i=function(){var a=b.dpDiv.find("iframe.ui-datepicker-cover");if(!!a.length){var c=$.datepicker._getBorders(b.dpDiv);a.css({left:-c[0],top:-c[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex($(a).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&$.effects[g]?b.dpDiv.show(g,$.datepicker._get(b,"showOptions"),h,i):b.dpDiv[g||"show"](g?h:null,i),(!g||!h)&&i(),b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus(),$.datepicker._curInst=b}},_updateDatepicker:function(a){var b=this;b.maxRows=4;var c=$.datepicker._getBorders(a.dpDiv);instActive=a,a.dpDiv.empty().append(this._generateHTML(a)),this._attachHandlers(a);var d=a.dpDiv.find("iframe.ui-datepicker-cover");!d.length||d.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}),a.dpDiv.find("."+this._dayOverClass+" a").mouseover();var e=this._getNumberOfMonths(a),f=e[1],g=17;a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),f>1&&a.dpDiv.addClass("ui-datepicker-multi-"+f).css("width",g*f+"em"),a.dpDiv[(e[0]!=1||e[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),a==$.datepicker._curInst&&$.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var h=a.yearshtml;setTimeout(function(){h===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml),h=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var d=a.dpDiv.outerWidth(),e=a.dpDiv.outerHeight(),f=a.input?a.input.outerWidth():0,g=a.input?a.input.outerHeight():0,h=document.documentElement.clientWidth+(c?0:$(document).scrollLeft()),i=document.documentElement.clientHeight+(c?0:$(document).scrollTop());return b.left-=this._get(a,"isRTL")?d-f:0,b.left-=c&&b.left==a.input.offset().left?$(document).scrollLeft():0,b.top-=c&&b.top==a.input.offset().top+g?$(document).scrollTop():0,b.left-=Math.min(b.left,b.left+d>h&&h>d?Math.abs(b.left+d-h):0),b.top-=Math.min(b.top,b.top+e>i&&i>e?Math.abs(e+g):0),b},_findPos:function(a){var b=this._getInst(a),c=this._get(b,"isRTL");while(a&&(a.type=="hidden"||a.nodeType!=1||$.expr.filters.hidden(a)))a=a[c?"previousSibling":"nextSibling"];var d=$(a).offset();return[d.left,d.top]},_hideDatepicker:function(a){var b=this._curInst;if(!b||a&&b!=$.data(a,PROP_NAME))return;if(this._datepickerShowing){var c=this._get(b,"showAnim"),d=this._get(b,"duration"),e=function(){$.datepicker._tidyDialog(b)};$.effects&&$.effects[c]?b.dpDiv.hide(c,$.datepicker._get(b,"showOptions"),d,e):b.dpDiv[c=="slideDown"?"slideUp":c=="fadeIn"?"fadeOut":"hide"](c?d:null,e),c||e(),this._datepickerShowing=!1;var f=this._get(b,"onClose");f&&f.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(!$.datepicker._curInst)return;var b=$(a.target),c=$.datepicker._getInst(b[0]);(b[0].id!=$.datepicker._mainDivId&&b.parents("#"+$.datepicker._mainDivId).length==0&&!b.hasClass($.datepicker.markerClassName)&&!b.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||b.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=c)&&$.datepicker._hideDatepicker()},_adjustDate:function(a,b,c){var d=$(a),e=this._getInst(d[0]);if(this._isDisabledDatepicker(d[0]))return;this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c),this._updateDatepicker(e)},_gotoToday:function(a){var b=$(a),c=this._getInst(b[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate(),c.drawMonth=c.selectedMonth=d.getMonth(),c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c),this._adjustDate(b)},_selectMonthYear:function(a,b,c){var d=$(a),e=this._getInst(d[0]);e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10),this._notifyChange(e),this._adjustDate(d)},_selectDay:function(a,b,c,d){var e=$(a);if($(d).hasClass(this._unselectableClass)||this._isDisabledDatepicker(e[0]))return;var f=this._getInst(e[0]);f.selectedDay=f.currentDay=$("a",d).html(),f.selectedMonth=f.currentMonth=b,f.selectedYear=f.currentYear=c,this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))},_clearDate:function(a){var b=$(a),c=this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(a,b){var c=$(a),d=this._getInst(c[0]);b=b!=null?b:this._formatDate(d),d.input&&d.input.val(b),this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[b,d]):d.input&&d.input.trigger("change"),d.inline?this._updateDatepicker(d):(this._hideDatepicker(),this._lastInput=d.input[0],typeof d.input[0]!="object"&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),d=this._getDate(a),e=this.formatDate(c,d,this._getFormatConfig(a));$(b).each(function(){$(this).val(e)})}},noWeekends:function(a){var b=a.getDay();return[b>0&&b<6,""]},iso8601Week:function(a){var b=new Date(a.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();return b.setMonth(0),b.setDate(1),Math.floor(Math.round((c-b)/864e5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var d=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;d=typeof d!="string"?d:(new Date).getFullYear()%100+parseInt(d,10);var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=-1,j=-1,k=-1,l=-1,m=!1,n=function(b){var c=s+1<a.length&&a.charAt(s+1)==b;return c&&s++,c},o=function(a){var c=n(a),d=a=="@"?14:a=="!"?20:a=="y"&&c?4:a=="o"?3:2,e=new RegExp("^\\d{1,"+d+"}"),f=b.substring(r).match(e);if(!f)throw"Missing number at position "+r;return r+=f[0].length,parseInt(f[0],10)},p=function(a,c,d){var e=$.map(n(a)?d:c,function(a,b){return[[b,a]]}).sort(function(a,b){return-(a[1].length-b[1].length)}),f=-1;$.each(e,function(a,c){var d=c[1];if(b.substr(r,d.length).toLowerCase()==d.toLowerCase())return f=c[0],r+=d.length,!1});if(f!=-1)return f+1;throw"Unknown name at position "+r},q=function(){if(b.charAt(r)!=a.charAt(s))throw"Unexpected literal at position "+r;r++},r=0;for(var s=0;s<a.length;s++)if(m)a.charAt(s)=="'"&&!n("'")?m=!1:q();else switch(a.charAt(s)){case"d":k=o("d");break;case"D":p("D",e,f);break;case"o":l=o("o");break;case"m":j=o("m");break;case"M":j=p("M",g,h);break;case"y":i=o("y");break;case"@":var t=new Date(o("@"));i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"!":var t=new Date((o("!")-this._ticksTo1970)/1e4);i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"'":n("'")?q():m=!0;break;default:q()}if(r<b.length)throw"Extra/unparsed characters found in date: "+b.substring(r);i==-1?i=(new Date).getFullYear():i<100&&(i+=(new Date).getFullYear()-(new Date).getFullYear()%100+(i<=d?0:-100));if(l>-1){j=1,k=l;do{var u=this._getDaysInMonth(i,j-1);if(k<=u)break;j++,k-=u}while(!0)}var t=this._daylightSavingAdjust(new Date(i,j-1,k));if(t.getFullYear()!=i||t.getMonth()+1!=j||t.getDate()!=k)throw"Invalid date";return t},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,e=(c?c.dayNames:null)||this._defaults.dayNames,f=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,h=function(b){var c=m+1<a.length&&a.charAt(m+1)==b;return c&&m++,c},i=function(a,b,c){var d=""+b;if(h(a))while(d.length<c)d="0"+d;return d},j=function(a,b,c,d){return h(a)?d[b]:c[b]},k="",l=!1;if(b)for(var m=0;m<a.length;m++)if(l)a.charAt(m)=="'"&&!h("'")?l=!1:k+=a.charAt(m);else switch(a.charAt(m)){case"d":k+=i("d",b.getDate(),2);break;case"D":k+=j("D",b.getDay(),d,e);break;case"o":k+=i("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864e5),3);break;case"m":k+=i("m",b.getMonth()+1,2);break;case"M":k+=j("M",b.getMonth(),f,g);break;case"y":k+=h("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case"@":k+=b.getTime();break;case"!":k+=b.getTime()*1e4+this._ticksTo1970;break;case"'":h("'")?k+="'":l=!0;break;default:k+=a.charAt(m)}return k},_possibleChars:function(a){var b="",c=!1,d=function(b){var c=e+1<a.length&&a.charAt(e+1)==b;return c&&e++,c};for(var e=0;e<a.length;e++)if(c)a.charAt(e)=="'"&&!d("'")?c=!1:b+=a.charAt(e);else switch(a.charAt(e)){case"d":case"m":case"y":case"@":b+="0123456789";break;case"D":case"M":return null;case"'":d("'")?b+="'":c=!0;break;default:b+=a.charAt(e)}return b},_get:function(a,b){return a.settings[b]!==undefined?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()==a.lastVal)return;var c=this._get(a,"dateFormat"),d=a.lastVal=a.input?a.input.val():null,e,f;e=f=this._getDefaultDate(a);var g=this._getFormatConfig(a);try{e=this.parseDate(c,d,g)||f}catch(h){this.log(h),d=b?"":d}a.selectedDay=e.getDate(),a.drawMonth=a.selectedMonth=e.getMonth(),a.drawYear=a.selectedYear=e.getFullYear(),a.currentDay=d?e.getDate():0,a.currentMonth=d?e.getMonth():0,a.currentYear=d?e.getFullYear():0,this._adjustInstDate(a)},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var d=function(a){var b=new Date;return b.setDate(b.getDate()+a),b},e=function(b){try{return $.datepicker.parseDate($.datepicker._get(a,"dateFormat"),b,$.datepicker._getFormatConfig(a))}catch(c){}var d=(b.toLowerCase().match(/^c/)?$.datepicker._getDate(a):null)||new Date,e=d.getFullYear(),f=d.getMonth(),g=d.getDate(),h=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,i=h.exec(b);while(i){switch(i[2]||"d"){case"d":case"D":g+=parseInt(i[1],10);break;case"w":case"W":g+=parseInt(i[1],10)*7;break;case"m":case"M":f+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f));break;case"y":case"Y":e+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f))}i=h.exec(b)}return new Date(e,f,g)},f=b==null||b===""?c:typeof b=="string"?e(b):typeof b=="number"?isNaN(b)?c:d(b):new Date(b.getTime());return f=f&&f.toString()=="Invalid Date"?c:f,f&&(f.setHours(0),f.setMinutes(0),f.setSeconds(0),f.setMilliseconds(0)),this._daylightSavingAdjust(f)},_daylightSavingAdjust:function(a){return a?(a.setHours(a.getHours()>12?a.getHours()+2:0),a):null},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),(e!=a.selectedMonth||f!=a.selectedYear)&&!c&&this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_attachHandlers:function(a){var b=this._get(a,"stepMonths"),c="#"+a.id.replace(/\\\\/g,"\\");a.dpDiv.find("[data-handler]").map(function(){var a={prev:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(c,-b,"M")},next:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(c,+b,"M")},hide:function(){window["DP_jQuery_"+dpuuid].datepicker._hideDatepicker()},today:function(){window["DP_jQuery_"+dpuuid].datepicker._gotoToday(c)},selectDay:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectDay(c,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(c,this,"M"),!1},selectYear:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(c,this,"Y"),!1}};$(this).bind(this.getAttribute("data-event"),a[this.getAttribute("data-handler")])})},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),d=this._get(a,"showButtonPanel"),e=this._get(a,"hideIfNoPrevNext"),f=this._get(a,"navigationAsDateFormat"),g=this._getNumberOfMonths(a),h=this._get(a,"showCurrentAtPos"),i=this._get(a,"stepMonths"),j=g[0]!=1||g[1]!=1,k=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),l=this._getMinMaxDate(a,"min"),m=this._getMinMaxDate(a,"max"),n=a.drawMonth-h,o=a.drawYear;n<0&&(n+=12,o--);if(m){var p=this._daylightSavingAdjust(new Date(m.getFullYear(),m.getMonth()-g[0]*g[1]+1,m.getDate()));p=l&&p<l?l:p;while(this._daylightSavingAdjust(new Date(o,n,1))>p)n--,n<0&&(n=11,o--)}a.drawMonth=n,a.drawYear=o;var q=this._get(a,"prevText");q=f?this.formatDate(q,this._daylightSavingAdjust(new Date(o,n-i,1)),this._getFormatConfig(a)):q;var r=this._canAdjustMonth(a,-1,o,n)?'<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click" title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>":e?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>",s=this._get(a,"nextText");s=f?this.formatDate(s,this._daylightSavingAdjust(new Date(o,n+i,1)),this._getFormatConfig(a)):s;var t=this._canAdjustMonth(a,1,o,n)?'<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>":e?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>",u=this._get(a,"currentText"),v=this._get(a,"gotoCurrent")&&a.currentDay?k:b;u=f?this.formatDate(u,v,this._getFormatConfig(a)):u;var w=a.inline?"":'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">'+this._get(a,"closeText")+"</button>",x=d?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?w:"")+(this._isInRange(a,v)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click">'+u+"</button>":"")+(c?"":w)+"</div>":"",y=parseInt(this._get(a,"firstDay"),10);y=isNaN(y)?0:y;var z=this._get(a,"showWeek"),A=this._get(a,"dayNames"),B=this._get(a,"dayNamesShort"),C=this._get(a,"dayNamesMin"),D=this._get(a,"monthNames"),E=this._get(a,"monthNamesShort"),F=this._get(a,"beforeShowDay"),G=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths"),I=this._get(a,"calculateWeek")||this.iso8601Week,J=this._getDefaultDate(a),K="";for(var L=0;L<g[0];L++){var M="";this.maxRows=4;for(var N=0;N<g[1];N++){var O=this._daylightSavingAdjust(new Date(o,n,a.selectedDay)),P=" ui-corner-all",Q="";if(j){Q+='<div class="ui-datepicker-group';if(g[1]>1)switch(N){case 0:Q+=" ui-datepicker-group-first",P=" ui-corner-"+(c?"right":"left");break;case g[1]-1:Q+=" ui-datepicker-group-last",P=" ui-corner-"+(c?"left":"right");break;default:Q+=" ui-datepicker-group-middle",P=""}Q+='">'}Q+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+P+'">'+(/all|left/.test(P)&&L==0?c?t:r:"")+(/all|right/.test(P)&&L==0?c?r:t:"")+this._generateMonthYearHeader(a,n,o,l,m,L>0||N>0,D,E)+'</div><table class="ui-datepicker-calendar"><thead>'+"<tr>";var R=z?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(var S=0;S<7;S++){var T=(S+y)%7;R+="<th"+((S+y+6)%7>=5?' class="ui-datepicker-week-end"':"")+">"+'<span title="'+A[T]+'">'+C[T]+"</span></th>"}Q+=R+"</tr></thead><tbody>";var U=this._getDaysInMonth(o,n);o==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,U));var V=(this._getFirstDayOfMonth(o,n)-y+7)%7,W=Math.ceil((V+U)/7),X=j?this.maxRows>W?this.maxRows:W:W;this.maxRows=X;var Y=this._daylightSavingAdjust(new Date(o,n,1-V));for(var Z=0;Z<X;Z++){Q+="<tr>";var _=z?'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(Y)+"</td>":"";for(var S=0;S<7;S++){var ba=F?F.apply(a.input?a.input[0]:null,[Y]):[!0,""],bb=Y.getMonth()!=n,bc=bb&&!H||!ba[0]||l&&Y<l||m&&Y>m;_+='<td class="'+((S+y+6)%7>=5?" ui-datepicker-week-end":"")+(bb?" ui-datepicker-other-month":"")+(Y.getTime()==O.getTime()&&n==a.selectedMonth&&a._keyEvent||J.getTime()==Y.getTime()&&J.getTime()==O.getTime()?" "+this._dayOverClass:"")+(bc?" "+this._unselectableClass+" ui-state-disabled":"")+(bb&&!G?"":" "+ba[1]+(Y.getTime()==k.getTime()?" "+this._currentClass:"")+(Y.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!bb||G)&&ba[2]?' title="'+ba[2]+'"':"")+(bc?"":' data-handler="selectDay" data-event="click" data-month="'+Y.getMonth()+'" data-year="'+Y.getFullYear()+'"')+">"+(bb&&!G?"&#xa0;":bc?'<span class="ui-state-default">'+Y.getDate()+"</span>":'<a class="ui-state-default'+(Y.getTime()==b.getTime()?" ui-state-highlight":"")+(Y.getTime()==k.getTime()?" ui-state-active":"")+(bb?" ui-priority-secondary":"")+'" href="#">'+Y.getDate()+"</a>")+"</td>",Y.setDate(Y.getDate()+1),Y=this._daylightSavingAdjust(Y)}Q+=_+"</tr>"}n++,n>11&&(n=0,o++),Q+="</tbody></table>"+(j?"</div>"+(g[0]>0&&N==g[1]-1?'<div class="ui-datepicker-row-break"></div>':""):""),M+=Q}K+=M}return K+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':""),a._keyEvent=!1,K},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i=this._get(a,"changeMonth"),j=this._get(a,"changeYear"),k=this._get(a,"showMonthAfterYear"),l='<div class="ui-datepicker-title">',m="";if(f||!i)m+='<span class="ui-datepicker-month">'+g[b]+"</span>";else{var n=d&&d.getFullYear()==c,o=e&&e.getFullYear()==c;m+='<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';for(var p=0;p<12;p++)(!n||p>=d.getMonth())&&(!o||p<=e.getMonth())&&(m+='<option value="'+p+'"'+(p==b?' selected="selected"':"")+">"+h[p]+"</option>");m+="</select>"}k||(l+=m+(f||!i||!j?"&#xa0;":""));if(!a.yearshtml){a.yearshtml="";if(f||!j)l+='<span class="ui-datepicker-year">'+c+"</span>";else{var q=this._get(a,"yearRange").split(":"),r=(new Date).getFullYear(),s=function(a){var b=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?r+parseInt(a,10):parseInt(a,10);return isNaN(b)?r:b},t=s(q[0]),u=Math.max(t,s(q[1]||""));t=d?Math.max(t,d.getFullYear()):t,u=e?Math.min(u,e.getFullYear()):u,a.yearshtml+='<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';for(;t<=u;t++)a.yearshtml+='<option value="'+t+'"'+(t==c?' selected="selected"':"")+">"+t+"</option>";a.yearshtml+="</select>",l+=a.yearshtml,a.yearshtml=null}}return l+=this._get(a,"yearSuffix"),k&&(l+=(f||!i||!j?"&#xa0;":"")+m),l+="</div>",l},_adjustInstDate:function(a,b,c){var d=a.drawYear+(c=="Y"?b:0),e=a.drawMonth+(c=="M"?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+(c=="D"?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),(c=="M"||c=="Y")&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&b<c?c:b;return e=d&&e>d?d:e,e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(b<0?b:e[0]*e[1]),1));return b<0&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth())),this._isInRange(a,f)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");return b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10),{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),$.fn.datepicker=function(a){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv),$.datepicker.initialized=!0);var b=Array.prototype.slice.call(arguments,1);return typeof a!="string"||a!="isDisabled"&&a!="getDate"&&a!="widget"?a=="option"&&arguments.length==2&&typeof arguments[1]=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b)):this.each(function(){typeof a=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this].concat(b)):$.datepicker._attachDatepicker(this,a)}):$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b))},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.8.23",window["DP_jQuery_"+dpuuid]=$}(jQuery),function(a,b){var c="ui-dialog ui-widget ui-widget-content ui-corner-all ",d={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},e={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};a.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(b){var c=a(this).css(b).offset().top;c<0&&a(this).css("top",b.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.options.title=this.options.title||this.originalTitle;var b=this,d=b.options,e=d.title||"&#160;",f=a.ui.dialog.getTitleId(b.element),g=(b.uiDialog=a("<div></div>")).appendTo(document.body).hide().addClass(c+d.dialogClass).css({zIndex:d.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(c){d.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(a){b.moveToTop(!1,a)}),h=b.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g),i=(b.uiDialogTitlebar=a("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),j=a('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){j.addClass("ui-state-hover")},function(){j.removeClass("ui-state-hover")}).focus(function(){j.addClass("ui-state-focus")}).blur(function(){j.removeClass("ui-state-focus")}).click(function(a){return b.close(a),!1}).appendTo(i),k=(b.uiDialogTitlebarCloseText=a("<span></span>")).addClass("ui-icon ui-icon-closethick").text(d.closeText).appendTo(j),l=a("<span></span>").addClass("ui-dialog-title").attr("id",f).html(e).prependTo(i);a.isFunction(d.beforeclose)&&!a.isFunction(d.beforeClose)&&(d.beforeClose=d.beforeclose),i.find("*").add(i).disableSelection(),d.draggable&&a.fn.draggable&&b._makeDraggable(),d.resizable&&a.fn.resizable&&b._makeResizable(),b._createButtons(d.buttons),b._isOpen=!1,a.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;return a.overlay&&a.overlay.destroy(),a.uiDialog.hide(),a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),a.uiDialog.remove(),a.originalTitle&&a.element.attr("title",a.originalTitle),a},widget:function(){return this.uiDialog},close:function(b){var c=this,d,e;if(!1===c._trigger("beforeClose",b))return;return c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",b)}):(c.uiDialog.hide(),c._trigger("close",b)),a.ui.dialog.overlay.resize(),c.options.modal&&(d=0,a(".ui-dialog").each(function(){this!==c.uiDialog[0]&&(e=a(this).css("z-index"),isNaN(e)||(d=Math.max(d,e)))}),a.ui.dialog.maxZ=d),c},isOpen:function(){return this._isOpen},moveToTop:function(b,c){var d=this,e=d.options,f;return e.modal&&!b||!e.stack&&!e.modal?d._trigger("focus",c):(e.zIndex>a.ui.dialog.maxZ&&(a.ui.dialog.maxZ=e.zIndex),d.overlay&&(a.ui.dialog.maxZ+=1,d.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)),f={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()},a.ui.dialog.maxZ+=1,d.uiDialog.css("z-index",a.ui.dialog.maxZ),d.element.attr(f),d._trigger("focus",c),d)},open:function(){if(this._isOpen)return;var b=this,c=b.options,d=b.uiDialog;return b.overlay=c.modal?new a.ui.dialog.overlay(b):null,b._size(),b._position(c.position),d.show(c.show),b.moveToTop(!0),c.modal&&d.bind("keydown.ui-dialog",function(b){if(b.keyCode!==a.ui.keyCode.TAB)return;var c=a(":tabbable",this),d=c.filter(":first"),e=c.filter(":last");if(b.target===e[0]&&!b.shiftKey)return d.focus(1),!1;if(b.target===d[0]&&b.shiftKey)return e.focus(1),!1}),a(b.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus(),b._isOpen=!0,b._trigger("open"),b},_createButtons:function(b){var c=this,d=!1,e=a("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),f=a("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);c.uiDialog.find(".ui-dialog-buttonpane").remove(),typeof b=="object"&&b!==null&&a.each(b,function(){return!(d=!0)}),d&&(a.each(b,function(b,d){d=a.isFunction(d)?{click:d,text:b}:d;var e=a('<button type="button"></button>').click(function(){d.click.apply(c.element[0],arguments)}).appendTo(f);a.each(d,function(a,b){if(a==="click")return;a in e?e[a](b):e.attr(a,b)}),a.fn.button&&e.button()}),e.appendTo(c.uiDialog))},_makeDraggable:function(){function f(a){return{position:a.position,offset:a.offset}}var b=this,c=b.options,d=a(document),e;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(d,g){e=c.height==="auto"?"auto":a(this).height(),a(this).height(a(this).height()).addClass("ui-dialog-dragging"),b._trigger("dragStart",d,f(g))},drag:function(a,c){b._trigger("drag",a,f(c))},stop:function(g,h){c.position=[h.position.left-d.scrollLeft(),h.position.top-d.scrollTop()],a(this).removeClass("ui-dialog-dragging").height(e),b._trigger("dragStop",g,f(h)),a.ui.dialog.overlay.resize()}})},_makeResizable:function(c){function h(a){return{originalPosition:a.originalPosition,originalSize:a.originalSize,position:a.position,size:a.size}}c=c===b?this.options.resizable:c;var d=this,e=d.options,f=d.uiDialog.css("position"),g=typeof c=="string"?c:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:g,start:function(b,c){a(this).addClass("ui-dialog-resizing"),d._trigger("resizeStart",b,h(c))},resize:function(a,b){d._trigger("resize",a,h(b))},stop:function(b,c){a(this).removeClass("ui-dialog-resizing"),e.height=a(this).height(),e.width=a(this).width(),d._trigger("resizeStop",b,h(c)),a.ui.dialog.overlay.resize()}}).css("position",f).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(b){var c=[],d=[0,0],e;if(b){if(typeof b=="string"||typeof b=="object"&&"0"in b)c=b.split?b.split(" "):[b[0],b[1]],c.length===1&&(c[1]=c[0]),a.each(["left","top"],function(a,b){+c[a]===c[a]&&(d[a]=c[a],c[a]=b)}),b={my:c.join(" "),at:c.join(" "),offset:d.join(" ")};b=a.extend({},a.ui.dialog.prototype.options.position,b)}else b=a.ui.dialog.prototype.options.position;e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},b)),e||this.uiDialog.hide()},_setOptions:function(b){var c=this,f={},g=!1;a.each(b,function(a,b){c._setOption(a,b),a in d&&(g=!0),a in e&&(f[a]=b)}),g&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(b,d){var e=this,f=e.uiDialog;switch(b){case"beforeclose":b="beforeClose";break;case"buttons":e._createButtons(d);break;case"closeText":e.uiDialogTitlebarCloseText.text(""+d);break;case"dialogClass":f.removeClass(e.options.dialogClass).addClass(c+d);break;case"disabled":d?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case"draggable":var g=f.is(":data(draggable)");g&&!d&&f.draggable("destroy"),!g&&d&&e._makeDraggable();break;case"position":e._position(d);break;case"resizable":var h=f.is(":data(resizable)");h&&!d&&f.resizable("destroy"),h&&typeof d=="string"&&f.resizable("option","handles",d),!h&&d!==!1&&e._makeResizable(d);break;case"title":a(".ui-dialog-title",e.uiDialogTitlebar).html(""+(d||"&#160;"))}a.Widget.prototype._setOption.apply(e,arguments)},_size:function(){var b=this.options,c,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),b.minWidth>b.width&&(b.width=b.minWidth),c=this.uiDialog.css({height:"auto",width:b.width}).height(),d=Math.max(0,b.minHeight-c);if(b.height==="auto")if(a.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();var f=this.element.css("height","auto").height();e||this.uiDialog.hide(),this.element.height(Math.max(f,d))}else this.element.height(Math.max(b.height-c,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),a.extend(a.ui.dialog,{version:"1.8.23",uuid:0,maxZ:0,getTitleId:function(a){var b=a.attr("id");return b||(this.uuid+=1,b=this.uuid),"ui-dialog-title-"+b},overlay:function(b){this.$el=a.ui.dialog.overlay.create(b)}}),a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(b){this.instances.length===0&&(setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()<a.ui.dialog.overlay.maxZ)return!1})},1),a(document).bind("keydown.dialog-overlay",function(c){b.options.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}),a(window).bind("resize.dialog-overlay",a.ui.dialog.overlay.resize));var c=(this.oldInstances.pop()||a("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});return a.fn.bgiframe&&c.bgiframe(),this.instances.push(c),c},destroy:function(b){var c=a.inArray(b,this.instances);c!=-1&&this.oldInstances.push(this.instances.splice(c,1)[0]),this.instances.length===0&&a([document,window]).unbind(".dialog-overlay"),b.remove();var d=0;a.each(this.instances,function(){d=Math.max(d,this.css("z-index"))}),this.maxZ=d},height:function(){var b,c;return a.browser.msie&&a.browser.version<7?(b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight),b<c?a(window).height()+"px":b+"px"):a(document).height()+"px"},width:function(){var b,c;return a.browser.msie?(b=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth),c=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth),b<c?a(window).width()+"px":b+"px"):a(document).width()+"px"},resize:function(){var b=a([]);a.each(a.ui.dialog.overlay.instances,function(){b=b.add(this)}),b.css({width:0,height:0}).css({width:a.ui.dialog.overlay.width(),height:a.ui.dialog.overlay.height()})}}),a.extend(a.ui.dialog.overlay.prototype,{destroy:function(){a.ui.dialog.overlay.destroy(this.$el)}})}(jQuery),function(a,b){a.ui=a.ui||{};var c=/left|center|right/,d=/top|center|bottom/,e="center",f={},g=a.fn.position,h=a.fn.offset;a.fn.position=function(b){if(!b||!b.of)return g.apply(this,arguments);b=a.extend({},b);var h=a(b.of),i=h[0],j=(b.collision||"flip").split(" "),k=b.offset?b.offset.split(" "):[0,0],l,m,n;return i.nodeType===9?(l=h.width(),m=h.height(),n={top:0,left:0}):i.setTimeout?(l=h.width(),m=h.height(),n={top:h.scrollTop(),left:h.scrollLeft()}):i.preventDefault?(b.at="left top",l=m=0,n={top:b.of.pageY,left:b.of.pageX}):(l=h.outerWidth(),m=h.outerHeight(),n=h.offset()),a.each(["my","at"],function(){var a=(b[this]||"").split(" ");a.length===1&&(a=c.test(a[0])?a.concat([e]):d.test(a[0])?[e].concat(a):[e,e]),a[0]=c.test(a[0])?a[0]:e,a[1]=d.test(a[1])?a[1]:e,b[this]=a}),j.length===1&&(j[1]=j[0]),k[0]=parseInt(k[0],10)||0,k.length===1&&(k[1]=k[0]),k[1]=parseInt(k[1],10)||0,b.at[0]==="right"?n.left+=l:b.at[0]===e&&(n.left+=l/2),b.at[1]==="bottom"?n.top+=m:b.at[1]===e&&(n.top+=m/2),n.left+=k[0],n.top+=k[1],this.each(function(){var c=a(this),d=c.outerWidth(),g=c.outerHeight(),h=parseInt(a.curCSS(this,"marginLeft",!0))||0,i=parseInt(a.curCSS(this,"marginTop",!0))||0,o=d+h+(parseInt(a.curCSS(this,"marginRight",!0))||0),p=g+i+(parseInt(a.curCSS(this,"marginBottom",!0))||0),q=a.extend({},n),r;b.my[0]==="right"?q.left-=d:b.my[0]===e&&(q.left-=d/2),b.my[1]==="bottom"?q.top-=g:b.my[1]===e&&(q.top-=g/2),f.fractions||(q.left=Math.round(q.left),q.top=Math.round(q.top)),r={left:q.left-h,top:q.top-i},a.each(["left","top"],function(c,e){a.ui.position[j[c]]&&a.ui.position[j[c]][e](q,{targetWidth:l,targetHeight:m,elemWidth:d,elemHeight:g,collisionPosition:r,collisionWidth:o,collisionHeight:p,offset:k,my:b.my,at:b.at})}),a.fn.bgiframe&&c.bgiframe(),c.offset(a.extend(q,{using:b.using}))})},a.ui.position={fit:{left:function(b,c){var d=a(window),e=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft();b.left=e>0?b.left-e:Math.max(b.left-c.collisionPosition.left,b.left)},top:function(b,c){var d=a(window),e=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop();b.top=e>0?b.top-e:Math.max(b.top-c.collisionPosition.top,b.top)}},flip:{left:function(b,c){if(c.at[0]===e)return;var d=a(window),f=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft(),g=c.my[0]==="left"?-c.elemWidth:c.my[0]==="right"?c.elemWidth:0,h=c.at[0]==="left"?c.targetWidth:-c.targetWidth,i=-2*c.offset[0];b.left+=c.collisionPosition.left<0?g+h+i:f>0?g+h+i:0},top:function(b,c){if(c.at[1]===e)return;var d=a(window),f=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop(),g=c.my[1]==="top"?-c.elemHeight:c.my[1]==="bottom"?c.elemHeight:0,h=c.at[1]==="top"?c.targetHeight:-c.targetHeight,i=-2*c.offset[1];b.top+=c.collisionPosition.top<0?g+h+i:f>0?g+h+i:0}}},a.offset.setOffset||(a.offset.setOffset=function(b,c){/static/.test(a.curCSS(b,"position"))&&(b.style.position="relative");var d=a(b),e=d.offset(),f=parseInt(a.curCSS(b,"top",!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,h={top:c.top-e.top+f,left:c.left-e.left+g};"using"in c?c.using.call(b,h):d.css(h)},a.fn.offset=function(b){var c=this[0];return!c||!c.ownerDocument?null:b?a.isFunction(b)?this.each(function(c){a(this).offset(b.call(this,c,a(this).offset()))}):this.each(function(){a.offset.setOffset(this,b)}):h.call(this)}),a.curCSS||(a.curCSS=a.css),function(){var b=document.getElementsByTagName("body")[0],c=document.createElement("div"),d,e,g,h,i;d=document.createElement(b?"div":"body"),g={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},b&&a.extend(g,{position:"absolute",left:"-1000px",top:"-1000px"});for(var j in g)d.style[j]=g[j];d.appendChild(c),e=b||document.documentElement,e.insertBefore(d,e.firstChild),c.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;",h=a(c).offset(function(a,b){return b}).offset(),d.innerHTML="",e.removeChild(d),i=h.top+h.left+(b?2e3:0),f.fractions=i>21&&i<22}()}(jQuery),function(a,b){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=a("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove(),a.Widget.prototype.destroy.apply(this,arguments)},value:function(a){return a===b?this._value():(this._setOption("value",a),this)},_setOption:function(b,c){b==="value"&&(this.options.value=c,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;return typeof a!="number"&&(a=0),Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var a=this.value(),b=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change")),this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(b.toFixed(0)+"%"),this.element.attr("aria-valuenow",a)}}),a.extend(a.ui.progressbar,{version:"1.8.23"})}(jQuery),function(a,b){var c=5;a.widget("ui.slider",a.ui.mouse,{widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var b=this,d=this.options,e=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),f="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",g=d.values&&d.values.length||1,h=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(d.disabled?" ui-slider-disabled ui-disabled":"")),this.range=a([]),d.range&&(d.range===!0&&(d.values||(d.values=[this._valueMin(),this._valueMin()]),d.values.length&&d.values.length!==2&&(d.values=[d.values[0],d.values[0]])),this.range=a("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(d.range==="min"||d.range==="max"?" ui-slider-range-"+d.range:"")));for(var i=e.length;i<g;i+=1)h.push(f);this.handles=e.add(a(h.join("")).appendTo(b.element)),this.handle=this.handles.eq(0),this.handles.add(this.range).filter("a").click(function(a){a.preventDefault()}).hover(function(){d.disabled||a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")}).focus(function(){d.disabled?a(this).blur():(a(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),a(this).addClass("ui-state-focus"))}).blur(function(){a(this).removeClass("ui-state-focus")}),this.handles.each(function(b){a(this).data("index.ui-slider-handle",b)}),this.handles.keydown(function(d){var e=a(this).data("index.ui-slider-handle"),f,g,h,i;if(b.options.disabled)return;switch(d.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:d.preventDefault();if(!b._keySliding){b._keySliding=!0,a(this).addClass("ui-state-active"),f=b._start(d,e);if(f===!1)return}}i=b.options.step,b.options.values&&b.options.values.length?g=h=b.values(e):g=h=b.value();switch(d.keyCode){case a.ui.keyCode.HOME:h=b._valueMin();break;case a.ui.keyCode.END:h=b._valueMax();break;case a.ui.keyCode.PAGE_UP:h=b._trimAlignValue(g+(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.PAGE_DOWN:h=b._trimAlignValue(g-(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(g===b._valueMax())return;h=b._trimAlignValue(g+i);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(g===b._valueMin())return;h=b._trimAlignValue(g-i)}b._slide(d,e,h)}).keyup(function(c){var d=a(this).data("index.ui-slider-handle");b._keySliding&&(b._keySliding=!1,b._stop(c,d),b._change(c,d),a(this).removeClass("ui-state-active"))}),this._refreshValue(),this._animateOff=!1},destroy:function(){return this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider"),this._mouseDestroy(),this},_mouseCapture:function(b){var c=this.options,d,e,f,g,h,i,j,k,l;return c.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),d={x:b.pageX,y:b.pageY},e=this._normValueFromMouse(d),f=this._valueMax()-this._valueMin()+1,h=this,this.handles.each(function(b){var c=Math.abs(e-h.values(b));f>c&&(f=c,g=a(this),i=b)}),c.range===!0&&this.values(1)===c.min&&(i+=1,g=a(this.handles[i])),j=this._start(b,i),j===!1?!1:(this._mouseSliding=!0,h._handleIndex=i,g.addClass("ui-state-active").focus(),k=g.offset(),l=!a(b.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:b.pageX-k.left-g.width()/2,top:b.pageY-k.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(b,i,e),this._animateOff=!0,!0))},_mouseStart:function(a){return!0},_mouseDrag:function(a){var b={x:a.pageX,y:a.pageY},c=this._normValueFromMouse(b);return this._slide(a,this._handleIndex,c),!1},_mouseStop:function(a){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b,c,d,e,f;return this.orientation==="horizontal"?(b=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(b=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),d=c/b,d>1&&(d=1),d<0&&(d=0),this.orientation==="vertical"&&(d=1-d),e=this._valueMax()-this._valueMin(),f=this._valueMin()+d*e,this._trimAlignValue(f)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};return this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("start",a,c)},_slide:function(a,b,c){var d,e,f;this.options.values&&this.options.values.length?(d=this.values(b?0:1),this.options.values.length===2&&this.options.range===!0&&(b===0&&c>d||b===1&&c<d)&&(c=d),c!==this.values(b)&&(e=this.values(),e[b]=c,f=this._trigger("slide",a,{handle:this.handles[b],value:c,values:e}),d=this.values(b?0:1),f!==!1&&this.values(b,c,!0))):c!==this.value()&&(f=this._trigger("slide",a,{handle:this.handles[b],value:c}),f!==!1&&this.value(c))},_stop:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("stop",a,c)},_change:function(a,b){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("change",a,c)}},value:function(a){if(arguments.length){this.options.value=this._trimAlignValue(a),this._refreshValue(),this._change(null,0);return}return this._value()},values:function(b,c){var d,e,f;if(arguments.length>1){this.options.values[b]=this._trimAlignValue(c),this._refreshValue(),this._change(null,b);return}if(!arguments.length)return this._values();if(!a.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(b):this.value();d=this.options.values,e=arguments[0];for(f=0;f<d.length;f+=1)d[f]=this._trimAlignValue(e[f]),this._change(null,f);this._refreshValue()},_setOption:function(b,c){var d,e=0;a.isArray(this.options.values)&&(e=this.options.values.length),a.Widget.prototype._setOption.apply(this,arguments);switch(b){case"disabled":c?(this.handles.filter(".ui-state-focus").blur(),this.handles.removeClass("ui-state-hover"),this.handles.propAttr("disabled",!0),this.element.addClass("ui-disabled")):(this.handles.propAttr("disabled",!1),this.element.removeClass("ui-disabled"));break;case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":this._animateOff=!0,this._refreshValue();for(d=0;d<e;d+=1)this._change(null,d);this._animateOff=!1}},_value:function(){var a=this.options.value;return a=this._trimAlignValue(a),a},_values:function(a){var b,c,d;if(arguments.length)return b=this.options.values[a],b=this._trimAlignValue(b),b;c=this.options.values.slice();for(d=0;d<c.length;d+=1)c[d]=this._trimAlignValue(c[d]);return c},_trimAlignValue:function(a){if(a<=this._valueMin())return this._valueMin();if(a>=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b,d=a-c;return Math.abs(c)*2>=b&&(d+=c>0?b:-b),parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var b=this.options.range,c=this.options,d=this,e=this._animateOff?!1:c.animate,f,g={},h,i,j,k;this.options.values&&this.options.values.length?this.handles.each(function(b,i){f=(d.values(b)-d._valueMin())/(d._valueMax()-d._valueMin())*100,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",a(this).stop(1,1)[e?"animate":"css"](g,c.animate),d.options.range===!0&&(d.orientation==="horizontal"?(b===0&&d.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({width:f-h+"%"},{queue:!1,duration:c.animate})):(b===0&&d.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({height:f-h+"%"},{queue:!1,duration:c.animate}))),h=f}):(i=this.value(),j=this._valueMin(),k=this._valueMax(),f=k!==j?(i-j)/(k-j)*100:0,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",this.handle.stop(1,1)[e?"animate":"css"](g,c.animate),b==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},c.animate),b==="max"&&this.orientation==="horizontal"&&this.range[e?"animate":"css"]({width:100-f+"%"},{queue:!1,duration:c.animate}),b==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},c.animate),b==="max"&&this.orientation==="vertical"&&this.range[e?"animate":"css"]({height:100-f+"%"},{queue:!1,duration:c.animate}))}}),a.extend(a.ui.slider,{version:"1.8.23"})}(jQuery),function(a,b){function e(){return++c}function f(){return++d}var c=0,d=0;a.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:!1,cookie:null,collapsible:!1,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(!0)},_setOption:function(a,b){if(a=="selected"){if(this.options.collapsible&&b==this.options.selected)return;this.select(b)}else this.options[a]=b,this._tabify()},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+e()},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+f());return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(a,b){return{tab:a,panel:b,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function m(b,c){b.css("display",""),!a.support.opacity&&c.opacity&&b[0].style.removeAttribute("filter")}var d=this,e=this.options,f=/^#.+/;this.list=this.element.find("ol,ul").eq(0),this.lis=a(" > li:has(a[href])",this.list),this.anchors=this.lis.map(function(){return a("a",this)[0]}),this.panels=a([]),this.anchors.each(function(b,c){var g=a(c).attr("href"),h=g.split("#")[0],i;h&&(h===location.toString().split("#")[0]||(i=a("base")[0])&&h===i.href)&&(g=c.hash,c.href=g);if(f.test(g))d.panels=d.panels.add(d.element.find(d._sanitizeSelector(g)));else if(g&&g!=="#"){a.data(c,"href.tabs",g),a.data(c,"load.tabs",g.replace(/#.*$/,""));var j=d._tabId(c);c.href="#"+j;var k=d.element.find("#"+j);k.length||(k=a(e.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),k.data("destroy.tabs",!0)),d.panels=d.panels.add(k)}else e.disabled.push(b)}),c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),e.selected===b?(location.hash&&this.anchors.each(function(a,b){if(b.hash==location.hash)return e.selected=a,!1}),typeof e.selected!="number"&&e.cookie&&(e.selected=parseInt(d._cookie(),10)),typeof e.selected!="number"&&this.lis.filter(".ui-tabs-selected").length&&(e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))),e.selected=e.selected||(this.lis.length?0:-1)):e.selected===null&&(e.selected=-1),e.selected=e.selected>=0&&this.anchors[e.selected]||e.selected<0?e.selected:0,e.disabled=a.unique(e.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(a,b){return d.lis.index(a)}))).sort(),a.inArray(e.selected,e.disabled)!=-1&&e.disabled.splice(a.inArray(e.selected,e.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"),e.selected>=0&&this.anchors.length&&(d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(e.selected).addClass("ui-tabs-selected ui-state-active"),d.element.queue("tabs",function(){d._trigger("show",null,d._ui(d.anchors[e.selected],d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash))[0]))}),this.load(e.selected)),a(window).bind("unload",function(){d.lis.add(d.anchors).unbind(".tabs"),d.lis=d.anchors=d.panels=null})):e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")),this.element[e.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible"),e.cookie&&this._cookie(e.selected,e.cookie);for(var g=0,h;h=this.lis[g];g++)a(h)[a.inArray(g,e.disabled)!=-1&&!a(h).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");e.cache===!1&&this.anchors.removeData("cache.tabs"),this.lis.add(this.anchors).unbind(".tabs");if(e.event!=="mouseover"){var i=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)},j=function(a,b){b.removeClass("ui-state-"+a)};this.lis.bind("mouseover.tabs",function(){i("hover",a(this))}),this.lis.bind("mouseout.tabs",function(){j("hover",a(this))}),this.anchors.bind("focus.tabs",function(){i("focus",a(this).closest("li"))}),this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var k,l;e.fx&&(a.isArray(e.fx)?(k=e.fx[0],l=e.fx[1]):k=l=e.fx);var n=l?function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.hide().removeClass("ui-tabs-hide").animate(l,l.duration||"normal",function(){m(c,l),d._trigger("show",null,d._ui(b,c[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.removeClass("ui-tabs-hide"),d._trigger("show",null,d._ui(b,c[0]))},o=k?function(a,b){b.animate(k,k.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),m(b,k),d.element.dequeue("tabs")})}:function(a,b,c){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),d.element.dequeue("tabs")};this.anchors.bind(e.event+".tabs",function(){var b=this,c=a(b).closest("li"),f=d.panels.filter(":not(.ui-tabs-hide)"),g=d.element.find(d._sanitizeSelector(b.hash));if(c.hasClass("ui-tabs-selected")&&!e.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||d.panels.filter(":animated").length||d._trigger("select",null,d._ui(this,g[0]))===!1)return this.blur(),!1;e.selected=d.anchors.index(this),d.abort();if(e.collapsible){if(c.hasClass("ui-tabs-selected"))return e.selected=-1,e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){o(b,f)}).dequeue("tabs"),this.blur(),!1;if(!f.length)return e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this)),this.blur(),!1}e.cookie&&d._cookie(e.selected,e.cookie);if(g.length)f.length&&d.element.queue("tabs",function(){o(b,f)}),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier.";a.browser.msie&&this.blur()}),this.anchors.bind("click.tabs",function(){return!1})},_getIndex:function(a){return typeof a=="string"&&(a=this.anchors.index(this.anchors.filter("[href$='"+a+"']"))),a},destroy:function(){var b=this.options;return this.abort(),this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs"),this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.anchors.each(function(){var b=a.data(this,"href.tabs");b&&(this.href=b);var c=a(this).unbind(".tabs");a.each(["href","load","cache"],function(a,b){c.removeData(b+".tabs")})}),this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}),b.cookie&&this._cookie(null,b.cookie),this},add:function(c,d,e){e===b&&(e=this.anchors.length);var f=this,g=this.options,h=a(g.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),i=c.indexOf("#")?this._tabId(a("a",h)[0]):c.replace("#","");h.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+i);return j.length||(j=a(g.panelTemplate).attr("id",i).data("destroy.tabs",!0)),j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),e>=this.lis.length?(h.appendTo(this.list),j.appendTo(this.list[0].parentNode)):(h.insertBefore(this.lis[e]),j.insertBefore(this.panels[e])),g.disabled=a.map(g.disabled,function(a,b){return a>=e?++a:a}),this._tabify(),this.anchors.length==1&&(g.selected=0,h.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[e],this.panels[e])),this},remove:function(b){b=this._getIndex(b);var c=this.options,d=this.lis.eq(b).remove(),e=this.panels.eq(b).remove();return d.hasClass("ui-tabs-selected")&&this.anchors.length>1&&this.select(b+(b+1<this.anchors.length?1:-1)),c.disabled=a.map(a.grep(c.disabled,function(a,c){return a!=b}),function(a,c){return a>=b?--a:a}),this._tabify(),this._trigger("remove",null,this._ui(d.find("a")[0],e[0])),this},enable:function(b){b=this._getIndex(b);var c=this.options;if(a.inArray(b,c.disabled)==-1)return;return this.lis.eq(b).removeClass("ui-state-disabled"),c.disabled=a.grep(c.disabled,function(a,c){return a!=b}),this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b])),this},disable:function(a){a=this._getIndex(a);var b=this,c=this.options;return a!=c.selected&&(this.lis.eq(a).addClass("ui-state-disabled"),c.disabled.push(a),c.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a]))),this},select:function(a){a=this._getIndex(a);if(a==-1)if(this.options.collapsible&&this.options.selected!=-1)a=this.options.selected;else return this;return this.anchors.eq(a).trigger(this.options.event+".tabs"),this},load:function(b){b=this._getIndex(b);var c=this,d=this.options,e=this.anchors.eq(b)[0],f=a.data(e,"load.tabs");this.abort();if(!f||this.element.queue("tabs").length!==0&&a.data(e,"cache.tabs")){this.element.dequeue("tabs");return}this.lis.eq(b).addClass("ui-state-processing");if(d.spinner){var g=a("span",e);g.data("label.tabs",g.html()).html(d.spinner)}return this.xhr=a.ajax(a.extend({},d.ajaxOptions,{url:f,success:function(f,g){c.element.find(c._sanitizeSelector(e.hash)).html(f),c._cleanup(),d.cache&&a.data(e,"cache.tabs",!0),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.success(f,g)}catch(h){}},error:function(a,f,g){c._cleanup(),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.error(a,f,b,e)}catch(g){}}})),c.element.dequeue("tabs"),this},abort:function(){return this.element.queue([]),this.panels.stop(!1,!0),this.element.queue("tabs",this.element.queue("tabs").splice(-2,2)),this.xhr&&(this.xhr.abort(),delete this.xhr),this._cleanup(),this},url:function(a,b){return this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",b),this},length:function(){return this.anchors.length}}),a.extend(a.ui.tabs,{version:"1.8.23"}),a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(a,b){var c=this,d=this.options,e=c._rotate||(c._rotate=function(b){clearTimeout(c.rotation),c.rotation=setTimeout(function(){var a=d.selected;c.select(++a<c.anchors.length?a:0)},a),b&&b.stopPropagation()}),f=c._unrotate||(c._unrotate=b?function(a){e()}:function(a){a.clientX&&c.rotate(null)});return a?(this.element.bind("tabsshow",e),this.anchors.bind(d.event+".tabs",f),e()):(clearTimeout(c.rotation),this.element.unbind("tabsshow",e),this.anchors.unbind(d.event+".tabs",f),delete this._rotate,delete this._unrotate),this}})}(jQuery);
js/tryon/jquery.hoverscroll.js ADDED
@@ -0,0 +1,449 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * HoverScroll jQuery Plugin
3
+ *
4
+ * Make an unordered list scrollable by hovering the mouse over it
5
+ *
6
+ * @author RasCarlito <carl.ogren@gmail.com>
7
+ * @version 0.2.3
8
+ * @revision 19
9
+ *
10
+ *
11
+ *
12
+ * FREE BEER LICENSE VERSION 1.02
13
+ *
14
+ * The free beer license is a license to give free software to you and free
15
+ * beer (in)to the author(s).
16
+ *
17
+ *
18
+ * Released: 09-12-2010 11:31pm
19
+ *
20
+ * Changelog
21
+ * ----------------------------------------------------
22
+ *
23
+ * 0.2.3 - Added fixed arrows option
24
+ * - Binded startMoving and stopMoving functions to the HoverScrolls HTML object for external access
25
+ *
26
+ * 0.2.2 Bug fixes
27
+ * - Backward compatibility with jQuery 1.1.x
28
+ * - Added test file to the archive
29
+ * - Bug fix: The right arrow appeared when it wasn't necessary (thanks to <admin at unix dot am>)
30
+ *
31
+ * 0.2.1 Bug fixes
32
+ * - Backward compatibility with jQuery 1.2.x (thanks to Andy Mull for compatibility with jQuery >= 1.2.4)
33
+ * - Added information to the debug log
34
+ *
35
+ * 0.2.0 Added some new features
36
+ * - Direction indicator arrows
37
+ * - Permanent override of default parameters
38
+ *
39
+ * 0.1.1 Minor bug fix
40
+ * - Hover zones did not cover the complete container
41
+ *
42
+ * note: The css file has not changed therefore it is still versioned 0.1.0
43
+ *
44
+ * 0.1.0 First release of the plugin. Supports:
45
+ * - Horizontal and vertical lists
46
+ * - Width and height control
47
+ * - Debug log (doesn't show useful information for the moment)
48
+ */
49
+
50
+ (function($) {
51
+
52
+ /**
53
+ * @method hoverscroll
54
+ * @param params {Object} Parameter list
55
+ * params = {
56
+ * vertical {Boolean}, // Vertical list or not ?
57
+ * width {Integer}, // Width of list container
58
+ * height {Integer}, // Height of list container
59
+ * arrows {Boolean}, // Show direction indicators or not
60
+ * arrowsOpacity {Float}, // Arrows maximum opacity
61
+ * fixedArrows {Boolean}, // Display arrows permenantly, this overrides arrowsOpacity option
62
+ * debug {Boolean} // Debug output in firebug console
63
+ * };
64
+ */
65
+ $.fn.hoverscroll = function(params) {
66
+ if (!params) { params = {}; }
67
+
68
+ // Extend default parameters
69
+ // note: empty object to prevent params object from overriding default params object
70
+ params = $.extend({}, $.fn.hoverscroll.params, params);
71
+
72
+ // Loop through all the elements
73
+ this.each(function() {
74
+ var $this = $(this);
75
+
76
+ if (params.debug) {
77
+ $.log('[HoverScroll] Trying to create hoverscroll on element ' + this.tagName + '#' + this.id);
78
+ }
79
+
80
+ // wrap ul list with a div.listcontainer
81
+ if (params.fixedArrows) {
82
+ $this.wrap('<div class="fixed-listcontainer"></div>')
83
+ }
84
+ else {
85
+ $this.wrap('<div class="listcontainer"></div>');
86
+ }
87
+
88
+ $this.addClass('list');
89
+ //.addClass('ui-helper-clearfix');
90
+
91
+ // store handle to listcontainer
92
+ var listctnr = $this.parent();
93
+
94
+ // wrap listcontainer with a div.hoverscroll
95
+ listctnr.wrap('<div class="ui-widget-content hoverscroll"></div>');
96
+ //listctnr.wrap('<div class="hoverscroll"></div>');
97
+
98
+ // store hoverscroll container
99
+ var ctnr = listctnr.parent();
100
+
101
+ var leftArrow, rightArrow, topArrow, bottomArrow;
102
+
103
+ // Add arrow containers
104
+ if (params.arrows) {
105
+ if (!params.vertical) {
106
+ if (params.fixedArrows) {
107
+ leftArrow = '<div class="fixed-arrow left"></div>';
108
+ rightArrow = '<div class="fixed-arrow right"></div>';
109
+
110
+ listctnr.before(leftArrow).after(rightArrow);
111
+ }
112
+ else {
113
+ leftArrow = '<div class="arrow left"></div>';
114
+ rightArrow = '<div class="arrow right"></div>';
115
+
116
+ listctnr.append(leftArrow).append(rightArrow);
117
+ }
118
+ }
119
+ else {
120
+ if (params.fixedArrows) {
121
+ topArrow = '<div class="fixed-arrow top"></div>';
122
+ bottomArrow = '<div class="fixed-arrow bottom"></div>';
123
+
124
+ listctnr.before(topArrow).after(bottomArrow);
125
+ }
126
+ else {
127
+ topArrow = '<div class="arrow top"></div>';
128
+ bottomArrow = '<div class="arrow bottom"></div>';
129
+
130
+ listctnr.append(topArrow).append(bottomArrow);
131
+ }
132
+ }
133
+ }
134
+
135
+ // Apply parameters width and height
136
+ ctnr.width(params.width).height(params.height);
137
+
138
+ if (params.arrows && params.fixedArrows) {
139
+ if (params.vertical) {
140
+ topArrow = listctnr.prev();
141
+ bottomArrow = listctnr.next();
142
+
143
+ listctnr.width(params.width)
144
+ .height(params.height - (topArrow.height() + bottomArrow.height()));
145
+ }
146
+ else {
147
+ leftArrow = listctnr.prev();
148
+ rightArrow = listctnr.next();
149
+
150
+ listctnr.height(params.height)
151
+ .width(params.width - (leftArrow.width() + rightArrow.width()));
152
+ }
153
+ }
154
+ else {
155
+ listctnr.width(params.width).height(params.height);
156
+ }
157
+
158
+ var size = 0;
159
+
160
+ if (!params.vertical) {
161
+ ctnr.addClass('horizontal');
162
+
163
+ // Determine content width
164
+ $this.children().each(function() {
165
+ $(this).addClass('item');
166
+
167
+ if ($(this).outerWidth) {
168
+ size += $(this).outerWidth(true);
169
+ }
170
+ else {
171
+ // jQuery < 1.2.x backward compatibility patch
172
+ size += $(this).width() + parseInt($(this).css('padding-left')) + parseInt($(this).css('padding-right'))
173
+ + parseInt($(this).css('margin-left')) + parseInt($(this).css('margin-right'));
174
+ }
175
+ });
176
+ // Apply computed width to listcontainer
177
+ $this.width(size);
178
+
179
+ if (params.debug) {
180
+ $.log('[HoverScroll] Computed content width : ' + size + 'px');
181
+ }
182
+
183
+ // Retrieve container width instead of using the given params.width to include padding
184
+ if (ctnr.outerWidth) {
185
+ size = ctnr.outerWidth();
186
+ }
187
+ else {
188
+ // jQuery < 1.2.x backward compatibility patch
189
+ size = ctnr.width() + parseInt(ctnr.css('padding-left')) + parseInt(ctnr.css('padding-right'))
190
+ + parseInt(ctnr.css('margin-left')) + parseInt(ctnr.css('margin-right'));
191
+ }
192
+
193
+ if (params.debug) {
194
+ $.log('[HoverScroll] Computed container width : ' + size + 'px');
195
+ }
196
+ }
197
+ else {
198
+ ctnr.addClass('vertical');
199
+
200
+ // Determine content height
201
+ $this.children().each(function() {
202
+ $(this).addClass('item')
203
+
204
+ if ($(this).outerHeight) {
205
+ size += $(this).outerHeight(true);
206
+ }
207
+ else {
208
+ // jQuery < 1.2.x backward compatibility patch
209
+ size += $(this).height() + parseInt($(this).css('padding-top')) + parseInt($(this).css('padding-bottom'))
210
+ + parseInt($(this).css('margin-bottom')) + parseInt($(this).css('margin-bottom'));
211
+ }
212
+ });
213
+ // Apply computed height to listcontainer
214
+ $this.height(size);
215
+
216
+ if (params.debug) {
217
+ $.log('[HoverScroll] Computed content height : ' + size + 'px');
218
+ }
219
+
220
+ // Retrieve container height instead of using the given params.height to include padding
221
+ if (ctnr.outerHeight) {
222
+ size = ctnr.outerHeight();
223
+ }
224
+ else {
225
+ // jQuery < 1.2.x backward compatibility patch
226
+ size = ctnr.height() + parseInt(ctnr.css('padding-top')) + parseInt(ctnr.css('padding-bottom'))
227
+ + parseInt(ctnr.css('margin-top')) + parseInt(ctnr.css('margin-bottom'));
228
+ }
229
+
230
+ if (params.debug) {
231
+ $.log('[HoverScroll] Computed container height : ' + size + 'px');
232
+ }
233
+ }
234
+
235
+ // Define hover zones on container
236
+ var zone = {
237
+ 1: {action: 'move', from: 0, to: 0.06 * size, direction: -1 , speed: 16},
238
+ 2: {action: 'move', from: 0.06 * size, to: 0.15 * size, direction: -1 , speed: 8},
239
+ 3: {action: 'move', from: 0.15 * size, to: 0.25 * size, direction: -1 , speed: 4},
240
+ 4: {action: 'move', from: 0.25 * size, to: 0.4 * size, direction: -1 , speed: 2},
241
+ 5: {action: 'stop', from: 0.4 * size, to: 0.6 * size},
242
+ 6: {action: 'move', from: 0.6 * size, to: 0.75 * size, direction: 1 , speed: 2},
243
+ 7: {action: 'move', from: 0.75 * size, to: 0.85 * size, direction: 1 , speed: 4},
244
+ 8: {action: 'move', from: 0.85 * size, to: 0.94 * size, direction: 1 , speed: 8},
245
+ 9: {action: 'move', from: 0.94 * size, to: size, direction: 1 , speed: 16}
246
+ }
247
+
248
+ // Store default state values in container
249
+ ctnr[0].isChanging = false;
250
+ ctnr[0].direction = 0;
251
+ ctnr[0].speed = 1;
252
+
253
+
254
+ /**
255
+ * Check mouse position relative to hoverscroll container
256
+ * and trigger actions according to the zone table
257
+ *
258
+ * @param x {Integer} Mouse X event position
259
+ * @param y {Integer} Mouse Y event position
260
+ */
261
+ function checkMouse(x, y) {
262
+ x = x - ctnr.offset().left;
263
+ y = y - ctnr.offset().top;
264
+
265
+ var pos;
266
+ if (!params.vertical) {pos = x;}
267
+ else {pos = y;}
268
+
269
+ for (i in zone) {
270
+ if (pos >= zone[i].from && pos < zone[i].to) {
271
+ if (zone[i].action == 'move') {startMoving(zone[i].direction, zone[i].speed);}
272
+ else {stopMoving();}
273
+ }
274
+ }
275
+ }
276
+
277
+
278
+ /**
279
+ * Sets the opacity of the left|top and right|bottom
280
+ * arrows according to the scroll position.
281
+ */
282
+ function setArrowOpacity() {
283
+ if (!params.arrows || params.fixedArrows) {return;}
284
+
285
+ var maxScroll;
286
+ var scroll;
287
+
288
+ if (!params.vertical) {
289
+ maxScroll = listctnr[0].scrollWidth - listctnr.width();
290
+ scroll = listctnr[0].scrollLeft;
291
+ }
292
+ else {
293
+ maxScroll = listctnr[0].scrollHeight - listctnr.height();
294
+ scroll = listctnr[0].scrollTop;
295
+ }
296
+
297
+ var opacity = (scroll / maxScroll);
298
+ var limit = params.arrowsOpacity;
299
+
300
+ if (isNaN(opacity)) {opacity = 0;}
301
+
302
+ // Check if the arrows are needed
303
+ // Thanks to <admin at unix dot am> for fixing the bug that displayed the right arrow when it was not needed
304
+ var done = false;
305
+ if (opacity <= 0) {$('div.arrow.left, div.arrow.top', ctnr).hide();done = true;}
306
+ if (opacity >= limit || maxScroll <= 0) {$('div.arrow.right, div.arrow.bottom', ctnr).hide();done = true;}
307
+
308
+ if (!done) {
309
+ $('div.arrow.left, div.arrow.top', ctnr).show().css('opacity', (opacity > limit ? limit : opacity));
310
+ $('div.arrow.right, div.arrow.bottom', ctnr).show().css('opacity', (1 - opacity > limit ? limit : 1 - opacity));
311
+ }
312
+ }
313
+
314
+
315
+ /**
316
+ * Start scrolling the list with a given speed and direction
317
+ *
318
+ * @param direction {Integer} Direction of the displacement, either -1|1
319
+ * @param speed {Integer} Speed of the displacement (20 being very fast)
320
+ */
321
+ function startMoving(direction, speed) {
322
+ if (ctnr[0].direction != direction) {
323
+ if (params.debug) {
324
+ $.log('[HoverScroll] Starting to move. direction: ' + direction + ', speed: ' + speed);
325
+ }
326
+
327
+ stopMoving();
328
+ ctnr[0].direction = direction;
329
+ ctnr[0].isChanging = true;
330
+ move();
331
+ }
332
+ if (ctnr[0].speed != speed) {
333
+ if (params.debug) {
334
+ $.log('[HoverScroll] Changed speed: ' + speed);
335
+ }
336
+
337
+ ctnr[0].speed = speed;
338
+ }
339
+ }
340
+
341
+ /**
342
+ * Stop scrolling the list
343
+ */
344
+ function stopMoving() {
345
+ if (ctnr[0].isChanging) {
346
+ if (params.debug) {
347
+ $.log('[HoverScroll] Stoped moving');
348
+ }
349
+
350
+ ctnr[0].isChanging = false;
351
+ ctnr[0].direction = 0;
352
+ ctnr[0].speed = 1;
353
+ clearTimeout(ctnr[0].timer);
354
+ }
355
+ }
356
+
357
+ /**
358
+ * Move the list one step in the given direction and speed
359
+ */
360
+ function move() {
361
+ if (ctnr[0].isChanging == false) {return;}
362
+
363
+ setArrowOpacity();
364
+
365
+ var scrollSide;
366
+ if (!params.vertical) {scrollSide = 'scrollLeft';}
367
+ else {scrollSide = 'scrollTop';}
368
+
369
+ listctnr[0][scrollSide] += ctnr[0].direction * ctnr[0].speed;
370
+ ctnr[0].timer = setTimeout(function() {move();}, 50);
371
+ }
372
+
373
+ // Bind actions to the hoverscroll container
374
+ ctnr
375
+ // Bind checkMouse to the mousemove
376
+ .mousemove(function(e) {checkMouse(e.pageX, e.pageY);})
377
+ // Bind stopMoving to the mouseleave
378
+ // jQuery 1.2.x backward compatibility, thanks to Andy Mull!
379
+ // replaced .mouseleave(...) with .bind('mouseleave', ...)
380
+ .bind('mouseleave', function() {stopMoving();});
381
+
382
+ // Bind the startMoving and stopMoving functions
383
+ // to the HTML object for external access
384
+ this.startMoving = startMoving;
385
+ this.stopMoving = stopMoving;
386
+
387
+ if (params.arrows && !params.fixedArrows) {
388
+ // Initialise arrow opacity
389
+ setArrowOpacity();
390
+ }
391
+ else {
392
+ // Hide arrows
393
+ $('.arrowleft, .arrowright, .arrowtop, .arrowbottom', ctnr).hide();
394
+ }
395
+ });
396
+
397
+ return this;
398
+ };
399
+
400
+
401
+ // Backward compatibility with jQuery 1.1.x
402
+ if (!$.fn.offset) {
403
+ $.fn.offset = function() {
404
+ this.left = this.top = 0;
405
+
406
+ if (this[0] && this[0].offsetParent) {
407
+ var obj = this[0];
408
+ do {
409
+ this.left += obj.offsetLeft;
410
+ this.top += obj.offsetTop;
411
+ } while (obj = obj.offsetParent);
412
+ }
413
+
414
+ return this;
415
+ }
416
+ }
417
+
418
+
419
+
420
+ /**
421
+ * HoverScroll default parameters
422
+ */
423
+ $.fn.hoverscroll.params = {
424
+ vertical: false, // Display the list vertically or not
425
+ width: 400, // Width of the list
426
+ height: 50, // Height of the list
427
+ arrows: true, // Display arrows to the left and top or the top and bottom
428
+ arrowsOpacity: 0.7, // Maximum opacity of the arrows if fixedArrows
429
+ fixedArrows: false, // Fix the displayed arrows to the side of the list
430
+ debug: false // Display some debugging information in firebug console
431
+ };
432
+
433
+
434
+
435
+ /**
436
+ * Log errors to consoles (firebug, opera) if exist, else uses alert()
437
+ */
438
+ $.log = function() {
439
+ try {console.log.apply(console, arguments);}
440
+ catch (e) {
441
+ try {opera.postError.apply(opera, arguments);}
442
+ catch (e) {
443
+ // alert(Array.prototype.join.call(arguments, " "));
444
+ }
445
+ }
446
+ };
447
+
448
+
449
+ })(jQuery);
js/tryon/jquery.stickyfloat.js ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * stickyfloat - jQuery plugin for verticaly floating anything in a constrained area
3
+ *
4
+ * Example: jQuery('#menu').stickyfloat({duration: 400});
5
+ * parameters:
6
+ * duration - the duration of the animation
7
+ * startOffset - the amount of scroll offset after it the animations kicks in
8
+ * offsetY - the offset from the top when the object is animated
9
+ * lockBottom - 'true' by default, set to false if you don't want your floating box to stop at parent's bottom
10
+ * $Version: 05.16.2009 r1
11
+ * Copyright (c) 2009 Yair Even-Or
12
+ * vsync.design@gmail.com
13
+
14
+ * Mods by: Christopher Haupt, Webvanta Inc.
15
+ * http://www.webvanta.com/, http://twitter.com/chaupt, http://github.com/chaupt
16
+ * Honor options set by user.
17
+ *
18
+ * Fork/plugin work by: Lee Carmichael
19
+ * http://github.com/lecar-red
20
+ * - update to support iteration on jquery object
21
+ */
22
+ ( function($) {
23
+ $.fn.stickyfloat = function(options) {
24
+ return this.each( function() {
25
+ // we check each parent for overflow to find valid option to use
26
+ // for positioning, need better name than base
27
+ var base = $(this).parents().map( function() {
28
+ if ( $(this).css('overflow') == 'scroll' ||
29
+ $(this).css('overflow') == 'auto' ) {
30
+ return this;
31
+ }
32
+ }).first();
33
+
34
+ // might pay to check css('overflow') too but if
35
+ // scrollHeight not equaling height indicates element
36
+ // with overflow and scrollbars
37
+ if ( base.prop('scrollHeight') != base.height() ) {
38
+ _position_overflow( $(this), options, base );
39
+ }
40
+ else {
41
+ _position($(this), options)
42
+ }
43
+ });
44
+
45
+ // setup position and scroll
46
+ function _position($obj, options) {
47
+ var parentPaddingTop = parseInt($obj.parent().css('padding-top'));
48
+ var startOffset = $obj.parent().offset().top;
49
+
50
+ var opts = $.extend({
51
+ startOffset: startOffset,
52
+ offsetY: parentPaddingTop,
53
+ duration: 400,
54
+ lockBottom: true
55
+ }, options);
56
+
57
+ $obj.css({ position: 'relative' });
58
+
59
+ if(opts.lockBottom){
60
+ var bottomPos = $obj.parent().height() - $obj.height() + opts.offsetY; //get the maximum scrollTop value
61
+ if( bottomPos < 0 )
62
+ bottomPos = 0;
63
+ }
64
+
65
+ $(window).scroll(function () {
66
+ $obj.stop(); // stop all calculations on scroll event
67
+
68
+ var pastStartOffset = $(window).scrollTop() > opts.startOffset; // check if the window was scrolled down more than the start offset declared.
69
+ var objFartherThanTopPos = $obj.offset().top > opts.startOffset; // check if the object is at it's top position (starting point)
70
+ var objBiggerThanWindow = $obj.outerHeight() < $(window).height(); // if the window size is smaller than the Obj size, then do not animate.
71
+
72
+ // if window scrolled down more than startOffset OR obj position is greater than
73
+ // the top position possible (+ offsetY) AND window size must be bigger than Obj size
74
+ if( (pastStartOffset || objFartherThanTopPos) && objBiggerThanWindow ){
75
+ var newpos = ($(document).scrollTop() - opts.startOffset + opts.offsetY );
76
+
77
+ if ( newpos > bottomPos )
78
+ newpos = bottomPos;
79
+
80
+ if ( $(document).scrollTop() < opts.startOffset ) // if window scrolled < starting offset, then reset Obj position (opts.offsetY);
81
+ newpos = opts.offsetY;
82
+
83
+ $obj.animate({ top: newpos }, opts.duration );
84
+ }
85
+ });
86
+ }; // end calc
87
+
88
+ // position when float is inside of overflow with scroll
89
+ // p - overflow element (not parent) need to change
90
+ function _position_overflow($obj, options, p) {
91
+ // var par = $obj.parent();
92
+ // not sure about this yet, if we are inside div > div > div
93
+ var parentPaddingTop = parseInt( $obj.parent().css('padding-top') );
94
+
95
+ // offset is relative to document not current element
96
+ //var startOffset = p.offset().top - $obj.parent().offset().top;
97
+ var startOffset = $obj.parent().offset().top - p.offset().top;
98
+
99
+ // set defaults and overrides
100
+ var opts = $.extend({
101
+ startOffset: startOffset,
102
+ offsetY: parentPaddingTop,
103
+ duration: 400,
104
+ lockBottom: true
105
+ }, options);
106
+
107
+ $obj.css({ position: 'relative' });
108
+
109
+ if(opts.lockBottom) {
110
+ // get the maximum scrollTop value but using scrollHeight
111
+ // (for overflow elements)
112
+ var bottomPos =
113
+ $obj.parent().prop('scrollHeight') - $obj.height() + opts.offsetY;
114
+
115
+ _emit_log("bottomPos [" + $obj.attr('id') + "]: " + bottomPos );
116
+
117
+ if( bottomPos < 0 )
118
+ bottomPos = 0;
119
+ }
120
+
121
+ // scroll attached to overflow element
122
+ $(p).scroll(function() {
123
+ var msg = "[" + $obj.attr('id') + "]: ";
124
+
125
+ // ** These don't appear to be needed inside scrolling overflow **
126
+ // check if the overflow element was scrolled down more
127
+ // than the start offset declared.
128
+ var pastStartOffset = $(this).scrollTop() > opts.startOffset;
129
+
130
+ // check if the object is at it's top position (starting point)
131
+ var objFartherThanTopPos = $obj.offset().top > opts.startOffset;
132
+
133
+ // scrollTop isn't completely correct here
134
+ // newpos will be need to take into account
135
+ var newpos = $(this).scrollTop() - opts.startOffset + opts.offsetY;
136
+
137
+ _emit_log(
138
+ msg +
139
+ "scrollTop: " + $(this).scrollTop() + " " +
140
+ "startOffset: " + opts.startOffset + " " +
141
+ "offsetY: " + opts.offsetY + " " +
142
+ "newpos: " + newpos + " " +
143
+ "bottomPos: " + bottomPos + " "
144
+ );
145
+
146
+ // stop scroll at bottom of parent
147
+ if ( newpos > bottomPos )
148
+ newpos = bottomPos;
149
+
150
+ if ( $(this).scrollTop() < opts.startOffset )
151
+ newpos = opts.offsetY;
152
+
153
+ $obj.stop();
154
+
155
+ if ( newpos < 0 )
156
+ newpos = 0;
157
+
158
+ // nothing to do here
159
+ //if ( !pastStartOffset && !objFartherThanTopPos )
160
+ // return;
161
+
162
+ // move until obj is outside of parent size, then stop
163
+ _emit_log(
164
+ msg +
165
+ "scrollTop: " + $(this).scrollTop() + " " +
166
+ "header + div size: " + ( $obj.parent().height() - $obj.height() ) + " " +
167
+ "newpos: " + newpos
168
+ );
169
+
170
+ $obj.animate({ top: newpos }, opts.duration );
171
+ });
172
+ };
173
+
174
+ function _emit_log(msg) {
175
+ if ( console.log && window.debug )
176
+ console.log(msg);
177
+ };
178
+ };
179
+ })(jQuery);
js/tryon/jquery.ui.button.js ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI Button @VERSION
3
+ *
4
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
6
+ * and GPL (GPL-LICENSE.txt) licenses.
7
+ *
8
+ * http://docs.jquery.com/UI/Button
9
+ *
10
+ * Depends:
11
+ * jquery.ui.core.js
12
+ */
13
+ (function($) {
14
+
15
+ var lastActive;
16
+
17
+ $.widget("ui.button", {
18
+ _init: function() {
19
+ var self = this;
20
+ this.element
21
+ .addClass("ui-button ui-widget ui-state-default ui-corner-all")
22
+ .bind("mouseenter.button", function() {
23
+ if (self.options.disabled) { return; }
24
+ $(this).addClass("ui-state-hover");
25
+ if (this == lastActive) {
26
+ $(this).addClass("ui-state-active");
27
+ }
28
+ })
29
+ .bind("mouseleave.button", function() {
30
+ if (self.options.disabled) { return; }
31
+ $(this).removeClass("ui-state-hover ui-state-active");
32
+ })
33
+ .bind("mousedown.button", function() {
34
+ if (self.options.disabled) { return; }
35
+ $(this).addClass("ui-state-active");
36
+ lastActive = this;
37
+ $(document).one('mouseup', function() {
38
+ lastActive = null;
39
+ });
40
+ })
41
+ .bind("mouseup.button", function() {
42
+ if (self.options.disabled) { return; }
43
+ $(this).removeClass("ui-state-active");
44
+ });
45
+ },
46
+
47
+ destroy: function() {
48
+ this.element
49
+ .removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-focus")
50
+ .unbind(".button");
51
+ $.widget.prototype.destroy.call(this);
52
+ }
53
+ });
54
+
55
+ // TODO merge with button-widget
56
+ $.widget("ui.toggleButton", {
57
+ _init: function() {
58
+ var self = this,
59
+ label = (this.label = $("[for='" + this.element.attr("id") + "']"));
60
+
61
+ label.add(this.element).hide();
62
+ this.button = $("<button/>")
63
+ .html("" + label.html())
64
+ .insertAfter(this.element)
65
+ .button()
66
+ .unbind("mousedown.button mouseup.button mouseleave.button")
67
+ .bind("click", function() {
68
+ if (self.options.disabled) { return; }
69
+ $(this).toggleClass("ui-state-active");
70
+ self.element.attr("checked", function() {
71
+ return !!this.checked;
72
+ })
73
+ .click();
74
+ })
75
+ .bind("mouseleave", function() {
76
+ if (self.options.disabled) { return; }
77
+ $(this).removeClass("ui-state-hover");
78
+ });
79
+
80
+ if (this.element.attr("checked")) {
81
+ this.button.addClass("ui-state-active");
82
+ }
83
+ },
84
+
85
+ destroy: function() {
86
+ this.element.add(this.label).show();
87
+ this.button.remove();
88
+ $.widget.prototype.destroy.call(this);
89
+ }
90
+ });
91
+
92
+ // TODO merge with button-widget
93
+ $.widget("ui.radioButton", {
94
+ _init: function() {
95
+ var self = this,
96
+ radios = (this.radios = this.element.find(":radio"));
97
+ self.buttons = $([]);
98
+ self.labels = $([]);
99
+ self.element.addClass("ui-button-set");
100
+ radios.each(function(index) {
101
+ var radio = $(this),
102
+ label = $("[for='" + this.id + "']");
103
+ label.add(radio).hide();
104
+ var button = $("<button/>")
105
+ .html("" + label.html())
106
+ .insertAfter(this)
107
+ .button()
108
+ .unbind("mousedown.button mouseup.button mouseleave.button")
109
+ .bind("click", function() {
110
+ if (self.options.disabled) { return; }
111
+ self.buttons.removeClass("ui-state-active");
112
+ $(this).addClass("ui-state-active");
113
+ radio.attr("checked", true).click();
114
+ })
115
+ .bind("mouseleave", function() {
116
+ if (self.options.disabled) { return; }
117
+ $(this).removeClass("ui-state-hover");
118
+ });
119
+
120
+ if (this.checked) {
121
+ button.addClass("ui-state-active");
122
+ }
123
+
124
+ self.buttons = self.buttons.add(button);
125
+ self.labels = self.labels.add(label);
126
+ });
127
+ },
128
+
129
+ destroy: function() {
130
+ this.buttons.remove();
131
+ this.labels.add(this.radios).show();
132
+ $.widget.prototype.destroy.call(this);
133
+ }
134
+ });
135
+
136
+ $.widget("ui.buttons", {
137
+ _init: function() {
138
+ var buttons = this.buttons = this.element.find("button").button();
139
+ if (!buttons.length) {
140
+ this.toggle = this.element.find(":checkbox").toggleButton();
141
+ buttons = this.toggle.next();
142
+ }
143
+ if (!buttons.length && this.element.is(":has(:radio)")) {
144
+ this.radio = this.element.radioButton();
145
+ buttons = this.radio.find("button");
146
+ }
147
+ if (buttons.length) {
148
+ this.element.addClass("ui-button-set");
149
+ buttons.removeClass("ui-corner-all");
150
+ buttons.filter(":first").addClass("ui-corner-left");
151
+ buttons.filter(":last").addClass("ui-corner-right");
152
+ } else {
153
+ this.buttons = this.element.filter("button").button();
154
+ }
155
+ },
156
+
157
+ destroy: function() {
158
+ if (this.toggle) {
159
+ this.toggle.toggleButton("destroy");
160
+ }
161
+ if (this.radio) {
162
+ this.radio.radioButton("destroy");
163
+ }
164
+ this.buttons.button("destroy");
165
+ $.widget.prototype.destroy.call(this);
166
+ }
167
+ });
168
+
169
+
170
+ })(jQuery);
js/tryon/jquery.ui.core.js ADDED
@@ -0,0 +1,334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery UI 1.8.24
3
+ *
4
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT or GPL Version 2 licenses.
6
+ * http://jquery.org/license
7
+ *
8
+ * http://docs.jquery.com/UI
9
+ */
10
+ (function( $, undefined ) {
11
+
12
+ // prevent duplicate loading
13
+ // this is only a problem because we proxy existing functions
14
+ // and we don't want to double proxy them
15
+ $.ui = $.ui || {};
16
+ if ( $.ui.version ) {
17
+ return;
18
+ }
19
+
20
+ $.extend( $.ui, {
21
+ version: "1.8.24",
22
+
23
+ keyCode: {
24
+ ALT: 18,
25
+ BACKSPACE: 8,
26
+ CAPS_LOCK: 20,
27
+ COMMA: 188,
28
+ COMMAND: 91,
29
+ COMMAND_LEFT: 91, // COMMAND
30
+ COMMAND_RIGHT: 93,
31
+ CONTROL: 17,
32
+ DELETE: 46,
33
+ DOWN: 40,
34
+ END: 35,
35
+ ENTER: 13,
36
+ ESCAPE: 27,
37
+ HOME: 36,
38
+ INSERT: 45,
39
+ LEFT: 37,
40
+ MENU: 93, // COMMAND_RIGHT
41
+ NUMPAD_ADD: 107,
42
+ NUMPAD_DECIMAL: 110,
43
+ NUMPAD_DIVIDE: 111,
44
+ NUMPAD_ENTER: 108,
45
+ NUMPAD_MULTIPLY: 106,
46
+ NUMPAD_SUBTRACT: 109,
47
+ PAGE_DOWN: 34,
48
+ PAGE_UP: 33,
49
+ PERIOD: 190,
50
+ RIGHT: 39,
51
+ SHIFT: 16,
52
+ SPACE: 32,
53
+ TAB: 9,
54
+ UP: 38,
55
+ WINDOWS: 91 // COMMAND
56
+ }
57
+ });
58
+
59
+ // plugins
60
+ $.fn.extend({
61
+ propAttr: $.fn.prop || $.fn.attr,
62
+
63
+ _focus: $.fn.focus,
64
+ focus: function( delay, fn ) {
65
+ return typeof delay === "number" ?
66
+ this.each(function() {
67
+ var elem = this;
68
+ setTimeout(function() {
69
+ $( elem ).focus();
70
+ if ( fn ) {
71
+ fn.call( elem );
72
+ }
73
+ }, delay );
74
+ }) :
75
+ this._focus.apply( this, arguments );
76
+ },
77
+
78
+ scrollParent: function() {
79
+ var scrollParent;
80
+ if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
81
+ scrollParent = this.parents().filter(function() {
82
+ 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));
83
+ }).eq(0);
84
+ } else {
85
+ scrollParent = this.parents().filter(function() {
86
+ return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
87
+ }).eq(0);
88
+ }
89
+
90
+ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
91
+ },
92
+
93
+ zIndex: function( zIndex ) {
94
+ if ( zIndex !== undefined ) {
95
+ return this.css( "zIndex", zIndex );
96
+ }
97
+
98
+ if ( this.length ) {
99
+ var elem = $( this[ 0 ] ), position, value;
100
+ while ( elem.length && elem[ 0 ] !== document ) {
101
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
102
+ // This makes behavior of this function consistent across browsers
103
+ // WebKit always returns auto if the element is positioned
104
+ position = elem.css( "position" );
105
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
106
+ // IE returns 0 when zIndex is not specified
107
+ // other browsers return a string
108
+ // we ignore the case of nested elements with an explicit value of 0
109
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
110
+ value = parseInt( elem.css( "zIndex" ), 10 );
111
+ if ( !isNaN( value ) && value !== 0 ) {
112
+ return value;
113
+ }
114
+ }
115
+ elem = elem.parent();
116
+ }
117
+ }
118
+
119
+ return 0;
120
+ },
121
+
122
+ disableSelection: function() {
123
+ return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
124
+ ".ui-disableSelection", function( event ) {
125
+ event.preventDefault();
126
+ });
127
+ },
128
+
129
+ enableSelection: function() {
130
+ return this.unbind( ".ui-disableSelection" );
131
+ }
132
+ });
133
+
134
+ // support: jQuery <1.8
135
+ if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
136
+ $.each( [ "Width", "Height" ], function( i, name ) {
137
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
138
+ type = name.toLowerCase(),
139
+ orig = {
140
+ innerWidth: $.fn.innerWidth,
141
+ innerHeight: $.fn.innerHeight,
142
+ outerWidth: $.fn.outerWidth,
143
+ outerHeight: $.fn.outerHeight
144
+ };
145
+
146
+ function reduce( elem, size, border, margin ) {
147
+ $.each( side, function() {
148
+ size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
149
+ if ( border ) {
150
+ size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
151
+ }
152
+ if ( margin ) {
153
+ size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
154
+ }
155
+ });
156
+ return size;
157
+ }
158
+
159
+ $.fn[ "inner" + name ] = function( size ) {
160
+ if ( size === undefined ) {
161
+ return orig[ "inner" + name ].call( this );
162
+ }
163
+
164
+ return this.each(function() {
165
+ $( this ).css( type, reduce( this, size ) + "px" );
166
+ });
167
+ };
168
+
169
+ $.fn[ "outer" + name] = function( size, margin ) {
170
+ if ( typeof size !== "number" ) {
171
+ return orig[ "outer" + name ].call( this, size );
172
+ }
173
+
174
+ return this.each(function() {
175
+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
176
+ });
177
+ };
178
+ });
179
+ }
180
+
181
+ // selectors
182
+ function focusable( element, isTabIndexNotNaN ) {
183
+ var nodeName = element.nodeName.toLowerCase();
184
+ if ( "area" === nodeName ) {
185
+ var map = element.parentNode,
186
+ mapName = map.name,
187
+ img;
188
+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
189
+ return false;
190
+ }
191
+ img = $( "img[usemap=#" + mapName + "]" )[0];
192
+ return !!img && visible( img );
193
+ }
194
+ return ( /input|select|textarea|button|object/.test( nodeName )
195
+ ? !element.disabled
196
+ : "a" == nodeName
197
+ ? element.href || isTabIndexNotNaN
198
+ : isTabIndexNotNaN)
199
+ // the element and all of its ancestors must be visible
200
+ && visible( element );
201
+ }
202
+
203
+ function visible( element ) {
204
+ return !$( element ).parents().andSelf().filter(function() {
205
+ return $.curCSS( this, "visibility" ) === "hidden" ||
206
+ $.expr.filters.hidden( this );
207
+ }).length;
208
+ }
209
+
210
+ $.extend( $.expr[ ":" ], {
211
+ data: $.expr.createPseudo ?
212
+ $.expr.createPseudo(function( dataName ) {
213
+ return function( elem ) {
214
+ return !!$.data( elem, dataName );
215
+ };
216
+ }) :
217
+ // support: jQuery <1.8
218
+ function( elem, i, match ) {
219
+ return !!$.data( elem, match[ 3 ] );
220
+ },
221
+
222
+ focusable: function( element ) {
223
+ return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
224
+ },
225
+
226
+ tabbable: function( element ) {
227
+ var tabIndex = $.attr( element, "tabindex" ),
228
+ isTabIndexNaN = isNaN( tabIndex );
229
+ return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
230
+ }
231
+ });
232
+
233
+ // support
234
+ $(function() {
235
+ var body = document.body,
236
+ div = body.appendChild( div = document.createElement( "div" ) );
237
+
238
+ // access offsetHeight before setting the style to prevent a layout bug
239
+ // in IE 9 which causes the elemnt to continue to take up space even
240
+ // after it is removed from the DOM (#8026)
241
+ div.offsetHeight;
242
+
243
+ $.extend( div.style, {
244
+ minHeight: "100px",
245
+ height: "auto",
246
+ padding: 0,
247
+ borderWidth: 0
248
+ });
249
+
250
+ $.support.minHeight = div.offsetHeight === 100;
251
+ $.support.selectstart = "onselectstart" in div;
252
+
253
+ // set display to none to avoid a layout bug in IE
254
+ // http://dev.jquery.com/ticket/4014
255
+ body.removeChild( div ).style.display = "none";
256
+ });
257
+
258
+ // jQuery <1.4.3 uses curCSS, in 1.4.3 - 1.7.2 curCSS = css, 1.8+ only has css
259
+ if ( !$.curCSS ) {
260
+ $.curCSS = $.css;
261
+ }
262
+
263
+
264
+
265
+
266
+
267
+ // deprecated
268
+ $.extend( $.ui, {
269
+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
270
+ plugin: {
271
+ add: function( module, option, set ) {
272
+ var proto = $.ui[ module ].prototype;
273
+ for ( var i in set ) {
274
+ proto.plugins[ i ] = proto.plugins[ i ] || [];
275
+ proto.plugins[ i ].push( [ option, set[ i ] ] );
276
+ }
277
+ },
278
+ call: function( instance, name, args ) {
279
+ var set = instance.plugins[ name ];
280
+ if ( !set || !instance.element[ 0 ].parentNode ) {
281
+ return;
282
+ }
283
+
284
+ for ( var i = 0; i < set.length; i++ ) {
285
+ if ( instance.options[ set[ i ][ 0 ] ] ) {
286
+ set[ i ][ 1 ].apply( instance.element, args );
287
+ }
288
+ }
289
+ }
290
+ },
291
+
292
+ // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
293
+ contains: function( a, b ) {
294
+ return document.compareDocumentPosition ?
295
+ a.compareDocumentPosition( b ) & 16 :
296
+ a !== b && a.contains( b );
297
+ },
298
+
299
+ // only used by resizable
300
+ hasScroll: function( el, a ) {
301
+
302
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
303
+ if ( $( el ).css( "overflow" ) === "hidden") {
304
+ return false;
305
+ }
306
+
307
+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
308
+ has = false;
309
+
310
+ if ( el[ scroll ] > 0 ) {
311
+ return true;
312
+ }
313
+
314
+ // TODO: determine which cases actually cause this to happen
315
+ // if the element doesn't have the scroll set, see if it's possible to
316
+ // set the scroll
317
+ el[ scroll ] = 1;
318
+ has = ( el[ scroll ] > 0 );
319
+ el[ scroll ] = 0;
320
+ return has;
321
+ },
322
+
323
+ // these are odd functions, fix the API or move into individual plugins
324
+ isOverAxis: function( x, reference, size ) {
325
+ //Determines when x coordinate is over "b" element axis
326
+ return ( x > reference ) && ( x < ( reference + size ) );
327
+ },
328
+ isOver: function( y, x, top, left, height, width ) {
329
+ //Determines when x, y coordinates is over "b" element
330
+ return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
331
+ }
332
+ });
333
+
334
+ })( jQuery );
js/tryon/jquery.ui.dialog.js ADDED
@@ -0,0 +1,820 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI Dialog @VERSION
3
+ *
4
+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
6
+ * and GPL (GPL-LICENSE.txt) licenses.
7
+ *
8
+ * http://docs.jquery.com/UI/Dialog
9
+ *
10
+ * Depends:
11
+ * jquery.ui.core.js
12
+ * jquery.ui.widget.js
13
+ * jquery.ui.button.js
14
+ * jquery.ui.draggable.js
15
+ * jquery.ui.mouse.js
16
+ * jquery.ui.position.js
17
+ * jquery.ui.resizable.js
18
+ */
19
+ (function($) {
20
+
21
+ var uiDialogClasses =
22
+ 'ui-dialog ' +
23
+ 'ui-widget ' +
24
+ 'ui-widget-content ' +
25
+ 'ui-corner-all ';
26
+
27
+ $.widget("ui.dialog", {
28
+ options: {
29
+ autoOpen: true,
30
+ buttons: {},
31
+ closeOnEscape: true,
32
+ closeText: 'close',
33
+ dialogClass: '',
34
+ draggable: true,
35
+ hide: null,
36
+ height: 'auto',
37
+ maxHeight: false,
38
+ maxWidth: false,
39
+ minHeight: 150,
40
+ minWidth: 150,
41
+ modal: false,
42
+ position: 'center',
43
+ resizable: true,
44
+ show: null,
45
+ stack: true,
46
+ title: '',
47
+ width: 300,
48
+ zIndex: 1000
49
+ },
50
+ _create: function() {
51
+ this.originalTitle = this.element.attr('title');
52
+
53
+ var self = this,
54
+ options = self.options,
55
+
56
+ title = options.title || self.originalTitle || '&#160;',
57
+ titleId = $.ui.dialog.getTitleId(self.element),
58
+
59
+ uiDialog = (self.uiDialog = $('<div></div>'))
60
+ .appendTo(document.body)
61
+ .hide()
62
+ .addClass(uiDialogClasses + options.dialogClass)
63
+ .css({
64
+ zIndex: options.zIndex
65
+ })
66
+ // setting tabIndex makes the div focusable
67
+ // setting outline to 0 prevents a border on focus in Mozilla
68
+ .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
69
+ if (options.closeOnEscape && event.keyCode &&
70
+ event.keyCode === $.ui.keyCode.ESCAPE) {
71
+
72
+ self.close(event);
73
+ event.preventDefault();
74
+ }
75
+ })
76
+ .attr({
77
+ role: 'dialog',
78
+ 'aria-labelledby': titleId
79
+ })
80
+ .mousedown(function(event) {
81
+ self.moveToTop(false, event);
82
+ }),
83
+
84
+ uiDialogContent = self.element
85
+ .show()
86
+ .removeAttr('title')
87
+ .addClass(
88
+ 'ui-dialog-content ' +
89
+ 'ui-widget-content')
90
+ .appendTo(uiDialog),
91
+
92
+ uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
93
+ .addClass(
94
+ 'ui-dialog-titlebar ' +
95
+ 'ui-widget-header ' +
96
+ 'ui-corner-all ' +
97
+ 'ui-helper-clearfix'
98
+ )
99
+ .prependTo(uiDialog),
100
+
101
+ uiDialogTitlebarClose = $('<a href="#"></a>')
102
+ .addClass(
103
+ 'ui-dialog-titlebar-close ' +
104
+ 'ui-corner-all'
105
+ )
106
+ .attr('role', 'button')
107
+ .hover(
108
+ function() {
109
+ uiDialogTitlebarClose.addClass('ui-state-hover');
110
+ },
111
+ function() {
112
+ uiDialogTitlebarClose.removeClass('ui-state-hover');
113
+ }
114
+ )
115
+ .focus(function() {
116
+ uiDialogTitlebarClose.addClass('ui-state-focus');
117
+ })
118
+ .blur(function() {
119
+ uiDialogTitlebarClose.removeClass('ui-state-focus');
120
+ })
121
+ .click(function(event) {
122
+ self.close(event);
123
+ return false;
124
+ })
125
+ .appendTo(uiDialogTitlebar),
126
+
127
+ uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
128
+ .addClass(
129
+ 'ui-icon ' +
130
+ 'ui-icon-closethick'
131
+ )
132
+ .text(options.closeText)
133
+ .appendTo(uiDialogTitlebarClose),
134
+
135
+ uiDialogTitle = $('<span></span>')
136
+ .addClass('ui-dialog-title')
137
+ .attr('id', titleId)
138
+ .html(title)
139
+ .prependTo(uiDialogTitlebar);
140
+
141
+ //handling of deprecated beforeclose (vs beforeClose) option
142
+ //Ticket #4669 http://dev.jqueryui.com/ticket/4669
143
+ //TODO: remove in 1.9pre
144
+ if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
145
+ options.beforeClose = options.beforeclose;
146
+ }
147
+
148
+ uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
149
+
150
+ if (options.draggable && $.fn.draggable) {
151
+ self._makeDraggable();
152
+ }
153
+ if (options.resizable && $.fn.resizable) {
154
+ self._makeResizable();
155
+ }
156
+
157
+ self._createButtons(options.buttons);
158
+ self._isOpen = false;
159
+
160
+ if ($.fn.bgiframe) {
161
+ uiDialog.bgiframe();
162
+ }
163
+ },
164
+ _init: function() {
165
+ if ( this.options.autoOpen ) {
166
+ this.open();
167
+ }
168
+ },
169
+
170
+ destroy: function() {
171
+ var self = this;
172
+
173
+ if (self.overlay) {
174
+ self.overlay.destroy();
175
+ }
176
+ self.uiDialog.hide();
177
+ self.element
178
+ .unbind('.dialog')
179
+ .removeData('dialog')
180
+ .removeClass('ui-dialog-content ui-widget-content')
181
+ .hide().appendTo('body');
182
+ self.uiDialog.remove();
183
+
184
+ if (self.originalTitle) {
185
+ self.element.attr('title', self.originalTitle);
186
+ }
187
+
188
+ return self;
189
+ },
190
+
191
+ widget: function() {
192
+ return this.uiDialog;
193
+ },
194
+
195
+ close: function(event) {
196
+ var self = this,
197
+ maxZ;
198
+
199
+ if (false === self._trigger('beforeClose', event)) {
200
+ return;
201
+ }
202
+
203
+ if (self.overlay) {
204
+ self.overlay.destroy();
205
+ }
206
+ self.uiDialog.unbind('keypress.ui-dialog');
207
+
208
+ self._isOpen = false;
209
+
210
+ if (self.options.hide) {
211
+ self.uiDialog.hide(self.options.hide, function() {
212
+ self._trigger('close', event);
213
+ });
214
+ } else {
215
+ self.uiDialog.hide();
216
+ self._trigger('close', event);
217
+ }
218
+
219
+ $.ui.dialog.overlay.resize();
220
+
221
+ // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
222
+ if (self.options.modal) {
223
+ maxZ = 0;
224
+ $('.ui-dialog').each(function() {
225
+ if (this !== self.uiDialog[0]) {
226
+ maxZ = Math.max(maxZ, $(this).css('z-index'));
227
+ }
228
+ });
229
+ $.ui.dialog.maxZ = maxZ;
230
+ }
231
+
232
+ return self;
233
+ },
234
+
235
+ isOpen: function() {
236
+ return this._isOpen;
237
+ },
238
+
239
+ // the force parameter allows us to move modal dialogs to their correct
240
+ // position on open
241
+ moveToTop: function(force, event) {
242
+ var self = this,
243
+ options = self.options,
244
+ saveScroll;
245
+
246
+ if ((options.modal && !force) ||
247
+ (!options.stack && !options.modal)) {
248
+ return self._trigger('focus', event);
249
+ }
250
+
251
+ if (options.zIndex > $.ui.dialog.maxZ) {
252
+ $.ui.dialog.maxZ = options.zIndex;
253
+ }
254
+ if (self.overlay) {
255
+ $.ui.dialog.maxZ += 1;
256
+ self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
257
+ }
258
+
259
+ //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
260
+ // http://ui.jquery.com/bugs/ticket/3193
261
+ saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') };
262
+ $.ui.dialog.maxZ += 1;
263
+ self.uiDialog.css('z-index', $.ui.dialog.maxZ);
264
+ self.element.attr(saveScroll);
265
+ self._trigger('focus', event);
266
+
267
+ return self;
268
+ },
269
+
270
+ open: function() {
271
+ if (this._isOpen) { return; }
272
+
273
+ var self = this,
274
+ options = self.options,
275
+ uiDialog = self.uiDialog;
276
+
277
+ self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
278
+ if (uiDialog.next().length) {
279
+ uiDialog.appendTo('body');
280
+ }
281
+ self._size();
282
+ self._position(options.position);
283
+ uiDialog.show(options.show);
284
+ self.moveToTop(true);
285
+
286
+ // prevent tabbing out of modal dialogs
287
+ if (options.modal) {
288
+ uiDialog.bind('keypress.ui-dialog', function(event) {
289
+ if (event.keyCode !== $.ui.keyCode.TAB) {
290
+ return;
291
+ }
292
+
293
+ var tabbables = $(':tabbable', this),
294
+ first = tabbables.filter(':first'),
295
+ last = tabbables.filter(':last');
296
+
297
+ if (event.target === last[0] && !event.shiftKey) {
298
+ first.focus(1);
299
+ return false;
300
+ } else if (event.target === first[0] && event.shiftKey) {
301
+ last.focus(1);
302
+ return false;
303
+ }
304
+ });
305
+ }
306
+
307
+ // set focus to the first tabbable element in the content area or the first button
308
+ // if there are no tabbable elements, set focus on the dialog itself
309
+ $([])
310
+ .add(uiDialog.find('.ui-dialog-content :tabbable:first'))
311
+ .add(uiDialog.find('.ui-dialog-buttonpane :tabbable:first'))
312
+ .add(uiDialog)
313
+ .filter(':first')
314
+ .focus();
315
+
316
+ self._trigger('open');
317
+ self._isOpen = true;
318
+
319
+ return self;
320
+ },
321
+
322
+ _createButtons: function(buttons) {
323
+ var self = this,
324
+ hasButtons = false,
325
+ uiDialogButtonPane = $('<div></div>')
326
+ .addClass(
327
+ 'ui-dialog-buttonpane ' +
328
+ 'ui-widget-content ' +
329
+ 'ui-helper-clearfix'
330
+ );
331
+
332
+ // if we already have a button pane, remove it
333
+ self.uiDialog.find('.ui-dialog-buttonpane').remove();
334
+
335
+ if (typeof buttons === 'object' && buttons !== null) {
336
+ $.each(buttons, function() {
337
+ return !(hasButtons = true);
338
+ });
339
+ }
340
+ if (hasButtons) {
341
+ $.each(buttons, function(name, fn) {
342
+ var button = $('<button type="button"></button>')
343
+ .text(name)
344
+ .click(function() { fn.apply(self.element[0], arguments); })
345
+ .appendTo(uiDialogButtonPane);
346
+ if ($.fn.button) {
347
+ button.button();
348
+ }
349
+ });
350
+ uiDialogButtonPane.appendTo(self.uiDialog);
351
+ }
352
+ },
353
+
354
+ _makeDraggable: function() {
355
+ var self = this,
356
+ options = self.options,
357
+ doc = $(document),
358
+ heightBeforeDrag;
359
+
360
+ function filteredUi(ui) {
361
+ return {
362
+ position: ui.position,
363
+ offset: ui.offset
364
+ };
365
+ }
366
+
367
+ self.uiDialog.draggable({
368
+ cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
369
+ handle: '.ui-dialog-titlebar',
370
+ containment: 'document',
371
+ start: function(event, ui) {
372
+ heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
373
+ $(this).height($(this).height()).addClass("ui-dialog-dragging");
374
+ self._trigger('dragStart', event, filteredUi(ui));
375
+ },
376
+ drag: function(event, ui) {
377
+ self._trigger('drag', event, filteredUi(ui));
378
+ },
379
+ stop: function(event, ui) {
380
+ options.position = [ui.position.left - doc.scrollLeft(),
381
+ ui.position.top - doc.scrollTop()];
382
+ $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
383
+ self._trigger('dragStop', event, filteredUi(ui));
384
+ $.ui.dialog.overlay.resize();
385
+ }
386
+ });
387
+ },
388
+
389
+ _makeResizable: function(handles) {
390
+ handles = (handles === undefined ? this.options.resizable : handles);
391
+ var self = this,
392
+ options = self.options,
393
+ // .ui-resizable has position: relative defined in the stylesheet
394
+ // but dialogs have to use absolute or fixed positioning
395
+ position = self.uiDialog.css('position'),
396
+ resizeHandles = (typeof handles === 'string' ?
397
+ handles :
398
+ 'n,e,s,w,se,sw,ne,nw'
399
+ );
400
+
401
+ function filteredUi(ui) {
402
+ return {
403
+ originalPosition: ui.originalPosition,
404
+ originalSize: ui.originalSize,
405
+ position: ui.position,
406
+ size: ui.size
407
+ };
408
+ }
409
+
410
+ self.uiDialog.resizable({
411
+ cancel: '.ui-dialog-content',
412
+ containment: 'document',
413
+ alsoResize: self.element,
414
+ maxWidth: options.maxWidth,
415
+ maxHeight: options.maxHeight,
416
+ minWidth: options.minWidth,
417
+ minHeight: self._minHeight(),
418
+ handles: resizeHandles,
419
+ start: function(event, ui) {
420
+ $(this).addClass("ui-dialog-resizing");
421
+ self._trigger('resizeStart', event, filteredUi(ui));
422
+ },
423
+ resize: function(event, ui) {
424
+ self._trigger('resize', event, filteredUi(ui));
425
+ },
426
+ stop: function(event, ui) {
427
+ $(this).removeClass("ui-dialog-resizing");
428
+ options.height = $(this).height();
429
+ options.width = $(this).width();
430
+ self._trigger('resizeStop', event, filteredUi(ui));
431
+ $.ui.dialog.overlay.resize();
432
+ }
433
+ })
434
+ .css('position', position)
435
+ .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
436
+ },
437
+
438
+ _minHeight: function() {
439
+ var options = this.options;
440
+
441
+ if (options.height === 'auto') {
442
+ return options.minHeight;
443
+ } else {
444
+ return Math.min(options.minHeight, options.height);
445
+ }
446
+ },
447
+
448
+ _position: function(position) {
449
+ var myAt = [],
450
+ offset = [0, 0],
451
+ isVisible;
452
+
453
+ position = position || $.ui.dialog.prototype.options.position;
454
+
455
+ // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
456
+ // if (typeof position == 'string' || $.isArray(position)) {
457
+ // myAt = $.isArray(position) ? position : position.split(' ');
458
+
459
+ if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
460
+ myAt = position.split ? position.split(' ') : [position[0], position[1]];
461
+ if (myAt.length === 1) {
462
+ myAt[1] = myAt[0];
463
+ }
464
+
465
+ $.each(['left', 'top'], function(i, offsetPosition) {
466
+ if (+myAt[i] === myAt[i]) {
467
+ offset[i] = myAt[i];
468
+ myAt[i] = offsetPosition;
469
+ }
470
+ });
471
+ } else if (typeof position === 'object') {
472
+ if ('left' in position) {
473
+ myAt[0] = 'left';
474
+ offset[0] = position.left;
475
+ } else if ('right' in position) {
476
+ myAt[0] = 'right';
477
+ offset[0] = -position.right;
478
+ }
479
+
480
+ if ('top' in position) {
481
+ myAt[1] = 'top';
482
+ offset[1] = position.top;
483
+ } else if ('bottom' in position) {
484
+ myAt[1] = 'bottom';
485
+ offset[1] = -position.bottom;
486
+ }
487
+ }
488
+
489
+ // need to show the dialog to get the actual offset in the position plugin
490
+ isVisible = this.uiDialog.is(':visible');
491
+ if (!isVisible) {
492
+ this.uiDialog.show();
493
+ }
494
+ this.uiDialog
495
+ // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
496
+ .css({ top: 0, left: 0 })
497
+ .position({
498
+ my: myAt.join(' '),
499
+ at: myAt.join(' '),
500
+ offset: offset.join(' '),
501
+ of: window,
502
+ collision: 'fit',
503
+ // ensure that the titlebar is never outside the document
504
+ using: function(pos) {
505
+ var topOffset = $(this).css(pos).offset().top;
506
+ if (topOffset < 0) {
507
+ $(this).css('top', pos.top - topOffset);
508
+ }
509
+ }
510
+ });
511
+ if (!isVisible) {
512
+ this.uiDialog.hide();
513
+ }
514
+ },
515
+
516
+ _setOption: function(key, value){
517
+ var self = this,
518
+ uiDialog = self.uiDialog,
519
+ isResizable = uiDialog.is(':data(resizable)'),
520
+ resize = false;
521
+
522
+ switch (key) {
523
+ //handling of deprecated beforeclose (vs beforeClose) option
524
+ //Ticket #4669 http://dev.jqueryui.com/ticket/4669
525
+ //TODO: remove in 1.9pre
526
+ case "beforeclose":
527
+ key = "beforeClose";
528
+ break;
529
+ case "buttons":
530
+ self._createButtons(value);
531
+ break;
532
+ case "closeText":
533
+ // convert whatever was passed in to a string, for text() to not throw up
534
+ self.uiDialogTitlebarCloseText.text("" + value);
535
+ break;
536
+ case "dialogClass":
537
+ uiDialog
538
+ .removeClass(self.options.dialogClass)
539
+ .addClass(uiDialogClasses + value);
540
+ break;
541
+ case "disabled":
542
+ if (value) {
543
+ uiDialog.addClass('ui-dialog-disabled');
544
+ } else {
545
+ uiDialog.removeClass('ui-dialog-disabled');
546
+ }
547
+ break;
548
+ case "draggable":
549
+ if (value) {
550
+ self._makeDraggable();
551
+ } else {
552
+ uiDialog.draggable('destroy');
553
+ }
554
+ break;
555
+ case "height":
556
+ resize = true;
557
+ break;
558
+ case "maxHeight":
559
+ if (isResizable) {
560
+ uiDialog.resizable('option', 'maxHeight', value);
561
+ }
562
+ resize = true;
563
+ break;
564
+ case "maxWidth":
565
+ if (isResizable) {
566
+ uiDialog.resizable('option', 'maxWidth', value);
567
+ }
568
+ resize = true;
569
+ break;
570
+ case "minHeight":
571
+ if (isResizable) {
572
+ uiDialog.resizable('option', 'minHeight', value);
573
+ }
574
+ resize = true;
575
+ break;
576
+ case "minWidth":
577
+ if (isResizable) {
578
+ uiDialog.resizable('option', 'minWidth', value);
579
+ }
580
+ resize = true;
581
+ break;
582
+ case "position":
583
+ self._position(value);
584
+ break;
585
+ case "resizable":
586
+ // currently resizable, becoming non-resizable
587
+ if (isResizable && !value) {
588
+ uiDialog.resizable('destroy');
589
+ }
590
+
591
+ // currently resizable, changing handles
592
+ if (isResizable && typeof value === 'string') {
593
+ uiDialog.resizable('option', 'handles', value);
594
+ }
595
+
596
+ // currently non-resizable, becoming resizable
597
+ if (!isResizable && value !== false) {
598
+ self._makeResizable(value);
599
+ }
600
+ break;
601
+ case "title":
602
+ // convert whatever was passed in o a string, for html() to not throw up
603
+ $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
604
+ break;
605
+ case "width":
606
+ resize = true;
607
+ break;
608
+ }
609
+
610
+ $.Widget.prototype._setOption.apply(self, arguments);
611
+ if (resize) {
612
+ self._size();
613
+ }
614
+ },
615
+
616
+ _size: function() {
617
+ /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
618
+ * divs will both have width and height set, so we need to reset them
619
+ */
620
+ var options = this.options,
621
+ nonContentHeight;
622
+
623
+ // reset content sizing
624
+ // hide for non content measurement because height: 0 doesn't work in IE quirks mode (see #4350)
625
+ this.element.css('width', 'auto')
626
+ .hide();
627
+
628
+ // reset wrapper sizing
629
+ // determine the height of all the non-content elements
630
+ nonContentHeight = this.uiDialog.css({
631
+ height: 'auto',
632
+ width: options.width
633
+ })
634
+ .height();
635
+
636
+ this.element
637
+ .css(options.height === 'auto' ? {
638
+ minHeight: Math.max(options.minHeight - nonContentHeight, 0),
639
+ height: 'auto'
640
+ } : {
641
+ minHeight: 0,
642
+ height: Math.max(options.height - nonContentHeight, 0)
643
+ })
644
+ .show();
645
+
646
+ if (this.uiDialog.is(':data(resizable)')) {
647
+ this.uiDialog.resizable('option', 'minHeight', this._minHeight());
648
+ }
649
+ }
650
+ });
651
+
652
+ $.extend($.ui.dialog, {
653
+ version: "@VERSION",
654
+
655
+ uuid: 0,
656
+ maxZ: 0,
657
+
658
+ getTitleId: function($el) {
659
+ var id = $el.attr('id');
660
+ if (!id) {
661
+ this.uuid += 1;
662
+ id = this.uuid;
663
+ }
664
+ return 'ui-dialog-title-' + id;
665
+ },
666
+
667
+ overlay: function(dialog) {
668
+ this.$el = $.ui.dialog.overlay.create(dialog);
669
+ }
670
+ });
671
+
672
+ $.extend($.ui.dialog.overlay, {
673
+ instances: [],
674
+ // reuse old instances due to IE memory leak with alpha transparency (see #5185)
675
+ oldInstances: [],
676
+ maxZ: 0,
677
+ events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
678
+ function(event) { return event + '.dialog-overlay'; }).join(' '),
679
+ create: function(dialog) {
680
+ if (this.instances.length === 0) {
681
+ // prevent use of anchors and inputs
682
+ // we use a setTimeout in case the overlay is created from an
683
+ // event that we're going to be cancelling (see #2804)
684
+ setTimeout(function() {
685
+ // handle $(el).dialog().dialog('close') (see #4065)
686
+ if ($.ui.dialog.overlay.instances.length) {
687
+ $(document).bind($.ui.dialog.overlay.events, function(event) {
688
+ // stop events if the z-index of the target is < the z-index of the overlay
689
+ return ($(event.target).zIndex() >= $.ui.dialog.overlay.maxZ);
690
+ });
691
+ }
692
+ }, 1);
693
+
694
+ // allow closing by pressing the escape key
695
+ $(document).bind('keydown.dialog-overlay', function(event) {
696
+ if (dialog.options.closeOnEscape && event.keyCode &&
697
+ event.keyCode === $.ui.keyCode.ESCAPE) {
698
+
699
+ dialog.close(event);
700
+ event.preventDefault();
701
+ }
702
+ });
703
+
704
+ // handle window resize
705
+ $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
706
+ }
707
+
708
+ var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
709
+ .appendTo(document.body)
710
+ .css({
711
+ width: this.width(),
712
+ height: this.height()
713
+ });
714
+
715
+ if ($.fn.bgiframe) {
716
+ $el.bgiframe();
717
+ }
718
+
719
+ this.instances.push($el);
720
+ return $el;
721
+ },
722
+
723
+ destroy: function($el) {
724
+ this.oldInstances.push(this.instances.splice($.inArray($el, this.instances), 1)[0]);
725
+
726
+ if (this.instances.length === 0) {
727
+ $([document, window]).unbind('.dialog-overlay');
728
+ }
729
+
730
+ $el.remove();
731
+
732
+ // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
733
+ var maxZ = 0;
734
+ $.each(this.instances, function() {
735
+ maxZ = Math.max(maxZ, this.css('z-index'));
736
+ });
737
+ this.maxZ = maxZ;
738
+ },
739
+
740
+ height: function() {
741
+ var scrollHeight,
742
+ offsetHeight;
743
+ // handle IE 6
744
+ if ($.browser.msie && $.browser.version < 7) {
745
+ scrollHeight = Math.max(
746
+ document.documentElement.scrollHeight,
747
+ document.body.scrollHeight
748
+ );
749
+ offsetHeight = Math.max(
750
+ document.documentElement.offsetHeight,
751
+ document.body.offsetHeight
752
+ );
753
+
754
+ if (scrollHeight < offsetHeight) {
755
+ return $(window).height() + 'px';
756
+ } else {
757
+ return scrollHeight + 'px';
758
+ }
759
+ // handle "good" browsers
760
+ } else {
761
+ return $(document).height() + 'px';
762
+ }
763
+ },
764
+
765
+ width: function() {
766
+ var scrollWidth,
767
+ offsetWidth;
768
+ // handle IE 6
769
+ if ($.browser.msie && $.browser.version < 7) {
770
+ scrollWidth = Math.max(
771
+ document.documentElement.scrollWidth,
772
+ document.body.scrollWidth
773
+ );
774
+ offsetWidth = Math.max(
775
+ document.documentElement.offsetWidth,
776
+ document.body.offsetWidth
777
+ );
778
+
779
+ if (scrollWidth < offsetWidth) {
780
+ return $(window).width() + 'px';
781
+ } else {
782
+ return scrollWidth + 'px';
783
+ }
784
+ // handle "good" browsers
785
+ } else {
786
+ return $(document).width() + 'px';
787
+ }
788
+ },
789
+
790
+ resize: function() {
791
+ /* If the dialog is draggable and the user drags it past the
792
+ * right edge of the window, the document becomes wider so we
793
+ * need to stretch the overlay. If the user then drags the
794
+ * dialog back to the left, the document will become narrower,
795
+ * so we need to shrink the overlay to the appropriate size.
796
+ * This is handled by shrinking the overlay before setting it
797
+ * to the full document size.
798
+ */
799
+ var $overlays = $([]);
800
+ $.each($.ui.dialog.overlay.instances, function() {
801
+ $overlays = $overlays.add(this);
802
+ });
803
+
804
+ $overlays.css({
805
+ width: 0,
806
+ height: 0
807
+ }).css({
808
+ width: $.ui.dialog.overlay.width(),
809
+ height: $.ui.dialog.overlay.height()
810
+ });
811
+ }
812
+ });
813
+
814
+ $.extend($.ui.dialog.overlay.prototype, {
815
+ destroy: function() {
816
+ $.ui.dialog.overlay.destroy(this.$el);
817
+ }
818
+ });
819
+
820
+ }(jQuery));
js/tryon/jquery.ui.draggable.js ADDED
@@ -0,0 +1,832 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery UI Draggable 1.8.24
3
+ *
4
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT or GPL Version 2 licenses.
6
+ * http://jquery.org/license
7
+ *
8
+ * http://docs.jquery.com/UI/Draggables
9
+ *
10
+ * Depends:
11
+ * jquery.ui.core.js
12
+ * jquery.ui.mouse.js
13
+ * jquery.ui.widget.js
14
+ */
15
+ (function( $, undefined ) {
16
+
17
+ $.widget("ui.draggable", $.ui.mouse, {
18
+ widgetEventPrefix: "drag",
19
+ options: {
20
+ addClasses: true,
21
+ appendTo: "parent",
22
+ axis: false,
23
+ connectToSortable: false,
24
+ containment: false,
25
+ cursor: "auto",
26
+ cursorAt: false,
27
+ grid: false,
28
+ handle: false,
29
+ helper: "original",
30
+ iframeFix: false,
31
+ opacity: false,
32
+ refreshPositions: false,
33
+ revert: false,
34
+ revertDuration: 500,
35
+ scope: "default",
36
+ scroll: true,
37
+ scrollSensitivity: 20,
38
+ scrollSpeed: 20,
39
+ snap: false,
40
+ snapMode: "both",
41
+ snapTolerance: 20,
42
+ stack: false,
43
+ zIndex: false
44
+ },
45
+ _create: function() {
46
+
47
+ if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
48
+ this.element[0].style.position = 'relative';
49
+
50
+ (this.options.addClasses && this.element.addClass("ui-draggable"));
51
+ (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
52
+
53
+ this._mouseInit();
54
+
55
+ },
56
+
57
+ destroy: function() {
58
+ if(!this.element.data('draggable')) return;
59
+ this.element
60
+ .removeData("draggable")
61
+ .unbind(".draggable")
62
+ .removeClass("ui-draggable"
63
+ + " ui-draggable-dragging"
64
+ + " ui-draggable-disabled");
65
+ this._mouseDestroy();
66
+
67
+ return this;
68
+ },
69
+
70
+ _mouseCapture: function(event) {
71
+
72
+ var o = this.options;
73
+
74
+ // among others, prevent a drag on a resizable-handle
75
+ if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
76
+ return false;
77
+
78
+ //Quit if we're not on a valid handle
79
+ this.handle = this._getHandle(event);
80
+ if (!this.handle)
81
+ return false;
82
+
83
+ if ( o.iframeFix ) {
84
+ $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
85
+ $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
86
+ .css({
87
+ width: this.offsetWidth+"px", height: this.offsetHeight+"px",
88
+ position: "absolute", opacity: "0.001", zIndex: 1000
89
+ })
90
+ .css($(this).offset())
91
+ .appendTo("body");
92
+ });
93
+ }
94
+
95
+ return true;
96
+
97
+ },
98
+
99
+ _mouseStart: function(event) {
100
+
101
+ var o = this.options;
102
+
103
+ //Create and append the visible helper
104
+ this.helper = this._createHelper(event);
105
+
106
+ this.helper.addClass("ui-draggable-dragging");
107
+
108
+ //Cache the helper size
109
+ this._cacheHelperProportions();
110
+
111
+ //If ddmanager is used for droppables, set the global draggable
112
+ if($.ui.ddmanager)
113
+ $.ui.ddmanager.current = this;
114
+
115
+ /*
116
+ * - Position generation -
117
+ * This block generates everything position related - it's the core of draggables.
118
+ */
119
+
120
+ //Cache the margins of the original element
121
+ this._cacheMargins();
122
+
123
+ //Store the helper's css position
124
+ this.cssPosition = this.helper.css("position");
125
+ this.scrollParent = this.helper.scrollParent();
126
+
127
+ //The element's absolute position on the page minus margins
128
+ this.offset = this.positionAbs = this.element.offset();
129
+ this.offset = {
130
+ top: this.offset.top - this.margins.top,
131
+ left: this.offset.left - this.margins.left
132
+ };
133
+
134
+ $.extend(this.offset, {
135
+ click: { //Where the click happened, relative to the element
136
+ left: event.pageX - this.offset.left,
137
+ top: event.pageY - this.offset.top
138
+ },
139
+ parent: this._getParentOffset(),
140
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
141
+ });
142
+
143
+ //Generate the original position
144
+ this.originalPosition = this.position = this._generatePosition(event);
145
+ this.originalPageX = event.pageX;
146
+ this.originalPageY = event.pageY;
147
+
148
+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
149
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
150
+
151
+ //Set a containment if given in the options
152
+ if(o.containment)
153
+ this._setContainment();
154
+
155
+ //Trigger event + callbacks
156
+ if(this._trigger("start", event) === false) {
157
+ this._clear();
158
+ return false;
159
+ }
160
+
161
+ //Recache the helper size
162
+ this._cacheHelperProportions();
163
+
164
+ //Prepare the droppable offsets
165
+ if ($.ui.ddmanager && !o.dropBehaviour)
166
+ $.ui.ddmanager.prepareOffsets(this, event);
167
+
168
+
169
+ this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
170
+
171
+ //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
172
+ if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
173
+
174
+ return true;
175
+ },
176
+
177
+ _mouseDrag: function(event, noPropagation) {
178
+
179
+ //Compute the helpers position
180
+ this.position = this._generatePosition(event);
181
+ this.positionAbs = this._convertPositionTo("absolute");
182
+
183
+ //Call plugins and callbacks and use the resulting position if something is returned
184
+ if (!noPropagation) {
185
+ var ui = this._uiHash();
186
+ if(this._trigger('drag', event, ui) === false) {
187
+ this._mouseUp({});
188
+ return false;
189
+ }
190
+ this.position = ui.position;
191
+ }
192
+
193
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
194
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
195
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
196
+
197
+ return false;
198
+ },
199
+
200
+ _mouseStop: function(event) {
201
+
202
+ //If we are using droppables, inform the manager about the drop
203
+ var dropped = false;
204
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
205
+ dropped = $.ui.ddmanager.drop(this, event);
206
+
207
+ //if a drop comes from outside (a sortable)
208
+ if(this.dropped) {
209
+ dropped = this.dropped;
210
+ this.dropped = false;
211
+ }
212
+
213
+ //if the original element is no longer in the DOM don't bother to continue (see #8269)
214
+ var element = this.element[0], elementInDom = false;
215
+ while ( element && (element = element.parentNode) ) {
216
+ if (element == document ) {
217
+ elementInDom = true;
218
+ }
219
+ }
220
+ if ( !elementInDom && this.options.helper === "original" )
221
+ return false;
222
+
223
+ 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))) {
224
+ var self = this;
225
+ $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
226
+ if(self._trigger("stop", event) !== false) {
227
+ self._clear();
228
+ }
229
+ });
230
+ } else {
231
+ if(this._trigger("stop", event) !== false) {
232
+ this._clear();
233
+ }
234
+ }
235
+
236
+ return false;
237
+ },
238
+
239
+ _mouseUp: function(event) {
240
+ //Remove frame helpers
241
+ $("div.ui-draggable-iframeFix").each(function() {
242
+ this.parentNode.removeChild(this);
243
+ });
244
+
245
+ //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
246
+ if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
247
+
248
+ return $.ui.mouse.prototype._mouseUp.call(this, event);
249
+ },
250
+
251
+ cancel: function() {
252
+
253
+ if(this.helper.is(".ui-draggable-dragging")) {
254
+ this._mouseUp({});
255
+ } else {
256
+ this._clear();
257
+ }
258
+
259
+ return this;
260
+
261
+ },
262
+
263
+ _getHandle: function(event) {
264
+
265
+ var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
266
+ $(this.options.handle, this.element)
267
+ .find("*")
268
+ .andSelf()
269
+ .each(function() {
270
+ if(this == event.target) handle = true;
271
+ });
272
+
273
+ return handle;
274
+
275
+ },
276
+
277
+ _createHelper: function(event) {
278
+
279
+ var o = this.options;
280
+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
281
+
282
+ if(!helper.parents('body').length)
283
+ helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
284
+
285
+ if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
286
+ helper.css("position", "absolute");
287
+
288
+ return helper;
289
+
290
+ },
291
+
292
+ _adjustOffsetFromHelper: function(obj) {
293
+ if (typeof obj == 'string') {
294
+ obj = obj.split(' ');
295
+ }
296
+ if ($.isArray(obj)) {
297
+ obj = {left: +obj[0], top: +obj[1] || 0};
298
+ }
299
+ if ('left' in obj) {
300
+ this.offset.click.left = obj.left + this.margins.left;
301
+ }
302
+ if ('right' in obj) {
303
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
304
+ }
305
+ if ('top' in obj) {
306
+ this.offset.click.top = obj.top + this.margins.top;
307
+ }
308
+ if ('bottom' in obj) {
309
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
310
+ }
311
+ },
312
+
313
+ _getParentOffset: function() {
314
+
315
+ //Get the offsetParent and cache its position
316
+ this.offsetParent = this.helper.offsetParent();
317
+ var po = this.offsetParent.offset();
318
+
319
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
320
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
321
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
322
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
323
+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
324
+ po.left += this.scrollParent.scrollLeft();
325
+ po.top += this.scrollParent.scrollTop();
326
+ }
327
+
328
+ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
329
+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
330
+ po = { top: 0, left: 0 };
331
+
332
+ return {
333
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
334
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
335
+ };
336
+
337
+ },
338
+
339
+ _getRelativeOffset: function() {
340
+
341
+ if(this.cssPosition == "relative") {
342
+ var p = this.element.position();
343
+ return {
344
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
345
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
346
+ };
347
+ } else {
348
+ return { top: 0, left: 0 };
349
+ }
350
+
351
+ },
352
+
353
+ _cacheMargins: function() {
354
+ this.margins = {
355
+ left: (parseInt(this.element.css("marginLeft"),10) || 0),
356
+ top: (parseInt(this.element.css("marginTop"),10) || 0),
357
+ right: (parseInt(this.element.css("marginRight"),10) || 0),
358
+ bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
359
+ };
360
+ },
361
+
362
+ _cacheHelperProportions: function() {
363
+ this.helperProportions = {
364
+ width: this.helper.outerWidth(),
365
+ height: this.helper.outerHeight()
366
+ };
367
+ },
368
+
369
+ _setContainment: function() {
370
+
371
+ var o = this.options;
372
+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
373
+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
374
+ o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
375
+ o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
376
+ (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
377
+ (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
378
+ ];
379
+
380
+ if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
381
+ var c = $(o.containment);
382
+ var ce = c[0]; if(!ce) return;
383
+ var co = c.offset();
384
+ var over = ($(ce).css("overflow") != 'hidden');
385
+
386
+ this.containment = [
387
+ (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
388
+ (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
389
+ (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,
390
+ (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
391
+ ];
392
+ this.relative_container = c;
393
+
394
+ } else if(o.containment.constructor == Array) {
395
+ this.containment = o.containment;
396
+ }
397
+
398
+ },
399
+
400
+ _convertPositionTo: function(d, pos) {
401
+
402
+ if(!pos) pos = this.position;
403
+ var mod = d == "absolute" ? 1 : -1;
404
+ 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);
405
+
406
+ return {
407
+ top: (
408
+ pos.top // The absolute mouse position
409
+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
410
+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
411
+ - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
412
+ ),
413
+ left: (
414
+ pos.left // The absolute mouse position
415
+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
416
+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
417
+ - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
418
+ )
419
+ };
420
+
421
+ },
422
+
423
+ _generatePosition: function(event) {
424
+
425
+ 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);
426
+ var pageX = event.pageX;
427
+ var pageY = event.pageY;
428
+
429
+ /*
430
+ * - Position constraining -
431
+ * Constrain the position to a mix of grid, containment.
432
+ */
433
+
434
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
435
+ var containment;
436
+ if(this.containment) {
437
+ if (this.relative_container){
438
+ var co = this.relative_container.offset();
439
+ containment = [ this.containment[0] + co.left,
440
+ this.containment[1] + co.top,
441
+ this.containment[2] + co.left,
442
+ this.containment[3] + co.top ];
443
+ }
444
+ else {
445
+ containment = this.containment;
446
+ }
447
+
448
+ if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
449
+ if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
450
+ if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
451
+ if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
452
+ }
453
+
454
+ if(o.grid) {
455
+ //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
456
+ var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
457
+ pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
458
+
459
+ var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
460
+ pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
461
+ }
462
+
463
+ }
464
+
465
+ return {
466
+ top: (
467
+ pageY // The absolute mouse position
468
+ - this.offset.click.top // Click offset (relative to the element)
469
+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
470
+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
471
+ + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
472
+ ),
473
+ left: (
474
+ pageX // The absolute mouse position
475
+ - this.offset.click.left // Click offset (relative to the element)
476
+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
477
+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
478
+ + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
479
+ )
480
+ };
481
+
482
+ },
483
+
484
+ _clear: function() {
485
+ this.helper.removeClass("ui-draggable-dragging");
486
+ if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
487
+ //if($.ui.ddmanager) $.ui.ddmanager.current = null;
488
+ this.helper = null;
489
+ this.cancelHelperRemoval = false;
490
+ },
491
+
492
+ // From now on bulk stuff - mainly helpers
493
+
494
+ _trigger: function(type, event, ui) {
495
+ ui = ui || this._uiHash();
496
+ $.ui.plugin.call(this, type, [event, ui]);
497
+ if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
498
+ return $.Widget.prototype._trigger.call(this, type, event, ui);
499
+ },
500
+
501
+ plugins: {},
502
+
503
+ _uiHash: function(event) {
504
+ return {
505
+ helper: this.helper,
506
+ position: this.position,
507
+ originalPosition: this.originalPosition,
508
+ offset: this.positionAbs
509
+ };
510
+ }
511
+
512
+ });
513
+
514
+ $.extend($.ui.draggable, {
515
+ version: "1.8.24"
516
+ });
517
+
518
+ $.ui.plugin.add("draggable", "connectToSortable", {
519
+ start: function(event, ui) {
520
+
521
+ var inst = $(this).data("draggable"), o = inst.options,
522
+ uiSortable = $.extend({}, ui, { item: inst.element });
523
+ inst.sortables = [];
524
+ $(o.connectToSortable).each(function() {
525
+ var sortable = $.data(this, 'sortable');
526
+ if (sortable && !sortable.options.disabled) {
527
+ inst.sortables.push({
528
+ instance: sortable,
529
+ shouldRevert: sortable.options.revert
530
+ });
531
+ 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).
532
+ sortable._trigger("activate", event, uiSortable);
533
+ }
534
+ });
535
+
536
+ },
537
+ stop: function(event, ui) {
538
+
539
+ //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
540
+ var inst = $(this).data("draggable"),
541
+ uiSortable = $.extend({}, ui, { item: inst.element });
542
+
543
+ $.each(inst.sortables, function() {
544
+ if(this.instance.isOver) {
545
+
546
+ this.instance.isOver = 0;
547
+
548
+ inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
549
+ this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
550
+
551
+ //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
552
+ if(this.shouldRevert) this.instance.options.revert = true;
553
+
554
+ //Trigger the stop of the sortable
555
+ this.instance._mouseStop(event);
556
+
557
+ this.instance.options.helper = this.instance.options._helper;
558
+
559
+ //If the helper has been the original item, restore properties in the sortable
560
+ if(inst.options.helper == 'original')
561
+ this.instance.currentItem.css({ top: 'auto', left: 'auto' });
562
+
563
+ } else {
564
+ this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
565
+ this.instance._trigger("deactivate", event, uiSortable);
566
+ }
567
+
568
+ });
569
+
570
+ },
571
+ drag: function(event, ui) {
572
+
573
+ var inst = $(this).data("draggable"), self = this;
574
+
575
+ var checkPos = function(o) {
576
+ var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
577
+ var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
578
+ var itemHeight = o.height, itemWidth = o.width;
579
+ var itemTop = o.top, itemLeft = o.left;
580
+
581
+ return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
582
+ };
583
+
584
+ $.each(inst.sortables, function(i) {
585
+
586
+ //Copy over some variables to allow calling the sortable's native _intersectsWith
587
+ this.instance.positionAbs = inst.positionAbs;
588
+ this.instance.helperProportions = inst.helperProportions;
589
+ this.instance.offset.click = inst.offset.click;
590
+
591
+ if(this.instance._intersectsWith(this.instance.containerCache)) {
592
+
593
+ //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
594
+ if(!this.instance.isOver) {
595
+
596
+ this.instance.isOver = 1;
597
+ //Now we fake the start of dragging for the sortable instance,
598
+ //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
599
+ //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)
600
+ this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
601
+ this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
602
+ this.instance.options.helper = function() { return ui.helper[0]; };
603
+
604
+ event.target = this.instance.currentItem[0];
605
+ this.instance._mouseCapture(event, true);
606
+ this.instance._mouseStart(event, true, true);
607
+
608
+ //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
609
+ this.instance.offset.click.top = inst.offset.click.top;
610
+ this.instance.offset.click.left = inst.offset.click.left;
611
+ this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
612
+ this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
613
+
614
+ inst._trigger("toSortable", event);
615
+ inst.dropped = this.instance.element; //draggable revert needs that
616
+ //hack so receive/update callbacks work (mostly)
617
+ inst.currentItem = inst.element;
618
+ this.instance.fromOutside = inst;
619
+
620
+ }
621
+
622
+ //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
623
+ if(this.instance.currentItem) this.instance._mouseDrag(event);
624
+
625
+ } else {
626
+
627
+ //If it doesn't intersect with the sortable, and it intersected before,
628
+ //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
629
+ if(this.instance.isOver) {
630
+
631
+ this.instance.isOver = 0;
632
+ this.instance.cancelHelperRemoval = true;
633
+
634
+ //Prevent reverting on this forced stop
635
+ this.instance.options.revert = false;
636
+
637
+ // The out event needs to be triggered independently
638
+ this.instance._trigger('out', event, this.instance._uiHash(this.instance));
639
+
640
+ this.instance._mouseStop(event, true);
641
+ this.instance.options.helper = this.instance.options._helper;
642
+
643
+ //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
644
+ this.instance.currentItem.remove();
645
+ if(this.instance.placeholder) this.instance.placeholder.remove();
646
+
647
+ inst._trigger("fromSortable", event);
648
+ inst.dropped = false; //draggable revert needs that
649
+ }
650
+
651
+ };
652
+
653
+ });
654
+
655
+ }
656
+ });
657
+
658
+ $.ui.plugin.add("draggable", "cursor", {
659
+ start: function(event, ui) {
660
+ var t = $('body'), o = $(this).data('draggable').options;
661
+ if (t.css("cursor")) o._cursor = t.css("cursor");
662
+ t.css("cursor", o.cursor);
663
+ },
664
+ stop: function(event, ui) {
665
+ var o = $(this).data('draggable').options;
666
+ if (o._cursor) $('body').css("cursor", o._cursor);
667
+ }
668
+ });
669
+
670
+ $.ui.plugin.add("draggable", "opacity", {
671
+ start: function(event, ui) {
672
+ var t = $(ui.helper), o = $(this).data('draggable').options;
673
+ if(t.css("opacity")) o._opacity = t.css("opacity");
674
+ t.css('opacity', o.opacity);
675
+ },
676
+ stop: function(event, ui) {
677
+ var o = $(this).data('draggable').options;
678
+ if(o._opacity) $(ui.helper).css('opacity', o._opacity);
679
+ }
680
+ });
681
+
682
+ $.ui.plugin.add("draggable", "scroll", {
683
+ start: function(event, ui) {
684
+ var i = $(this).data("draggable");
685
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
686
+ },
687
+ drag: function(event, ui) {
688
+
689
+ var i = $(this).data("draggable"), o = i.options, scrolled = false;
690
+
691
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
692
+
693
+ if(!o.axis || o.axis != 'x') {
694
+ if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
695
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
696
+ else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
697
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
698
+ }
699
+
700
+ if(!o.axis || o.axis != 'y') {
701
+ if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
702
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
703
+ else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
704
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
705
+ }
706
+
707
+ } else {
708
+
709
+ if(!o.axis || o.axis != 'x') {
710
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
711
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
712
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
713
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
714
+ }
715
+
716
+ if(!o.axis || o.axis != 'y') {
717
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
718
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
719
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
720
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
721
+ }
722
+
723
+ }
724
+
725
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
726
+ $.ui.ddmanager.prepareOffsets(i, event);
727
+
728
+ }
729
+ });
730
+
731
+ $.ui.plugin.add("draggable", "snap", {
732
+ start: function(event, ui) {
733
+
734
+ var i = $(this).data("draggable"), o = i.options;
735
+ i.snapElements = [];
736
+
737
+ $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
738
+ var $t = $(this); var $o = $t.offset();
739
+ if(this != i.element[0]) i.snapElements.push({
740
+ item: this,
741
+ width: $t.outerWidth(), height: $t.outerHeight(),
742
+ top: $o.top, left: $o.left
743
+ });
744
+ });
745
+
746
+ },
747
+ drag: function(event, ui) {
748
+
749
+ var inst = $(this).data("draggable"), o = inst.options;
750
+ var d = o.snapTolerance;
751
+
752
+ var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
753
+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
754
+
755
+ for (var i = inst.snapElements.length - 1; i >= 0; i--){
756
+
757
+ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
758
+ t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
759
+
760
+ //Yes, I know, this is insane ;)
761
+ 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))) {
762
+ 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 })));
763
+ inst.snapElements[i].snapping = false;
764
+ continue;
765
+ }
766
+
767
+ if(o.snapMode != 'inner') {
768
+ var ts = Math.abs(t - y2) <= d;
769
+ var bs = Math.abs(b - y1) <= d;
770
+ var ls = Math.abs(l - x2) <= d;
771
+ var rs = Math.abs(r - x1) <= d;
772
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
773
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
774
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
775
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
776
+ }
777
+
778
+ var first = (ts || bs || ls || rs);
779
+
780
+ if(o.snapMode != 'outer') {
781
+ var ts = Math.abs(t - y1) <= d;
782
+ var bs = Math.abs(b - y2) <= d;
783
+ var ls = Math.abs(l - x1) <= d;
784
+ var rs = Math.abs(r - x2) <= d;
785
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
786
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
787
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
788
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
789
+ }
790
+
791
+ if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
792
+ (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
793
+ inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
794
+
795
+ };
796
+
797
+ }
798
+ });
799
+
800
+ $.ui.plugin.add("draggable", "stack", {
801
+ start: function(event, ui) {
802
+
803
+ var o = $(this).data("draggable").options;
804
+
805
+ var group = $.makeArray($(o.stack)).sort(function(a,b) {
806
+ return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
807
+ });
808
+ if (!group.length) { return; }
809
+
810
+ var min = parseInt(group[0].style.zIndex) || 0;
811
+ $(group).each(function(i) {
812
+ this.style.zIndex = min + i;
813
+ });
814
+
815
+ this[0].style.zIndex = min + group.length;
816
+
817
+ }
818
+ });
819
+
820
+ $.ui.plugin.add("draggable", "zIndex", {
821
+ start: function(event, ui) {
822
+ var t = $(ui.helper), o = $(this).data("draggable").options;
823
+ if(t.css("zIndex")) o._zIndex = t.css("zIndex");
824
+ t.css('zIndex', o.zIndex);
825
+ },
826
+ stop: function(event, ui) {
827
+ var o = $(this).data("draggable").options;
828
+ if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
829
+ }
830
+ });
831
+
832
+ })(jQuery);
js/tryon/jquery.ui.mouse.js ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery UI Mouse 1.8.24
3
+ *
4
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT or GPL Version 2 licenses.
6
+ * http://jquery.org/license
7
+ *
8
+ * http://docs.jquery.com/UI/Mouse
9
+ *
10
+ * Depends:
11
+ * jquery.ui.widget.js
12
+ */
13
+ (function( $, undefined ) {
14
+
15
+ var mouseHandled = false;
16
+ $( document ).mouseup( function( e ) {
17
+ mouseHandled = false;
18
+ });
19
+
20
+ $.widget("ui.mouse", {
21
+ options: {
22
+ cancel: ':input,option',
23
+ distance: 1,
24
+ delay: 0
25
+ },
26
+ _mouseInit: function() {
27
+ var self = this;
28
+
29
+ this.element
30
+ .bind('mousedown.'+this.widgetName, function(event) {
31
+ return self._mouseDown(event);
32
+ })
33
+ .bind('click.'+this.widgetName, function(event) {
34
+ if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
35
+ $.removeData(event.target, self.widgetName + '.preventClickEvent');
36
+ event.stopImmediatePropagation();
37
+ return false;
38
+ }
39
+ });
40
+
41
+ this.started = false;
42
+ },
43
+
44
+ // TODO: make sure destroying one instance of mouse doesn't mess with
45
+ // other instances of mouse
46
+ _mouseDestroy: function() {
47
+ this.element.unbind('.'+this.widgetName);
48
+ if ( this._mouseMoveDelegate ) {
49
+ $(document)
50
+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
51
+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
52
+ }
53
+ },
54
+
55
+ _mouseDown: function(event) {
56
+ // don't let more than one widget handle mouseStart
57
+ if( mouseHandled ) { return };
58
+
59
+ // we may have missed mouseup (out of window)
60
+ (this._mouseStarted && this._mouseUp(event));
61
+
62
+ this._mouseDownEvent = event;
63
+
64
+ var self = this,
65
+ btnIsLeft = (event.which == 1),
66
+ // event.target.nodeName works around a bug in IE 8 with
67
+ // disabled inputs (#7620)
68
+ elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
69
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
70
+ return true;
71
+ }
72
+
73
+ this.mouseDelayMet = !this.options.delay;
74
+ if (!this.mouseDelayMet) {
75
+ this._mouseDelayTimer = setTimeout(function() {
76
+ self.mouseDelayMet = true;
77
+ }, this.options.delay);
78
+ }
79
+
80
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
81
+ this._mouseStarted = (this._mouseStart(event) !== false);
82
+ if (!this._mouseStarted) {
83
+ event.preventDefault();
84
+ return true;
85
+ }
86
+ }
87
+
88
+ // Click event may never have fired (Gecko & Opera)
89
+ if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
90
+ $.removeData(event.target, this.widgetName + '.preventClickEvent');
91
+ }
92
+
93
+ // these delegates are required to keep context
94
+ this._mouseMoveDelegate = function(event) {
95
+ return self._mouseMove(event);
96
+ };
97
+ this._mouseUpDelegate = function(event) {
98
+ return self._mouseUp(event);
99
+ };
100
+ $(document)
101
+ .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
102
+ .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
103
+
104
+ event.preventDefault();
105
+
106
+ mouseHandled = true;
107
+ return true;
108
+ },
109
+
110
+ _mouseMove: function(event) {
111
+ // IE mouseup check - mouseup happened when mouse was out of window
112
+ if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
113
+ return this._mouseUp(event);
114
+ }
115
+
116
+ if (this._mouseStarted) {
117
+ this._mouseDrag(event);
118
+ return event.preventDefault();
119
+ }
120
+
121
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
122
+ this._mouseStarted =
123
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
124
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
125
+ }
126
+
127
+ return !this._mouseStarted;
128
+ },
129
+
130
+ _mouseUp: function(event) {
131
+ $(document)
132
+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
133
+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
134
+
135
+ if (this._mouseStarted) {
136
+ this._mouseStarted = false;
137
+
138
+ if (event.target == this._mouseDownEvent.target) {
139
+ $.data(event.target, this.widgetName + '.preventClickEvent', true);
140
+ }
141
+
142
+ this._mouseStop(event);
143
+ }
144
+
145
+ return false;
146
+ },
147
+
148
+ _mouseDistanceMet: function(event) {
149
+ return (Math.max(
150
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
151
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
152
+ ) >= this.options.distance
153
+ );
154
+ },
155
+
156
+ _mouseDelayMet: function(event) {
157
+ return this.mouseDelayMet;
158
+ },
159
+
160
+ // These are placeholder methods, to be overriden by extending plugin
161
+ _mouseStart: function(event) {},
162
+ _mouseDrag: function(event) {},
163
+ _mouseStop: function(event) {},
164
+ _mouseCapture: function(event) { return true; }
165
+ });
166
+
167
+ })(jQuery);
js/tryon/jquery.ui.widget.js ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery UI Widget 1.8.24
3
+ *
4
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT or GPL Version 2 licenses.
6
+ * http://jquery.org/license
7
+ *
8
+ * http://docs.jquery.com/UI/Widget
9
+ */
10
+ (function( $, undefined ) {
11
+
12
+ // jQuery 1.4+
13
+ if ( $.cleanData ) {
14
+ var _cleanData = $.cleanData;
15
+ $.cleanData = function( elems ) {
16
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
17
+ try {
18
+ $( elem ).triggerHandler( "remove" );
19
+ // http://bugs.jquery.com/ticket/8235
20
+ } catch( e ) {}
21
+ }
22
+ _cleanData( elems );
23
+ };
24
+ } else {
25
+ var _remove = $.fn.remove;
26
+ $.fn.remove = function( selector, keepData ) {
27
+ return this.each(function() {
28
+ if ( !keepData ) {
29
+ if ( !selector || $.filter( selector, [ this ] ).length ) {
30
+ $( "*", this ).add( [ this ] ).each(function() {
31
+ try {
32
+ $( this ).triggerHandler( "remove" );
33
+ // http://bugs.jquery.com/ticket/8235
34
+ } catch( e ) {}
35
+ });
36
+ }
37
+ }
38
+ return _remove.call( $(this), selector, keepData );
39
+ });
40
+ };
41
+ }
42
+
43
+ $.widget = function( name, base, prototype ) {
44
+ var namespace = name.split( "." )[ 0 ],
45
+ fullName;
46
+ name = name.split( "." )[ 1 ];
47
+ fullName = namespace + "-" + name;
48
+
49
+ if ( !prototype ) {
50
+ prototype = base;
51
+ base = $.Widget;
52
+ }
53
+
54
+ // create selector for plugin
55
+ $.expr[ ":" ][ fullName ] = function( elem ) {
56
+ return !!$.data( elem, name );
57
+ };
58
+
59
+ $[ namespace ] = $[ namespace ] || {};
60
+ $[ namespace ][ name ] = function( options, element ) {
61
+ // allow instantiation without initializing for simple inheritance
62
+ if ( arguments.length ) {
63
+ this._createWidget( options, element );
64
+ }
65
+ };
66
+
67
+ var basePrototype = new base();
68
+ // we need to make the options hash a property directly on the new instance
69
+ // otherwise we'll modify the options hash on the prototype that we're
70
+ // inheriting from
71
+ // $.each( basePrototype, function( key, val ) {
72
+ // if ( $.isPlainObject(val) ) {
73
+ // basePrototype[ key ] = $.extend( {}, val );
74
+ // }
75
+ // });
76
+ basePrototype.options = $.extend( true, {}, basePrototype.options );
77
+ $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
78
+ namespace: namespace,
79
+ widgetName: name,
80
+ widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
81
+ widgetBaseClass: fullName
82
+ }, prototype );
83
+
84
+ $.widget.bridge( name, $[ namespace ][ name ] );
85
+ };
86
+
87
+ $.widget.bridge = function( name, object ) {
88
+ $.fn[ name ] = function( options ) {
89
+ var isMethodCall = typeof options === "string",
90
+ args = Array.prototype.slice.call( arguments, 1 ),
91
+ returnValue = this;
92
+
93
+ // allow multiple hashes to be passed on init
94
+ options = !isMethodCall && args.length ?
95
+ $.extend.apply( null, [ true, options ].concat(args) ) :
96
+ options;
97
+
98
+ // prevent calls to internal methods
99
+ if ( isMethodCall && options.charAt( 0 ) === "_" ) {
100
+ return returnValue;
101
+ }
102
+
103
+ if ( isMethodCall ) {
104
+ this.each(function() {
105
+ var instance = $.data( this, name ),
106
+ methodValue = instance && $.isFunction( instance[options] ) ?
107
+ instance[ options ].apply( instance, args ) :
108
+ instance;
109
+ // TODO: add this back in 1.9 and use $.error() (see #5972)
110
+ // if ( !instance ) {
111
+ // throw "cannot call methods on " + name + " prior to initialization; " +
112
+ // "attempted to call method '" + options + "'";
113
+ // }
114
+ // if ( !$.isFunction( instance[options] ) ) {
115
+ // throw "no such method '" + options + "' for " + name + " widget instance";
116
+ // }
117
+ // var methodValue = instance[ options ].apply( instance, args );
118
+ if ( methodValue !== instance && methodValue !== undefined ) {
119
+ returnValue = methodValue;
120
+ return false;
121
+ }
122
+ });
123
+ } else {
124
+ this.each(function() {
125
+ var instance = $.data( this, name );
126
+ if ( instance ) {
127
+ instance.option( options || {} )._init();
128
+ } else {
129
+ $.data( this, name, new object( options, this ) );
130
+ }
131
+ });
132
+ }
133
+
134
+ return returnValue;
135
+ };
136
+ };
137
+
138
+ $.Widget = function( options, element ) {
139
+ // allow instantiation without initializing for simple inheritance
140
+ if ( arguments.length ) {
141
+ this._createWidget( options, element );
142
+ }
143
+ };
144
+
145
+ $.Widget.prototype = {
146
+ widgetName: "widget",
147
+ widgetEventPrefix: "",
148
+ options: {
149
+ disabled: false
150
+ },
151
+ _createWidget: function( options, element ) {
152
+ // $.widget.bridge stores the plugin instance, but we do it anyway
153
+ // so that it's stored even before the _create function runs
154
+ $.data( element, this.widgetName, this );
155
+ this.element = $( element );
156
+ this.options = $.extend( true, {},
157
+ this.options,
158
+ this._getCreateOptions(),
159
+ options );
160
+
161
+ var self = this;
162
+ this.element.bind( "remove." + this.widgetName, function() {
163
+ self.destroy();
164
+ });
165
+
166
+ this._create();
167
+ this._trigger( "create" );
168
+ this._init();
169
+ },
170
+ _getCreateOptions: function() {
171
+ return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
172
+ },
173
+ _create: function() {},
174
+ _init: function() {},
175
+
176
+ destroy: function() {
177
+ this.element
178
+ .unbind( "." + this.widgetName )
179
+ .removeData( this.widgetName );
180
+ this.widget()
181
+ .unbind( "." + this.widgetName )
182
+ .removeAttr( "aria-disabled" )
183
+ .removeClass(
184
+ this.widgetBaseClass + "-disabled " +
185
+ "ui-state-disabled" );
186
+ },
187
+
188
+ widget: function() {
189
+ return this.element;
190
+ },
191
+
192
+ option: function( key, value ) {
193
+ var options = key;
194
+
195
+ if ( arguments.length === 0 ) {
196
+ // don't return a reference to the internal hash
197
+ return $.extend( {}, this.options );
198
+ }
199
+
200
+ if (typeof key === "string" ) {
201
+ if ( value === undefined ) {
202
+ return this.options[ key ];
203
+ }
204
+ options = {};
205
+ options[ key ] = value;
206
+ }
207
+
208
+ this._setOptions( options );
209
+
210
+ return this;
211
+ },
212
+ _setOptions: function( options ) {
213
+ var self = this;
214
+ $.each( options, function( key, value ) {
215
+ self._setOption( key, value );
216
+ });
217
+
218
+ return this;
219
+ },
220
+ _setOption: function( key, value ) {
221
+ this.options[ key ] = value;
222
+
223
+ if ( key === "disabled" ) {
224
+ this.widget()
225
+ [ value ? "addClass" : "removeClass"](
226
+ this.widgetBaseClass + "-disabled" + " " +
227
+ "ui-state-disabled" )
228
+ .attr( "aria-disabled", value );
229
+ }
230
+
231
+ return this;
232
+ },
233
+
234
+ enable: function() {
235
+ return this._setOption( "disabled", false );
236
+ },
237
+ disable: function() {
238
+ return this._setOption( "disabled", true );
239
+ },
240
+
241
+ _trigger: function( type, event, data ) {
242
+ var prop, orig,
243
+ callback = this.options[ type ];
244
+
245
+ data = data || {};
246
+ event = $.Event( event );
247
+ event.type = ( type === this.widgetEventPrefix ?
248
+ type :
249
+ this.widgetEventPrefix + type ).toLowerCase();
250
+ // the original event may come from any element
251
+ // so we need to reset the target on the new event
252
+ event.target = this.element[ 0 ];
253
+
254
+ // copy original event properties over to the new event
255
+ orig = event.originalEvent;
256
+ if ( orig ) {
257
+ for ( prop in orig ) {
258
+ if ( !( prop in event ) ) {
259
+ event[ prop ] = orig[ prop ];
260
+ }
261
+ }
262
+ }
263
+
264
+ this.element.trigger( event, data );
265
+
266
+ return !( $.isFunction(callback) &&
267
+ callback.call( this.element[0], event, data ) === false ||
268
+ event.isDefaultPrevented() );
269
+ }
270
+ };
271
+
272
+ })( jQuery );
media/modelphotos/face.jpg ADDED
Binary file
media/modelphotos/model1.jpg ADDED
Binary file
media/modelphotos/model2.jpg ADDED
Binary file
media/modelphotos/model3.jpg ADDED
Binary file
media/modelphotos/model4.jpg ADDED
Binary file
media/modelphotos/model5.jpg ADDED
Binary file
media/modelphotos/model6.jpg ADDED
Binary file
media/modelphotos/model7.jpg ADDED
Binary file
media/modelphotos/model8.jpg ADDED
Binary file
media/uploads/1337296847_2.jpg ADDED
Binary file
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Daffodil_Tryon</name>
4
+ <version>1.0.0.1</version>
5
+ <stability>stable</stability>
6
+ <license>GPL</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Try Spects on your face</summary>
10
+ <description>This extension provides facility to try spects on your face</description>
11
+ <notes>First Release</notes>
12
+ <authors><author><name>Daffodil Software</name><user>daffodilsw</user><email>ashish.mittal@daffodilsw.com</email></author></authors>
13
+ <date>2013-01-02</date>
14
+ <time>10:57:26</time>
15
+ <contents><target name="magelocal"><dir name="Daffodil"><dir name="Tryon"><dir name="Block"><dir name="Product"><file name="list.php" hash="0aaac28ff2ced105538ca2578fead067"/><file name="list.php~" hash="57189d2840348e9c8d3f7673c7998203"/></dir></dir><dir name="controllers"><file name="Face.php" hash="b034da601265dd0663dfaabec60d2ed6"/><file name="Face.php~" hash="57efefacc4a9107f0f769b4c165c10cf"/><file name="IndexController.php" hash="6ebe229f274616abb997358e66acd84d"/><file name="IndexController.php~" hash="2db01ef71f6bf1c3b95825b6e4aaebfb"/><dir name="mashape"><dir name="authentication"><file name="Authentication.php" hash="140e6fd8c1038a2ce1f5874450678159"/><file name="Authentication.php~" hash="38240503dc05891ce3415e02c18655ca"/><file name="AuthenticationUtil.php" hash="46c266884421159bd28b3c634cf44a9c"/><file name="AuthenticationUtil.php~" hash="14aaef4df816e009c6152672214518f0"/><file name="BasicAuthentication.php" hash="45d59ff6218f11dee3bcfc33cf27e3d4"/><file name="CustomHeaderAuthentication.php" hash="d4f24be77948c3c5ca3e18759bcdb1f0"/><file name="HeaderAuthentication.php" hash="8c42d72c7c40a8226b3a8cf56d18fff0"/><file name="MashapeAuthentication.php" hash="57eefc110068b6a7440be5dc46200bfb"/><file name="OAuth10aAuthentication.php" hash="1d66c38cede7860ce7c1a4e3a036764a"/><file name="OAuth2Authentication.php" hash="34aa6166e40ef4f5d0295fa8478c2242"/><file name="OAuthAuthentication.php" hash="b6ab08d392c69c2eadd1e7ea98235a8c"/><file name="QueryAuthentication.php" hash="50a397bb359bab7e4083721729236a79"/></dir><dir name="exceptions"><file name="ExceptionConstants.php" hash="bae1b708ff7a62cf3d9053b7c55bc1ba"/><file name="ExceptionConstants.php~" hash="2c3c4fe3b82a83cd8b11ce5b716ef4d0"/><file name="MashapeClientException.php" hash="06beb5760ed89dc88907be632a1de072"/></dir><dir name="http"><file name="Chunked.php" hash="70ecae1a198139f749b470d31ba8eb67"/><file name="ContentType.php" hash="130c33d67e085a95e3dc0dd863aad1ed"/><file name="HttpClient.php" hash="cbf0f5fe4effbf999175128428985d4f"/><file name="HttpMethod.php" hash="432ae8101aaa0f0f656124e9525a9e41"/><file name="HttpUtils.php" hash="1d0f32b9d76545f85896604a0db5efa3"/><file name="HttpUtils.php~" hash="ade4bb2cb9cf7262e9bc0fd2c8bd35ea"/><file name="MashapeResponse.php" hash="12a21457952b328ca0f0c8bf28beb2bf"/><file name="UrlUtils.php" hash="b62d341af96d782bcd305e55054862d0"/></dir><dir name="json"><file name="Json.php" hash="4b25f7e50258096d8da40f611340c188"/><file name="Services_JSON.php" hash="b47d5b3b2fc64a68da7089254c0b1c41"/></dir><file name="MashapeClient.php" hash="e117e53e2f7c47585388e958cc353e74"/></dir><file name="SimpleImage.php" hash="8d4b42f47a6ea7ccf7b3c6b89a984166"/><file name="SimpleImage.php~" hash="a3b16905a9ef4f8be93e81e58af793c6"/></dir><dir name="etc"><file name="config.xml" hash="f6e7dbd8ac5017c8c294baef618cd7fa"/><file name="config.xml~" hash="612e6a429dc949136722dd1d23dc4ec7"/><file name="system.xml" hash="ea7db4e47eab2c1578d97f3377896fc8"/><file name="system.xml~" hash="ceece26fff63dce6018e715a52c03e22"/></dir><dir name="Helper"><file name="Data.php" hash="cea5c8c9c289c880b59322e7f1b12447"/><file name="Data.php~" hash="6f6e849aa88e03944464256b62797838"/><file name="data.php.bak" hash="837cd7da1ef3efacb3b78ad42c71f6e8"/></dir><dir name="Model"><file name="Avatar.php" hash="a00a963af2d2264f1487e343c5ef25bd"/><file name="Avatar.php~" hash="e27e98b374075e6062f046a632ac5d60"/><dir name="Mysql4"><dir name="Avatar"><file name="collection.php" hash="6912db36e5303c5b2adef37c26289b55"/><file name="collection.php~" hash="6506d7af4ac37d99f760525bf4ca0376"/><file name="collection.php.bak" hash="ec4a6e6df26253481f18c215495dfc4b"/></dir><file name="Avatar.php" hash="0c7240471e3d4779dd04d305a502687c"/><file name="Avatar.php~" hash="c60f6df350b07b867848c37f8ef8b9f2"/><file name="Avatar.php.bak" hash="b1b12f9fed35396fe0b77e4555a9fbbb"/></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Position.php" hash="e1afbf6d7686e5975307040af4f995c5"/><file name="Position.php~" hash="955544bf2d896fe3891801ad2fa03101"/></dir></dir></dir></dir><dir name="sql"><dir name="avatar_setup"><file name="mysql4-install-0.1.0.php" hash="4c57fbf910bc8ed869016a7273c7e875"/><file name="mysql4-install-0.1.0.php~" hash="ac3308791cdb7cc979d32dbf7c262253"/></dir></dir></dir></dir><dir name="Ajax"><dir name="Face"><dir name="controllers"><file name="Face.php" hash="01d93a4e52ef880a863fc3384a8d8445"/><file name="IndexController.php" hash="129153bf8a8bed1829535962ab2314ac"/><file name="IndexController.php.bak" hash="f2517e9df06dc1120333f930982f1530"/><dir name="mashape"><dir name="authentication"><file name="Authentication.php" hash="39bd42a8f7f565e9fc8d61dc541dde65"/><file name="AuthenticationUtil.php" hash="20121799ff6d57dbc45d0c1667ca2210"/><file name="BasicAuthentication.php" hash="45d59ff6218f11dee3bcfc33cf27e3d4"/><file name="CustomHeaderAuthentication.php" hash="d4f24be77948c3c5ca3e18759bcdb1f0"/><file name="HeaderAuthentication.php" hash="8c42d72c7c40a8226b3a8cf56d18fff0"/><file name="MashapeAuthentication.php" hash="57eefc110068b6a7440be5dc46200bfb"/><file name="OAuth10aAuthentication.php" hash="1d66c38cede7860ce7c1a4e3a036764a"/><file name="OAuth2Authentication.php" hash="34aa6166e40ef4f5d0295fa8478c2242"/><file name="OAuthAuthentication.php" hash="b6ab08d392c69c2eadd1e7ea98235a8c"/><file name="QueryAuthentication.php" hash="50a397bb359bab7e4083721729236a79"/></dir><dir name="exceptions"><file name="ExceptionConstants.php" hash="ba1b74efa0ba4e649dce02daa9491585"/><file name="MashapeClientException.php" hash="06beb5760ed89dc88907be632a1de072"/></dir><dir name="http"><file name="Chunked.php" hash="70ecae1a198139f749b470d31ba8eb67"/><file name="ContentType.php" hash="130c33d67e085a95e3dc0dd863aad1ed"/><file name="HttpClient.php" hash="cbf0f5fe4effbf999175128428985d4f"/><file name="HttpMethod.php" hash="432ae8101aaa0f0f656124e9525a9e41"/><file name="HttpUtils.php" hash="5d73616bee94a06229a2a09ec7ef2c6c"/><file name="MashapeResponse.php" hash="12a21457952b328ca0f0c8bf28beb2bf"/><file name="UrlUtils.php" hash="b62d341af96d782bcd305e55054862d0"/></dir><dir name="json"><file name="Json.php" hash="4b25f7e50258096d8da40f611340c188"/><file name="Services_JSON.php" hash="b47d5b3b2fc64a68da7089254c0b1c41"/></dir><file name="MashapeClient.php" hash="e117e53e2f7c47585388e958cc353e74"/></dir><file name="SimpleImage.php" hash="7de41fa501f1b8cec40660e28a924796"/></dir><dir name="etc"><file name="config.xml" hash="f67d66dae7c6b75023475d725d18d3e8"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Ajax_Face.xml" hash="c0501fcd6c2896bb09765fd867048c7e"/><file name="Daffodil_Tryon.xml" hash="e704135253f6e3d48cf84aa443a4a70e"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="default"><dir name="default"><dir name="layout"><file name="tryon.xml" hash="54309dc73dd187fa4865fe111ec007a0"/></dir><dir name="template"><dir name="tryon"><file name="list.phtml" hash="e09971043616aeeffb0cfacc9421187d"/><file name="list.phtml~" hash="b7cbbeb0fa41a7cae666ebe886b9fcf1"/><file name="rightsection.phtml" hash="0a6c535b247064d0a74ab72ac703127a"/><file name="rightsection.phtml~" hash="bd438bf65d1586252ba043aba7970cca"/><file name="view.phtml" hash="7c8e6ce8d87a596a1dfbc178d3296681"/><file name="view.phtml~" hash="10e5338bf156d61f4262f41dc4fd0312"/></dir></dir></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="tryon"><file name="ajaxupload.3.5.js" hash="5632c333730461779de9546008fda1b3"/><file name="jquery-1.8.2.js" hash="34fa0f57c2315fa29504a962d6f497b5"/><file name="jquery.hoverscroll.js" hash="e859398e63dc45cb8fa9c114b0800ab2"/><file name="jquery.stickyfloat.js" hash="ba38f90f4d388a3e9e8f8578a5101c79"/><file name="jquery.ui.button.js" hash="feac7915a6353f021c53e31c73f7a9fa"/><file name="jquery.ui.core.js" hash="e7177f46ec4ce6c367c474a0e9572980"/><file name="jquery.ui.dialog.js" hash="7c25fbc7674b076120d7e391e3b71893"/><file name="jquery.ui.draggable.js" hash="934c00f6e408e7def6bb0620f046a1af"/><file name="jquery-ui.min.js" hash="5f3aac6cc5c93c8361de6daafdacc736"/><file name="jquery.ui.mouse.js" hash="c76c7860af968a0f77605bca873857f3"/><file name="jquery.ui.widget.js" hash="1d8065c9473b22823fece822b2295ae8"/></dir></dir></target><target name="magemedia"><dir name="modelphotos"><file name="face.jpg" hash="dfa46ae706a9bfe1be28f304f02034ce"/><file name="model1.jpg" hash="558f193bc61d21284e1d66e6ebeeda8d"/><file name="model2.jpg" hash="a606ac95f31e802768dbe6512a40598a"/><file name="model3.jpg" hash="44c84846c8a8637453dc48a8c2bfc612"/><file name="model4.jpg" hash="cab250e50a7c490e18d1901d4969b13d"/><file name="model5.jpg" hash="f51bc85608b48706be88688d2a0a671d"/><file name="model6.jpg" hash="ca7cc04b9d99fb8fb0d5cad594e6807a"/><file name="model7.jpg" hash="2a6f6051d2f93a21d8b45b03a1d81bb3"/><file name="model8.jpg" hash="5a1ae9ec22ebf5ff8db84f6db150c593"/></dir><dir name="uploads"><file name="1337296847_2.jpg" hash="f521647669057700739aae8e3366a9d2"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="default"><dir name="default"><dir name="tryon"><file name="tryon.css" hash="797ca77395a8c0b21c9b9e7958d52236"/></dir><dir name="images"><file name="ajax-loader.gif" hash="e4234472afb925ddb203ad99cb2ec0b0"/><file name="cross.png" hash="f787d0b0069027fc7b571dbbdabaa3c5"/><file name="images.jpeg" hash="acbac9474770238c648bbcd107f4f00e"/><file name="model2.jpg" hash="a606ac95f31e802768dbe6512a40598a"/></dir></dir></dir></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
18
+ </package>
skin/frontend/default/default/images/ajax-loader.gif ADDED
Binary file
skin/frontend/default/default/images/cross.png ADDED
Binary file
skin/frontend/default/default/images/images.jpeg ADDED
Binary file
skin/frontend/default/default/images/model2.jpg ADDED
Binary file
skin/frontend/default/default/tryon/tryon.css ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #upload{
2
+ background: none repeat scroll 0 0 #F2F2F2;
3
+ border: 2px solid #CCCCCC;
4
+ color: black;
5
+ cursor: pointer !important;
6
+ font-family: Arial,Helvetica,sans-serif;
7
+ font-size: 14px;
8
+ font-weight: bold;
9
+ left: 11px;
10
+ margin: 9px 1px;
11
+ padding: 3px;
12
+ text-align: center;
13
+ width: 97px;
14
+ }
15
+
16
+ #upload span{cursor:pointer !important;}
17
+ .darkbg{
18
+ background:#ddd !important;
19
+ }
20
+ #status{
21
+ font-family:Arial; padding:5px;
22
+ }
23
+
24
+ ul#files{ list-style:none; padding:0; margin:0; }
25
+ ul#files li{ padding:10px; margin-bottom:2px; width:200px; float:left; margin-right:10px;}
26
+ ul#files li img{ max-width:180px; max-height:150px; }
27
+ .success{ background:#99f099; border:1px solid #339933; }
28
+ .error{ background:#f0c6c3; border:1px solid #cc6622; }
29
+ .thumb{ position: absolute; }
30
+ .hoverscroll {
31
+ border: #000 solid 1px;
32
+ width:200px!important;
33
+ height:40px!important
34
+ }
35
+ #my-list li {
36
+ width: 40px
37
+ height: 40px;
38
+ background: #fff;
39
+ border: #000 solid 1px;
40
+ cursor: pointer;
41
+ }
42
+ div.hoverscroll {
43
+ position:relative;
44
+ z-index=999;
45
+ }
46
+
47
+
48
+ /* List container */
49
+ div.hoverscroll div.listcontainer {
50
+ overflow:hidden;
51
+ width:200px!important;
52
+ height:40px!important
53
+ }
54
+ div.hoverscroll div.fixed-listcontainer {
55
+ overflow: hidden;
56
+ float: left;
57
+ }
58
+
59
+ /* Actual list containing items */
60
+ div.hoverscroll ul.list {
61
+ list-style:none;
62
+ margin:0;
63
+ padding:0;
64
+ }
65
+
66
+ /* Items contained in the list */
67
+ div.hoverscroll ul.list li.item {
68
+ display:block;
69
+ padding:0;
70
+ }
71
+ div.hoverscroll.horizontal ul.list li.item {
72
+ float:left;
73
+ }
74
+ .pic { background: none repeat scroll 0 0 #F2F2F2;
75
+ border: 2px solid #CCCCCC;
76
+ cursor: pointer;
77
+ float: right;
78
+ font-size: 15px;
79
+ font-weight: bold;
80
+ height: 27px;
81
+ margin-right: -24px;
82
+ margin-top: 10px;
83
+ padding-left: 4px;
84
+ top: 6px;
85
+ width: 96px;}
86
+ .textdisplay{position:absolute; top:218px; left:18px; display:none; color:#fff;font-size:16px}
87
+ .firstdiv{width:201px; height:250px; overflow:hidden; position:relative;}
88
+ .second{position:absolute; width:100px; height:20px; top:15px; left:39px; display:none}
89
+ .thumb{display:none; width:200px; height:37px; overflow:hidden;}
90
+ .undersec{width:202px; height:37px;}
91
+ .ajaxloader{position:absolute; top:91px; left:83px; display:none}
92
+ .maincontainer{position:relative}
93
+ #mainbody {width:58px; float:left}
94
+ .try{color: red;
95
+ font-size: 16px;}
96
+ .hover{cursor:pointer !important}
97
+ .remove-option{
98
+ cursor: pointer;
99
+ font-size: 20px;
100
+ font-weight: bold;
101
+ margin: -274px 0 0 172px;}
102
+ .remove-model{ margin: -22px 177px;
103
+ position: absolute; cursor:pointer;
104
+ }
105
+ .try-this-right-setting{height: 331px;}