local_documentation 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);