local_documentation 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/app/assets/images/documentation/link.svg +28 -0
  4. data/app/assets/images/documentation/logo-black.svg +23 -0
  5. data/app/assets/images/documentation/logo-white.svg +23 -0
  6. data/app/assets/images/documentation/page.svg +16 -0
  7. data/app/assets/images/documentation/pin.svg +15 -0
  8. data/app/assets/images/documentation/recommendation.svg +11 -0
  9. data/app/assets/images/documentation/search.svg +10 -0
  10. data/app/assets/images/documentation/unhappy.svg +15 -0
  11. data/app/assets/images/documentation/warning.svg +16 -0
  12. data/app/assets/javascripts/documentation/application.coffee +78 -0
  13. data/app/assets/javascripts/documentation/jquery-ui.js +4146 -0
  14. data/app/assets/javascripts/documentation/jquery.autosize.js +263 -0
  15. data/app/assets/stylesheets/documentation/application.scss +322 -0
  16. data/app/assets/stylesheets/documentation/markdown.scss +168 -0
  17. data/app/assets/stylesheets/documentation/page_form.scss +39 -0
  18. data/app/assets/stylesheets/documentation/reset.scss +101 -0
  19. data/app/controllers/documentation/application_controller.rb +27 -0
  20. data/app/controllers/documentation/pages_controller.rb +93 -0
  21. data/app/helpers/documentation/application_helper.rb +13 -0
  22. data/app/models/documentation/page.rb +214 -0
  23. data/app/models/documentation/screenshot.rb +15 -0
  24. data/app/views/documentation/pages/_admin_buttons.html.haml +18 -0
  25. data/app/views/documentation/pages/form.html.haml +16 -0
  26. data/app/views/documentation/pages/index.html.haml +13 -0
  27. data/app/views/documentation/pages/positioning.html.haml +22 -0
  28. data/app/views/documentation/pages/screenshot.html.haml +15 -0
  29. data/app/views/documentation/pages/search.html.haml +12 -0
  30. data/app/views/documentation/pages/show.html.haml +14 -0
  31. data/app/views/documentation/shared/access_denied.html.haml +10 -0
  32. data/app/views/documentation/shared/not_found.html.haml +10 -0
  33. data/app/views/layouts/documentation/_footer.html.haml +0 -0
  34. data/app/views/layouts/documentation/_head.html.haml +0 -0
  35. data/app/views/layouts/documentation/_header.html.haml +3 -0
  36. data/app/views/layouts/documentation/_search.html.haml +5 -0
  37. data/app/views/layouts/documentation/application.html.haml +22 -0
  38. data/config/locales/en.yml +62 -0
  39. data/config/routes.rb +11 -0
  40. data/db/migrate/20140711185212_create_documentation_pages.rb +10 -0
  41. data/db/migrate/20140724111844_create_nifty_attachments_table.rb +16 -0
  42. data/db/migrate/20140724114255_create_documentation_screenshots.rb +7 -0
  43. data/db/seeds.rb +15 -0
  44. data/doc/developers-guide/authorization.md +37 -0
  45. data/doc/developers-guide/building-views/accessing-pages.md +38 -0
  46. data/doc/developers-guide/building-views/helpers.md +105 -0
  47. data/doc/developers-guide/building-views/overview.md +3 -0
  48. data/doc/developers-guide/customization.md +9 -0
  49. data/doc/developers-guide/overview.md +20 -0
  50. data/doc/developers-guide/search-backends.md +17 -0
  51. data/doc/markdown/overview.md +37 -0
  52. data/lib/documentation.rb +20 -0
  53. data/lib/documentation/authorizer.rb +60 -0
  54. data/lib/documentation/config.rb +31 -0
  55. data/lib/documentation/engine.rb +29 -0
  56. data/lib/documentation/errors.rb +7 -0
  57. data/lib/documentation/generators/setup_generator.rb +17 -0
  58. data/lib/documentation/markdown_renderer.rb +62 -0
  59. data/lib/documentation/search_result.rb +84 -0
  60. data/lib/documentation/searchers/abstract.rb +47 -0
  61. data/lib/documentation/searchers/simple.rb +40 -0
  62. data/lib/documentation/version.rb +3 -0
  63. data/lib/documentation/view_helpers.rb +159 -0
  64. data/lib/tasks/documentation.rake +44 -0
  65. metadata +307 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 873a192837ea847a485f3791ed2514071028385a
4
+ data.tar.gz: c756067c0bdbdcb5f4e069607c9e1ca9690fbb92
5
+ SHA512:
6
+ metadata.gz: c6a207c615ebb23fcdcabc94af8915896aa2e70dd3b2bfa07a6106c1d080eac3e05a72cb39bd13cea8e6bde492d427f177b530b6461a0a76a6ef694bf5951f00
7
+ data.tar.gz: 73682d9f6dd40a94f21788feaefc4508449d20ace557369b7bc492a22217922bca1a2ea0c64b6b75aa70f1fc0e3e98286b9659cacad6c3a235a1dd9eff0a17bd
@@ -0,0 +1,20 @@
1
+ Copyright 2014 Zakaria Braksa.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,28 @@
1
+ <!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In -->
2
+ <svg version="1.1"
3
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
4
+ x="0px" y="0px" width="32.002px" height="32px" viewBox="0 0 32.002 32" enable-background="new 0 0 32.002 32"
5
+ xml:space="preserve">
6
+ <defs>
7
+ </defs>
8
+ <path id="chain_x5F_link_1_" fill="#9257B0" d="M27.601,2l2.4,2.402l-5.666,5.664l-2.4-2.4L27.601,2 M22.615,2.033
9
+ c0.967,0,1.93,0.23,2.811,0.679l-3.637,3.637c-0.039,0.017-0.088,0.023-0.146,0.023c-0.156,0-0.371-0.044-0.553-0.044
10
+ c-0.127,0-0.238,0.021-0.307,0.09l-2.562,2.564c-0.207,0.207,0.023,0.794-0.07,1.005l-3.639,3.638
11
+ c-1.186-2.332-0.809-5.255,1.145-7.206l2.564-2.564C19.433,2.639,21.025,2.033,22.615,2.033 M29.293,6.577
12
+ c1.185,2.332,0.807,5.255-1.145,7.205l-2.562,2.565c-1.213,1.214-2.805,1.819-4.395,1.819c-0.965,0-1.928-0.229-2.809-0.679
13
+ l3.635-3.637c0.039-0.017,0.09-0.023,0.146-0.023c0.158,0,0.371,0.044,0.555,0.044c0.125,0,0.236-0.021,0.305-0.089l2.562-2.564
14
+ c0.207-0.207-0.023-0.794,0.068-1.005L29.293,6.577 M19.502,10.1l2.4,2.402L12.203,22.2l-2.402-2.402L19.502,10.1 M10.779,13.867
15
+ c0.967,0,1.93,0.229,2.811,0.679l-3.637,3.637c-0.037,0.017-0.088,0.022-0.144,0.022c-0.158,0-0.371-0.044-0.555-0.044
16
+ c-0.125,0-0.234,0.021-0.305,0.089l-2.564,2.563c-0.207,0.207,0.023,0.794-0.068,1.005l-3.639,3.638
17
+ c-1.185-2.332-0.807-5.255,1.145-7.206l2.562-2.564C7.599,14.473,9.189,13.867,10.779,13.867 M17.459,18.411
18
+ c1.185,2.332,0.809,5.254-1.143,7.205l-2.564,2.565C12.537,29.395,10.947,30,9.357,30c-0.967,0-1.93-0.23-2.811-0.679l3.637-3.637
19
+ c0.037-0.017,0.088-0.023,0.147-0.023c0.156,0,0.369,0.044,0.553,0.044c0.125,0,0.236-0.021,0.305-0.09l2.563-2.563
20
+ c0.207-0.207-0.022-0.793,0.07-1.004L17.459,18.411 M7.668,21.933l2.4,2.403L4.402,30l-2.4-2.401L7.668,21.933 M27.601,0
21
+ c-0.529,0-1.039,0.211-1.414,0.586l-0.184,0.185c-1.064-0.483-2.228-0.737-3.389-0.737c-2.197,0-4.26,0.854-5.811,2.405
22
+ l-2.562,2.564c-1.865,1.862-2.682,4.441-2.328,6.944c-0.377-0.053-0.756-0.08-1.135-0.08c-2.193,0-4.256,0.854-5.809,2.404
23
+ l-2.562,2.564c-2.434,2.435-3.084,6.089-1.67,9.199l-0.15,0.149c-0.781,0.781-0.781,2.047,0,2.828l2.4,2.401
24
+ C3.363,31.789,3.873,32,4.402,32c0.531,0,1.039-0.211,1.414-0.586l0.152-0.152C7.035,31.746,8.197,32,9.357,32
25
+ c2.193,0,4.258-0.854,5.809-2.404l2.564-2.565c1.863-1.863,2.68-4.442,2.326-6.945c0.377,0.054,0.756,0.081,1.135,0.081
26
+ c2.195,0,4.258-0.854,5.809-2.405l2.562-2.564C31.998,12.764,32.646,9.11,31.234,6l0.182-0.184c0.781-0.78,0.781-2.047,0.002-2.828
27
+ l-2.4-2.402C28.642,0.211,28.133,0,27.601,0L27.601,0L27.601,0z"/>
28
+ </svg>
@@ -0,0 +1,23 @@
1
+ <!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In -->
2
+ <svg version="1.1"
3
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
4
+ x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
5
+ <defs>
6
+ </defs>
7
+ <g>
8
+ <rect x="5" y="22" fill="#000000" width="12" height="1"/>
9
+ <rect x="5" y="26" fill="#000000" width="12" height="1"/>
10
+ <path fill="#000000" d="M30.828,18.171l-3.639-3.64C27.722,13.256,28,11.886,28,10.5C28,4.71,23.29,0,17.5,0
11
+ C12.571,0,8.425,3.413,7.301,8H2c-1.105,0-2,0.896-2,2v20c0,1.104,0.895,2,2,2h18c1.104,0,2-0.896,2-2v-9.343l3.172,3.171
12
+ C25.926,24.583,26.931,25,28,25c1.069,0,2.074-0.417,2.829-1.173C31.583,23.073,32,22.069,32,21S31.583,18.927,30.828,18.171z
13
+ M20,30H2V10h5.525C7.517,10.167,7.5,10.331,7.5,10.5c0,1.232,0.235,2.409,0.644,3.5H5v1h3.582c0.58,1.144,1.372,2.16,2.326,3H5v1
14
+ h7.258c1.526,0.945,3.318,1.5,5.242,1.5c0.848,0,1.685-0.122,2.5-0.334V30z M29.414,22.414C29.024,22.805,28.512,23,28,23
15
+ c-0.512,0-1.024-0.195-1.414-0.586l-4.664-4.665c-1.29,0.788-2.8,1.25-4.421,1.25c-3.248,0-6.068-1.823-7.5-4.502V14H9.76
16
+ C9.276,12.932,9,11.749,9,10.5C9,5.806,12.806,2,17.5,2c4.694,0,8.5,3.806,8.5,8.5c0,1.622-0.462,3.132-1.251,4.421l4.665,4.664
17
+ C30.195,20.367,30.195,21.633,29.414,22.414z"/>
18
+ <path fill="#000000" d="M17.5,4C13.91,4,11,6.91,11,10.5c0,3.59,2.91,6.5,6.5,6.5c1.291,0,2.492-0.381,3.504-1.031
19
+ c0.788-0.507,1.459-1.177,1.965-1.965C23.619,12.992,24,11.792,24,10.5C24,6.91,21.09,4,17.5,4z M22.128,13.463
20
+ c-0.426,0.663-1.002,1.239-1.664,1.665C19.575,15.698,18.55,16,17.5,16c-3.033,0-5.5-2.467-5.5-5.5C12,7.467,14.467,5,17.5,5
21
+ c3.033,0,5.5,2.467,5.5,5.5C23,11.55,22.698,12.575,22.128,13.463z"/>
22
+ </g>
23
+ </svg>
@@ -0,0 +1,23 @@
1
+ <!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In -->
2
+ <svg version="1.1"
3
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
4
+ x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
5
+ <defs>
6
+ </defs>
7
+ <g>
8
+ <rect x="5" y="22" fill="#FFFFFF" width="12" height="1"/>
9
+ <rect x="5" y="26" fill="#FFFFFF" width="12" height="1"/>
10
+ <path fill="#FFFFFF" d="M30.828,18.171l-3.639-3.64C27.722,13.256,28,11.886,28,10.5C28,4.71,23.29,0,17.5,0
11
+ C12.571,0,8.425,3.413,7.301,8H2c-1.105,0-2,0.896-2,2v20c0,1.104,0.895,2,2,2h18c1.104,0,2-0.896,2-2v-9.343l3.172,3.171
12
+ C25.926,24.583,26.931,25,28,25c1.069,0,2.074-0.417,2.829-1.173C31.583,23.073,32,22.069,32,21S31.583,18.927,30.828,18.171z
13
+ M20,30H2V10h5.525C7.517,10.167,7.5,10.331,7.5,10.5c0,1.232,0.235,2.409,0.644,3.5H5v1h3.582c0.58,1.144,1.372,2.16,2.326,3H5v1
14
+ h7.258c1.526,0.945,3.318,1.5,5.242,1.5c0.848,0,1.685-0.122,2.5-0.334V30z M29.414,22.414C29.024,22.805,28.512,23,28,23
15
+ c-0.512,0-1.024-0.195-1.414-0.586l-4.664-4.665c-1.29,0.788-2.8,1.25-4.421,1.25c-3.248,0-6.068-1.823-7.5-4.502V14H9.76
16
+ C9.276,12.932,9,11.749,9,10.5C9,5.806,12.806,2,17.5,2c4.694,0,8.5,3.806,8.5,8.5c0,1.622-0.462,3.132-1.251,4.421l4.665,4.664
17
+ C30.195,20.367,30.195,21.633,29.414,22.414z"/>
18
+ <path fill="#FFFFFF" d="M17.5,4C13.91,4,11,6.91,11,10.5c0,3.59,2.91,6.5,6.5,6.5c1.291,0,2.492-0.381,3.504-1.031
19
+ c0.788-0.507,1.459-1.177,1.965-1.965C23.619,12.992,24,11.792,24,10.5C24,6.91,21.09,4,17.5,4z M22.128,13.463
20
+ c-0.426,0.663-1.002,1.239-1.664,1.665C19.575,15.698,18.55,16,17.5,16c-3.033,0-5.5-2.467-5.5-5.5C12,7.467,14.467,5,17.5,5
21
+ c3.033,0,5.5,2.467,5.5,5.5C23,11.55,22.698,12.575,22.128,13.463z"/>
22
+ </g>
23
+ </svg>
@@ -0,0 +1,16 @@
1
+ <!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In -->
2
+ <svg version="1.1"
3
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
4
+ x="0px" y="0px" width="25px" height="32px" viewBox="0 0 25 32" enable-background="new 0 0 25 32" xml:space="preserve">
5
+ <defs>
6
+ </defs>
7
+ <g>
8
+ <rect x="5" y="26" fill="#231F20" width="15" height="1"/>
9
+ <rect x="5" y="23" fill="#231F20" width="15" height="1"/>
10
+ <rect x="5" y="20" fill="#231F20" width="15" height="1"/>
11
+ <path fill="#231F20" d="M24.998,10.592c0-0.521-0.202-1.031-0.584-1.414l-8.5-8.592C15.531,0.203,15.019,0,14.499,0
12
+ C14.45,0,5.787,0,4,0v2h10v9h9v19H2V16H0v14c0,1.104,0.895,2,2,2h21c1.104,0,2-0.896,2-2V10.592H24.998z M15,10V2l7.999,8H15z"/>
13
+ </g>
14
+ <rect fill="#231F20" width="2" height="16"/>
15
+ <rect x="1" fill="#231F20" width="3" height="2"/>
16
+ </svg>
@@ -0,0 +1,15 @@
1
+ <!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In -->
2
+ <svg version="1.1"
3
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
4
+ x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
5
+ <defs>
6
+ </defs>
7
+ <path fill="#231F20" d="M31.414,10.529l-9.943-9.943C21.08,0.195,20.568,0,20.057,0c-0.512,0-1.023,0.195-1.414,0.585
8
+ c-1.519,1.518-2.261,3.61-2.107,5.862l-3.276,3.274c-0.638-0.123-1.278-0.186-1.915-0.186c-1.926,0-3.957,0.248-5.758,2.05
9
+ c-0.781,0.781-0.781,2.047,0,2.828l2.819,2.82l-8.05,11.627c-0.55,0.795-0.453,1.869,0.23,2.553C0.973,31.801,1.485,32,2.001,32
10
+ c0.395,0,0.793-0.117,1.138-0.355l11.627-8.05l2.82,2.819C17.977,26.805,18.488,27,19,27c0.512,0,1.023-0.195,1.414-0.586
11
+ c1.382-1.382,2.75-3.804,1.88-7.69l3.26-3.261c0.187,0.013,0.372,0.019,0.557,0.019c2.052,0,3.936-0.755,5.305-2.126
12
+ C32.195,12.576,32.195,11.31,31.414,10.529z M2,30l8.43-12.176l3.745,3.747L2,30z M26.11,13.482c-0.422,0-0.851-0.042-1.278-0.125
13
+ L20.06,18.13c0.834,2.606,0.769,5.041-1.06,6.87L7,13c1.241-1.241,2.588-1.464,4.344-1.464c0.834,0,1.688,0.136,2.525,0.403
14
+ l4.773-4.771C18.271,5.254,18.723,3.333,20.057,2L30,11.943C28.966,12.979,27.577,13.482,26.11,13.482z"/>
15
+ </svg>
@@ -0,0 +1,11 @@
1
+ <!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In -->
2
+ <svg version="1.1"
3
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
4
+ x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
5
+ <defs>
6
+ </defs>
7
+ <path id="info_1_" fill="#354050" d="M16,2c7.73,0,14,6.268,14,14c0,7.734-6.27,14-14,14C8.268,30,2,23.734,2,16
8
+ C2,8.268,8.268,2,16,2 M15.972,11.074c1.069,0,2.028-0.889,2.028-2s-0.904-2-1.974-2c-1.068,0-2.026,0.889-2.026,2
9
+ S14.904,11.074,15.972,11.074 M13,16h2v6h-2v3h7v-3h-2v-9h-5V16 M16,0C7.178,0,0,7.178,0,16s7.178,16,16,16c8.822,0,16-7.178,16-16
10
+ S24.822,0,16,0L16,0z"/>
11
+ </svg>
@@ -0,0 +1,10 @@
1
+ <!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In -->
2
+ <svg version="1.1"
3
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
4
+ x="0px" y="0px" width="47.9px" height="47.9px" viewBox="0 0 47.9 47.9" enable-background="new 0 0 47.9 47.9"
5
+ xml:space="preserve">
6
+ <defs>
7
+ </defs>
8
+ <path d="M46.6,40.2L36.1,29.7c1.8-3,2.9-6.4,2.9-10.2C39,8.7,30.3,0,19.5,0S0,8.7,0,19.5S8.7,39,19.5,39c3.8,0,7.2-1.1,10.2-2.9
9
+ l10.5,10.5c1.8,1.8,4.6,1.8,6.4,0S48.4,42,46.6,40.2z M19.5,33C12,33,6,27,6,19.5S12,6,19.5,6S33,12,33,19.5S27,33,19.5,33z" fill="#BBC5DA" />
10
+ </svg>
@@ -0,0 +1,15 @@
1
+ <!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In -->
2
+ <svg version="1.1"
3
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
4
+ x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
5
+ <defs>
6
+ </defs>
7
+ <g>
8
+ <circle fill="#cccccc" cx="12.4" cy="11.5" r="1.9"/>
9
+ <circle fill="#cccccc" cx="19.6" cy="11.5" r="1.9"/>
10
+ <path fill="#cccccc" d="M16,17.8c-3.7,0-6.9,2.1-8.3,5.2l1.9,0.8c1-2.4,3.5-4,6.4-4c2.8,0,5.3,1.6,6.3,4l1.9-0.8
11
+ C22.9,19.8,19.6,17.8,16,17.8z"/>
12
+ <path fill="#cccccc" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16c8.8,0,16-7.2,16-16S24.8,0,16,0z M16,30C8.3,30,2,23.7,2,16
13
+ C2,8.3,8.3,2,16,2c7.7,0,14,6.3,14,14C30,23.7,23.7,30,16,30z"/>
14
+ </g>
15
+ </svg>
@@ -0,0 +1,16 @@
1
+ <!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In -->
2
+ <svg version="1.1"
3
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
4
+ x="0px" y="0px" width="31.989px" height="32px" viewBox="0 0 31.989 32" enable-background="new 0 0 31.989 32"
5
+ xml:space="preserve">
6
+ <defs>
7
+ </defs>
8
+ <g>
9
+ <path fill="#97894f" d="M31.023,22.406l-9.76-18.588C19.988,1.392,18.068,0,15.994,0c-1.218,0-3.523,0.496-5.268,3.815
10
+ L0.965,22.408c-1.225,2.333-1.287,4.729-0.171,6.576C1.953,30.9,4.236,32,7.058,32h17.873c2.822,0,5.105-1.1,6.264-3.017
11
+ C32.311,27.137,32.248,24.739,31.023,22.406z M24.931,30H7.058c-4.3,0-6.244-3.001-4.322-6.662l9.761-18.592
12
+ C13.46,2.915,14.727,2,15.994,2c1.267,0,2.536,0.917,3.497,2.748l9.76,18.588C31.175,26.998,29.231,30,24.931,30z"/>
13
+ <circle fill="#97894f" cx="15.995" cy="24.5" r="1.5"/>
14
+ <polygon fill="#97894f" points="14.495,21 17.495,21 18.495,11 13.495,11 "/>
15
+ </g>
16
+ </svg>
@@ -0,0 +1,78 @@
1
+ #= require jquery
2
+ #= require jquery_ujs
3
+ #= require documentation/jquery-ui
4
+ #= require documentation/jquery.autosize
5
+ #= require nifty/dialog
6
+
7
+ $ ->
8
+ $('form.pageForm textarea').autosize({append: '\n\n'})
9
+ $('form.reordering ul').sortable
10
+ containment: 'parent'
11
+ update: ->
12
+ form = $(this).parents('form')
13
+ url = form.attr('action')
14
+ $.post(url, form.serialize());
15
+
16
+ $('.js-screenshot').on 'click', (e)->
17
+ e.preventDefault()
18
+ openUploadDialog()
19
+
20
+ $('.edit-article').on 'drop', (e)->
21
+ e.stopPropagation()
22
+ e.preventDefault()
23
+
24
+ file = e.originalEvent.dataTransfer.files[0]
25
+
26
+ openUploadDialog(file)
27
+
28
+ openUploadDialog = (file)->
29
+ editForm = $('.edit-article').find('form')
30
+ contentArea = editForm.find('#page_content')
31
+ caretPosition = contentArea.get(0).selectionStart
32
+ content = contentArea.val()
33
+
34
+ uploadFormUrl = editForm.find('.js-screenshot').attr('href')
35
+ uploadFormUrl = uploadFormUrl + "?filename=#{file.name}" if file?
36
+
37
+ Nifty.Dialog.open
38
+ url: uploadFormUrl
39
+ afterLoad: (dialog)->
40
+ form = dialog.find('form')
41
+ form.find('#screenshot_alt_text').focus()
42
+
43
+ dialog.on 'submit', 'form', (e)->
44
+ form = $(this)
45
+ formData = new FormData(form.get(0))
46
+
47
+ if file?
48
+ filename = file.name
49
+ formData.append('screenshot[upload_file]', file)
50
+ else
51
+ filename = form.find('#screenshot_upload_file').val()
52
+
53
+ fileExt = filename.split('.').pop().toLowerCase()
54
+ if $.inArray(fileExt, ['gif','png','jpg','jpeg']) == -1
55
+ alert("Invalid file extension (allowed: gif, png, jpg, jpeg)")
56
+ return false
57
+
58
+ $.ajax
59
+ url: form.attr('action')
60
+ type: form.attr('method')
61
+ data: formData
62
+ processData: false
63
+ contentType: false
64
+ success: (data)->
65
+ screenshotLink = "![#{data.title}*centre](#{data.path})"
66
+ newContent = content.substring(0, caretPosition) + screenshotLink + content.substring(caretPosition)
67
+ newCaretPosition = (content.substring(0, caretPosition) + screenshotLink).length
68
+ contentArea.val(newContent)
69
+
70
+ contentArea.focus()
71
+ contentArea.get(0).setSelectionRange(newCaretPosition, newCaretPosition)
72
+
73
+ Nifty.Dialog.closeTopDialog()
74
+
75
+ error: (xhr, status, errorThrown)->
76
+ console.log xhr.responseText
77
+
78
+ false
@@ -0,0 +1,4146 @@
1
+ /*! jQuery UI - v1.10.4 - 2014-03-04
2
+ * http://jqueryui.com
3
+ * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.effect-drop.js, jquery.ui.effect-fade.js, jquery.ui.effect-slide.js
4
+ * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5
+
6
+ (function( $, undefined ) {
7
+
8
+ var uuid = 0,
9
+ runiqueId = /^ui-id-\d+$/;
10
+
11
+ // $.ui might exist from components with no dependencies, e.g., $.ui.position
12
+ $.ui = $.ui || {};
13
+
14
+ $.extend( $.ui, {
15
+ version: "1.10.4",
16
+
17
+ keyCode: {
18
+ BACKSPACE: 8,
19
+ COMMA: 188,
20
+ DELETE: 46,
21
+ DOWN: 40,
22
+ END: 35,
23
+ ENTER: 13,
24
+ ESCAPE: 27,
25
+ HOME: 36,
26
+ LEFT: 37,
27
+ NUMPAD_ADD: 107,
28
+ NUMPAD_DECIMAL: 110,
29
+ NUMPAD_DIVIDE: 111,
30
+ NUMPAD_ENTER: 108,
31
+ NUMPAD_MULTIPLY: 106,
32
+ NUMPAD_SUBTRACT: 109,
33
+ PAGE_DOWN: 34,
34
+ PAGE_UP: 33,
35
+ PERIOD: 190,
36
+ RIGHT: 39,
37
+ SPACE: 32,
38
+ TAB: 9,
39
+ UP: 38
40
+ }
41
+ });
42
+
43
+ // plugins
44
+ $.fn.extend({
45
+ focus: (function( orig ) {
46
+ return function( delay, fn ) {
47
+ return typeof delay === "number" ?
48
+ this.each(function() {
49
+ var elem = this;
50
+ setTimeout(function() {
51
+ $( elem ).focus();
52
+ if ( fn ) {
53
+ fn.call( elem );
54
+ }
55
+ }, delay );
56
+ }) :
57
+ orig.apply( this, arguments );
58
+ };
59
+ })( $.fn.focus ),
60
+
61
+ scrollParent: function() {
62
+ var scrollParent;
63
+ if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
64
+ scrollParent = this.parents().filter(function() {
65
+ return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
66
+ }).eq(0);
67
+ } else {
68
+ scrollParent = this.parents().filter(function() {
69
+ return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
70
+ }).eq(0);
71
+ }
72
+
73
+ return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
74
+ },
75
+
76
+ zIndex: function( zIndex ) {
77
+ if ( zIndex !== undefined ) {
78
+ return this.css( "zIndex", zIndex );
79
+ }
80
+
81
+ if ( this.length ) {
82
+ var elem = $( this[ 0 ] ), position, value;
83
+ while ( elem.length && elem[ 0 ] !== document ) {
84
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
85
+ // This makes behavior of this function consistent across browsers
86
+ // WebKit always returns auto if the element is positioned
87
+ position = elem.css( "position" );
88
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
89
+ // IE returns 0 when zIndex is not specified
90
+ // other browsers return a string
91
+ // we ignore the case of nested elements with an explicit value of 0
92
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
93
+ value = parseInt( elem.css( "zIndex" ), 10 );
94
+ if ( !isNaN( value ) && value !== 0 ) {
95
+ return value;
96
+ }
97
+ }
98
+ elem = elem.parent();
99
+ }
100
+ }
101
+
102
+ return 0;
103
+ },
104
+
105
+ uniqueId: function() {
106
+ return this.each(function() {
107
+ if ( !this.id ) {
108
+ this.id = "ui-id-" + (++uuid);
109
+ }
110
+ });
111
+ },
112
+
113
+ removeUniqueId: function() {
114
+ return this.each(function() {
115
+ if ( runiqueId.test( this.id ) ) {
116
+ $( this ).removeAttr( "id" );
117
+ }
118
+ });
119
+ }
120
+ });
121
+
122
+ // selectors
123
+ function focusable( element, isTabIndexNotNaN ) {
124
+ var map, mapName, img,
125
+ nodeName = element.nodeName.toLowerCase();
126
+ if ( "area" === nodeName ) {
127
+ map = element.parentNode;
128
+ mapName = map.name;
129
+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
130
+ return false;
131
+ }
132
+ img = $( "img[usemap=#" + mapName + "]" )[0];
133
+ return !!img && visible( img );
134
+ }
135
+ return ( /input|select|textarea|button|object/.test( nodeName ) ?
136
+ !element.disabled :
137
+ "a" === nodeName ?
138
+ element.href || isTabIndexNotNaN :
139
+ isTabIndexNotNaN) &&
140
+ // the element and all of its ancestors must be visible
141
+ visible( element );
142
+ }
143
+
144
+ function visible( element ) {
145
+ return $.expr.filters.visible( element ) &&
146
+ !$( element ).parents().addBack().filter(function() {
147
+ return $.css( this, "visibility" ) === "hidden";
148
+ }).length;
149
+ }
150
+
151
+ $.extend( $.expr[ ":" ], {
152
+ data: $.expr.createPseudo ?
153
+ $.expr.createPseudo(function( dataName ) {
154
+ return function( elem ) {
155
+ return !!$.data( elem, dataName );
156
+ };
157
+ }) :
158
+ // support: jQuery <1.8
159
+ function( elem, i, match ) {
160
+ return !!$.data( elem, match[ 3 ] );
161
+ },
162
+
163
+ focusable: function( element ) {
164
+ return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
165
+ },
166
+
167
+ tabbable: function( element ) {
168
+ var tabIndex = $.attr( element, "tabindex" ),
169
+ isTabIndexNaN = isNaN( tabIndex );
170
+ return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
171
+ }
172
+ });
173
+
174
+ // support: jQuery <1.8
175
+ if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
176
+ $.each( [ "Width", "Height" ], function( i, name ) {
177
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
178
+ type = name.toLowerCase(),
179
+ orig = {
180
+ innerWidth: $.fn.innerWidth,
181
+ innerHeight: $.fn.innerHeight,
182
+ outerWidth: $.fn.outerWidth,
183
+ outerHeight: $.fn.outerHeight
184
+ };
185
+
186
+ function reduce( elem, size, border, margin ) {
187
+ $.each( side, function() {
188
+ size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
189
+ if ( border ) {
190
+ size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
191
+ }
192
+ if ( margin ) {
193
+ size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
194
+ }
195
+ });
196
+ return size;
197
+ }
198
+
199
+ $.fn[ "inner" + name ] = function( size ) {
200
+ if ( size === undefined ) {
201
+ return orig[ "inner" + name ].call( this );
202
+ }
203
+
204
+ return this.each(function() {
205
+ $( this ).css( type, reduce( this, size ) + "px" );
206
+ });
207
+ };
208
+
209
+ $.fn[ "outer" + name] = function( size, margin ) {
210
+ if ( typeof size !== "number" ) {
211
+ return orig[ "outer" + name ].call( this, size );
212
+ }
213
+
214
+ return this.each(function() {
215
+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
216
+ });
217
+ };
218
+ });
219
+ }
220
+
221
+ // support: jQuery <1.8
222
+ if ( !$.fn.addBack ) {
223
+ $.fn.addBack = function( selector ) {
224
+ return this.add( selector == null ?
225
+ this.prevObject : this.prevObject.filter( selector )
226
+ );
227
+ };
228
+ }
229
+
230
+ // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
231
+ if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
232
+ $.fn.removeData = (function( removeData ) {
233
+ return function( key ) {
234
+ if ( arguments.length ) {
235
+ return removeData.call( this, $.camelCase( key ) );
236
+ } else {
237
+ return removeData.call( this );
238
+ }
239
+ };
240
+ })( $.fn.removeData );
241
+ }
242
+
243
+
244
+
245
+
246
+
247
+ // deprecated
248
+ $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
249
+
250
+ $.support.selectstart = "onselectstart" in document.createElement( "div" );
251
+ $.fn.extend({
252
+ disableSelection: function() {
253
+ return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
254
+ ".ui-disableSelection", function( event ) {
255
+ event.preventDefault();
256
+ });
257
+ },
258
+
259
+ enableSelection: function() {
260
+ return this.unbind( ".ui-disableSelection" );
261
+ }
262
+ });
263
+
264
+ $.extend( $.ui, {
265
+ // $.ui.plugin is deprecated. Use $.widget() extensions instead.
266
+ plugin: {
267
+ add: function( module, option, set ) {
268
+ var i,
269
+ proto = $.ui[ module ].prototype;
270
+ for ( i in set ) {
271
+ proto.plugins[ i ] = proto.plugins[ i ] || [];
272
+ proto.plugins[ i ].push( [ option, set[ i ] ] );
273
+ }
274
+ },
275
+ call: function( instance, name, args ) {
276
+ var i,
277
+ set = instance.plugins[ name ];
278
+ if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
279
+ return;
280
+ }
281
+
282
+ for ( i = 0; i < set.length; i++ ) {
283
+ if ( instance.options[ set[ i ][ 0 ] ] ) {
284
+ set[ i ][ 1 ].apply( instance.element, args );
285
+ }
286
+ }
287
+ }
288
+ },
289
+
290
+ // only used by resizable
291
+ hasScroll: function( el, a ) {
292
+
293
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
294
+ if ( $( el ).css( "overflow" ) === "hidden") {
295
+ return false;
296
+ }
297
+
298
+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
299
+ has = false;
300
+
301
+ if ( el[ scroll ] > 0 ) {
302
+ return true;
303
+ }
304
+
305
+ // TODO: determine which cases actually cause this to happen
306
+ // if the element doesn't have the scroll set, see if it's possible to
307
+ // set the scroll
308
+ el[ scroll ] = 1;
309
+ has = ( el[ scroll ] > 0 );
310
+ el[ scroll ] = 0;
311
+ return has;
312
+ }
313
+ });
314
+
315
+ })( jQuery );
316
+ (function( $, undefined ) {
317
+
318
+ var uuid = 0,
319
+ slice = Array.prototype.slice,
320
+ _cleanData = $.cleanData;
321
+ $.cleanData = function( elems ) {
322
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323
+ try {
324
+ $( elem ).triggerHandler( "remove" );
325
+ // http://bugs.jquery.com/ticket/8235
326
+ } catch( e ) {}
327
+ }
328
+ _cleanData( elems );
329
+ };
330
+
331
+ $.widget = function( name, base, prototype ) {
332
+ var fullName, existingConstructor, constructor, basePrototype,
333
+ // proxiedPrototype allows the provided prototype to remain unmodified
334
+ // so that it can be used as a mixin for multiple widgets (#8876)
335
+ proxiedPrototype = {},
336
+ namespace = name.split( "." )[ 0 ];
337
+
338
+ name = name.split( "." )[ 1 ];
339
+ fullName = namespace + "-" + name;
340
+
341
+ if ( !prototype ) {
342
+ prototype = base;
343
+ base = $.Widget;
344
+ }
345
+
346
+ // create selector for plugin
347
+ $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348
+ return !!$.data( elem, fullName );
349
+ };
350
+
351
+ $[ namespace ] = $[ namespace ] || {};
352
+ existingConstructor = $[ namespace ][ name ];
353
+ constructor = $[ namespace ][ name ] = function( options, element ) {
354
+ // allow instantiation without "new" keyword
355
+ if ( !this._createWidget ) {
356
+ return new constructor( options, element );
357
+ }
358
+
359
+ // allow instantiation without initializing for simple inheritance
360
+ // must use "new" keyword (the code above always passes args)
361
+ if ( arguments.length ) {
362
+ this._createWidget( options, element );
363
+ }
364
+ };
365
+ // extend with the existing constructor to carry over any static properties
366
+ $.extend( constructor, existingConstructor, {
367
+ version: prototype.version,
368
+ // copy the object used to create the prototype in case we need to
369
+ // redefine the widget later
370
+ _proto: $.extend( {}, prototype ),
371
+ // track widgets that inherit from this widget in case this widget is
372
+ // redefined after a widget inherits from it
373
+ _childConstructors: []
374
+ });
375
+
376
+ basePrototype = new base();
377
+ // we need to make the options hash a property directly on the new instance
378
+ // otherwise we'll modify the options hash on the prototype that we're
379
+ // inheriting from
380
+ basePrototype.options = $.widget.extend( {}, basePrototype.options );
381
+ $.each( prototype, function( prop, value ) {
382
+ if ( !$.isFunction( value ) ) {
383
+ proxiedPrototype[ prop ] = value;
384
+ return;
385
+ }
386
+ proxiedPrototype[ prop ] = (function() {
387
+ var _super = function() {
388
+ return base.prototype[ prop ].apply( this, arguments );
389
+ },
390
+ _superApply = function( args ) {
391
+ return base.prototype[ prop ].apply( this, args );
392
+ };
393
+ return function() {
394
+ var __super = this._super,
395
+ __superApply = this._superApply,
396
+ returnValue;
397
+
398
+ this._super = _super;
399
+ this._superApply = _superApply;
400
+
401
+ returnValue = value.apply( this, arguments );
402
+
403
+ this._super = __super;
404
+ this._superApply = __superApply;
405
+
406
+ return returnValue;
407
+ };
408
+ })();
409
+ });
410
+ constructor.prototype = $.widget.extend( basePrototype, {
411
+ // TODO: remove support for widgetEventPrefix
412
+ // always use the name + a colon as the prefix, e.g., draggable:start
413
+ // don't prefix for widgets that aren't DOM-based
414
+ widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
415
+ }, proxiedPrototype, {
416
+ constructor: constructor,
417
+ namespace: namespace,
418
+ widgetName: name,
419
+ widgetFullName: fullName
420
+ });
421
+
422
+ // If this widget is being redefined then we need to find all widgets that
423
+ // are inheriting from it and redefine all of them so that they inherit from
424
+ // the new version of this widget. We're essentially trying to replace one
425
+ // level in the prototype chain.
426
+ if ( existingConstructor ) {
427
+ $.each( existingConstructor._childConstructors, function( i, child ) {
428
+ var childPrototype = child.prototype;
429
+
430
+ // redefine the child widget using the same prototype that was
431
+ // originally used, but inherit from the new version of the base
432
+ $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433
+ });
434
+ // remove the list of existing child constructors from the old constructor
435
+ // so the old child constructors can be garbage collected
436
+ delete existingConstructor._childConstructors;
437
+ } else {
438
+ base._childConstructors.push( constructor );
439
+ }
440
+
441
+ $.widget.bridge( name, constructor );
442
+ };
443
+
444
+ $.widget.extend = function( target ) {
445
+ var input = slice.call( arguments, 1 ),
446
+ inputIndex = 0,
447
+ inputLength = input.length,
448
+ key,
449
+ value;
450
+ for ( ; inputIndex < inputLength; inputIndex++ ) {
451
+ for ( key in input[ inputIndex ] ) {
452
+ value = input[ inputIndex ][ key ];
453
+ if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454
+ // Clone objects
455
+ if ( $.isPlainObject( value ) ) {
456
+ target[ key ] = $.isPlainObject( target[ key ] ) ?
457
+ $.widget.extend( {}, target[ key ], value ) :
458
+ // Don't extend strings, arrays, etc. with objects
459
+ $.widget.extend( {}, value );
460
+ // Copy everything else by reference
461
+ } else {
462
+ target[ key ] = value;
463
+ }
464
+ }
465
+ }
466
+ }
467
+ return target;
468
+ };
469
+
470
+ $.widget.bridge = function( name, object ) {
471
+ var fullName = object.prototype.widgetFullName || name;
472
+ $.fn[ name ] = function( options ) {
473
+ var isMethodCall = typeof options === "string",
474
+ args = slice.call( arguments, 1 ),
475
+ returnValue = this;
476
+
477
+ // allow multiple hashes to be passed on init
478
+ options = !isMethodCall && args.length ?
479
+ $.widget.extend.apply( null, [ options ].concat(args) ) :
480
+ options;
481
+
482
+ if ( isMethodCall ) {
483
+ this.each(function() {
484
+ var methodValue,
485
+ instance = $.data( this, fullName );
486
+ if ( !instance ) {
487
+ return $.error( "cannot call methods on " + name + " prior to initialization; " +
488
+ "attempted to call method '" + options + "'" );
489
+ }
490
+ if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491
+ return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492
+ }
493
+ methodValue = instance[ options ].apply( instance, args );
494
+ if ( methodValue !== instance && methodValue !== undefined ) {
495
+ returnValue = methodValue && methodValue.jquery ?
496
+ returnValue.pushStack( methodValue.get() ) :
497
+ methodValue;
498
+ return false;
499
+ }
500
+ });
501
+ } else {
502
+ this.each(function() {
503
+ var instance = $.data( this, fullName );
504
+ if ( instance ) {
505
+ instance.option( options || {} )._init();
506
+ } else {
507
+ $.data( this, fullName, new object( options, this ) );
508
+ }
509
+ });
510
+ }
511
+
512
+ return returnValue;
513
+ };
514
+ };
515
+
516
+ $.Widget = function( /* options, element */ ) {};
517
+ $.Widget._childConstructors = [];
518
+
519
+ $.Widget.prototype = {
520
+ widgetName: "widget",
521
+ widgetEventPrefix: "",
522
+ defaultElement: "<div>",
523
+ options: {
524
+ disabled: false,
525
+
526
+ // callbacks
527
+ create: null
528
+ },
529
+ _createWidget: function( options, element ) {
530
+ element = $( element || this.defaultElement || this )[ 0 ];
531
+ this.element = $( element );
532
+ this.uuid = uuid++;
533
+ this.eventNamespace = "." + this.widgetName + this.uuid;
534
+ this.options = $.widget.extend( {},
535
+ this.options,
536
+ this._getCreateOptions(),
537
+ options );
538
+
539
+ this.bindings = $();
540
+ this.hoverable = $();
541
+ this.focusable = $();
542
+
543
+ if ( element !== this ) {
544
+ $.data( element, this.widgetFullName, this );
545
+ this._on( true, this.element, {
546
+ remove: function( event ) {
547
+ if ( event.target === element ) {
548
+ this.destroy();
549
+ }
550
+ }
551
+ });
552
+ this.document = $( element.style ?
553
+ // element within the document
554
+ element.ownerDocument :
555
+ // element is window or document
556
+ element.document || element );
557
+ this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558
+ }
559
+
560
+ this._create();
561
+ this._trigger( "create", null, this._getCreateEventData() );
562
+ this._init();
563
+ },
564
+ _getCreateOptions: $.noop,
565
+ _getCreateEventData: $.noop,
566
+ _create: $.noop,
567
+ _init: $.noop,
568
+
569
+ destroy: function() {
570
+ this._destroy();
571
+ // we can probably remove the unbind calls in 2.0
572
+ // all event bindings should go through this._on()
573
+ this.element
574
+ .unbind( this.eventNamespace )
575
+ // 1.9 BC for #7810
576
+ // TODO remove dual storage
577
+ .removeData( this.widgetName )
578
+ .removeData( this.widgetFullName )
579
+ // support: jquery <1.6.3
580
+ // http://bugs.jquery.com/ticket/9413
581
+ .removeData( $.camelCase( this.widgetFullName ) );
582
+ this.widget()
583
+ .unbind( this.eventNamespace )
584
+ .removeAttr( "aria-disabled" )
585
+ .removeClass(
586
+ this.widgetFullName + "-disabled " +
587
+ "ui-state-disabled" );
588
+
589
+ // clean up events and states
590
+ this.bindings.unbind( this.eventNamespace );
591
+ this.hoverable.removeClass( "ui-state-hover" );
592
+ this.focusable.removeClass( "ui-state-focus" );
593
+ },
594
+ _destroy: $.noop,
595
+
596
+ widget: function() {
597
+ return this.element;
598
+ },
599
+
600
+ option: function( key, value ) {
601
+ var options = key,
602
+ parts,
603
+ curOption,
604
+ i;
605
+
606
+ if ( arguments.length === 0 ) {
607
+ // don't return a reference to the internal hash
608
+ return $.widget.extend( {}, this.options );
609
+ }
610
+
611
+ if ( typeof key === "string" ) {
612
+ // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613
+ options = {};
614
+ parts = key.split( "." );
615
+ key = parts.shift();
616
+ if ( parts.length ) {
617
+ curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618
+ for ( i = 0; i < parts.length - 1; i++ ) {
619
+ curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620
+ curOption = curOption[ parts[ i ] ];
621
+ }
622
+ key = parts.pop();
623
+ if ( arguments.length === 1 ) {
624
+ return curOption[ key ] === undefined ? null : curOption[ key ];
625
+ }
626
+ curOption[ key ] = value;
627
+ } else {
628
+ if ( arguments.length === 1 ) {
629
+ return this.options[ key ] === undefined ? null : this.options[ key ];
630
+ }
631
+ options[ key ] = value;
632
+ }
633
+ }
634
+
635
+ this._setOptions( options );
636
+
637
+ return this;
638
+ },
639
+ _setOptions: function( options ) {
640
+ var key;
641
+
642
+ for ( key in options ) {
643
+ this._setOption( key, options[ key ] );
644
+ }
645
+
646
+ return this;
647
+ },
648
+ _setOption: function( key, value ) {
649
+ this.options[ key ] = value;
650
+
651
+ if ( key === "disabled" ) {
652
+ this.widget()
653
+ .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654
+ .attr( "aria-disabled", value );
655
+ this.hoverable.removeClass( "ui-state-hover" );
656
+ this.focusable.removeClass( "ui-state-focus" );
657
+ }
658
+
659
+ return this;
660
+ },
661
+
662
+ enable: function() {
663
+ return this._setOption( "disabled", false );
664
+ },
665
+ disable: function() {
666
+ return this._setOption( "disabled", true );
667
+ },
668
+
669
+ _on: function( suppressDisabledCheck, element, handlers ) {
670
+ var delegateElement,
671
+ instance = this;
672
+
673
+ // no suppressDisabledCheck flag, shuffle arguments
674
+ if ( typeof suppressDisabledCheck !== "boolean" ) {
675
+ handlers = element;
676
+ element = suppressDisabledCheck;
677
+ suppressDisabledCheck = false;
678
+ }
679
+
680
+ // no element argument, shuffle and use this.element
681
+ if ( !handlers ) {
682
+ handlers = element;
683
+ element = this.element;
684
+ delegateElement = this.widget();
685
+ } else {
686
+ // accept selectors, DOM elements
687
+ element = delegateElement = $( element );
688
+ this.bindings = this.bindings.add( element );
689
+ }
690
+
691
+ $.each( handlers, function( event, handler ) {
692
+ function handlerProxy() {
693
+ // allow widgets to customize the disabled handling
694
+ // - disabled as an array instead of boolean
695
+ // - disabled class as method for disabling individual parts
696
+ if ( !suppressDisabledCheck &&
697
+ ( instance.options.disabled === true ||
698
+ $( this ).hasClass( "ui-state-disabled" ) ) ) {
699
+ return;
700
+ }
701
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
702
+ .apply( instance, arguments );
703
+ }
704
+
705
+ // copy the guid so direct unbinding works
706
+ if ( typeof handler !== "string" ) {
707
+ handlerProxy.guid = handler.guid =
708
+ handler.guid || handlerProxy.guid || $.guid++;
709
+ }
710
+
711
+ var match = event.match( /^(\w+)\s*(.*)$/ ),
712
+ eventName = match[1] + instance.eventNamespace,
713
+ selector = match[2];
714
+ if ( selector ) {
715
+ delegateElement.delegate( selector, eventName, handlerProxy );
716
+ } else {
717
+ element.bind( eventName, handlerProxy );
718
+ }
719
+ });
720
+ },
721
+
722
+ _off: function( element, eventName ) {
723
+ eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724
+ element.unbind( eventName ).undelegate( eventName );
725
+ },
726
+
727
+ _delay: function( handler, delay ) {
728
+ function handlerProxy() {
729
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
730
+ .apply( instance, arguments );
731
+ }
732
+ var instance = this;
733
+ return setTimeout( handlerProxy, delay || 0 );
734
+ },
735
+
736
+ _hoverable: function( element ) {
737
+ this.hoverable = this.hoverable.add( element );
738
+ this._on( element, {
739
+ mouseenter: function( event ) {
740
+ $( event.currentTarget ).addClass( "ui-state-hover" );
741
+ },
742
+ mouseleave: function( event ) {
743
+ $( event.currentTarget ).removeClass( "ui-state-hover" );
744
+ }
745
+ });
746
+ },
747
+
748
+ _focusable: function( element ) {
749
+ this.focusable = this.focusable.add( element );
750
+ this._on( element, {
751
+ focusin: function( event ) {
752
+ $( event.currentTarget ).addClass( "ui-state-focus" );
753
+ },
754
+ focusout: function( event ) {
755
+ $( event.currentTarget ).removeClass( "ui-state-focus" );
756
+ }
757
+ });
758
+ },
759
+
760
+ _trigger: function( type, event, data ) {
761
+ var prop, orig,
762
+ callback = this.options[ type ];
763
+
764
+ data = data || {};
765
+ event = $.Event( event );
766
+ event.type = ( type === this.widgetEventPrefix ?
767
+ type :
768
+ this.widgetEventPrefix + type ).toLowerCase();
769
+ // the original event may come from any element
770
+ // so we need to reset the target on the new event
771
+ event.target = this.element[ 0 ];
772
+
773
+ // copy original event properties over to the new event
774
+ orig = event.originalEvent;
775
+ if ( orig ) {
776
+ for ( prop in orig ) {
777
+ if ( !( prop in event ) ) {
778
+ event[ prop ] = orig[ prop ];
779
+ }
780
+ }
781
+ }
782
+
783
+ this.element.trigger( event, data );
784
+ return !( $.isFunction( callback ) &&
785
+ callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786
+ event.isDefaultPrevented() );
787
+ }
788
+ };
789
+
790
+ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791
+ $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792
+ if ( typeof options === "string" ) {
793
+ options = { effect: options };
794
+ }
795
+ var hasOptions,
796
+ effectName = !options ?
797
+ method :
798
+ options === true || typeof options === "number" ?
799
+ defaultEffect :
800
+ options.effect || defaultEffect;
801
+ options = options || {};
802
+ if ( typeof options === "number" ) {
803
+ options = { duration: options };
804
+ }
805
+ hasOptions = !$.isEmptyObject( options );
806
+ options.complete = callback;
807
+ if ( options.delay ) {
808
+ element.delay( options.delay );
809
+ }
810
+ if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811
+ element[ method ]( options );
812
+ } else if ( effectName !== method && element[ effectName ] ) {
813
+ element[ effectName ]( options.duration, options.easing, callback );
814
+ } else {
815
+ element.queue(function( next ) {
816
+ $( this )[ method ]();
817
+ if ( callback ) {
818
+ callback.call( element[ 0 ] );
819
+ }
820
+ next();
821
+ });
822
+ }
823
+ };
824
+ });
825
+
826
+ })( jQuery );
827
+ (function( $, undefined ) {
828
+
829
+ var mouseHandled = false;
830
+ $( document ).mouseup( function() {
831
+ mouseHandled = false;
832
+ });
833
+
834
+ $.widget("ui.mouse", {
835
+ version: "1.10.4",
836
+ options: {
837
+ cancel: "input,textarea,button,select,option",
838
+ distance: 1,
839
+ delay: 0
840
+ },
841
+ _mouseInit: function() {
842
+ var that = this;
843
+
844
+ this.element
845
+ .bind("mousedown."+this.widgetName, function(event) {
846
+ return that._mouseDown(event);
847
+ })
848
+ .bind("click."+this.widgetName, function(event) {
849
+ if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
850
+ $.removeData(event.target, that.widgetName + ".preventClickEvent");
851
+ event.stopImmediatePropagation();
852
+ return false;
853
+ }
854
+ });
855
+
856
+ this.started = false;
857
+ },
858
+
859
+ // TODO: make sure destroying one instance of mouse doesn't mess with
860
+ // other instances of mouse
861
+ _mouseDestroy: function() {
862
+ this.element.unbind("."+this.widgetName);
863
+ if ( this._mouseMoveDelegate ) {
864
+ $(document)
865
+ .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
866
+ .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
867
+ }
868
+ },
869
+
870
+ _mouseDown: function(event) {
871
+ // don't let more than one widget handle mouseStart
872
+ if( mouseHandled ) { return; }
873
+
874
+ // we may have missed mouseup (out of window)
875
+ (this._mouseStarted && this._mouseUp(event));
876
+
877
+ this._mouseDownEvent = event;
878
+
879
+ var that = this,
880
+ btnIsLeft = (event.which === 1),
881
+ // event.target.nodeName works around a bug in IE 8 with
882
+ // disabled inputs (#7620)
883
+ elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
884
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
885
+ return true;
886
+ }
887
+
888
+ this.mouseDelayMet = !this.options.delay;
889
+ if (!this.mouseDelayMet) {
890
+ this._mouseDelayTimer = setTimeout(function() {
891
+ that.mouseDelayMet = true;
892
+ }, this.options.delay);
893
+ }
894
+
895
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
896
+ this._mouseStarted = (this._mouseStart(event) !== false);
897
+ if (!this._mouseStarted) {
898
+ event.preventDefault();
899
+ return true;
900
+ }
901
+ }
902
+
903
+ // Click event may never have fired (Gecko & Opera)
904
+ if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
905
+ $.removeData(event.target, this.widgetName + ".preventClickEvent");
906
+ }
907
+
908
+ // these delegates are required to keep context
909
+ this._mouseMoveDelegate = function(event) {
910
+ return that._mouseMove(event);
911
+ };
912
+ this._mouseUpDelegate = function(event) {
913
+ return that._mouseUp(event);
914
+ };
915
+ $(document)
916
+ .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
917
+ .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
918
+
919
+ event.preventDefault();
920
+
921
+ mouseHandled = true;
922
+ return true;
923
+ },
924
+
925
+ _mouseMove: function(event) {
926
+ // IE mouseup check - mouseup happened when mouse was out of window
927
+ if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
928
+ return this._mouseUp(event);
929
+ }
930
+
931
+ if (this._mouseStarted) {
932
+ this._mouseDrag(event);
933
+ return event.preventDefault();
934
+ }
935
+
936
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
937
+ this._mouseStarted =
938
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
939
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
940
+ }
941
+
942
+ return !this._mouseStarted;
943
+ },
944
+
945
+ _mouseUp: function(event) {
946
+ $(document)
947
+ .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
948
+ .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
949
+
950
+ if (this._mouseStarted) {
951
+ this._mouseStarted = false;
952
+
953
+ if (event.target === this._mouseDownEvent.target) {
954
+ $.data(event.target, this.widgetName + ".preventClickEvent", true);
955
+ }
956
+
957
+ this._mouseStop(event);
958
+ }
959
+
960
+ return false;
961
+ },
962
+
963
+ _mouseDistanceMet: function(event) {
964
+ return (Math.max(
965
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
966
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
967
+ ) >= this.options.distance
968
+ );
969
+ },
970
+
971
+ _mouseDelayMet: function(/* event */) {
972
+ return this.mouseDelayMet;
973
+ },
974
+
975
+ // These are placeholder methods, to be overriden by extending plugin
976
+ _mouseStart: function(/* event */) {},
977
+ _mouseDrag: function(/* event */) {},
978
+ _mouseStop: function(/* event */) {},
979
+ _mouseCapture: function(/* event */) { return true; }
980
+ });
981
+
982
+ })(jQuery);
983
+ (function( $, undefined ) {
984
+
985
+ $.ui = $.ui || {};
986
+
987
+ var cachedScrollbarWidth,
988
+ max = Math.max,
989
+ abs = Math.abs,
990
+ round = Math.round,
991
+ rhorizontal = /left|center|right/,
992
+ rvertical = /top|center|bottom/,
993
+ roffset = /[\+\-]\d+(\.[\d]+)?%?/,
994
+ rposition = /^\w+/,
995
+ rpercent = /%$/,
996
+ _position = $.fn.position;
997
+
998
+ function getOffsets( offsets, width, height ) {
999
+ return [
1000
+ parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1001
+ parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1002
+ ];
1003
+ }
1004
+
1005
+ function parseCss( element, property ) {
1006
+ return parseInt( $.css( element, property ), 10 ) || 0;
1007
+ }
1008
+
1009
+ function getDimensions( elem ) {
1010
+ var raw = elem[0];
1011
+ if ( raw.nodeType === 9 ) {
1012
+ return {
1013
+ width: elem.width(),
1014
+ height: elem.height(),
1015
+ offset: { top: 0, left: 0 }
1016
+ };
1017
+ }
1018
+ if ( $.isWindow( raw ) ) {
1019
+ return {
1020
+ width: elem.width(),
1021
+ height: elem.height(),
1022
+ offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1023
+ };
1024
+ }
1025
+ if ( raw.preventDefault ) {
1026
+ return {
1027
+ width: 0,
1028
+ height: 0,
1029
+ offset: { top: raw.pageY, left: raw.pageX }
1030
+ };
1031
+ }
1032
+ return {
1033
+ width: elem.outerWidth(),
1034
+ height: elem.outerHeight(),
1035
+ offset: elem.offset()
1036
+ };
1037
+ }
1038
+
1039
+ $.position = {
1040
+ scrollbarWidth: function() {
1041
+ if ( cachedScrollbarWidth !== undefined ) {
1042
+ return cachedScrollbarWidth;
1043
+ }
1044
+ var w1, w2,
1045
+ div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1046
+ innerDiv = div.children()[0];
1047
+
1048
+ $( "body" ).append( div );
1049
+ w1 = innerDiv.offsetWidth;
1050
+ div.css( "overflow", "scroll" );
1051
+
1052
+ w2 = innerDiv.offsetWidth;
1053
+
1054
+ if ( w1 === w2 ) {
1055
+ w2 = div[0].clientWidth;
1056
+ }
1057
+
1058
+ div.remove();
1059
+
1060
+ return (cachedScrollbarWidth = w1 - w2);
1061
+ },
1062
+ getScrollInfo: function( within ) {
1063
+ var overflowX = within.isWindow || within.isDocument ? "" :
1064
+ within.element.css( "overflow-x" ),
1065
+ overflowY = within.isWindow || within.isDocument ? "" :
1066
+ within.element.css( "overflow-y" ),
1067
+ hasOverflowX = overflowX === "scroll" ||
1068
+ ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1069
+ hasOverflowY = overflowY === "scroll" ||
1070
+ ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1071
+ return {
1072
+ width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1073
+ height: hasOverflowX ? $.position.scrollbarWidth() : 0
1074
+ };
1075
+ },
1076
+ getWithinInfo: function( element ) {
1077
+ var withinElement = $( element || window ),
1078
+ isWindow = $.isWindow( withinElement[0] ),
1079
+ isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1080
+ return {
1081
+ element: withinElement,
1082
+ isWindow: isWindow,
1083
+ isDocument: isDocument,
1084
+ offset: withinElement.offset() || { left: 0, top: 0 },
1085
+ scrollLeft: withinElement.scrollLeft(),
1086
+ scrollTop: withinElement.scrollTop(),
1087
+ width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1088
+ height: isWindow ? withinElement.height() : withinElement.outerHeight()
1089
+ };
1090
+ }
1091
+ };
1092
+
1093
+ $.fn.position = function( options ) {
1094
+ if ( !options || !options.of ) {
1095
+ return _position.apply( this, arguments );
1096
+ }
1097
+
1098
+ // make a copy, we don't want to modify arguments
1099
+ options = $.extend( {}, options );
1100
+
1101
+ var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1102
+ target = $( options.of ),
1103
+ within = $.position.getWithinInfo( options.within ),
1104
+ scrollInfo = $.position.getScrollInfo( within ),
1105
+ collision = ( options.collision || "flip" ).split( " " ),
1106
+ offsets = {};
1107
+
1108
+ dimensions = getDimensions( target );
1109
+ if ( target[0].preventDefault ) {
1110
+ // force left top to allow flipping
1111
+ options.at = "left top";
1112
+ }
1113
+ targetWidth = dimensions.width;
1114
+ targetHeight = dimensions.height;
1115
+ targetOffset = dimensions.offset;
1116
+ // clone to reuse original targetOffset later
1117
+ basePosition = $.extend( {}, targetOffset );
1118
+
1119
+ // force my and at to have valid horizontal and vertical positions
1120
+ // if a value is missing or invalid, it will be converted to center
1121
+ $.each( [ "my", "at" ], function() {
1122
+ var pos = ( options[ this ] || "" ).split( " " ),
1123
+ horizontalOffset,
1124
+ verticalOffset;
1125
+
1126
+ if ( pos.length === 1) {
1127
+ pos = rhorizontal.test( pos[ 0 ] ) ?
1128
+ pos.concat( [ "center" ] ) :
1129
+ rvertical.test( pos[ 0 ] ) ?
1130
+ [ "center" ].concat( pos ) :
1131
+ [ "center", "center" ];
1132
+ }
1133
+ pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1134
+ pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1135
+
1136
+ // calculate offsets
1137
+ horizontalOffset = roffset.exec( pos[ 0 ] );
1138
+ verticalOffset = roffset.exec( pos[ 1 ] );
1139
+ offsets[ this ] = [
1140
+ horizontalOffset ? horizontalOffset[ 0 ] : 0,
1141
+ verticalOffset ? verticalOffset[ 0 ] : 0
1142
+ ];
1143
+
1144
+ // reduce to just the positions without the offsets
1145
+ options[ this ] = [
1146
+ rposition.exec( pos[ 0 ] )[ 0 ],
1147
+ rposition.exec( pos[ 1 ] )[ 0 ]
1148
+ ];
1149
+ });
1150
+
1151
+ // normalize collision option
1152
+ if ( collision.length === 1 ) {
1153
+ collision[ 1 ] = collision[ 0 ];
1154
+ }
1155
+
1156
+ if ( options.at[ 0 ] === "right" ) {
1157
+ basePosition.left += targetWidth;
1158
+ } else if ( options.at[ 0 ] === "center" ) {
1159
+ basePosition.left += targetWidth / 2;
1160
+ }
1161
+
1162
+ if ( options.at[ 1 ] === "bottom" ) {
1163
+ basePosition.top += targetHeight;
1164
+ } else if ( options.at[ 1 ] === "center" ) {
1165
+ basePosition.top += targetHeight / 2;
1166
+ }
1167
+
1168
+ atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1169
+ basePosition.left += atOffset[ 0 ];
1170
+ basePosition.top += atOffset[ 1 ];
1171
+
1172
+ return this.each(function() {
1173
+ var collisionPosition, using,
1174
+ elem = $( this ),
1175
+ elemWidth = elem.outerWidth(),
1176
+ elemHeight = elem.outerHeight(),
1177
+ marginLeft = parseCss( this, "marginLeft" ),
1178
+ marginTop = parseCss( this, "marginTop" ),
1179
+ collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1180
+ collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1181
+ position = $.extend( {}, basePosition ),
1182
+ myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1183
+
1184
+ if ( options.my[ 0 ] === "right" ) {
1185
+ position.left -= elemWidth;
1186
+ } else if ( options.my[ 0 ] === "center" ) {
1187
+ position.left -= elemWidth / 2;
1188
+ }
1189
+
1190
+ if ( options.my[ 1 ] === "bottom" ) {
1191
+ position.top -= elemHeight;
1192
+ } else if ( options.my[ 1 ] === "center" ) {
1193
+ position.top -= elemHeight / 2;
1194
+ }
1195
+
1196
+ position.left += myOffset[ 0 ];
1197
+ position.top += myOffset[ 1 ];
1198
+
1199
+ // if the browser doesn't support fractions, then round for consistent results
1200
+ if ( !$.support.offsetFractions ) {
1201
+ position.left = round( position.left );
1202
+ position.top = round( position.top );
1203
+ }
1204
+
1205
+ collisionPosition = {
1206
+ marginLeft: marginLeft,
1207
+ marginTop: marginTop
1208
+ };
1209
+
1210
+ $.each( [ "left", "top" ], function( i, dir ) {
1211
+ if ( $.ui.position[ collision[ i ] ] ) {
1212
+ $.ui.position[ collision[ i ] ][ dir ]( position, {
1213
+ targetWidth: targetWidth,
1214
+ targetHeight: targetHeight,
1215
+ elemWidth: elemWidth,
1216
+ elemHeight: elemHeight,
1217
+ collisionPosition: collisionPosition,
1218
+ collisionWidth: collisionWidth,
1219
+ collisionHeight: collisionHeight,
1220
+ offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1221
+ my: options.my,
1222
+ at: options.at,
1223
+ within: within,
1224
+ elem : elem
1225
+ });
1226
+ }
1227
+ });
1228
+
1229
+ if ( options.using ) {
1230
+ // adds feedback as second argument to using callback, if present
1231
+ using = function( props ) {
1232
+ var left = targetOffset.left - position.left,
1233
+ right = left + targetWidth - elemWidth,
1234
+ top = targetOffset.top - position.top,
1235
+ bottom = top + targetHeight - elemHeight,
1236
+ feedback = {
1237
+ target: {
1238
+ element: target,
1239
+ left: targetOffset.left,
1240
+ top: targetOffset.top,
1241
+ width: targetWidth,
1242
+ height: targetHeight
1243
+ },
1244
+ element: {
1245
+ element: elem,
1246
+ left: position.left,
1247
+ top: position.top,
1248
+ width: elemWidth,
1249
+ height: elemHeight
1250
+ },
1251
+ horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1252
+ vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1253
+ };
1254
+ if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1255
+ feedback.horizontal = "center";
1256
+ }
1257
+ if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1258
+ feedback.vertical = "middle";
1259
+ }
1260
+ if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1261
+ feedback.important = "horizontal";
1262
+ } else {
1263
+ feedback.important = "vertical";
1264
+ }
1265
+ options.using.call( this, props, feedback );
1266
+ };
1267
+ }
1268
+
1269
+ elem.offset( $.extend( position, { using: using } ) );
1270
+ });
1271
+ };
1272
+
1273
+ $.ui.position = {
1274
+ fit: {
1275
+ left: function( position, data ) {
1276
+ var within = data.within,
1277
+ withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1278
+ outerWidth = within.width,
1279
+ collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1280
+ overLeft = withinOffset - collisionPosLeft,
1281
+ overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1282
+ newOverRight;
1283
+
1284
+ // element is wider than within
1285
+ if ( data.collisionWidth > outerWidth ) {
1286
+ // element is initially over the left side of within
1287
+ if ( overLeft > 0 && overRight <= 0 ) {
1288
+ newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1289
+ position.left += overLeft - newOverRight;
1290
+ // element is initially over right side of within
1291
+ } else if ( overRight > 0 && overLeft <= 0 ) {
1292
+ position.left = withinOffset;
1293
+ // element is initially over both left and right sides of within
1294
+ } else {
1295
+ if ( overLeft > overRight ) {
1296
+ position.left = withinOffset + outerWidth - data.collisionWidth;
1297
+ } else {
1298
+ position.left = withinOffset;
1299
+ }
1300
+ }
1301
+ // too far left -> align with left edge
1302
+ } else if ( overLeft > 0 ) {
1303
+ position.left += overLeft;
1304
+ // too far right -> align with right edge
1305
+ } else if ( overRight > 0 ) {
1306
+ position.left -= overRight;
1307
+ // adjust based on position and margin
1308
+ } else {
1309
+ position.left = max( position.left - collisionPosLeft, position.left );
1310
+ }
1311
+ },
1312
+ top: function( position, data ) {
1313
+ var within = data.within,
1314
+ withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1315
+ outerHeight = data.within.height,
1316
+ collisionPosTop = position.top - data.collisionPosition.marginTop,
1317
+ overTop = withinOffset - collisionPosTop,
1318
+ overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1319
+ newOverBottom;
1320
+
1321
+ // element is taller than within
1322
+ if ( data.collisionHeight > outerHeight ) {
1323
+ // element is initially over the top of within
1324
+ if ( overTop > 0 && overBottom <= 0 ) {
1325
+ newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1326
+ position.top += overTop - newOverBottom;
1327
+ // element is initially over bottom of within
1328
+ } else if ( overBottom > 0 && overTop <= 0 ) {
1329
+ position.top = withinOffset;
1330
+ // element is initially over both top and bottom of within
1331
+ } else {
1332
+ if ( overTop > overBottom ) {
1333
+ position.top = withinOffset + outerHeight - data.collisionHeight;
1334
+ } else {
1335
+ position.top = withinOffset;
1336
+ }
1337
+ }
1338
+ // too far up -> align with top
1339
+ } else if ( overTop > 0 ) {
1340
+ position.top += overTop;
1341
+ // too far down -> align with bottom edge
1342
+ } else if ( overBottom > 0 ) {
1343
+ position.top -= overBottom;
1344
+ // adjust based on position and margin
1345
+ } else {
1346
+ position.top = max( position.top - collisionPosTop, position.top );
1347
+ }
1348
+ }
1349
+ },
1350
+ flip: {
1351
+ left: function( position, data ) {
1352
+ var within = data.within,
1353
+ withinOffset = within.offset.left + within.scrollLeft,
1354
+ outerWidth = within.width,
1355
+ offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1356
+ collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1357
+ overLeft = collisionPosLeft - offsetLeft,
1358
+ overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1359
+ myOffset = data.my[ 0 ] === "left" ?
1360
+ -data.elemWidth :
1361
+ data.my[ 0 ] === "right" ?
1362
+ data.elemWidth :
1363
+ 0,
1364
+ atOffset = data.at[ 0 ] === "left" ?
1365
+ data.targetWidth :
1366
+ data.at[ 0 ] === "right" ?
1367
+ -data.targetWidth :
1368
+ 0,
1369
+ offset = -2 * data.offset[ 0 ],
1370
+ newOverRight,
1371
+ newOverLeft;
1372
+
1373
+ if ( overLeft < 0 ) {
1374
+ newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1375
+ if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1376
+ position.left += myOffset + atOffset + offset;
1377
+ }
1378
+ }
1379
+ else if ( overRight > 0 ) {
1380
+ newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1381
+ if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1382
+ position.left += myOffset + atOffset + offset;
1383
+ }
1384
+ }
1385
+ },
1386
+ top: function( position, data ) {
1387
+ var within = data.within,
1388
+ withinOffset = within.offset.top + within.scrollTop,
1389
+ outerHeight = within.height,
1390
+ offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1391
+ collisionPosTop = position.top - data.collisionPosition.marginTop,
1392
+ overTop = collisionPosTop - offsetTop,
1393
+ overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1394
+ top = data.my[ 1 ] === "top",
1395
+ myOffset = top ?
1396
+ -data.elemHeight :
1397
+ data.my[ 1 ] === "bottom" ?
1398
+ data.elemHeight :
1399
+ 0,
1400
+ atOffset = data.at[ 1 ] === "top" ?
1401
+ data.targetHeight :
1402
+ data.at[ 1 ] === "bottom" ?
1403
+ -data.targetHeight :
1404
+ 0,
1405
+ offset = -2 * data.offset[ 1 ],
1406
+ newOverTop,
1407
+ newOverBottom;
1408
+ if ( overTop < 0 ) {
1409
+ newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1410
+ if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1411
+ position.top += myOffset + atOffset + offset;
1412
+ }
1413
+ }
1414
+ else if ( overBottom > 0 ) {
1415
+ newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1416
+ if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1417
+ position.top += myOffset + atOffset + offset;
1418
+ }
1419
+ }
1420
+ }
1421
+ },
1422
+ flipfit: {
1423
+ left: function() {
1424
+ $.ui.position.flip.left.apply( this, arguments );
1425
+ $.ui.position.fit.left.apply( this, arguments );
1426
+ },
1427
+ top: function() {
1428
+ $.ui.position.flip.top.apply( this, arguments );
1429
+ $.ui.position.fit.top.apply( this, arguments );
1430
+ }
1431
+ }
1432
+ };
1433
+
1434
+ // fraction support test
1435
+ (function () {
1436
+ var testElement, testElementParent, testElementStyle, offsetLeft, i,
1437
+ body = document.getElementsByTagName( "body" )[ 0 ],
1438
+ div = document.createElement( "div" );
1439
+
1440
+ //Create a "fake body" for testing based on method used in jQuery.support
1441
+ testElement = document.createElement( body ? "div" : "body" );
1442
+ testElementStyle = {
1443
+ visibility: "hidden",
1444
+ width: 0,
1445
+ height: 0,
1446
+ border: 0,
1447
+ margin: 0,
1448
+ background: "none"
1449
+ };
1450
+ if ( body ) {
1451
+ $.extend( testElementStyle, {
1452
+ position: "absolute",
1453
+ left: "-1000px",
1454
+ top: "-1000px"
1455
+ });
1456
+ }
1457
+ for ( i in testElementStyle ) {
1458
+ testElement.style[ i ] = testElementStyle[ i ];
1459
+ }
1460
+ testElement.appendChild( div );
1461
+ testElementParent = body || document.documentElement;
1462
+ testElementParent.insertBefore( testElement, testElementParent.firstChild );
1463
+
1464
+ div.style.cssText = "position: absolute; left: 10.7432222px;";
1465
+
1466
+ offsetLeft = $( div ).offset().left;
1467
+ $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
1468
+
1469
+ testElement.innerHTML = "";
1470
+ testElementParent.removeChild( testElement );
1471
+ })();
1472
+
1473
+ }( jQuery ) );
1474
+ (function( $, undefined ) {
1475
+
1476
+ function isOverAxis( x, reference, size ) {
1477
+ return ( x > reference ) && ( x < ( reference + size ) );
1478
+ }
1479
+
1480
+ function isFloating(item) {
1481
+ return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
1482
+ }
1483
+
1484
+ $.widget("ui.sortable", $.ui.mouse, {
1485
+ version: "1.10.4",
1486
+ widgetEventPrefix: "sort",
1487
+ ready: false,
1488
+ options: {
1489
+ appendTo: "parent",
1490
+ axis: false,
1491
+ connectWith: false,
1492
+ containment: false,
1493
+ cursor: "auto",
1494
+ cursorAt: false,
1495
+ dropOnEmpty: true,
1496
+ forcePlaceholderSize: false,
1497
+ forceHelperSize: false,
1498
+ grid: false,
1499
+ handle: false,
1500
+ helper: "original",
1501
+ items: "> *",
1502
+ opacity: false,
1503
+ placeholder: false,
1504
+ revert: false,
1505
+ scroll: true,
1506
+ scrollSensitivity: 20,
1507
+ scrollSpeed: 20,
1508
+ scope: "default",
1509
+ tolerance: "intersect",
1510
+ zIndex: 1000,
1511
+
1512
+ // callbacks
1513
+ activate: null,
1514
+ beforeStop: null,
1515
+ change: null,
1516
+ deactivate: null,
1517
+ out: null,
1518
+ over: null,
1519
+ receive: null,
1520
+ remove: null,
1521
+ sort: null,
1522
+ start: null,
1523
+ stop: null,
1524
+ update: null
1525
+ },
1526
+ _create: function() {
1527
+
1528
+ var o = this.options;
1529
+ this.containerCache = {};
1530
+ this.element.addClass("ui-sortable");
1531
+
1532
+ //Get the items
1533
+ this.refresh();
1534
+
1535
+ //Let's determine if the items are being displayed horizontally
1536
+ this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
1537
+
1538
+ //Let's determine the parent's offset
1539
+ this.offset = this.element.offset();
1540
+
1541
+ //Initialize mouse events for interaction
1542
+ this._mouseInit();
1543
+
1544
+ //We're ready to go
1545
+ this.ready = true;
1546
+
1547
+ },
1548
+
1549
+ _destroy: function() {
1550
+ this.element
1551
+ .removeClass("ui-sortable ui-sortable-disabled");
1552
+ this._mouseDestroy();
1553
+
1554
+ for ( var i = this.items.length - 1; i >= 0; i-- ) {
1555
+ this.items[i].item.removeData(this.widgetName + "-item");
1556
+ }
1557
+
1558
+ return this;
1559
+ },
1560
+
1561
+ _setOption: function(key, value){
1562
+ if ( key === "disabled" ) {
1563
+ this.options[ key ] = value;
1564
+
1565
+ this.widget().toggleClass( "ui-sortable-disabled", !!value );
1566
+ } else {
1567
+ // Don't call widget base _setOption for disable as it adds ui-state-disabled class
1568
+ $.Widget.prototype._setOption.apply(this, arguments);
1569
+ }
1570
+ },
1571
+
1572
+ _mouseCapture: function(event, overrideHandle) {
1573
+ var currentItem = null,
1574
+ validHandle = false,
1575
+ that = this;
1576
+
1577
+ if (this.reverting) {
1578
+ return false;
1579
+ }
1580
+
1581
+ if(this.options.disabled || this.options.type === "static") {
1582
+ return false;
1583
+ }
1584
+
1585
+ //We have to refresh the items data once first
1586
+ this._refreshItems(event);
1587
+
1588
+ //Find out if the clicked node (or one of its parents) is a actual item in this.items
1589
+ $(event.target).parents().each(function() {
1590
+ if($.data(this, that.widgetName + "-item") === that) {
1591
+ currentItem = $(this);
1592
+ return false;
1593
+ }
1594
+ });
1595
+ if($.data(event.target, that.widgetName + "-item") === that) {
1596
+ currentItem = $(event.target);
1597
+ }
1598
+
1599
+ if(!currentItem) {
1600
+ return false;
1601
+ }
1602
+ if(this.options.handle && !overrideHandle) {
1603
+ $(this.options.handle, currentItem).find("*").addBack().each(function() {
1604
+ if(this === event.target) {
1605
+ validHandle = true;
1606
+ }
1607
+ });
1608
+ if(!validHandle) {
1609
+ return false;
1610
+ }
1611
+ }
1612
+
1613
+ this.currentItem = currentItem;
1614
+ this._removeCurrentsFromItems();
1615
+ return true;
1616
+
1617
+ },
1618
+
1619
+ _mouseStart: function(event, overrideHandle, noActivation) {
1620
+
1621
+ var i, body,
1622
+ o = this.options;
1623
+
1624
+ this.currentContainer = this;
1625
+
1626
+ //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
1627
+ this.refreshPositions();
1628
+
1629
+ //Create and append the visible helper
1630
+ this.helper = this._createHelper(event);
1631
+
1632
+ //Cache the helper size
1633
+ this._cacheHelperProportions();
1634
+
1635
+ /*
1636
+ * - Position generation -
1637
+ * This block generates everything position related - it's the core of draggables.
1638
+ */
1639
+
1640
+ //Cache the margins of the original element
1641
+ this._cacheMargins();
1642
+
1643
+ //Get the next scrolling parent
1644
+ this.scrollParent = this.helper.scrollParent();
1645
+
1646
+ //The element's absolute position on the page minus margins
1647
+ this.offset = this.currentItem.offset();
1648
+ this.offset = {
1649
+ top: this.offset.top - this.margins.top,
1650
+ left: this.offset.left - this.margins.left
1651
+ };
1652
+
1653
+ $.extend(this.offset, {
1654
+ click: { //Where the click happened, relative to the element
1655
+ left: event.pageX - this.offset.left,
1656
+ top: event.pageY - this.offset.top
1657
+ },
1658
+ parent: this._getParentOffset(),
1659
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1660
+ });
1661
+
1662
+ // Only after we got the offset, we can change the helper's position to absolute
1663
+ // TODO: Still need to figure out a way to make relative sorting possible
1664
+ this.helper.css("position", "absolute");
1665
+ this.cssPosition = this.helper.css("position");
1666
+
1667
+ //Generate the original position
1668
+ this.originalPosition = this._generatePosition(event);
1669
+ this.originalPageX = event.pageX;
1670
+ this.originalPageY = event.pageY;
1671
+
1672
+ //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1673
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1674
+
1675
+ //Cache the former DOM position
1676
+ this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
1677
+
1678
+ //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
1679
+ if(this.helper[0] !== this.currentItem[0]) {
1680
+ this.currentItem.hide();
1681
+ }
1682
+
1683
+ //Create the placeholder
1684
+ this._createPlaceholder();
1685
+
1686
+ //Set a containment if given in the options
1687
+ if(o.containment) {
1688
+ this._setContainment();
1689
+ }
1690
+
1691
+ if( o.cursor && o.cursor !== "auto" ) { // cursor option
1692
+ body = this.document.find( "body" );
1693
+
1694
+ // support: IE
1695
+ this.storedCursor = body.css( "cursor" );
1696
+ body.css( "cursor", o.cursor );
1697
+
1698
+ this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
1699
+ }
1700
+
1701
+ if(o.opacity) { // opacity option
1702
+ if (this.helper.css("opacity")) {
1703
+ this._storedOpacity = this.helper.css("opacity");
1704
+ }
1705
+ this.helper.css("opacity", o.opacity);
1706
+ }
1707
+
1708
+ if(o.zIndex) { // zIndex option
1709
+ if (this.helper.css("zIndex")) {
1710
+ this._storedZIndex = this.helper.css("zIndex");
1711
+ }
1712
+ this.helper.css("zIndex", o.zIndex);
1713
+ }
1714
+
1715
+ //Prepare scrolling
1716
+ if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
1717
+ this.overflowOffset = this.scrollParent.offset();
1718
+ }
1719
+
1720
+ //Call callbacks
1721
+ this._trigger("start", event, this._uiHash());
1722
+
1723
+ //Recache the helper size
1724
+ if(!this._preserveHelperProportions) {
1725
+ this._cacheHelperProportions();
1726
+ }
1727
+
1728
+
1729
+ //Post "activate" events to possible containers
1730
+ if( !noActivation ) {
1731
+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
1732
+ this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
1733
+ }
1734
+ }
1735
+
1736
+ //Prepare possible droppables
1737
+ if($.ui.ddmanager) {
1738
+ $.ui.ddmanager.current = this;
1739
+ }
1740
+
1741
+ if ($.ui.ddmanager && !o.dropBehaviour) {
1742
+ $.ui.ddmanager.prepareOffsets(this, event);
1743
+ }
1744
+
1745
+ this.dragging = true;
1746
+
1747
+ this.helper.addClass("ui-sortable-helper");
1748
+ this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1749
+ return true;
1750
+
1751
+ },
1752
+
1753
+ _mouseDrag: function(event) {
1754
+ var i, item, itemElement, intersection,
1755
+ o = this.options,
1756
+ scrolled = false;
1757
+
1758
+ //Compute the helpers position
1759
+ this.position = this._generatePosition(event);
1760
+ this.positionAbs = this._convertPositionTo("absolute");
1761
+
1762
+ if (!this.lastPositionAbs) {
1763
+ this.lastPositionAbs = this.positionAbs;
1764
+ }
1765
+
1766
+ //Do scrolling
1767
+ if(this.options.scroll) {
1768
+ if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
1769
+
1770
+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1771
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
1772
+ } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
1773
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
1774
+ }
1775
+
1776
+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1777
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
1778
+ } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
1779
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
1780
+ }
1781
+
1782
+ } else {
1783
+
1784
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1785
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1786
+ } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1787
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1788
+ }
1789
+
1790
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1791
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1792
+ } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1793
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1794
+ }
1795
+
1796
+ }
1797
+
1798
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1799
+ $.ui.ddmanager.prepareOffsets(this, event);
1800
+ }
1801
+ }
1802
+
1803
+ //Regenerate the absolute position used for position checks
1804
+ this.positionAbs = this._convertPositionTo("absolute");
1805
+
1806
+ //Set the helper position
1807
+ if(!this.options.axis || this.options.axis !== "y") {
1808
+ this.helper[0].style.left = this.position.left+"px";
1809
+ }
1810
+ if(!this.options.axis || this.options.axis !== "x") {
1811
+ this.helper[0].style.top = this.position.top+"px";
1812
+ }
1813
+
1814
+ //Rearrange
1815
+ for (i = this.items.length - 1; i >= 0; i--) {
1816
+
1817
+ //Cache variables and intersection, continue if no intersection
1818
+ item = this.items[i];
1819
+ itemElement = item.item[0];
1820
+ intersection = this._intersectsWithPointer(item);
1821
+ if (!intersection) {
1822
+ continue;
1823
+ }
1824
+
1825
+ // Only put the placeholder inside the current Container, skip all
1826
+ // items from other containers. This works because when moving
1827
+ // an item from one container to another the
1828
+ // currentContainer is switched before the placeholder is moved.
1829
+ //
1830
+ // Without this, moving items in "sub-sortables" can cause
1831
+ // the placeholder to jitter beetween the outer and inner container.
1832
+ if (item.instance !== this.currentContainer) {
1833
+ continue;
1834
+ }
1835
+
1836
+ // cannot intersect with itself
1837
+ // no useless actions that have been done before
1838
+ // no action if the item moved is the parent of the item checked
1839
+ if (itemElement !== this.currentItem[0] &&
1840
+ this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
1841
+ !$.contains(this.placeholder[0], itemElement) &&
1842
+ (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
1843
+ ) {
1844
+
1845
+ this.direction = intersection === 1 ? "down" : "up";
1846
+
1847
+ if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
1848
+ this._rearrange(event, item);
1849
+ } else {
1850
+ break;
1851
+ }
1852
+
1853
+ this._trigger("change", event, this._uiHash());
1854
+ break;
1855
+ }
1856
+ }
1857
+
1858
+ //Post events to containers
1859
+ this._contactContainers(event);
1860
+
1861
+ //Interconnect with droppables
1862
+ if($.ui.ddmanager) {
1863
+ $.ui.ddmanager.drag(this, event);
1864
+ }
1865
+
1866
+ //Call callbacks
1867
+ this._trigger("sort", event, this._uiHash());
1868
+
1869
+ this.lastPositionAbs = this.positionAbs;
1870
+ return false;
1871
+
1872
+ },
1873
+
1874
+ _mouseStop: function(event, noPropagation) {
1875
+
1876
+ if(!event) {
1877
+ return;
1878
+ }
1879
+
1880
+ //If we are using droppables, inform the manager about the drop
1881
+ if ($.ui.ddmanager && !this.options.dropBehaviour) {
1882
+ $.ui.ddmanager.drop(this, event);
1883
+ }
1884
+
1885
+ if(this.options.revert) {
1886
+ var that = this,
1887
+ cur = this.placeholder.offset(),
1888
+ axis = this.options.axis,
1889
+ animation = {};
1890
+
1891
+ if ( !axis || axis === "x" ) {
1892
+ animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
1893
+ }
1894
+ if ( !axis || axis === "y" ) {
1895
+ animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
1896
+ }
1897
+ this.reverting = true;
1898
+ $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
1899
+ that._clear(event);
1900
+ });
1901
+ } else {
1902
+ this._clear(event, noPropagation);
1903
+ }
1904
+
1905
+ return false;
1906
+
1907
+ },
1908
+
1909
+ cancel: function() {
1910
+
1911
+ if(this.dragging) {
1912
+
1913
+ this._mouseUp({ target: null });
1914
+
1915
+ if(this.options.helper === "original") {
1916
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
1917
+ } else {
1918
+ this.currentItem.show();
1919
+ }
1920
+
1921
+ //Post deactivating events to containers
1922
+ for (var i = this.containers.length - 1; i >= 0; i--){
1923
+ this.containers[i]._trigger("deactivate", null, this._uiHash(this));
1924
+ if(this.containers[i].containerCache.over) {
1925
+ this.containers[i]._trigger("out", null, this._uiHash(this));
1926
+ this.containers[i].containerCache.over = 0;
1927
+ }
1928
+ }
1929
+
1930
+ }
1931
+
1932
+ if (this.placeholder) {
1933
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
1934
+ if(this.placeholder[0].parentNode) {
1935
+ this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
1936
+ }
1937
+ if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
1938
+ this.helper.remove();
1939
+ }
1940
+
1941
+ $.extend(this, {
1942
+ helper: null,
1943
+ dragging: false,
1944
+ reverting: false,
1945
+ _noFinalSort: null
1946
+ });
1947
+
1948
+ if(this.domPosition.prev) {
1949
+ $(this.domPosition.prev).after(this.currentItem);
1950
+ } else {
1951
+ $(this.domPosition.parent).prepend(this.currentItem);
1952
+ }
1953
+ }
1954
+
1955
+ return this;
1956
+
1957
+ },
1958
+
1959
+ serialize: function(o) {
1960
+
1961
+ var items = this._getItemsAsjQuery(o && o.connected),
1962
+ str = [];
1963
+ o = o || {};
1964
+
1965
+ $(items).each(function() {
1966
+ var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
1967
+ if (res) {
1968
+ str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
1969
+ }
1970
+ });
1971
+
1972
+ if(!str.length && o.key) {
1973
+ str.push(o.key + "=");
1974
+ }
1975
+
1976
+ return str.join("&");
1977
+
1978
+ },
1979
+
1980
+ toArray: function(o) {
1981
+
1982
+ var items = this._getItemsAsjQuery(o && o.connected),
1983
+ ret = [];
1984
+
1985
+ o = o || {};
1986
+
1987
+ items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
1988
+ return ret;
1989
+
1990
+ },
1991
+
1992
+ /* Be careful with the following core functions */
1993
+ _intersectsWith: function(item) {
1994
+
1995
+ var x1 = this.positionAbs.left,
1996
+ x2 = x1 + this.helperProportions.width,
1997
+ y1 = this.positionAbs.top,
1998
+ y2 = y1 + this.helperProportions.height,
1999
+ l = item.left,
2000
+ r = l + item.width,
2001
+ t = item.top,
2002
+ b = t + item.height,
2003
+ dyClick = this.offset.click.top,
2004
+ dxClick = this.offset.click.left,
2005
+ isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
2006
+ isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
2007
+ isOverElement = isOverElementHeight && isOverElementWidth;
2008
+
2009
+ if ( this.options.tolerance === "pointer" ||
2010
+ this.options.forcePointerForContainers ||
2011
+ (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
2012
+ ) {
2013
+ return isOverElement;
2014
+ } else {
2015
+
2016
+ return (l < x1 + (this.helperProportions.width / 2) && // Right Half
2017
+ x2 - (this.helperProportions.width / 2) < r && // Left Half
2018
+ t < y1 + (this.helperProportions.height / 2) && // Bottom Half
2019
+ y2 - (this.helperProportions.height / 2) < b ); // Top Half
2020
+
2021
+ }
2022
+ },
2023
+
2024
+ _intersectsWithPointer: function(item) {
2025
+
2026
+ var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
2027
+ isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
2028
+ isOverElement = isOverElementHeight && isOverElementWidth,
2029
+ verticalDirection = this._getDragVerticalDirection(),
2030
+ horizontalDirection = this._getDragHorizontalDirection();
2031
+
2032
+ if (!isOverElement) {
2033
+ return false;
2034
+ }
2035
+
2036
+ return this.floating ?
2037
+ ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
2038
+ : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
2039
+
2040
+ },
2041
+
2042
+ _intersectsWithSides: function(item) {
2043
+
2044
+ var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
2045
+ isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
2046
+ verticalDirection = this._getDragVerticalDirection(),
2047
+ horizontalDirection = this._getDragHorizontalDirection();
2048
+
2049
+ if (this.floating && horizontalDirection) {
2050
+ return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
2051
+ } else {
2052
+ return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
2053
+ }
2054
+
2055
+ },
2056
+
2057
+ _getDragVerticalDirection: function() {
2058
+ var delta = this.positionAbs.top - this.lastPositionAbs.top;
2059
+ return delta !== 0 && (delta > 0 ? "down" : "up");
2060
+ },
2061
+
2062
+ _getDragHorizontalDirection: function() {
2063
+ var delta = this.positionAbs.left - this.lastPositionAbs.left;
2064
+ return delta !== 0 && (delta > 0 ? "right" : "left");
2065
+ },
2066
+
2067
+ refresh: function(event) {
2068
+ this._refreshItems(event);
2069
+ this.refreshPositions();
2070
+ return this;
2071
+ },
2072
+
2073
+ _connectWith: function() {
2074
+ var options = this.options;
2075
+ return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
2076
+ },
2077
+
2078
+ _getItemsAsjQuery: function(connected) {
2079
+
2080
+ var i, j, cur, inst,
2081
+ items = [],
2082
+ queries = [],
2083
+ connectWith = this._connectWith();
2084
+
2085
+ if(connectWith && connected) {
2086
+ for (i = connectWith.length - 1; i >= 0; i--){
2087
+ cur = $(connectWith[i]);
2088
+ for ( j = cur.length - 1; j >= 0; j--){
2089
+ inst = $.data(cur[j], this.widgetFullName);
2090
+ if(inst && inst !== this && !inst.options.disabled) {
2091
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
2092
+ }
2093
+ }
2094
+ }
2095
+ }
2096
+
2097
+ queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
2098
+
2099
+ function addItems() {
2100
+ items.push( this );
2101
+ }
2102
+ for (i = queries.length - 1; i >= 0; i--){
2103
+ queries[i][0].each( addItems );
2104
+ }
2105
+
2106
+ return $(items);
2107
+
2108
+ },
2109
+
2110
+ _removeCurrentsFromItems: function() {
2111
+
2112
+ var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
2113
+
2114
+ this.items = $.grep(this.items, function (item) {
2115
+ for (var j=0; j < list.length; j++) {
2116
+ if(list[j] === item.item[0]) {
2117
+ return false;
2118
+ }
2119
+ }
2120
+ return true;
2121
+ });
2122
+
2123
+ },
2124
+
2125
+ _refreshItems: function(event) {
2126
+
2127
+ this.items = [];
2128
+ this.containers = [this];
2129
+
2130
+ var i, j, cur, inst, targetData, _queries, item, queriesLength,
2131
+ items = this.items,
2132
+ queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
2133
+ connectWith = this._connectWith();
2134
+
2135
+ if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
2136
+ for (i = connectWith.length - 1; i >= 0; i--){
2137
+ cur = $(connectWith[i]);
2138
+ for (j = cur.length - 1; j >= 0; j--){
2139
+ inst = $.data(cur[j], this.widgetFullName);
2140
+ if(inst && inst !== this && !inst.options.disabled) {
2141
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
2142
+ this.containers.push(inst);
2143
+ }
2144
+ }
2145
+ }
2146
+ }
2147
+
2148
+ for (i = queries.length - 1; i >= 0; i--) {
2149
+ targetData = queries[i][1];
2150
+ _queries = queries[i][0];
2151
+
2152
+ for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
2153
+ item = $(_queries[j]);
2154
+
2155
+ item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
2156
+
2157
+ items.push({
2158
+ item: item,
2159
+ instance: targetData,
2160
+ width: 0, height: 0,
2161
+ left: 0, top: 0
2162
+ });
2163
+ }
2164
+ }
2165
+
2166
+ },
2167
+
2168
+ refreshPositions: function(fast) {
2169
+
2170
+ //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
2171
+ if(this.offsetParent && this.helper) {
2172
+ this.offset.parent = this._getParentOffset();
2173
+ }
2174
+
2175
+ var i, item, t, p;
2176
+
2177
+ for (i = this.items.length - 1; i >= 0; i--){
2178
+ item = this.items[i];
2179
+
2180
+ //We ignore calculating positions of all connected containers when we're not over them
2181
+ if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
2182
+ continue;
2183
+ }
2184
+
2185
+ t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
2186
+
2187
+ if (!fast) {
2188
+ item.width = t.outerWidth();
2189
+ item.height = t.outerHeight();
2190
+ }
2191
+
2192
+ p = t.offset();
2193
+ item.left = p.left;
2194
+ item.top = p.top;
2195
+ }
2196
+
2197
+ if(this.options.custom && this.options.custom.refreshContainers) {
2198
+ this.options.custom.refreshContainers.call(this);
2199
+ } else {
2200
+ for (i = this.containers.length - 1; i >= 0; i--){
2201
+ p = this.containers[i].element.offset();
2202
+ this.containers[i].containerCache.left = p.left;
2203
+ this.containers[i].containerCache.top = p.top;
2204
+ this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
2205
+ this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
2206
+ }
2207
+ }
2208
+
2209
+ return this;
2210
+ },
2211
+
2212
+ _createPlaceholder: function(that) {
2213
+ that = that || this;
2214
+ var className,
2215
+ o = that.options;
2216
+
2217
+ if(!o.placeholder || o.placeholder.constructor === String) {
2218
+ className = o.placeholder;
2219
+ o.placeholder = {
2220
+ element: function() {
2221
+
2222
+ var nodeName = that.currentItem[0].nodeName.toLowerCase(),
2223
+ element = $( "<" + nodeName + ">", that.document[0] )
2224
+ .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
2225
+ .removeClass("ui-sortable-helper");
2226
+
2227
+ if ( nodeName === "tr" ) {
2228
+ that.currentItem.children().each(function() {
2229
+ $( "<td>&#160;</td>", that.document[0] )
2230
+ .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
2231
+ .appendTo( element );
2232
+ });
2233
+ } else if ( nodeName === "img" ) {
2234
+ element.attr( "src", that.currentItem.attr( "src" ) );
2235
+ }
2236
+
2237
+ if ( !className ) {
2238
+ element.css( "visibility", "hidden" );
2239
+ }
2240
+
2241
+ return element;
2242
+ },
2243
+ update: function(container, p) {
2244
+
2245
+ // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
2246
+ // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
2247
+ if(className && !o.forcePlaceholderSize) {
2248
+ return;
2249
+ }
2250
+
2251
+ //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
2252
+ if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
2253
+ if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
2254
+ }
2255
+ };
2256
+ }
2257
+
2258
+ //Create the placeholder
2259
+ that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
2260
+
2261
+ //Append it after the actual current item
2262
+ that.currentItem.after(that.placeholder);
2263
+
2264
+ //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
2265
+ o.placeholder.update(that, that.placeholder);
2266
+
2267
+ },
2268
+
2269
+ _contactContainers: function(event) {
2270
+ var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
2271
+ innermostContainer = null,
2272
+ innermostIndex = null;
2273
+
2274
+ // get innermost container that intersects with item
2275
+ for (i = this.containers.length - 1; i >= 0; i--) {
2276
+
2277
+ // never consider a container that's located within the item itself
2278
+ if($.contains(this.currentItem[0], this.containers[i].element[0])) {
2279
+ continue;
2280
+ }
2281
+
2282
+ if(this._intersectsWith(this.containers[i].containerCache)) {
2283
+
2284
+ // if we've already found a container and it's more "inner" than this, then continue
2285
+ if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
2286
+ continue;
2287
+ }
2288
+
2289
+ innermostContainer = this.containers[i];
2290
+ innermostIndex = i;
2291
+
2292
+ } else {
2293
+ // container doesn't intersect. trigger "out" event if necessary
2294
+ if(this.containers[i].containerCache.over) {
2295
+ this.containers[i]._trigger("out", event, this._uiHash(this));
2296
+ this.containers[i].containerCache.over = 0;
2297
+ }
2298
+ }
2299
+
2300
+ }
2301
+
2302
+ // if no intersecting containers found, return
2303
+ if(!innermostContainer) {
2304
+ return;
2305
+ }
2306
+
2307
+ // move the item into the container if it's not there already
2308
+ if(this.containers.length === 1) {
2309
+ if (!this.containers[innermostIndex].containerCache.over) {
2310
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
2311
+ this.containers[innermostIndex].containerCache.over = 1;
2312
+ }
2313
+ } else {
2314
+
2315
+ //When entering a new container, we will find the item with the least distance and append our item near it
2316
+ dist = 10000;
2317
+ itemWithLeastDistance = null;
2318
+ floating = innermostContainer.floating || isFloating(this.currentItem);
2319
+ posProperty = floating ? "left" : "top";
2320
+ sizeProperty = floating ? "width" : "height";
2321
+ base = this.positionAbs[posProperty] + this.offset.click[posProperty];
2322
+ for (j = this.items.length - 1; j >= 0; j--) {
2323
+ if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
2324
+ continue;
2325
+ }
2326
+ if(this.items[j].item[0] === this.currentItem[0]) {
2327
+ continue;
2328
+ }
2329
+ if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
2330
+ continue;
2331
+ }
2332
+ cur = this.items[j].item.offset()[posProperty];
2333
+ nearBottom = false;
2334
+ if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
2335
+ nearBottom = true;
2336
+ cur += this.items[j][sizeProperty];
2337
+ }
2338
+
2339
+ if(Math.abs(cur - base) < dist) {
2340
+ dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
2341
+ this.direction = nearBottom ? "up": "down";
2342
+ }
2343
+ }
2344
+
2345
+ //Check if dropOnEmpty is enabled
2346
+ if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
2347
+ return;
2348
+ }
2349
+
2350
+ if(this.currentContainer === this.containers[innermostIndex]) {
2351
+ return;
2352
+ }
2353
+
2354
+ itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
2355
+ this._trigger("change", event, this._uiHash());
2356
+ this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
2357
+ this.currentContainer = this.containers[innermostIndex];
2358
+
2359
+ //Update the placeholder
2360
+ this.options.placeholder.update(this.currentContainer, this.placeholder);
2361
+
2362
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
2363
+ this.containers[innermostIndex].containerCache.over = 1;
2364
+ }
2365
+
2366
+
2367
+ },
2368
+
2369
+ _createHelper: function(event) {
2370
+
2371
+ var o = this.options,
2372
+ helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
2373
+
2374
+ //Add the helper to the DOM if that didn't happen already
2375
+ if(!helper.parents("body").length) {
2376
+ $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
2377
+ }
2378
+
2379
+ if(helper[0] === this.currentItem[0]) {
2380
+ 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") };
2381
+ }
2382
+
2383
+ if(!helper[0].style.width || o.forceHelperSize) {
2384
+ helper.width(this.currentItem.width());
2385
+ }
2386
+ if(!helper[0].style.height || o.forceHelperSize) {
2387
+ helper.height(this.currentItem.height());
2388
+ }
2389
+
2390
+ return helper;
2391
+
2392
+ },
2393
+
2394
+ _adjustOffsetFromHelper: function(obj) {
2395
+ if (typeof obj === "string") {
2396
+ obj = obj.split(" ");
2397
+ }
2398
+ if ($.isArray(obj)) {
2399
+ obj = {left: +obj[0], top: +obj[1] || 0};
2400
+ }
2401
+ if ("left" in obj) {
2402
+ this.offset.click.left = obj.left + this.margins.left;
2403
+ }
2404
+ if ("right" in obj) {
2405
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
2406
+ }
2407
+ if ("top" in obj) {
2408
+ this.offset.click.top = obj.top + this.margins.top;
2409
+ }
2410
+ if ("bottom" in obj) {
2411
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
2412
+ }
2413
+ },
2414
+
2415
+ _getParentOffset: function() {
2416
+
2417
+
2418
+ //Get the offsetParent and cache its position
2419
+ this.offsetParent = this.helper.offsetParent();
2420
+ var po = this.offsetParent.offset();
2421
+
2422
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
2423
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
2424
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
2425
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
2426
+ if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
2427
+ po.left += this.scrollParent.scrollLeft();
2428
+ po.top += this.scrollParent.scrollTop();
2429
+ }
2430
+
2431
+ // This needs to be actually done for all browsers, since pageX/pageY includes this information
2432
+ // with an ugly IE fix
2433
+ if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
2434
+ po = { top: 0, left: 0 };
2435
+ }
2436
+
2437
+ return {
2438
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
2439
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
2440
+ };
2441
+
2442
+ },
2443
+
2444
+ _getRelativeOffset: function() {
2445
+
2446
+ if(this.cssPosition === "relative") {
2447
+ var p = this.currentItem.position();
2448
+ return {
2449
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
2450
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
2451
+ };
2452
+ } else {
2453
+ return { top: 0, left: 0 };
2454
+ }
2455
+
2456
+ },
2457
+
2458
+ _cacheMargins: function() {
2459
+ this.margins = {
2460
+ left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
2461
+ top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
2462
+ };
2463
+ },
2464
+
2465
+ _cacheHelperProportions: function() {
2466
+ this.helperProportions = {
2467
+ width: this.helper.outerWidth(),
2468
+ height: this.helper.outerHeight()
2469
+ };
2470
+ },
2471
+
2472
+ _setContainment: function() {
2473
+
2474
+ var ce, co, over,
2475
+ o = this.options;
2476
+ if(o.containment === "parent") {
2477
+ o.containment = this.helper[0].parentNode;
2478
+ }
2479
+ if(o.containment === "document" || o.containment === "window") {
2480
+ this.containment = [
2481
+ 0 - this.offset.relative.left - this.offset.parent.left,
2482
+ 0 - this.offset.relative.top - this.offset.parent.top,
2483
+ $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
2484
+ ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
2485
+ ];
2486
+ }
2487
+
2488
+ if(!(/^(document|window|parent)$/).test(o.containment)) {
2489
+ ce = $(o.containment)[0];
2490
+ co = $(o.containment).offset();
2491
+ over = ($(ce).css("overflow") !== "hidden");
2492
+
2493
+ this.containment = [
2494
+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
2495
+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
2496
+ co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
2497
+ co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
2498
+ ];
2499
+ }
2500
+
2501
+ },
2502
+
2503
+ _convertPositionTo: function(d, pos) {
2504
+
2505
+ if(!pos) {
2506
+ pos = this.position;
2507
+ }
2508
+ var mod = d === "absolute" ? 1 : -1,
2509
+ scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
2510
+ scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
2511
+
2512
+ return {
2513
+ top: (
2514
+ pos.top + // The absolute mouse position
2515
+ this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
2516
+ this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
2517
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
2518
+ ),
2519
+ left: (
2520
+ pos.left + // The absolute mouse position
2521
+ this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
2522
+ this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
2523
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
2524
+ )
2525
+ };
2526
+
2527
+ },
2528
+
2529
+ _generatePosition: function(event) {
2530
+
2531
+ var top, left,
2532
+ o = this.options,
2533
+ pageX = event.pageX,
2534
+ pageY = event.pageY,
2535
+ scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
2536
+
2537
+ // This is another very weird special case that only happens for relative elements:
2538
+ // 1. If the css position is relative
2539
+ // 2. and the scroll parent is the document or similar to the offset parent
2540
+ // we have to refresh the relative offset during the scroll so there are no jumps
2541
+ if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
2542
+ this.offset.relative = this._getRelativeOffset();
2543
+ }
2544
+
2545
+ /*
2546
+ * - Position constraining -
2547
+ * Constrain the position to a mix of grid, containment.
2548
+ */
2549
+
2550
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
2551
+
2552
+ if(this.containment) {
2553
+ if(event.pageX - this.offset.click.left < this.containment[0]) {
2554
+ pageX = this.containment[0] + this.offset.click.left;
2555
+ }
2556
+ if(event.pageY - this.offset.click.top < this.containment[1]) {
2557
+ pageY = this.containment[1] + this.offset.click.top;
2558
+ }
2559
+ if(event.pageX - this.offset.click.left > this.containment[2]) {
2560
+ pageX = this.containment[2] + this.offset.click.left;
2561
+ }
2562
+ if(event.pageY - this.offset.click.top > this.containment[3]) {
2563
+ pageY = this.containment[3] + this.offset.click.top;
2564
+ }
2565
+ }
2566
+
2567
+ if(o.grid) {
2568
+ top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
2569
+ pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
2570
+
2571
+ left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
2572
+ pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
2573
+ }
2574
+
2575
+ }
2576
+
2577
+ return {
2578
+ top: (
2579
+ pageY - // The absolute mouse position
2580
+ this.offset.click.top - // Click offset (relative to the element)
2581
+ this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
2582
+ this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
2583
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
2584
+ ),
2585
+ left: (
2586
+ pageX - // The absolute mouse position
2587
+ this.offset.click.left - // Click offset (relative to the element)
2588
+ this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
2589
+ this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
2590
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
2591
+ )
2592
+ };
2593
+
2594
+ },
2595
+
2596
+ _rearrange: function(event, i, a, hardRefresh) {
2597
+
2598
+ a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
2599
+
2600
+ //Various things done here to improve the performance:
2601
+ // 1. we create a setTimeout, that calls refreshPositions
2602
+ // 2. on the instance, we have a counter variable, that get's higher after every append
2603
+ // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
2604
+ // 4. this lets only the last addition to the timeout stack through
2605
+ this.counter = this.counter ? ++this.counter : 1;
2606
+ var counter = this.counter;
2607
+
2608
+ this._delay(function() {
2609
+ if(counter === this.counter) {
2610
+ this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
2611
+ }
2612
+ });
2613
+
2614
+ },
2615
+
2616
+ _clear: function(event, noPropagation) {
2617
+
2618
+ this.reverting = false;
2619
+ // We delay all events that have to be triggered to after the point where the placeholder has been removed and
2620
+ // everything else normalized again
2621
+ var i,
2622
+ delayedTriggers = [];
2623
+
2624
+ // We first have to update the dom position of the actual currentItem
2625
+ // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
2626
+ if(!this._noFinalSort && this.currentItem.parent().length) {
2627
+ this.placeholder.before(this.currentItem);
2628
+ }
2629
+ this._noFinalSort = null;
2630
+
2631
+ if(this.helper[0] === this.currentItem[0]) {
2632
+ for(i in this._storedCSS) {
2633
+ if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
2634
+ this._storedCSS[i] = "";
2635
+ }
2636
+ }
2637
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
2638
+ } else {
2639
+ this.currentItem.show();
2640
+ }
2641
+
2642
+ if(this.fromOutside && !noPropagation) {
2643
+ delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
2644
+ }
2645
+ if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
2646
+ delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
2647
+ }
2648
+
2649
+ // Check if the items Container has Changed and trigger appropriate
2650
+ // events.
2651
+ if (this !== this.currentContainer) {
2652
+ if(!noPropagation) {
2653
+ delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
2654
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
2655
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
2656
+ }
2657
+ }
2658
+
2659
+
2660
+ //Post events to containers
2661
+ function delayEvent( type, instance, container ) {
2662
+ return function( event ) {
2663
+ container._trigger( type, event, instance._uiHash( instance ) );
2664
+ };
2665
+ }
2666
+ for (i = this.containers.length - 1; i >= 0; i--){
2667
+ if (!noPropagation) {
2668
+ delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
2669
+ }
2670
+ if(this.containers[i].containerCache.over) {
2671
+ delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
2672
+ this.containers[i].containerCache.over = 0;
2673
+ }
2674
+ }
2675
+
2676
+ //Do what was originally in plugins
2677
+ if ( this.storedCursor ) {
2678
+ this.document.find( "body" ).css( "cursor", this.storedCursor );
2679
+ this.storedStylesheet.remove();
2680
+ }
2681
+ if(this._storedOpacity) {
2682
+ this.helper.css("opacity", this._storedOpacity);
2683
+ }
2684
+ if(this._storedZIndex) {
2685
+ this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
2686
+ }
2687
+
2688
+ this.dragging = false;
2689
+ if(this.cancelHelperRemoval) {
2690
+ if(!noPropagation) {
2691
+ this._trigger("beforeStop", event, this._uiHash());
2692
+ for (i=0; i < delayedTriggers.length; i++) {
2693
+ delayedTriggers[i].call(this, event);
2694
+ } //Trigger all delayed events
2695
+ this._trigger("stop", event, this._uiHash());
2696
+ }
2697
+
2698
+ this.fromOutside = false;
2699
+ return false;
2700
+ }
2701
+
2702
+ if(!noPropagation) {
2703
+ this._trigger("beforeStop", event, this._uiHash());
2704
+ }
2705
+
2706
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
2707
+ this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
2708
+
2709
+ if(this.helper[0] !== this.currentItem[0]) {
2710
+ this.helper.remove();
2711
+ }
2712
+ this.helper = null;
2713
+
2714
+ if(!noPropagation) {
2715
+ for (i=0; i < delayedTriggers.length; i++) {
2716
+ delayedTriggers[i].call(this, event);
2717
+ } //Trigger all delayed events
2718
+ this._trigger("stop", event, this._uiHash());
2719
+ }
2720
+
2721
+ this.fromOutside = false;
2722
+ return true;
2723
+
2724
+ },
2725
+
2726
+ _trigger: function() {
2727
+ if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
2728
+ this.cancel();
2729
+ }
2730
+ },
2731
+
2732
+ _uiHash: function(_inst) {
2733
+ var inst = _inst || this;
2734
+ return {
2735
+ helper: inst.helper,
2736
+ placeholder: inst.placeholder || $([]),
2737
+ position: inst.position,
2738
+ originalPosition: inst.originalPosition,
2739
+ offset: inst.positionAbs,
2740
+ item: inst.currentItem,
2741
+ sender: _inst ? _inst.element : null
2742
+ };
2743
+ }
2744
+
2745
+ });
2746
+
2747
+ })(jQuery);
2748
+ (function($, undefined) {
2749
+
2750
+ var dataSpace = "ui-effects-";
2751
+
2752
+ $.effects = {
2753
+ effect: {}
2754
+ };
2755
+
2756
+ /*!
2757
+ * jQuery Color Animations v2.1.2
2758
+ * https://github.com/jquery/jquery-color
2759
+ *
2760
+ * Copyright 2013 jQuery Foundation and other contributors
2761
+ * Released under the MIT license.
2762
+ * http://jquery.org/license
2763
+ *
2764
+ * Date: Wed Jan 16 08:47:09 2013 -0600
2765
+ */
2766
+ (function( jQuery, undefined ) {
2767
+
2768
+ var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
2769
+
2770
+ // plusequals test for += 100 -= 100
2771
+ rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
2772
+ // a set of RE's that can match strings and generate color tuples.
2773
+ stringParsers = [{
2774
+ re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
2775
+ parse: function( execResult ) {
2776
+ return [
2777
+ execResult[ 1 ],
2778
+ execResult[ 2 ],
2779
+ execResult[ 3 ],
2780
+ execResult[ 4 ]
2781
+ ];
2782
+ }
2783
+ }, {
2784
+ re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
2785
+ parse: function( execResult ) {
2786
+ return [
2787
+ execResult[ 1 ] * 2.55,
2788
+ execResult[ 2 ] * 2.55,
2789
+ execResult[ 3 ] * 2.55,
2790
+ execResult[ 4 ]
2791
+ ];
2792
+ }
2793
+ }, {
2794
+ // this regex ignores A-F because it's compared against an already lowercased string
2795
+ re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
2796
+ parse: function( execResult ) {
2797
+ return [
2798
+ parseInt( execResult[ 1 ], 16 ),
2799
+ parseInt( execResult[ 2 ], 16 ),
2800
+ parseInt( execResult[ 3 ], 16 )
2801
+ ];
2802
+ }
2803
+ }, {
2804
+ // this regex ignores A-F because it's compared against an already lowercased string
2805
+ re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
2806
+ parse: function( execResult ) {
2807
+ return [
2808
+ parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
2809
+ parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
2810
+ parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
2811
+ ];
2812
+ }
2813
+ }, {
2814
+ re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
2815
+ space: "hsla",
2816
+ parse: function( execResult ) {
2817
+ return [
2818
+ execResult[ 1 ],
2819
+ execResult[ 2 ] / 100,
2820
+ execResult[ 3 ] / 100,
2821
+ execResult[ 4 ]
2822
+ ];
2823
+ }
2824
+ }],
2825
+
2826
+ // jQuery.Color( )
2827
+ color = jQuery.Color = function( color, green, blue, alpha ) {
2828
+ return new jQuery.Color.fn.parse( color, green, blue, alpha );
2829
+ },
2830
+ spaces = {
2831
+ rgba: {
2832
+ props: {
2833
+ red: {
2834
+ idx: 0,
2835
+ type: "byte"
2836
+ },
2837
+ green: {
2838
+ idx: 1,
2839
+ type: "byte"
2840
+ },
2841
+ blue: {
2842
+ idx: 2,
2843
+ type: "byte"
2844
+ }
2845
+ }
2846
+ },
2847
+
2848
+ hsla: {
2849
+ props: {
2850
+ hue: {
2851
+ idx: 0,
2852
+ type: "degrees"
2853
+ },
2854
+ saturation: {
2855
+ idx: 1,
2856
+ type: "percent"
2857
+ },
2858
+ lightness: {
2859
+ idx: 2,
2860
+ type: "percent"
2861
+ }
2862
+ }
2863
+ }
2864
+ },
2865
+ propTypes = {
2866
+ "byte": {
2867
+ floor: true,
2868
+ max: 255
2869
+ },
2870
+ "percent": {
2871
+ max: 1
2872
+ },
2873
+ "degrees": {
2874
+ mod: 360,
2875
+ floor: true
2876
+ }
2877
+ },
2878
+ support = color.support = {},
2879
+
2880
+ // element for support tests
2881
+ supportElem = jQuery( "<p>" )[ 0 ],
2882
+
2883
+ // colors = jQuery.Color.names
2884
+ colors,
2885
+
2886
+ // local aliases of functions called often
2887
+ each = jQuery.each;
2888
+
2889
+ // determine rgba support immediately
2890
+ supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
2891
+ support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
2892
+
2893
+ // define cache name and alpha properties
2894
+ // for rgba and hsla spaces
2895
+ each( spaces, function( spaceName, space ) {
2896
+ space.cache = "_" + spaceName;
2897
+ space.props.alpha = {
2898
+ idx: 3,
2899
+ type: "percent",
2900
+ def: 1
2901
+ };
2902
+ });
2903
+
2904
+ function clamp( value, prop, allowEmpty ) {
2905
+ var type = propTypes[ prop.type ] || {};
2906
+
2907
+ if ( value == null ) {
2908
+ return (allowEmpty || !prop.def) ? null : prop.def;
2909
+ }
2910
+
2911
+ // ~~ is an short way of doing floor for positive numbers
2912
+ value = type.floor ? ~~value : parseFloat( value );
2913
+
2914
+ // IE will pass in empty strings as value for alpha,
2915
+ // which will hit this case
2916
+ if ( isNaN( value ) ) {
2917
+ return prop.def;
2918
+ }
2919
+
2920
+ if ( type.mod ) {
2921
+ // we add mod before modding to make sure that negatives values
2922
+ // get converted properly: -10 -> 350
2923
+ return (value + type.mod) % type.mod;
2924
+ }
2925
+
2926
+ // for now all property types without mod have min and max
2927
+ return 0 > value ? 0 : type.max < value ? type.max : value;
2928
+ }
2929
+
2930
+ function stringParse( string ) {
2931
+ var inst = color(),
2932
+ rgba = inst._rgba = [];
2933
+
2934
+ string = string.toLowerCase();
2935
+
2936
+ each( stringParsers, function( i, parser ) {
2937
+ var parsed,
2938
+ match = parser.re.exec( string ),
2939
+ values = match && parser.parse( match ),
2940
+ spaceName = parser.space || "rgba";
2941
+
2942
+ if ( values ) {
2943
+ parsed = inst[ spaceName ]( values );
2944
+
2945
+ // if this was an rgba parse the assignment might happen twice
2946
+ // oh well....
2947
+ inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
2948
+ rgba = inst._rgba = parsed._rgba;
2949
+
2950
+ // exit each( stringParsers ) here because we matched
2951
+ return false;
2952
+ }
2953
+ });
2954
+
2955
+ // Found a stringParser that handled it
2956
+ if ( rgba.length ) {
2957
+
2958
+ // if this came from a parsed string, force "transparent" when alpha is 0
2959
+ // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
2960
+ if ( rgba.join() === "0,0,0,0" ) {
2961
+ jQuery.extend( rgba, colors.transparent );
2962
+ }
2963
+ return inst;
2964
+ }
2965
+
2966
+ // named colors
2967
+ return colors[ string ];
2968
+ }
2969
+
2970
+ color.fn = jQuery.extend( color.prototype, {
2971
+ parse: function( red, green, blue, alpha ) {
2972
+ if ( red === undefined ) {
2973
+ this._rgba = [ null, null, null, null ];
2974
+ return this;
2975
+ }
2976
+ if ( red.jquery || red.nodeType ) {
2977
+ red = jQuery( red ).css( green );
2978
+ green = undefined;
2979
+ }
2980
+
2981
+ var inst = this,
2982
+ type = jQuery.type( red ),
2983
+ rgba = this._rgba = [];
2984
+
2985
+ // more than 1 argument specified - assume ( red, green, blue, alpha )
2986
+ if ( green !== undefined ) {
2987
+ red = [ red, green, blue, alpha ];
2988
+ type = "array";
2989
+ }
2990
+
2991
+ if ( type === "string" ) {
2992
+ return this.parse( stringParse( red ) || colors._default );
2993
+ }
2994
+
2995
+ if ( type === "array" ) {
2996
+ each( spaces.rgba.props, function( key, prop ) {
2997
+ rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
2998
+ });
2999
+ return this;
3000
+ }
3001
+
3002
+ if ( type === "object" ) {
3003
+ if ( red instanceof color ) {
3004
+ each( spaces, function( spaceName, space ) {
3005
+ if ( red[ space.cache ] ) {
3006
+ inst[ space.cache ] = red[ space.cache ].slice();
3007
+ }
3008
+ });
3009
+ } else {
3010
+ each( spaces, function( spaceName, space ) {
3011
+ var cache = space.cache;
3012
+ each( space.props, function( key, prop ) {
3013
+
3014
+ // if the cache doesn't exist, and we know how to convert
3015
+ if ( !inst[ cache ] && space.to ) {
3016
+
3017
+ // if the value was null, we don't need to copy it
3018
+ // if the key was alpha, we don't need to copy it either
3019
+ if ( key === "alpha" || red[ key ] == null ) {
3020
+ return;
3021
+ }
3022
+ inst[ cache ] = space.to( inst._rgba );
3023
+ }
3024
+
3025
+ // this is the only case where we allow nulls for ALL properties.
3026
+ // call clamp with alwaysAllowEmpty
3027
+ inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
3028
+ });
3029
+
3030
+ // everything defined but alpha?
3031
+ if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
3032
+ // use the default of 1
3033
+ inst[ cache ][ 3 ] = 1;
3034
+ if ( space.from ) {
3035
+ inst._rgba = space.from( inst[ cache ] );
3036
+ }
3037
+ }
3038
+ });
3039
+ }
3040
+ return this;
3041
+ }
3042
+ },
3043
+ is: function( compare ) {
3044
+ var is = color( compare ),
3045
+ same = true,
3046
+ inst = this;
3047
+
3048
+ each( spaces, function( _, space ) {
3049
+ var localCache,
3050
+ isCache = is[ space.cache ];
3051
+ if (isCache) {
3052
+ localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
3053
+ each( space.props, function( _, prop ) {
3054
+ if ( isCache[ prop.idx ] != null ) {
3055
+ same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
3056
+ return same;
3057
+ }
3058
+ });
3059
+ }
3060
+ return same;
3061
+ });
3062
+ return same;
3063
+ },
3064
+ _space: function() {
3065
+ var used = [],
3066
+ inst = this;
3067
+ each( spaces, function( spaceName, space ) {
3068
+ if ( inst[ space.cache ] ) {
3069
+ used.push( spaceName );
3070
+ }
3071
+ });
3072
+ return used.pop();
3073
+ },
3074
+ transition: function( other, distance ) {
3075
+ var end = color( other ),
3076
+ spaceName = end._space(),
3077
+ space = spaces[ spaceName ],
3078
+ startColor = this.alpha() === 0 ? color( "transparent" ) : this,
3079
+ start = startColor[ space.cache ] || space.to( startColor._rgba ),
3080
+ result = start.slice();
3081
+
3082
+ end = end[ space.cache ];
3083
+ each( space.props, function( key, prop ) {
3084
+ var index = prop.idx,
3085
+ startValue = start[ index ],
3086
+ endValue = end[ index ],
3087
+ type = propTypes[ prop.type ] || {};
3088
+
3089
+ // if null, don't override start value
3090
+ if ( endValue === null ) {
3091
+ return;
3092
+ }
3093
+ // if null - use end
3094
+ if ( startValue === null ) {
3095
+ result[ index ] = endValue;
3096
+ } else {
3097
+ if ( type.mod ) {
3098
+ if ( endValue - startValue > type.mod / 2 ) {
3099
+ startValue += type.mod;
3100
+ } else if ( startValue - endValue > type.mod / 2 ) {
3101
+ startValue -= type.mod;
3102
+ }
3103
+ }
3104
+ result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
3105
+ }
3106
+ });
3107
+ return this[ spaceName ]( result );
3108
+ },
3109
+ blend: function( opaque ) {
3110
+ // if we are already opaque - return ourself
3111
+ if ( this._rgba[ 3 ] === 1 ) {
3112
+ return this;
3113
+ }
3114
+
3115
+ var rgb = this._rgba.slice(),
3116
+ a = rgb.pop(),
3117
+ blend = color( opaque )._rgba;
3118
+
3119
+ return color( jQuery.map( rgb, function( v, i ) {
3120
+ return ( 1 - a ) * blend[ i ] + a * v;
3121
+ }));
3122
+ },
3123
+ toRgbaString: function() {
3124
+ var prefix = "rgba(",
3125
+ rgba = jQuery.map( this._rgba, function( v, i ) {
3126
+ return v == null ? ( i > 2 ? 1 : 0 ) : v;
3127
+ });
3128
+
3129
+ if ( rgba[ 3 ] === 1 ) {
3130
+ rgba.pop();
3131
+ prefix = "rgb(";
3132
+ }
3133
+
3134
+ return prefix + rgba.join() + ")";
3135
+ },
3136
+ toHslaString: function() {
3137
+ var prefix = "hsla(",
3138
+ hsla = jQuery.map( this.hsla(), function( v, i ) {
3139
+ if ( v == null ) {
3140
+ v = i > 2 ? 1 : 0;
3141
+ }
3142
+
3143
+ // catch 1 and 2
3144
+ if ( i && i < 3 ) {
3145
+ v = Math.round( v * 100 ) + "%";
3146
+ }
3147
+ return v;
3148
+ });
3149
+
3150
+ if ( hsla[ 3 ] === 1 ) {
3151
+ hsla.pop();
3152
+ prefix = "hsl(";
3153
+ }
3154
+ return prefix + hsla.join() + ")";
3155
+ },
3156
+ toHexString: function( includeAlpha ) {
3157
+ var rgba = this._rgba.slice(),
3158
+ alpha = rgba.pop();
3159
+
3160
+ if ( includeAlpha ) {
3161
+ rgba.push( ~~( alpha * 255 ) );
3162
+ }
3163
+
3164
+ return "#" + jQuery.map( rgba, function( v ) {
3165
+
3166
+ // default to 0 when nulls exist
3167
+ v = ( v || 0 ).toString( 16 );
3168
+ return v.length === 1 ? "0" + v : v;
3169
+ }).join("");
3170
+ },
3171
+ toString: function() {
3172
+ return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
3173
+ }
3174
+ });
3175
+ color.fn.parse.prototype = color.fn;
3176
+
3177
+ // hsla conversions adapted from:
3178
+ // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
3179
+
3180
+ function hue2rgb( p, q, h ) {
3181
+ h = ( h + 1 ) % 1;
3182
+ if ( h * 6 < 1 ) {
3183
+ return p + (q - p) * h * 6;
3184
+ }
3185
+ if ( h * 2 < 1) {
3186
+ return q;
3187
+ }
3188
+ if ( h * 3 < 2 ) {
3189
+ return p + (q - p) * ((2/3) - h) * 6;
3190
+ }
3191
+ return p;
3192
+ }
3193
+
3194
+ spaces.hsla.to = function ( rgba ) {
3195
+ if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
3196
+ return [ null, null, null, rgba[ 3 ] ];
3197
+ }
3198
+ var r = rgba[ 0 ] / 255,
3199
+ g = rgba[ 1 ] / 255,
3200
+ b = rgba[ 2 ] / 255,
3201
+ a = rgba[ 3 ],
3202
+ max = Math.max( r, g, b ),
3203
+ min = Math.min( r, g, b ),
3204
+ diff = max - min,
3205
+ add = max + min,
3206
+ l = add * 0.5,
3207
+ h, s;
3208
+
3209
+ if ( min === max ) {
3210
+ h = 0;
3211
+ } else if ( r === max ) {
3212
+ h = ( 60 * ( g - b ) / diff ) + 360;
3213
+ } else if ( g === max ) {
3214
+ h = ( 60 * ( b - r ) / diff ) + 120;
3215
+ } else {
3216
+ h = ( 60 * ( r - g ) / diff ) + 240;
3217
+ }
3218
+
3219
+ // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
3220
+ // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
3221
+ if ( diff === 0 ) {
3222
+ s = 0;
3223
+ } else if ( l <= 0.5 ) {
3224
+ s = diff / add;
3225
+ } else {
3226
+ s = diff / ( 2 - add );
3227
+ }
3228
+ return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
3229
+ };
3230
+
3231
+ spaces.hsla.from = function ( hsla ) {
3232
+ if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
3233
+ return [ null, null, null, hsla[ 3 ] ];
3234
+ }
3235
+ var h = hsla[ 0 ] / 360,
3236
+ s = hsla[ 1 ],
3237
+ l = hsla[ 2 ],
3238
+ a = hsla[ 3 ],
3239
+ q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
3240
+ p = 2 * l - q;
3241
+
3242
+ return [
3243
+ Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
3244
+ Math.round( hue2rgb( p, q, h ) * 255 ),
3245
+ Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
3246
+ a
3247
+ ];
3248
+ };
3249
+
3250
+
3251
+ each( spaces, function( spaceName, space ) {
3252
+ var props = space.props,
3253
+ cache = space.cache,
3254
+ to = space.to,
3255
+ from = space.from;
3256
+
3257
+ // makes rgba() and hsla()
3258
+ color.fn[ spaceName ] = function( value ) {
3259
+
3260
+ // generate a cache for this space if it doesn't exist
3261
+ if ( to && !this[ cache ] ) {
3262
+ this[ cache ] = to( this._rgba );
3263
+ }
3264
+ if ( value === undefined ) {
3265
+ return this[ cache ].slice();
3266
+ }
3267
+
3268
+ var ret,
3269
+ type = jQuery.type( value ),
3270
+ arr = ( type === "array" || type === "object" ) ? value : arguments,
3271
+ local = this[ cache ].slice();
3272
+
3273
+ each( props, function( key, prop ) {
3274
+ var val = arr[ type === "object" ? key : prop.idx ];
3275
+ if ( val == null ) {
3276
+ val = local[ prop.idx ];
3277
+ }
3278
+ local[ prop.idx ] = clamp( val, prop );
3279
+ });
3280
+
3281
+ if ( from ) {
3282
+ ret = color( from( local ) );
3283
+ ret[ cache ] = local;
3284
+ return ret;
3285
+ } else {
3286
+ return color( local );
3287
+ }
3288
+ };
3289
+
3290
+ // makes red() green() blue() alpha() hue() saturation() lightness()
3291
+ each( props, function( key, prop ) {
3292
+ // alpha is included in more than one space
3293
+ if ( color.fn[ key ] ) {
3294
+ return;
3295
+ }
3296
+ color.fn[ key ] = function( value ) {
3297
+ var vtype = jQuery.type( value ),
3298
+ fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
3299
+ local = this[ fn ](),
3300
+ cur = local[ prop.idx ],
3301
+ match;
3302
+
3303
+ if ( vtype === "undefined" ) {
3304
+ return cur;
3305
+ }
3306
+
3307
+ if ( vtype === "function" ) {
3308
+ value = value.call( this, cur );
3309
+ vtype = jQuery.type( value );
3310
+ }
3311
+ if ( value == null && prop.empty ) {
3312
+ return this;
3313
+ }
3314
+ if ( vtype === "string" ) {
3315
+ match = rplusequals.exec( value );
3316
+ if ( match ) {
3317
+ value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
3318
+ }
3319
+ }
3320
+ local[ prop.idx ] = value;
3321
+ return this[ fn ]( local );
3322
+ };
3323
+ });
3324
+ });
3325
+
3326
+ // add cssHook and .fx.step function for each named hook.
3327
+ // accept a space separated string of properties
3328
+ color.hook = function( hook ) {
3329
+ var hooks = hook.split( " " );
3330
+ each( hooks, function( i, hook ) {
3331
+ jQuery.cssHooks[ hook ] = {
3332
+ set: function( elem, value ) {
3333
+ var parsed, curElem,
3334
+ backgroundColor = "";
3335
+
3336
+ if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
3337
+ value = color( parsed || value );
3338
+ if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
3339
+ curElem = hook === "backgroundColor" ? elem.parentNode : elem;
3340
+ while (
3341
+ (backgroundColor === "" || backgroundColor === "transparent") &&
3342
+ curElem && curElem.style
3343
+ ) {
3344
+ try {
3345
+ backgroundColor = jQuery.css( curElem, "backgroundColor" );
3346
+ curElem = curElem.parentNode;
3347
+ } catch ( e ) {
3348
+ }
3349
+ }
3350
+
3351
+ value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
3352
+ backgroundColor :
3353
+ "_default" );
3354
+ }
3355
+
3356
+ value = value.toRgbaString();
3357
+ }
3358
+ try {
3359
+ elem.style[ hook ] = value;
3360
+ } catch( e ) {
3361
+ // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
3362
+ }
3363
+ }
3364
+ };
3365
+ jQuery.fx.step[ hook ] = function( fx ) {
3366
+ if ( !fx.colorInit ) {
3367
+ fx.start = color( fx.elem, hook );
3368
+ fx.end = color( fx.end );
3369
+ fx.colorInit = true;
3370
+ }
3371
+ jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
3372
+ };
3373
+ });
3374
+
3375
+ };
3376
+
3377
+ color.hook( stepHooks );
3378
+
3379
+ jQuery.cssHooks.borderColor = {
3380
+ expand: function( value ) {
3381
+ var expanded = {};
3382
+
3383
+ each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
3384
+ expanded[ "border" + part + "Color" ] = value;
3385
+ });
3386
+ return expanded;
3387
+ }
3388
+ };
3389
+
3390
+ // Basic color names only.
3391
+ // Usage of any of the other color names requires adding yourself or including
3392
+ // jquery.color.svg-names.js.
3393
+ colors = jQuery.Color.names = {
3394
+ // 4.1. Basic color keywords
3395
+ aqua: "#00ffff",
3396
+ black: "#000000",
3397
+ blue: "#0000ff",
3398
+ fuchsia: "#ff00ff",
3399
+ gray: "#808080",
3400
+ green: "#008000",
3401
+ lime: "#00ff00",
3402
+ maroon: "#800000",
3403
+ navy: "#000080",
3404
+ olive: "#808000",
3405
+ purple: "#800080",
3406
+ red: "#ff0000",
3407
+ silver: "#c0c0c0",
3408
+ teal: "#008080",
3409
+ white: "#ffffff",
3410
+ yellow: "#ffff00",
3411
+
3412
+ // 4.2.3. "transparent" color keyword
3413
+ transparent: [ null, null, null, 0 ],
3414
+
3415
+ _default: "#ffffff"
3416
+ };
3417
+
3418
+ })( jQuery );
3419
+
3420
+
3421
+ /******************************************************************************/
3422
+ /****************************** CLASS ANIMATIONS ******************************/
3423
+ /******************************************************************************/
3424
+ (function() {
3425
+
3426
+ var classAnimationActions = [ "add", "remove", "toggle" ],
3427
+ shorthandStyles = {
3428
+ border: 1,
3429
+ borderBottom: 1,
3430
+ borderColor: 1,
3431
+ borderLeft: 1,
3432
+ borderRight: 1,
3433
+ borderTop: 1,
3434
+ borderWidth: 1,
3435
+ margin: 1,
3436
+ padding: 1
3437
+ };
3438
+
3439
+ $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
3440
+ $.fx.step[ prop ] = function( fx ) {
3441
+ if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
3442
+ jQuery.style( fx.elem, prop, fx.end );
3443
+ fx.setAttr = true;
3444
+ }
3445
+ };
3446
+ });
3447
+
3448
+ function getElementStyles( elem ) {
3449
+ var key, len,
3450
+ style = elem.ownerDocument.defaultView ?
3451
+ elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
3452
+ elem.currentStyle,
3453
+ styles = {};
3454
+
3455
+ if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
3456
+ len = style.length;
3457
+ while ( len-- ) {
3458
+ key = style[ len ];
3459
+ if ( typeof style[ key ] === "string" ) {
3460
+ styles[ $.camelCase( key ) ] = style[ key ];
3461
+ }
3462
+ }
3463
+ // support: Opera, IE <9
3464
+ } else {
3465
+ for ( key in style ) {
3466
+ if ( typeof style[ key ] === "string" ) {
3467
+ styles[ key ] = style[ key ];
3468
+ }
3469
+ }
3470
+ }
3471
+
3472
+ return styles;
3473
+ }
3474
+
3475
+
3476
+ function styleDifference( oldStyle, newStyle ) {
3477
+ var diff = {},
3478
+ name, value;
3479
+
3480
+ for ( name in newStyle ) {
3481
+ value = newStyle[ name ];
3482
+ if ( oldStyle[ name ] !== value ) {
3483
+ if ( !shorthandStyles[ name ] ) {
3484
+ if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
3485
+ diff[ name ] = value;
3486
+ }
3487
+ }
3488
+ }
3489
+ }
3490
+
3491
+ return diff;
3492
+ }
3493
+
3494
+ // support: jQuery <1.8
3495
+ if ( !$.fn.addBack ) {
3496
+ $.fn.addBack = function( selector ) {
3497
+ return this.add( selector == null ?
3498
+ this.prevObject : this.prevObject.filter( selector )
3499
+ );
3500
+ };
3501
+ }
3502
+
3503
+ $.effects.animateClass = function( value, duration, easing, callback ) {
3504
+ var o = $.speed( duration, easing, callback );
3505
+
3506
+ return this.queue( function() {
3507
+ var animated = $( this ),
3508
+ baseClass = animated.attr( "class" ) || "",
3509
+ applyClassChange,
3510
+ allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
3511
+
3512
+ // map the animated objects to store the original styles.
3513
+ allAnimations = allAnimations.map(function() {
3514
+ var el = $( this );
3515
+ return {
3516
+ el: el,
3517
+ start: getElementStyles( this )
3518
+ };
3519
+ });
3520
+
3521
+ // apply class change
3522
+ applyClassChange = function() {
3523
+ $.each( classAnimationActions, function(i, action) {
3524
+ if ( value[ action ] ) {
3525
+ animated[ action + "Class" ]( value[ action ] );
3526
+ }
3527
+ });
3528
+ };
3529
+ applyClassChange();
3530
+
3531
+ // map all animated objects again - calculate new styles and diff
3532
+ allAnimations = allAnimations.map(function() {
3533
+ this.end = getElementStyles( this.el[ 0 ] );
3534
+ this.diff = styleDifference( this.start, this.end );
3535
+ return this;
3536
+ });
3537
+
3538
+ // apply original class
3539
+ animated.attr( "class", baseClass );
3540
+
3541
+ // map all animated objects again - this time collecting a promise
3542
+ allAnimations = allAnimations.map(function() {
3543
+ var styleInfo = this,
3544
+ dfd = $.Deferred(),
3545
+ opts = $.extend({}, o, {
3546
+ queue: false,
3547
+ complete: function() {
3548
+ dfd.resolve( styleInfo );
3549
+ }
3550
+ });
3551
+
3552
+ this.el.animate( this.diff, opts );
3553
+ return dfd.promise();
3554
+ });
3555
+
3556
+ // once all animations have completed:
3557
+ $.when.apply( $, allAnimations.get() ).done(function() {
3558
+
3559
+ // set the final class
3560
+ applyClassChange();
3561
+
3562
+ // for each animated element,
3563
+ // clear all css properties that were animated
3564
+ $.each( arguments, function() {
3565
+ var el = this.el;
3566
+ $.each( this.diff, function(key) {
3567
+ el.css( key, "" );
3568
+ });
3569
+ });
3570
+
3571
+ // this is guarnteed to be there if you use jQuery.speed()
3572
+ // it also handles dequeuing the next anim...
3573
+ o.complete.call( animated[ 0 ] );
3574
+ });
3575
+ });
3576
+ };
3577
+
3578
+ $.fn.extend({
3579
+ addClass: (function( orig ) {
3580
+ return function( classNames, speed, easing, callback ) {
3581
+ return speed ?
3582
+ $.effects.animateClass.call( this,
3583
+ { add: classNames }, speed, easing, callback ) :
3584
+ orig.apply( this, arguments );
3585
+ };
3586
+ })( $.fn.addClass ),
3587
+
3588
+ removeClass: (function( orig ) {
3589
+ return function( classNames, speed, easing, callback ) {
3590
+ return arguments.length > 1 ?
3591
+ $.effects.animateClass.call( this,
3592
+ { remove: classNames }, speed, easing, callback ) :
3593
+ orig.apply( this, arguments );
3594
+ };
3595
+ })( $.fn.removeClass ),
3596
+
3597
+ toggleClass: (function( orig ) {
3598
+ return function( classNames, force, speed, easing, callback ) {
3599
+ if ( typeof force === "boolean" || force === undefined ) {
3600
+ if ( !speed ) {
3601
+ // without speed parameter
3602
+ return orig.apply( this, arguments );
3603
+ } else {
3604
+ return $.effects.animateClass.call( this,
3605
+ (force ? { add: classNames } : { remove: classNames }),
3606
+ speed, easing, callback );
3607
+ }
3608
+ } else {
3609
+ // without force parameter
3610
+ return $.effects.animateClass.call( this,
3611
+ { toggle: classNames }, force, speed, easing );
3612
+ }
3613
+ };
3614
+ })( $.fn.toggleClass ),
3615
+
3616
+ switchClass: function( remove, add, speed, easing, callback) {
3617
+ return $.effects.animateClass.call( this, {
3618
+ add: add,
3619
+ remove: remove
3620
+ }, speed, easing, callback );
3621
+ }
3622
+ });
3623
+
3624
+ })();
3625
+
3626
+ /******************************************************************************/
3627
+ /*********************************** EFFECTS **********************************/
3628
+ /******************************************************************************/
3629
+
3630
+ (function() {
3631
+
3632
+ $.extend( $.effects, {
3633
+ version: "1.10.4",
3634
+
3635
+ // Saves a set of properties in a data storage
3636
+ save: function( element, set ) {
3637
+ for( var i=0; i < set.length; i++ ) {
3638
+ if ( set[ i ] !== null ) {
3639
+ element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
3640
+ }
3641
+ }
3642
+ },
3643
+
3644
+ // Restores a set of previously saved properties from a data storage
3645
+ restore: function( element, set ) {
3646
+ var val, i;
3647
+ for( i=0; i < set.length; i++ ) {
3648
+ if ( set[ i ] !== null ) {
3649
+ val = element.data( dataSpace + set[ i ] );
3650
+ // support: jQuery 1.6.2
3651
+ // http://bugs.jquery.com/ticket/9917
3652
+ // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
3653
+ // We can't differentiate between "" and 0 here, so we just assume
3654
+ // empty string since it's likely to be a more common value...
3655
+ if ( val === undefined ) {
3656
+ val = "";
3657
+ }
3658
+ element.css( set[ i ], val );
3659
+ }
3660
+ }
3661
+ },
3662
+
3663
+ setMode: function( el, mode ) {
3664
+ if (mode === "toggle") {
3665
+ mode = el.is( ":hidden" ) ? "show" : "hide";
3666
+ }
3667
+ return mode;
3668
+ },
3669
+
3670
+ // Translates a [top,left] array into a baseline value
3671
+ // this should be a little more flexible in the future to handle a string & hash
3672
+ getBaseline: function( origin, original ) {
3673
+ var y, x;
3674
+ switch ( origin[ 0 ] ) {
3675
+ case "top": y = 0; break;
3676
+ case "middle": y = 0.5; break;
3677
+ case "bottom": y = 1; break;
3678
+ default: y = origin[ 0 ] / original.height;
3679
+ }
3680
+ switch ( origin[ 1 ] ) {
3681
+ case "left": x = 0; break;
3682
+ case "center": x = 0.5; break;
3683
+ case "right": x = 1; break;
3684
+ default: x = origin[ 1 ] / original.width;
3685
+ }
3686
+ return {
3687
+ x: x,
3688
+ y: y
3689
+ };
3690
+ },
3691
+
3692
+ // Wraps the element around a wrapper that copies position properties
3693
+ createWrapper: function( element ) {
3694
+
3695
+ // if the element is already wrapped, return it
3696
+ if ( element.parent().is( ".ui-effects-wrapper" )) {
3697
+ return element.parent();
3698
+ }
3699
+
3700
+ // wrap the element
3701
+ var props = {
3702
+ width: element.outerWidth(true),
3703
+ height: element.outerHeight(true),
3704
+ "float": element.css( "float" )
3705
+ },
3706
+ wrapper = $( "<div></div>" )
3707
+ .addClass( "ui-effects-wrapper" )
3708
+ .css({
3709
+ fontSize: "100%",
3710
+ background: "transparent",
3711
+ border: "none",
3712
+ margin: 0,
3713
+ padding: 0
3714
+ }),
3715
+ // Store the size in case width/height are defined in % - Fixes #5245
3716
+ size = {
3717
+ width: element.width(),
3718
+ height: element.height()
3719
+ },
3720
+ active = document.activeElement;
3721
+
3722
+ // support: Firefox
3723
+ // Firefox incorrectly exposes anonymous content
3724
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
3725
+ try {
3726
+ active.id;
3727
+ } catch( e ) {
3728
+ active = document.body;
3729
+ }
3730
+
3731
+ element.wrap( wrapper );
3732
+
3733
+ // Fixes #7595 - Elements lose focus when wrapped.
3734
+ if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
3735
+ $( active ).focus();
3736
+ }
3737
+
3738
+ wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
3739
+
3740
+ // transfer positioning properties to the wrapper
3741
+ if ( element.css( "position" ) === "static" ) {
3742
+ wrapper.css({ position: "relative" });
3743
+ element.css({ position: "relative" });
3744
+ } else {
3745
+ $.extend( props, {
3746
+ position: element.css( "position" ),
3747
+ zIndex: element.css( "z-index" )
3748
+ });
3749
+ $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
3750
+ props[ pos ] = element.css( pos );
3751
+ if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
3752
+ props[ pos ] = "auto";
3753
+ }
3754
+ });
3755
+ element.css({
3756
+ position: "relative",
3757
+ top: 0,
3758
+ left: 0,
3759
+ right: "auto",
3760
+ bottom: "auto"
3761
+ });
3762
+ }
3763
+ element.css(size);
3764
+
3765
+ return wrapper.css( props ).show();
3766
+ },
3767
+
3768
+ removeWrapper: function( element ) {
3769
+ var active = document.activeElement;
3770
+
3771
+ if ( element.parent().is( ".ui-effects-wrapper" ) ) {
3772
+ element.parent().replaceWith( element );
3773
+
3774
+ // Fixes #7595 - Elements lose focus when wrapped.
3775
+ if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
3776
+ $( active ).focus();
3777
+ }
3778
+ }
3779
+
3780
+
3781
+ return element;
3782
+ },
3783
+
3784
+ setTransition: function( element, list, factor, value ) {
3785
+ value = value || {};
3786
+ $.each( list, function( i, x ) {
3787
+ var unit = element.cssUnit( x );
3788
+ if ( unit[ 0 ] > 0 ) {
3789
+ value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
3790
+ }
3791
+ });
3792
+ return value;
3793
+ }
3794
+ });
3795
+
3796
+ // return an effect options object for the given parameters:
3797
+ function _normalizeArguments( effect, options, speed, callback ) {
3798
+
3799
+ // allow passing all options as the first parameter
3800
+ if ( $.isPlainObject( effect ) ) {
3801
+ options = effect;
3802
+ effect = effect.effect;
3803
+ }
3804
+
3805
+ // convert to an object
3806
+ effect = { effect: effect };
3807
+
3808
+ // catch (effect, null, ...)
3809
+ if ( options == null ) {
3810
+ options = {};
3811
+ }
3812
+
3813
+ // catch (effect, callback)
3814
+ if ( $.isFunction( options ) ) {
3815
+ callback = options;
3816
+ speed = null;
3817
+ options = {};
3818
+ }
3819
+
3820
+ // catch (effect, speed, ?)
3821
+ if ( typeof options === "number" || $.fx.speeds[ options ] ) {
3822
+ callback = speed;
3823
+ speed = options;
3824
+ options = {};
3825
+ }
3826
+
3827
+ // catch (effect, options, callback)
3828
+ if ( $.isFunction( speed ) ) {
3829
+ callback = speed;
3830
+ speed = null;
3831
+ }
3832
+
3833
+ // add options to effect
3834
+ if ( options ) {
3835
+ $.extend( effect, options );
3836
+ }
3837
+
3838
+ speed = speed || options.duration;
3839
+ effect.duration = $.fx.off ? 0 :
3840
+ typeof speed === "number" ? speed :
3841
+ speed in $.fx.speeds ? $.fx.speeds[ speed ] :
3842
+ $.fx.speeds._default;
3843
+
3844
+ effect.complete = callback || options.complete;
3845
+
3846
+ return effect;
3847
+ }
3848
+
3849
+ function standardAnimationOption( option ) {
3850
+ // Valid standard speeds (nothing, number, named speed)
3851
+ if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
3852
+ return true;
3853
+ }
3854
+
3855
+ // Invalid strings - treat as "normal" speed
3856
+ if ( typeof option === "string" && !$.effects.effect[ option ] ) {
3857
+ return true;
3858
+ }
3859
+
3860
+ // Complete callback
3861
+ if ( $.isFunction( option ) ) {
3862
+ return true;
3863
+ }
3864
+
3865
+ // Options hash (but not naming an effect)
3866
+ if ( typeof option === "object" && !option.effect ) {
3867
+ return true;
3868
+ }
3869
+
3870
+ // Didn't match any standard API
3871
+ return false;
3872
+ }
3873
+
3874
+ $.fn.extend({
3875
+ effect: function( /* effect, options, speed, callback */ ) {
3876
+ var args = _normalizeArguments.apply( this, arguments ),
3877
+ mode = args.mode,
3878
+ queue = args.queue,
3879
+ effectMethod = $.effects.effect[ args.effect ];
3880
+
3881
+ if ( $.fx.off || !effectMethod ) {
3882
+ // delegate to the original method (e.g., .show()) if possible
3883
+ if ( mode ) {
3884
+ return this[ mode ]( args.duration, args.complete );
3885
+ } else {
3886
+ return this.each( function() {
3887
+ if ( args.complete ) {
3888
+ args.complete.call( this );
3889
+ }
3890
+ });
3891
+ }
3892
+ }
3893
+
3894
+ function run( next ) {
3895
+ var elem = $( this ),
3896
+ complete = args.complete,
3897
+ mode = args.mode;
3898
+
3899
+ function done() {
3900
+ if ( $.isFunction( complete ) ) {
3901
+ complete.call( elem[0] );
3902
+ }
3903
+ if ( $.isFunction( next ) ) {
3904
+ next();
3905
+ }
3906
+ }
3907
+
3908
+ // If the element already has the correct final state, delegate to
3909
+ // the core methods so the internal tracking of "olddisplay" works.
3910
+ if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
3911
+ elem[ mode ]();
3912
+ done();
3913
+ } else {
3914
+ effectMethod.call( elem[0], args, done );
3915
+ }
3916
+ }
3917
+
3918
+ return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
3919
+ },
3920
+
3921
+ show: (function( orig ) {
3922
+ return function( option ) {
3923
+ if ( standardAnimationOption( option ) ) {
3924
+ return orig.apply( this, arguments );
3925
+ } else {
3926
+ var args = _normalizeArguments.apply( this, arguments );
3927
+ args.mode = "show";
3928
+ return this.effect.call( this, args );
3929
+ }
3930
+ };
3931
+ })( $.fn.show ),
3932
+
3933
+ hide: (function( orig ) {
3934
+ return function( option ) {
3935
+ if ( standardAnimationOption( option ) ) {
3936
+ return orig.apply( this, arguments );
3937
+ } else {
3938
+ var args = _normalizeArguments.apply( this, arguments );
3939
+ args.mode = "hide";
3940
+ return this.effect.call( this, args );
3941
+ }
3942
+ };
3943
+ })( $.fn.hide ),
3944
+
3945
+ toggle: (function( orig ) {
3946
+ return function( option ) {
3947
+ if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
3948
+ return orig.apply( this, arguments );
3949
+ } else {
3950
+ var args = _normalizeArguments.apply( this, arguments );
3951
+ args.mode = "toggle";
3952
+ return this.effect.call( this, args );
3953
+ }
3954
+ };
3955
+ })( $.fn.toggle ),
3956
+
3957
+ // helper functions
3958
+ cssUnit: function(key) {
3959
+ var style = this.css( key ),
3960
+ val = [];
3961
+
3962
+ $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
3963
+ if ( style.indexOf( unit ) > 0 ) {
3964
+ val = [ parseFloat( style ), unit ];
3965
+ }
3966
+ });
3967
+ return val;
3968
+ }
3969
+ });
3970
+
3971
+ })();
3972
+
3973
+ /******************************************************************************/
3974
+ /*********************************** EASING ***********************************/
3975
+ /******************************************************************************/
3976
+
3977
+ (function() {
3978
+
3979
+ // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
3980
+
3981
+ var baseEasings = {};
3982
+
3983
+ $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
3984
+ baseEasings[ name ] = function( p ) {
3985
+ return Math.pow( p, i + 2 );
3986
+ };
3987
+ });
3988
+
3989
+ $.extend( baseEasings, {
3990
+ Sine: function ( p ) {
3991
+ return 1 - Math.cos( p * Math.PI / 2 );
3992
+ },
3993
+ Circ: function ( p ) {
3994
+ return 1 - Math.sqrt( 1 - p * p );
3995
+ },
3996
+ Elastic: function( p ) {
3997
+ return p === 0 || p === 1 ? p :
3998
+ -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
3999
+ },
4000
+ Back: function( p ) {
4001
+ return p * p * ( 3 * p - 2 );
4002
+ },
4003
+ Bounce: function ( p ) {
4004
+ var pow2,
4005
+ bounce = 4;
4006
+
4007
+ while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
4008
+ return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
4009
+ }
4010
+ });
4011
+
4012
+ $.each( baseEasings, function( name, easeIn ) {
4013
+ $.easing[ "easeIn" + name ] = easeIn;
4014
+ $.easing[ "easeOut" + name ] = function( p ) {
4015
+ return 1 - easeIn( 1 - p );
4016
+ };
4017
+ $.easing[ "easeInOut" + name ] = function( p ) {
4018
+ return p < 0.5 ?
4019
+ easeIn( p * 2 ) / 2 :
4020
+ 1 - easeIn( p * -2 + 2 ) / 2;
4021
+ };
4022
+ });
4023
+
4024
+ })();
4025
+
4026
+ })(jQuery);
4027
+ (function( $, undefined ) {
4028
+
4029
+ $.effects.effect.drop = function( o, done ) {
4030
+
4031
+ var el = $( this ),
4032
+ props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
4033
+ mode = $.effects.setMode( el, o.mode || "hide" ),
4034
+ show = mode === "show",
4035
+ direction = o.direction || "left",
4036
+ ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
4037
+ motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
4038
+ animation = {
4039
+ opacity: show ? 1 : 0
4040
+ },
4041
+ distance;
4042
+
4043
+ // Adjust
4044
+ $.effects.save( el, props );
4045
+ el.show();
4046
+ $.effects.createWrapper( el );
4047
+
4048
+ distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
4049
+
4050
+ if ( show ) {
4051
+ el
4052
+ .css( "opacity", 0 )
4053
+ .css( ref, motion === "pos" ? -distance : distance );
4054
+ }
4055
+
4056
+ // Animation
4057
+ animation[ ref ] = ( show ?
4058
+ ( motion === "pos" ? "+=" : "-=" ) :
4059
+ ( motion === "pos" ? "-=" : "+=" ) ) +
4060
+ distance;
4061
+
4062
+ // Animate
4063
+ el.animate( animation, {
4064
+ queue: false,
4065
+ duration: o.duration,
4066
+ easing: o.easing,
4067
+ complete: function() {
4068
+ if ( mode === "hide" ) {
4069
+ el.hide();
4070
+ }
4071
+ $.effects.restore( el, props );
4072
+ $.effects.removeWrapper( el );
4073
+ done();
4074
+ }
4075
+ });
4076
+ };
4077
+
4078
+ })(jQuery);
4079
+ (function( $, undefined ) {
4080
+
4081
+ $.effects.effect.fade = function( o, done ) {
4082
+ var el = $( this ),
4083
+ mode = $.effects.setMode( el, o.mode || "toggle" );
4084
+
4085
+ el.animate({
4086
+ opacity: mode
4087
+ }, {
4088
+ queue: false,
4089
+ duration: o.duration,
4090
+ easing: o.easing,
4091
+ complete: done
4092
+ });
4093
+ };
4094
+
4095
+ })( jQuery );
4096
+ (function( $, undefined ) {
4097
+
4098
+ $.effects.effect.slide = function( o, done ) {
4099
+
4100
+ // Create element
4101
+ var el = $( this ),
4102
+ props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
4103
+ mode = $.effects.setMode( el, o.mode || "show" ),
4104
+ show = mode === "show",
4105
+ direction = o.direction || "left",
4106
+ ref = (direction === "up" || direction === "down") ? "top" : "left",
4107
+ positiveMotion = (direction === "up" || direction === "left"),
4108
+ distance,
4109
+ animation = {};
4110
+
4111
+ // Adjust
4112
+ $.effects.save( el, props );
4113
+ el.show();
4114
+ distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
4115
+
4116
+ $.effects.createWrapper( el ).css({
4117
+ overflow: "hidden"
4118
+ });
4119
+
4120
+ if ( show ) {
4121
+ el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
4122
+ }
4123
+
4124
+ // Animation
4125
+ animation[ ref ] = ( show ?
4126
+ ( positiveMotion ? "+=" : "-=") :
4127
+ ( positiveMotion ? "-=" : "+=")) +
4128
+ distance;
4129
+
4130
+ // Animate
4131
+ el.animate( animation, {
4132
+ queue: false,
4133
+ duration: o.duration,
4134
+ easing: o.easing,
4135
+ complete: function() {
4136
+ if ( mode === "hide" ) {
4137
+ el.hide();
4138
+ }
4139
+ $.effects.restore( el, props );
4140
+ $.effects.removeWrapper( el );
4141
+ done();
4142
+ }
4143
+ });
4144
+ };
4145
+
4146
+ })(jQuery);