Email Subscribers & Newsletters - Version 4.0

Version Description

(01.03.2019) = * New: Revamped the plugin - Changes in UI and terminology * New: Added domain blocking to prevent spam attacks * Update: POT file

Download this release

Release Info

Developer Icegram
Plugin Icon 128x128 Email Subscribers & Newsletters
Version 4.0
Comparing to
See all releases

Code changes from version 3.5.18 to 4.0

license.txt → LICENSE.txt RENAMED
@@ -1,280 +1,339 @@
1
- GNU GENERAL PUBLIC LICENSE
2
- Version 2, June 1991
3
-
4
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5
- 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
6
-
7
- Everyone is permitted to copy and distribute verbatim copies
8
- of this license document, but changing it is not allowed.
9
-
10
- Preamble
11
-
12
- The licenses for most software are designed to take away your
13
- freedom to share and change it. By contrast, the GNU General Public
14
- License is intended to guarantee your freedom to share and change free
15
- software--to make sure the software is free for all its users. This
16
- General Public License applies to most of the Free Software
17
- Foundation's software and to any other program whose authors commit to
18
- using it. (Some other Free Software Foundation software is covered by
19
- the GNU Library General Public License instead.) You can apply it to
20
- your programs, too.
21
-
22
- When we speak of free software, we are referring to freedom, not
23
- price. Our General Public Licenses are designed to make sure that you
24
- have the freedom to distribute copies of free software (and charge for
25
- this service if you wish), that you receive source code or can get it
26
- if you want it, that you can change the software or use pieces of it
27
- in new free programs; and that you know you can do these things.
28
-
29
- To protect your rights, we need to make restrictions that forbid
30
- anyone to deny you these rights or to ask you to surrender the rights.
31
- These restrictions translate to certain responsibilities for you if you
32
- distribute copies of the software, or if you modify it.
33
-
34
- For example, if you distribute copies of such a program, whether
35
- gratis or for a fee, you must give the recipients all the rights that
36
- you have. You must make sure that they, too, receive or can get the
37
- source code. And you must show them these terms so they know their
38
- rights.
39
-
40
- We protect your rights with two steps: (1) copyright the software, and
41
- (2) offer you this license which gives you legal permission to copy,
42
- distribute and/or modify the software.
43
-
44
- Also, for each author's protection and ours, we want to make certain
45
- that everyone understands that there is no warranty for this free
46
- software. If the software is modified by someone else and passed on, we
47
- want its recipients to know that what they have is not the original, so
48
- that any problems introduced by others will not reflect on the original
49
- authors' reputations.
50
-
51
- Finally, any free program is threatened constantly by software
52
- patents. We wish to avoid the danger that redistributors of a free
53
- program will individually obtain patent licenses, in effect making the
54
- program proprietary. To prevent this, we have made it clear that any
55
- patent must be licensed for everyone's free use or not licensed at all.
56
-
57
- The precise terms and conditions for copying, distribution and
58
- modification follow.
59
-
60
- GNU GENERAL PUBLIC LICENSE
61
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
62
-
63
- 0. This License applies to any program or other work which contains
64
- a notice placed by the copyright holder saying it may be distributed
65
- under the terms of this General Public License. The "Program", below,
66
- refers to any such program or work, and a "work based on the Program"
67
- means either the Program or any derivative work under copyright law:
68
- that is to say, a work containing the Program or a portion of it,
69
- either verbatim or with modifications and/or translated into another
70
- language. (Hereinafter, translation is included without limitation in
71
- the term "modification".) Each licensee is addressed as "you".
72
-
73
- Activities other than copying, distribution and modification are not
74
- covered by this License; they are outside its scope. The act of
75
- running the Program is not restricted, and the output from the Program
76
- is covered only if its contents constitute a work based on the
77
- Program (independent of having been made by running the Program).
78
- Whether that is true depends on what the Program does.
79
-
80
- 1. You may copy and distribute verbatim copies of the Program's
81
- source code as you receive it, in any medium, provided that you
82
- conspicuously and appropriately publish on each copy an appropriate
83
- copyright notice and disclaimer of warranty; keep intact all the
84
- notices that refer to this License and to the absence of any warranty;
85
- and give any other recipients of the Program a copy of this License
86
- along with the Program.
87
-
88
- You may charge a fee for the physical act of transferring a copy, and
89
- you may at your option offer warranty protection in exchange for a fee.
90
-
91
- 2. You may modify your copy or copies of the Program or any portion
92
- of it, thus forming a work based on the Program, and copy and
93
- distribute such modifications or work under the terms of Section 1
94
- above, provided that you also meet all of these conditions:
95
-
96
- a) You must cause the modified files to carry prominent notices
97
- stating that you changed the files and the date of any change.
98
-
99
- b) You must cause any work that you distribute or publish, that in
100
- whole or in part contains or is derived from the Program or any
101
- part thereof, to be licensed as a whole at no charge to all third
102
- parties under the terms of this License.
103
-
104
- c) If the modified program normally reads commands interactively
105
- when run, you must cause it, when started running for such
106
- interactive use in the most ordinary way, to print or display an
107
- announcement including an appropriate copyright notice and a
108
- notice that there is no warranty (or else, saying that you provide
109
- a warranty) and that users may redistribute the program under
110
- these conditions, and telling the user how to view a copy of this
111
- License. (Exception: if the Program itself is interactive but
112
- does not normally print such an announcement, your work based on
113
- the Program is not required to print an announcement.)
114
-
115
- These requirements apply to the modified work as a whole. If
116
- identifiable sections of that work are not derived from the Program,
117
- and can be reasonably considered independent and separate works in
118
- themselves, then this License, and its terms, do not apply to those
119
- sections when you distribute them as separate works. But when you
120
- distribute the same sections as part of a whole which is a work based
121
- on the Program, the distribution of the whole must be on the terms of
122
- this License, whose permissions for other licensees extend to the
123
- entire whole, and thus to each and every part regardless of who wrote it.
124
- Thus, it is not the intent of this section to claim rights or contest
125
- your rights to work written entirely by you; rather, the intent is to
126
- exercise the right to control the distribution of derivative or
127
- collective works based on the Program.
128
-
129
- In addition, mere aggregation of another work not based on the Program
130
- with the Program (or with a work based on the Program) on a volume of
131
- a storage or distribution medium does not bring the other work under
132
- the scope of this License.
133
-
134
- 3. You may copy and distribute the Program (or a work based on it,
135
- under Section 2) in object code or executable form under the terms of
136
- Sections 1 and 2 above provided that you also do one of the following:
137
-
138
- a) Accompany it with the complete corresponding machine-readable
139
- source code, which must be distributed under the terms of Sections
140
- 1 and 2 above on a medium customarily used for software interchange; or,
141
-
142
- b) Accompany it with a written offer, valid for at least three
143
- years, to give any third party, for a charge no more than your
144
- cost of physically performing source distribution, a complete
145
- machine-readable copy of the corresponding source code, to be
146
- distributed under the terms of Sections 1 and 2 above on a medium
147
- customarily used for software interchange; or,
148
-
149
- c) Accompany it with the information you received as to the offer
150
- to distribute corresponding source code. (This alternative is
151
- allowed only for noncommercial distribution and only if you
152
- received the program in object code or executable form with such
153
- an offer, in accord with Subsection b above.)
154
-
155
- The source code for a work means the preferred form of the work for
156
- making modifications to it. For an executable work, complete source
157
- code means all the source code for all modules it contains, plus any
158
- associated interface definition files, plus the scripts used to
159
- control compilation and installation of the executable. However, as a
160
- special exception, the source code distributed need not include
161
- anything that is normally distributed (in either source or binary
162
- form) with the major components (compiler, kernel, and so on) of the
163
- operating system on which the executable runs, unless that component
164
- itself accompanies the executable.
165
-
166
- If distribution of executable or object code is made by offering
167
- access to copy from a designated place, then offering equivalent
168
- access to copy the source code from the same place counts as
169
- distribution of the source code, even though third parties are not
170
- compelled to copy the source along with the object code.
171
-
172
- 4. You may not copy, modify, sublicense, or distribute the Program
173
- except as expressly provided under this License. Any attempt
174
- otherwise to copy, modify, sublicense or distribute the Program is
175
- void, and will automatically terminate your rights under this License.
176
- However, parties who have received copies, or rights, from you under
177
- this License will not have their licenses terminated so long as such
178
- parties remain in full compliance.
179
-
180
- 5. You are not required to accept this License, since you have not
181
- signed it. However, nothing else grants you permission to modify or
182
- distribute the Program or its derivative works. These actions are
183
- prohibited by law if you do not accept this License. Therefore, by
184
- modifying or distributing the Program (or any work based on the
185
- Program), you indicate your acceptance of this License to do so, and
186
- all its terms and conditions for copying, distributing or modifying
187
- the Program or works based on it.
188
-
189
- 6. Each time you redistribute the Program (or any work based on the
190
- Program), the recipient automatically receives a license from the
191
- original licensor to copy, distribute or modify the Program subject to
192
- these terms and conditions. You may not impose any further
193
- restrictions on the recipients' exercise of the rights granted herein.
194
- You are not responsible for enforcing compliance by third parties to
195
- this License.
196
-
197
- 7. If, as a consequence of a court judgment or allegation of patent
198
- infringement or for any other reason (not limited to patent issues),
199
- conditions are imposed on you (whether by court order, agreement or
200
- otherwise) that contradict the conditions of this License, they do not
201
- excuse you from the conditions of this License. If you cannot
202
- distribute so as to satisfy simultaneously your obligations under this
203
- License and any other pertinent obligations, then as a consequence you
204
- may not distribute the Program at all. For example, if a patent
205
- license would not permit royalty-free redistribution of the Program by
206
- all those who receive copies directly or indirectly through you, then
207
- the only way you could satisfy both it and this License would be to
208
- refrain entirely from distribution of the Program.
209
-
210
- If any portion of this section is held invalid or unenforceable under
211
- any particular circumstance, the balance of the section is intended to
212
- apply and the section as a whole is intended to apply in other
213
- circumstances.
214
-
215
- It is not the purpose of this section to induce you to infringe any
216
- patents or other property right claims or to contest validity of any
217
- such claims; this section has the sole purpose of protecting the
218
- integrity of the free software distribution system, which is
219
- implemented by public license practices. Many people have made
220
- generous contributions to the wide range of software distributed
221
- through that system in reliance on consistent application of that
222
- system; it is up to the author/donor to decide if he or she is willing
223
- to distribute software through any other system and a licensee cannot
224
- impose that choice.
225
-
226
- This section is intended to make thoroughly clear what is believed to
227
- be a consequence of the rest of this License.
228
-
229
- 8. If the distribution and/or use of the Program is restricted in
230
- certain countries either by patents or by copyrighted interfaces, the
231
- original copyright holder who places the Program under this License
232
- may add an explicit geographical distribution limitation excluding
233
- those countries, so that distribution is permitted only in or among
234
- countries not thus excluded. In such case, this License incorporates
235
- the limitation as if written in the body of this License.
236
-
237
- 9. The Free Software Foundation may publish revised and/or new versions
238
- of the General Public License from time to time. Such new versions will
239
- be similar in spirit to the present version, but may differ in detail to
240
- address new problems or concerns.
241
-
242
- Each version is given a distinguishing version number. If the Program
243
- specifies a version number of this License which applies to it and "any
244
- later version", you have the option of following the terms and conditions
245
- either of that version or of any later version published by the Free
246
- Software Foundation. If the Program does not specify a version number of
247
- this License, you may choose any version ever published by the Free Software
248
- Foundation.
249
-
250
- 10. If you wish to incorporate parts of the Program into other free
251
- programs whose distribution conditions are different, write to the author
252
- to ask for permission. For software which is copyrighted by the Free
253
- Software Foundation, write to the Free Software Foundation; we sometimes
254
- make exceptions for this. Our decision will be guided by the two goals
255
- of preserving the free status of all derivatives of our free software and
256
- of promoting the sharing and reuse of software generally.
257
-
258
- NO WARRANTY
259
-
260
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
- FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
- OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
- PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
- OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
- TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
- PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
- REPAIR OR CORRECTION.
269
-
270
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
- REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
- INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
- OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
- TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
- YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
- PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
- POSSIBILITY OF SUCH DAMAGES.
279
-
280
- END OF TERMS AND CONDITIONS
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ Preamble
10
+
11
+ The licenses for most software are designed to take away your
12
+ freedom to share and change it. By contrast, the GNU General Public
13
+ License is intended to guarantee your freedom to share and change free
14
+ software--to make sure the software is free for all its users. This
15
+ General Public License applies to most of the Free Software
16
+ Foundation's software and to any other program whose authors commit to
17
+ using it. (Some other Free Software Foundation software is covered by
18
+ the GNU Lesser General Public License instead.) You can apply it to
19
+ your programs, too.
20
+
21
+ When we speak of free software, we are referring to freedom, not
22
+ price. Our General Public Licenses are designed to make sure that you
23
+ have the freedom to distribute copies of free software (and charge for
24
+ this service if you wish), that you receive source code or can get it
25
+ if you want it, that you can change the software or use pieces of it
26
+ in new free programs; and that you know you can do these things.
27
+
28
+ To protect your rights, we need to make restrictions that forbid
29
+ anyone to deny you these rights or to ask you to surrender the rights.
30
+ These restrictions translate to certain responsibilities for you if you
31
+ distribute copies of the software, or if you modify it.
32
+
33
+ For example, if you distribute copies of such a program, whether
34
+ gratis or for a fee, you must give the recipients all the rights that
35
+ you have. You must make sure that they, too, receive or can get the
36
+ source code. And you must show them these terms so they know their
37
+ rights.
38
+
39
+ We protect your rights with two steps: (1) copyright the software, and
40
+ (2) offer you this license which gives you legal permission to copy,
41
+ distribute and/or modify the software.
42
+
43
+ Also, for each author's protection and ours, we want to make certain
44
+ that everyone understands that there is no warranty for this free
45
+ software. If the software is modified by someone else and passed on, we
46
+ want its recipients to know that what they have is not the original, so
47
+ that any problems introduced by others will not reflect on the original
48
+ authors' reputations.
49
+
50
+ Finally, any free program is threatened constantly by software
51
+ patents. We wish to avoid the danger that redistributors of a free
52
+ program will individually obtain patent licenses, in effect making the
53
+ program proprietary. To prevent this, we have made it clear that any
54
+ patent must be licensed for everyone's free use or not licensed at all.
55
+
56
+ The precise terms and conditions for copying, distribution and
57
+ modification follow.
58
+
59
+ GNU GENERAL PUBLIC LICENSE
60
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
+
62
+ 0. This License applies to any program or other work which contains
63
+ a notice placed by the copyright holder saying it may be distributed
64
+ under the terms of this General Public License. The "Program", below,
65
+ refers to any such program or work, and a "work based on the Program"
66
+ means either the Program or any derivative work under copyright law:
67
+ that is to say, a work containing the Program or a portion of it,
68
+ either verbatim or with modifications and/or translated into another
69
+ language. (Hereinafter, translation is included without limitation in
70
+ the term "modification".) Each licensee is addressed as "you".
71
+
72
+ Activities other than copying, distribution and modification are not
73
+ covered by this License; they are outside its scope. The act of
74
+ running the Program is not restricted, and the output from the Program
75
+ is covered only if its contents constitute a work based on the
76
+ Program (independent of having been made by running the Program).
77
+ Whether that is true depends on what the Program does.
78
+
79
+ 1. You may copy and distribute verbatim copies of the Program's
80
+ source code as you receive it, in any medium, provided that you
81
+ conspicuously and appropriately publish on each copy an appropriate
82
+ copyright notice and disclaimer of warranty; keep intact all the
83
+ notices that refer to this License and to the absence of any warranty;
84
+ and give any other recipients of the Program a copy of this License
85
+ along with the Program.
86
+
87
+ You may charge a fee for the physical act of transferring a copy, and
88
+ you may at your option offer warranty protection in exchange for a fee.
89
+
90
+ 2. You may modify your copy or copies of the Program or any portion
91
+ of it, thus forming a work based on the Program, and copy and
92
+ distribute such modifications or work under the terms of Section 1
93
+ above, provided that you also meet all of these conditions:
94
+
95
+ a) You must cause the modified files to carry prominent notices
96
+ stating that you changed the files and the date of any change.
97
+
98
+ b) You must cause any work that you distribute or publish, that in
99
+ whole or in part contains or is derived from the Program or any
100
+ part thereof, to be licensed as a whole at no charge to all third
101
+ parties under the terms of this License.
102
+
103
+ c) If the modified program normally reads commands interactively
104
+ when run, you must cause it, when started running for such
105
+ interactive use in the most ordinary way, to print or display an
106
+ announcement including an appropriate copyright notice and a
107
+ notice that there is no warranty (or else, saying that you provide
108
+ a warranty) and that users may redistribute the program under
109
+ these conditions, and telling the user how to view a copy of this
110
+ License. (Exception: if the Program itself is interactive but
111
+ does not normally print such an announcement, your work based on
112
+ the Program is not required to print an announcement.)
113
+
114
+ These requirements apply to the modified work as a whole. If
115
+ identifiable sections of that work are not derived from the Program,
116
+ and can be reasonably considered independent and separate works in
117
+ themselves, then this License, and its terms, do not apply to those
118
+ sections when you distribute them as separate works. But when you
119
+ distribute the same sections as part of a whole which is a work based
120
+ on the Program, the distribution of the whole must be on the terms of
121
+ this License, whose permissions for other licensees extend to the
122
+ entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or with a work based on the Program) on a volume of
131
+ a storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at least three
143
+ years, to give any third party, for a charge no more than your
144
+ cost of physically performing source distribution, a complete
145
+ machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for noncommercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy the source along with the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sublicense or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties to
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgment or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court order, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is intended to apply in other
213
+ circumstances.
214
+
215
+ It is not the purpose of this section to induce you to infringe any
216
+ patents or other property right claims or to contest validity of any
217
+ such claims; this section has the sole purpose of protecting the
218
+ integrity of the free software distribution system, which is
219
+ implemented by public license practices. Many people have made
220
+ generous contributions to the wide range of software distributed
221
+ through that system in reliance on consistent application of that
222
+ system; it is up to the author/donor to decide if he or she is willing
223
+ to distribute software through any other system and a licensee cannot
224
+ impose that choice.
225
+
226
+ This section is intended to make thoroughly clear what is believed to
227
+ be a consequence of the rest of this License.
228
+
229
+ 8. If the distribution and/or use of the Program is restricted in
230
+ certain countries either by patents or by copyrighted interfaces, the
231
+ original copyright holder who places the Program under this License
232
+ may add an explicit geographical distribution limitation excluding
233
+ those countries, so that distribution is permitted only in or among
234
+ countries not thus excluded. In such case, this License incorporates
235
+ the limitation as if written in the body of this License.
236
+
237
+ 9. The Free Software Foundation may publish revised and/or new versions
238
+ of the General Public License from time to time. Such new versions will
239
+ be similar in spirit to the present version, but may differ in detail to
240
+ address new problems or concerns.
241
+
242
+ Each version is given a distinguishing version number. If the Program
243
+ specifies a version number of this License which applies to it and "any
244
+ later version", you have the option of following the terms and conditions
245
+ either of that version or of any later version published by the Free
246
+ Software Foundation. If the Program does not specify a version number of
247
+ this License, you may choose any version ever published by the Free Software
248
+ Foundation.
249
+
250
+ 10. If you wish to incorporate parts of the Program into other free
251
+ programs whose distribution conditions are different, write to the author
252
+ to ask for permission. For software which is copyrighted by the Free
253
+ Software Foundation, write to the Free Software Foundation; we sometimes
254
+ make exceptions for this. Our decision will be guided by the two goals
255
+ of preserving the free status of all derivatives of our free software and
256
+ of promoting the sharing and reuse of software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+ POSSIBILITY OF SUCH DAMAGES.
279
+
280
+ END OF TERMS AND CONDITIONS
281
+
282
+ How to Apply These Terms to Your New Programs
283
+
284
+ If you develop a new program, and you want it to be of the greatest
285
+ possible use to the public, the best way to achieve this is to make it
286
+ free software which everyone can redistribute and change under these terms.
287
+
288
+ To do so, attach the following notices to the program. It is safest
289
+ to attach them to the start of each source file to most effectively
290
+ convey the exclusion of warranty; and each file should have at least
291
+ the "copyright" line and a pointer to where the full notice is found.
292
+
293
+ <one line to give the program's name and a brief idea of what it does.>
294
+ Copyright (C) <year> <name of author>
295
+
296
+ This program is free software; you can redistribute it and/or modify
297
+ it under the terms of the GNU General Public License as published by
298
+ the Free Software Foundation; either version 2 of the License, or
299
+ (at your option) any later version.
300
+
301
+ This program is distributed in the hope that it will be useful,
302
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
303
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
+ GNU General Public License for more details.
305
+
306
+ You should have received a copy of the GNU General Public License along
307
+ with this program; if not, write to the Free Software Foundation, Inc.,
308
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
+
310
+ Also add information on how to contact you by electronic and paper mail.
311
+
312
+ If the program is interactive, make it output a short notice like this
313
+ when it starts in an interactive mode:
314
+
315
+ Gnomovision version 69, Copyright (C) year name of author
316
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
+ This is free software, and you are welcome to redistribute it
318
+ under certain conditions; type `show c' for details.
319
+
320
+ The hypothetical commands `show w' and `show c' should show the appropriate
321
+ parts of the General Public License. Of course, the commands you use may
322
+ be called something other than `show w' and `show c'; they could even be
323
+ mouse-clicks or menu items--whatever suits your program.
324
+
325
+ You should also get your employer (if you work as a programmer) or your
326
+ school, if any, to sign a "copyright disclaimer" for the program, if
327
+ necessary. Here is a sample; alter the names:
328
+
329
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
+
332
+ <signature of Ty Coon>, 1 April 1989
333
+ Ty Coon, President of Vice
334
+
335
+ This General Public License does not permit incorporating your program into
336
+ proprietary programs. If your program is a subroutine library, you may
337
+ consider it more useful to permit linking proprietary applications with the
338
+ library. If this is what you want to do, use the GNU Lesser General
339
+ Public License instead of this License.
admin/class-email-subscribers-admin.php ADDED
@@ -0,0 +1,330 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ exit;
6
+ }
7
+
8
+ /**
9
+ * The admin-specific functionality of the plugin.
10
+ *
11
+ * @link http://example.com
12
+ * @since 4.0
13
+ *
14
+ * @package Email_Subscribers
15
+ * @subpackage Email_Subscribers/admin
16
+ */
17
+
18
+ /**
19
+ * The admin-specific functionality of the plugin.
20
+ *
21
+ * Defines the plugin name, version, and two examples hooks for how to
22
+ * enqueue the admin-specific stylesheet and JavaScript.
23
+ *
24
+ * @package Email_Subscribers
25
+ * @subpackage Email_Subscribers/admin
26
+ * @author Your Name <email@example.com>
27
+ */
28
+ class Email_Subscribers_Admin {
29
+
30
+ /**
31
+ * The ID of this plugin.
32
+ *
33
+ * @since 4.0
34
+ * @access private
35
+ * @var string $email_subscribers The ID of this plugin.
36
+ */
37
+ private $email_subscribers;
38
+
39
+ /**
40
+ * The version of this plugin.
41
+ *
42
+ * @since 4.0
43
+ * @access private
44
+ * @var string $version The current version of this plugin.
45
+ */
46
+ private $version;
47
+
48
+ /**
49
+ * Initialize the class and set its properties.
50
+ *
51
+ * @since 4.0
52
+ *
53
+ * @param string $email_subscribers The name of this plugin.
54
+ * @param string $version The version of this plugin.
55
+ */
56
+ public function __construct( $email_subscribers, $version ) {
57
+
58
+ $this->email_subscribers = $email_subscribers;
59
+ $this->version = $version;
60
+
61
+ // Reorder ES Submenu
62
+ add_filter( 'custom_menu_order', array( $this, 'submenu_order' ) );
63
+
64
+
65
+ add_action( 'admin_menu', array( $this, 'email_subscribers_admin_menu' ) );
66
+ add_action( 'wp_ajax_es_klawoo_subscribe', array( $this, 'klawoo_subscribe' ) );
67
+
68
+ self::admin_show();
69
+ }
70
+
71
+ /**
72
+ * Register the stylesheets for the admin area.
73
+ *
74
+ * @since 4.0
75
+ */
76
+ public function enqueue_styles() {
77
+
78
+ /**
79
+ * This function is provided for demonstration purposes only.
80
+ *
81
+ * An instance of this class should be passed to the run() function
82
+ * defined in Email_Subscribers_Loader as all of the hooks are defined
83
+ * in that particular class.
84
+ *
85
+ * The Email_Subscribers_Loader will then create the relationship
86
+ * between the defined hooks and the functions defined in this
87
+ * class.
88
+ */
89
+
90
+ wp_enqueue_style( $this->email_subscribers, plugin_dir_url( __FILE__ ) . 'css/email-subscribers-admin.css', array(), $this->version, 'all' );
91
+
92
+
93
+ $get_page = Email_Subscribers::get_request( 'page' );
94
+
95
+ if ( ! empty( $get_page ) && 'es_settings' === $get_page ) {
96
+ wp_enqueue_style( 'thickbox' );
97
+ wp_enqueue_style( 'email-jquery-ui', plugin_dir_url( __FILE__ ) . 'css/jquery-ui.css', array(), $this->version, 'all' );
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Register the JavaScript for the admin area.
103
+ *
104
+ * @since 4.0
105
+ */
106
+ public function enqueue_scripts() {
107
+
108
+ /**
109
+ * This function is provided for demonstration purposes only.
110
+ *
111
+ * An instance of this class should be passed to the run() function
112
+ * defined in Email_Subscribers_Loader as all of the hooks are defined
113
+ * in that particular class.
114
+ *
115
+ * The Email_Subscribers_Loader will then create the relationship
116
+ * between the defined hooks and the functions defined in this
117
+ * class.
118
+ */
119
+
120
+
121
+ $get_page = Email_Subscribers::get_request( 'page' );
122
+
123
+ if ( ! empty( $get_page ) && 'es_settings' === $get_page ) {
124
+
125
+ wp_enqueue_script( 'thickbox' );
126
+ wp_enqueue_script( 'media-upload' );
127
+
128
+ }
129
+
130
+ wp_enqueue_script( $this->email_subscribers, plugin_dir_url( __FILE__ ) . 'js/email-subscribers-admin.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-tabs' ), $this->version, false );
131
+ }
132
+
133
+ public function email_subscribers_admin_menu() {
134
+ // This adds the main menu page
135
+ add_menu_page( 'Email Subscribers', 'Email Subscribers', 'edit_posts', 'es_dashboard', array( $this, 'es_dashboard_callback' ), 'dashicons-email', 30 );
136
+
137
+ // Submenu
138
+ add_submenu_page( 'es_dashboard', 'Dashboard', 'Dashboard', 'edit_posts', 'es_dashboard', array( $this, 'es_dashboard_callback' ) );
139
+ add_submenu_page( 'es_dashboard', 'Lists', '<span id="ig-es-lists">Lists</span>', 'edit_posts', 'es_lists', array( $this, 'load_lists' ) );
140
+ add_submenu_page( 'es_dashboard', 'Post Notifications', '<span id="ig-es-post-notifications">Post Notifications</span>', get_option( 'es_roles_notification', true ), 'es_notifications', array( $this, 'load_post_notifications' ) );
141
+ add_submenu_page( 'es_dashboard', 'Broadcast', '<span id="ig-es-broadcast">Broadcast</span>', get_option( 'es_roles_sendmail', true ), 'es_newsletters', array( $this, 'load_newsletters' ) );
142
+ add_submenu_page( 'es_dashboard', 'Reports', 'Reports', get_option( 'es_roles_sentmail', true ), 'es_reports', array( $this, 'load_reports' ) );
143
+ add_submenu_page( 'es_dashboard', 'Audience', __( 'Audience', 'email-subscribers' ), get_option( 'es_roles_subscriber', true ), 'es_subscribers', array( $this, 'load_audience' ) );
144
+ add_submenu_page( 'es_dashboard', 'Campaigns', 'Campaigns', get_option( 'es_roles_notification', true ), 'es_campaigns', array( $this, 'load_campaigns' ) );
145
+ add_submenu_page( 'es_dashboard', 'Settings', 'Settings', get_option( 'es_roles_notification', true ), 'es_settings', array( $this, 'load_settings' ) );
146
+ add_submenu_page( 'es_dashboard', 'Forms', 'Forms', get_option( 'es_roles_notification', true ), 'es_forms', array( $this, 'load_forms' ) );
147
+ add_submenu_page( 'es_dashboard', 'Tools', 'Tools', get_option( 'es_roles_notification', true ), 'es_tools', array( $this, 'load_tools' ) );
148
+ add_submenu_page( null, 'Template Preview', 'Template Preview', get_option( 'es_roles_notification', true ), 'es_template_preview', array( $this, 'load_preview' ) );
149
+ }
150
+
151
+ // Function for Klawoo's Subscribe form on Help & Info page
152
+ public static function klawoo_subscribe() {
153
+ $url = 'http://app.klawoo.com/subscribe';
154
+
155
+ if ( ! empty( $_POST ) ) {
156
+ $params = $_POST;
157
+ } else {
158
+ exit();
159
+ }
160
+ $method = 'POST';
161
+ $qs = http_build_query( $params );
162
+
163
+ $options = array(
164
+ 'timeout' => 15,
165
+ 'method' => $method
166
+ );
167
+
168
+ if ( $method == 'POST' ) {
169
+ $options['body'] = $qs;
170
+ } else {
171
+ if ( strpos( $url, '?' ) !== false ) {
172
+ $url .= '&' . $qs;
173
+ } else {
174
+ $url .= '?' . $qs;
175
+ }
176
+ }
177
+
178
+ $response = wp_remote_request( $url, $options );
179
+
180
+ if ( wp_remote_retrieve_response_code( $response ) == 200 ) {
181
+ $data = $response['body'];
182
+ if ( $data != 'error' ) {
183
+
184
+ $message_start = substr( $data, strpos( $data, '<body>' ) + 6 );
185
+ $remove = substr( $message_start, strpos( $message_start, '</body>' ) );
186
+ $message = trim( str_replace( $remove, '', $message_start ) );
187
+ echo( $message );
188
+ exit();
189
+ }
190
+ }
191
+ exit();
192
+ }
193
+
194
+ public function load_lists() {
195
+ $list = ES_Lists_Table::get_instance();
196
+ $list->es_lists_callback();
197
+ }
198
+
199
+ public function load_post_notifications() {
200
+ $post_notifications = ES_Post_Notifications_Table::get_instance();
201
+ $post_notifications->es_notifications_callback();
202
+ }
203
+
204
+ public function load_newsletters() {
205
+ $newsletters = ES_Newsletters::get_instance();
206
+ $newsletters->es_newsletters_settings_callback();
207
+ }
208
+
209
+ public function load_reports() {
210
+ $reports = ES_Reports_Table::get_instance();
211
+ $reports->es_reports_callback();
212
+ }
213
+
214
+ public function load_audience() {
215
+ $contacts = ES_Subscribers_Table::get_instance();
216
+ $contacts->plugin_settings_page();
217
+ }
218
+
219
+ public function load_campaigns() {
220
+ $campaigns = ES_Campaigns_Table::get_instance();
221
+ $campaigns->es_campaigns_callback();
222
+ }
223
+
224
+
225
+ public function load_settings() {
226
+ $settings = ES_Admin_Settings::get_instance();
227
+ $settings->es_settings_callback();
228
+ }
229
+
230
+ public function load_forms() {
231
+ $forms = ES_Forms_Table::get_instance();
232
+ $forms->es_forms_callback();
233
+ }
234
+
235
+ public function load_preview() {
236
+ $preview = ES_Templates_Table::get_instance();
237
+ $preview->es_template_preview_callback();
238
+ }
239
+
240
+ public function load_tools() {
241
+ $tools = ES_Tools::get_instance();
242
+ $tools->es_tools_settings_callback();
243
+ }
244
+
245
+ function submenu_order( $menu_order ) {
246
+ global $submenu;
247
+
248
+ $es_menus = isset( $submenu['es_dashboard'] ) ? $submenu['es_dashboard'] : array();
249
+
250
+ if ( ! empty( $es_menus ) ) {
251
+
252
+ $es_menu_order = array(
253
+ 'es_dashboard',
254
+ 'es_subscribers',
255
+ 'es_lists',
256
+ 'es_forms',
257
+ 'es_campaigns',
258
+ 'edit.php?post_type=es_template',
259
+ 'es_notifications',
260
+ 'es_newsletters',
261
+ 'es_reports',
262
+ 'es_tools',
263
+ 'es_settings',
264
+ 'es_general_information',
265
+ 'es_pricing'
266
+ );
267
+
268
+ $order = array_flip( $es_menu_order );
269
+
270
+ $reorder_es_menu = array();
271
+ foreach ( $es_menus as $menu ) {
272
+ $reorder_es_menu[ $order[ $menu[2] ] ] = $menu;
273
+ }
274
+
275
+ ksort( $reorder_es_menu );
276
+
277
+ $submenu['es_dashboard'] = $reorder_es_menu;
278
+
279
+ }
280
+
281
+ # Return the new submenu order
282
+ return $menu_order;
283
+ }
284
+
285
+ public function es_dashboard_callback() {
286
+ if ( Email_Subscribers::get_request( 'dismiss_admin_notice' ) == 1 ) {
287
+ update_option( 'es_star_review', 1 );
288
+ }
289
+ $es_plugin_data = get_plugin_data( plugin_dir_path( __DIR__ ) . 'email-subscribers.php' );
290
+ $es_current_version = $es_plugin_data['Version'];
291
+ $admin_email = get_option( 'admin_email' );
292
+
293
+ include plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/dashboard.php';
294
+
295
+ }
296
+
297
+ public static function es_feedback() {
298
+ if ( get_option( 'es_star_review' ) != 1 ) {
299
+ echo '<div class="notice notice-warning" style="background-color: #FFF;"><p style="letter-spacing: 0.6px;">If you like <strong>Email Subscribers</strong>, please consider leaving us a <a target="_blank" href="https://wordpress.org/support/plugin/email-subscribers/reviews/?filter=5#new-post"><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span></a> rating. A huge thank you from Icegram in advance! <a style="float:right" class="es-admin-btn es-admin-btn-secondary" href="' . admin_url() . 'admin.php?page=es_dashboard&dismiss_admin_notice=1&option_name=es_star_review">No, I don\'t like it</a></p></div>';
300
+
301
+ }
302
+
303
+ }
304
+
305
+ public static function admin_show() {
306
+ add_action( 'load-edit.php', function () {
307
+ $screen = get_current_screen();
308
+
309
+ if ( $screen->post_type == 'es_template' ) {
310
+ add_action( 'all_admin_notices', array( 'Email_Subscribers_Admin', 'es_feedback' ) );
311
+ }
312
+ } );
313
+
314
+ add_action( 'load-post.php', function () {
315
+ $screen = get_current_screen();
316
+
317
+ if ( $screen->post_type == 'es_template' ) {
318
+ add_action( 'all_admin_notices', array( 'Email_Subscribers_Admin', 'es_feedback' ) );
319
+ }
320
+ } );
321
+
322
+ add_action( 'load-post-new.php', function () {
323
+ $screen = get_current_screen();
324
+ if ( $screen->post_type == 'es_template' ) {
325
+ add_action( 'all_admin_notices', array( 'Email_Subscribers_Admin', 'es_feedback' ) );
326
+ }
327
+ } );
328
+ }
329
+
330
+ }
admin/css/email-subscribers-admin.css ADDED
@@ -0,0 +1,736 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ div#tabs {
2
+ margin-top: 20px;
3
+ padding: 0;
4
+ }
5
+
6
+ div#tabs div#menu-tab-listing {
7
+ width: 20%;
8
+ float: left;
9
+ }
10
+
11
+ div#tabs div#menu-tab-content {
12
+ width: 75%;
13
+ float: left;
14
+ }
15
+
16
+ div#tabs div#menu-tab-listing ul {
17
+ width: 100%;
18
+ display: block;
19
+ background: #f3f6ff;
20
+ border: 0px;
21
+ padding: 0; /*min-height: 500px;*/
22
+ border-right: 1px solid #CCC;
23
+ border-left: 1px solid #CCC;
24
+ border-bottom: 1px solid #CCC;
25
+ }
26
+
27
+ div#tabs div#menu-tab-listing ul li {
28
+ width: 100%;
29
+ display: block;
30
+ border-radius: 0px;
31
+ cursor: pointer;
32
+ margin: 0px;
33
+ border: 0px;
34
+ border-bottom: 1px solid #CCC;
35
+ }
36
+
37
+ div#tabs div#menu-tab-listing ul li a {
38
+ padding: 20px 10px;
39
+ width: 90%;
40
+ font-size: 16px;
41
+ }
42
+
43
+ div#tabs div#menu-tab-content h1 {
44
+ width: auto;
45
+ display: block;
46
+ border-bottom: 1px solid #CCC;
47
+ padding: 15px 20px;
48
+ }
49
+
50
+ div#tabs div#menu-tab-content h2 {
51
+ border-bottom: 1px solid #CCC;
52
+ margin: 0px;
53
+ padding: 10px 0;
54
+ text-align: center;
55
+ }
56
+
57
+
58
+ .help-info-content {
59
+ background: #FFF;
60
+ padding: 10px;
61
+ width: 98%;
62
+ float: left;
63
+ margin-top: 10px;
64
+ /*border-radius: 10px;*/
65
+ box-shadow: 0 0 10px #CCC;
66
+ }
67
+
68
+ .help-info-content .left-blog {
69
+ width: 48%;
70
+ float: left;
71
+ padding: 10px;
72
+ }
73
+
74
+ .help-info-content .right-blog {
75
+ width: 48%;
76
+ float: right;
77
+ padding: 10px;
78
+ }
79
+
80
+ .help-info-content ul {
81
+ width: 90%;
82
+ margin-left: 20px;
83
+ list-style: unset;
84
+ }
85
+
86
+ .help-info-content ul li {
87
+ line-height: 22px;
88
+ }
89
+
90
+ .feature-section {
91
+ width: 98%;
92
+ padding: 10px;
93
+ background: #FFF;
94
+ float: left;
95
+ margin: 20px auto;
96
+ /*border-radius: 10px;*/
97
+ }
98
+
99
+ .feature-section .feature-blog {
100
+ width: 29%;
101
+ float: left;
102
+ vertical-align: top;
103
+ min-height: 200px;
104
+ padding: 10px;
105
+ background: #f1f1f1;
106
+ margin: 10px;
107
+ /*border-radius: 10px;*/
108
+ }
109
+
110
+ .feature-section .feature-blog ul {
111
+ list-style: unset;
112
+ width: 90%;
113
+ margin-left: 20px;
114
+ }
115
+
116
+ .feature-section .feature-blog ul li {
117
+ line-height: 20px;
118
+ margin: 10px 0;
119
+ }
120
+
121
+ .feature-section .feature-blog ul li a {
122
+ font-size: 14px;
123
+ font-weight: bold;
124
+ }
125
+
126
+ .feature-section .feature-blog h3 {
127
+ font-size: 18px;
128
+ font-weight: bold;
129
+ border-bottom: 1px solid #CCC;
130
+ padding: 10px;
131
+ margin: 0px;
132
+ }
133
+ .feature-blog-wrapper .feature-blog{
134
+ float: inherit;
135
+ display: inline-block;
136
+ width: 35%;
137
+ }
138
+ .feature-blog-wrapper {
139
+ text-align: center;
140
+ }
141
+
142
+ .feature-section .feature-header {
143
+ width: 100%;
144
+ text-align: center;
145
+ }
146
+
147
+ .feature-section .feature-header h2 {
148
+ font-size: 28px;
149
+ border-bottom: 1px solid #CCC;
150
+ margin: 0px;
151
+ padding: 20px 0;
152
+ margin-bottom: 10px;
153
+ }
154
+
155
+ .feature-section.feature-section-last h3 {
156
+ line-height: 20px;
157
+ text-align: center;
158
+ }
159
+
160
+ .feature-section.feature-section-last img {
161
+ width: 90%;
162
+ padding: 10px;
163
+ border: 1px solid #CCC;
164
+ margin: 10px 0;
165
+ background: #000;
166
+ }
167
+
168
+ .feature-section.feature-section-last p {
169
+ font-size: 14px;
170
+ line-height: 22px;
171
+ }
172
+
173
+ .email-subscribers_page_es_settings input[type=text], .email-subscribers_page_es_settings input[type=password], .email-subscribers_page_es_settings input[type=email], .email-subscribers_page_es_settings textarea, #list_description, .email-subscribers_page_es_settings select {
174
+ width: 70%;
175
+ }
176
+
177
+ .tablenav-pages span.paging-input {
178
+ width: auto;
179
+ display: inline-block;
180
+ }
181
+
182
+ div#post-body-content {
183
+ width: 100%;
184
+ float: left;
185
+ }
186
+
187
+ div#post-body-content .meta-box-sortables .row-blog {
188
+ padding: 10px 0;
189
+ }
190
+
191
+ div#post-body-content .meta-box-sortables .row-blog label {
192
+ margin-right: 10px;
193
+ display: inline-block;
194
+ width: 10%;
195
+ font-weight: bold;
196
+ }
197
+
198
+ div#post-body-content .meta-box-sortables .row-blog input[type="text"], div#post-body-content .meta-box-sortables .row-blog input[type="email"], div#post-body-content .meta-box-sortables .row-blog select {
199
+ width: 30%;
200
+ height: 35px;
201
+ }
202
+
203
+
204
+ div#post-body-content .meta-box-sortables .row-blog p.submit input#submit {
205
+ width: auto;
206
+ height: auto;
207
+ }
208
+
209
+ .blog-content {
210
+ width: 100%;
211
+ }
212
+
213
+ .blog-content .blog-row {
214
+ padding: 10px 0;
215
+ }
216
+
217
+ .blog-content .blog-row p {
218
+ width: 10%;
219
+ display: inline-block;
220
+ margin: 0px;
221
+ }
222
+
223
+ .blog-content .blog-row input, .blog-content .blog-row select {
224
+ height: 35px;
225
+ line-height: 35px;
226
+ width: 35%;
227
+ }
228
+
229
+ .blog-content .blog-row.blog-row-submit input#submit {
230
+ width: 100%;
231
+ }
232
+
233
+ .email-subscribers_page_es_newsletters table.form-table td select {
234
+ height: 40px;
235
+ width: 35%;
236
+ line-height: 40px;
237
+ }
238
+
239
+
240
+ /* Customize Admin Settings */
241
+
242
+ .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active, a.ui-button:active, .ui-button:active, .ui-button.ui-state-active:hover {
243
+ background: #ffffff !important;
244
+ font-weight: normal;
245
+ color: #000 !important;
246
+ }
247
+
248
+ .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {
249
+ color: #000 !important;
250
+ }
251
+
252
+ .wp-person a:focus .gravatar, a:focus, a:focus .media-icon img {
253
+ box-shadow: none !important;
254
+ }
255
+
256
+ .content.save {
257
+ float: right;
258
+ }
259
+
260
+ .es-settings-submit-btn {
261
+ float: left;
262
+ }
263
+
264
+ .email-subscribers_page_es_subscribers .es-settings-submit-btn .button {
265
+ background-color: #3ad01e;
266
+ }
267
+
268
+ div#tabs {
269
+ clear: both;
270
+ }
271
+
272
+ div#tabs div#menu-tab-content h1 {
273
+ padding: 14px;
274
+ }
275
+
276
+ .esbghead {
277
+ /*background-image: url(https://multiratingpro.com/wp-content/uploads/2016/05/bg-9-full.jpg);*/
278
+ background: #4f85a1;
279
+ padding: 50px;
280
+ }
281
+
282
+ .esbghead h1 {
283
+ color: #fff !important;
284
+ font-weight: bold;
285
+ }
286
+
287
+ .ui-tabs-panel h2 {
288
+ background: white;
289
+ color: black;
290
+ font-size: 20px;
291
+ }
292
+
293
+ .essettings input#submit, .email-subscribers_page_es_subscribers input#submit {
294
+ background: #0085ba;
295
+ border-color: #0085ba;
296
+ box-shadow: 0 1px 0 #0085ba;
297
+ color: #fff;
298
+ text-decoration: none;
299
+ text-shadow: 0 -1px 1px #0085ba, 1px 0 1px #0085ba, 0 1px 1px #0085ba, -1px 0 1px #0085ba;
300
+ }
301
+
302
+ p.search-box.box-ma10 {
303
+ margin: 0 5px;
304
+ }
305
+
306
+ .esbgheader {
307
+ background-image: url('../images/bg3.png');
308
+ /*background: #f55764;*/
309
+ padding: 50px;
310
+ background-repeat: no-repeat;
311
+ background-size: cover;
312
+ background-position: center center;
313
+ }
314
+
315
+ .esbgheader h1 {
316
+ color: #fff !important;
317
+ font-weight: bold;
318
+ }
319
+
320
+ .headerpart {
321
+ margin: 10px 20px 0 2px;
322
+ }
323
+
324
+ .select2-container {
325
+ margin: 0 2px 0 2px;
326
+ }
327
+
328
+ .tablenav.top #doaction, #doaction2, #post-query-submit {
329
+ margin: 0px 4px 0 4px;
330
+ }
331
+
332
+ .leftside, .rightside {
333
+ float: left;
334
+ width: 10%;
335
+ margin: 20px 0;
336
+ }
337
+
338
+ .leftside p.submit, .rightside p.submit {
339
+ padding: 0 !important;
340
+ margin: 0 !important;
341
+ }
342
+
343
+ /* Admin Settings */
344
+
345
+ .email-subscribers_page_es_settings #wpwrap {
346
+ background-color: white;
347
+ }
348
+
349
+ .form-table .helper {
350
+ font-style: italic;
351
+ font-weight: 100;
352
+ font-size: 12px;
353
+ color: #9398a7;
354
+ }
355
+
356
+ .form-table .es_sub_headline{
357
+ margin-bottom: 0.5em;
358
+ font-size: 12px;
359
+ }
360
+
361
+ #menu-tab-listing .ui-state-default {
362
+ background-color: #f3f6ff;
363
+ }
364
+
365
+ #menu-tab-listing .ig-menu-tab.ui-tabs-active {
366
+ background-color: white;
367
+ }
368
+
369
+ .es-settings-submit-btn {
370
+ float: left;
371
+ }
372
+
373
+ .es-cta{
374
+ font-size: 1.2em;
375
+ font-weight: bold;
376
+ }
377
+
378
+ .wrap .page-title-action.es-imp-button:hover {
379
+ color: #FFFFFF;
380
+ background-color: #03a025;
381
+ }
382
+
383
+ .page-title-action.es-imp-button {
384
+ background-color: #03a025;
385
+ color: #FFFFFF;
386
+ }
387
+
388
+ .es-contact-form {
389
+ width: 70%;
390
+ }
391
+ /**** Dashboard : start ***/
392
+ .wrap.about-wrap {
393
+ background-color: transparent;
394
+ position: relative;
395
+ margin: 25px 40px 0 20px;
396
+ box-shadow: none;
397
+ -webkit-box-shadow: none;
398
+ }
399
+ .about-wrap.es {
400
+ max-width: 100%
401
+ }
402
+ .about-header .wrap .button-hero, .button-main {
403
+ color: #FFFFFF!important;
404
+ border-color: #03a025!important;
405
+ background: #03a025 !important;
406
+ box-shadow: 0 1px 0 #03a025;
407
+ font-weight: bold;
408
+ height: 3em;
409
+ line-height: 1em;
410
+ }
411
+ .about-header .wrap .button-hero:hover, .button-main {
412
+ color: #FFF!important;
413
+ background: #0AAB2E!important;
414
+ border-color: #0AAB2E!important;
415
+ }
416
+ .about-header {
417
+ background-color: #FFF;
418
+ padding: 2em 1.5em;
419
+ -webkit-box-shadow: 0 0 7px 0 rgba(0, 0, 0, .2);
420
+ box-shadow: 0 0 7px 0 rgba(0, 0, 0, .2);
421
+ }
422
+ .form-table th {
423
+ width: 350px !important;
424
+ }
425
+ .es-ltr {
426
+ width: 20em;
427
+ height: 2em;
428
+ margin-bottom: 10px;
429
+ padding: 1.4em;
430
+ }
431
+ .es-about-text {
432
+ /*margin-bottom: 2em;*/
433
+ font-size: 1em;
434
+ /*padding-top: 0.5em;*/
435
+ }
436
+ .es-notify-about-new-post-1 {
437
+ margin-top: 1em;
438
+ margin-right: 13em;
439
+ margin-bottom: 0.3em;
440
+ font-size: 1.1em;
441
+ }
442
+ .es-notify-about-new-post-2 {
443
+ margin-right: 13em;
444
+ font-size: 1em;
445
+ color: gray;
446
+ }
447
+ .wrap.about-wrap h1 {
448
+ font-size: 2.5em;
449
+ line-height: 0.9em;
450
+ }
451
+ .feature-section.col>div {
452
+ position: relative;
453
+ width: 29.95%;
454
+ margin-right: 4.999999999%;
455
+ float: left
456
+ }
457
+ .feature-section.col.two-col>div {
458
+ width: 45.95%
459
+ }
460
+ .feature-section.col img {
461
+ width: 150px;
462
+ border: none;
463
+ }
464
+ .feature-section.col p {
465
+ margin-bottom: 1.5em
466
+ }
467
+ .about-wrap .feature-section h4 {
468
+ margin-top: .4em
469
+ }
470
+ .about-wrap.es .feature-section {
471
+ display: block!important
472
+ }
473
+
474
+
475
+ .about-wrap [class$=col] .last-feature {
476
+ margin-right: 0
477
+ }
478
+ .es-support {
479
+ color: #000;
480
+ margin: 178px 0 0;
481
+ height: 10px;
482
+ width: 180px;
483
+ text-rendering: optimizeLegibility;
484
+ text-align: right;
485
+ right: 0;
486
+ margin-top: 9em;
487
+ padding-right: 1em;
488
+ }
489
+ .es-contact-us {
490
+ font-size: 20px;
491
+ line-height: 1.5em;
492
+ font-weight: 800;
493
+ margin-right: 20px;
494
+ }
495
+ .es-contact-us a {
496
+ color: #E1564B;
497
+ }
498
+ .es-donate-link {
499
+ text-align: right;
500
+ font-size: 0.8em;
501
+ margin-top: 1em;
502
+ }
503
+ .es-esaf-integration {
504
+ width: 75% !important;
505
+ }
506
+ .es-ig-integration {
507
+ width: 100% !important;
508
+ }
509
+ .es-rm-integration {
510
+ width: 79% !important;
511
+ }
512
+ .es-integration-guide {
513
+ text-align:justify;
514
+ }
515
+ .es_feature, .es_summary {
516
+ line-height: 1.7em!important;
517
+ }
518
+ .es_summary {
519
+ margin-left: 0em!important;
520
+ }
521
+ .es_feature_list, .es_faq_list {
522
+ list-style-type:disc;
523
+ margin-left: 1.5em!important;
524
+ }
525
+ .es_faq {
526
+ margin-bottom: 1em;
527
+ font-weight: 700;
528
+ }
529
+
530
+ .form-table td.es-optin-headline {
531
+ color: red;
532
+ text-align: center;
533
+ font-weight: bold;
534
+ font-size: 24px;
535
+ }
536
+
537
+ .form-table td.es-emm-image {
538
+ padding: 15px 10px;
539
+ width: 45%;
540
+ text-align: center;
541
+ }
542
+
543
+ .form-table td.es-emm-text{
544
+ padding: 15px 10px;
545
+ width: 50%;
546
+ }
547
+
548
+ .form-table td.es-emm-optin{
549
+ /*padding: 15px 10px;*/
550
+ /*width: 25%;*/
551
+ padding: 1em 0;
552
+ }
553
+
554
+ .form-table td.es-emm-optin form[name="klawoo_subscribe"] {
555
+ margin-right: 1px;
556
+ }
557
+
558
+ #klawoo_response {
559
+ background-color: yellow;
560
+ }
561
+ .es-about-line{
562
+ width: 85%;
563
+ font-size: 14px;
564
+ line-height: 1.8em;
565
+ }
566
+ .es-help-wrap{
567
+ border-top:1px dotted #CCC;
568
+ }
569
+ .subscribe-form{
570
+ margin-top: 2em;
571
+ }
572
+ .subscribe-form li{
573
+ list-style: disc;
574
+ list-style-position: inside;
575
+ }
576
+ .es-upper{
577
+ display: flex;
578
+ }
579
+ .es-upper .es-info{
580
+ width: 60%;
581
+ padding-right: 3em;
582
+ border-right: 1px solid #f7f7f7;
583
+ margin-left: 1.2em;
584
+ }
585
+ .es-info img{
586
+ vertical-align: bottom;
587
+ }
588
+ .es-lower{
589
+ margin-top: 1.5em;
590
+
591
+ }
592
+ .es-quick-links-wrapper{
593
+ margin-top: 2em;
594
+ margin-bottom: 1em;
595
+ }
596
+ span.es-quick-links{
597
+ margin: 0 1em;
598
+ font-size: 16px;
599
+ font-weight: 800;
600
+ }
601
+ .es-quick-links a {
602
+ color: #f55764;
603
+ }
604
+ .button-main{
605
+ color: #FFFFFF!important;
606
+ border-color: #03a025!important;
607
+ background: #03a025 !important;
608
+ box-shadow: 0 1px 0 #03a025;
609
+ font-weight: bold;
610
+ height: 3em !important;
611
+ line-height: 3em !important;
612
+ margin: 1em auto !important;
613
+ }
614
+ .about-header .es-version {
615
+ /*position: absolute;*/
616
+ top: 0;
617
+ right: 0;
618
+ text-align: center;
619
+ padding: 10px;
620
+ }
621
+
622
+ h5.es-badge {
623
+ margin: 0px;
624
+ /*color: #E1564B;*/
625
+ font-size: 12px;
626
+ /*text-align: right;*/
627
+ font-weight: 600;
628
+ }
629
+
630
+ .about-header .es-version h3 {
631
+ margin: 10px 0;
632
+ color: #333;
633
+ display: inline;
634
+ }
635
+
636
+ .about-header .es-version a {
637
+ color: #E1564B;
638
+ text-decoration: none;
639
+ font-size: 20px;
640
+ font-weight: bold;
641
+ }
642
+
643
+ .about-header {
644
+ background: #FFF;
645
+ border-radius: 5px;
646
+ padding: 10px;
647
+ width: 98%;
648
+ position: relative;
649
+ box-shadow: 0 0 10px #CCC;
650
+ }
651
+
652
+ .about-header h2 {
653
+ font-size: 1.9em;
654
+ margin: 20px 0 10px 0;
655
+ display: inline-block;
656
+ color: #f55764;
657
+ }
658
+
659
+ .about-header .es-about-text {
660
+ font-size: 1.5em;
661
+ line-height: 1.6em;
662
+ margin-top: 0.5em;
663
+ }
664
+
665
+ .about-header .es-notify-about-new-post-1 {
666
+ margin: 10px 0;
667
+ font-size: 18px;
668
+ }
669
+
670
+ .about-header ul {
671
+ width: 100%;
672
+ font-size: 14px;
673
+ margin: 10px 0;
674
+ /*color: #808080;*/
675
+ font-weight: normal;
676
+ }
677
+
678
+ .about-header ul li {
679
+ margin: 15px 0;
680
+ }
681
+
682
+ .about-header .wrap.klawoo-form {
683
+ /*border-top: 1px dotted #CCC;*/
684
+ width: 40%;
685
+ margin-left: 2.5em;
686
+ }
687
+
688
+ .about-header .wrap.klawoo-form td.es-optin-headline {
689
+ color: #f55764;
690
+ text-align: center;
691
+ font-weight: bold;
692
+ font-size: 24px;
693
+ padding: 0;
694
+ }
695
+
696
+ .about-header .wrap.klawoo-form td.es-emm-text {
697
+ margin: 0px;
698
+ padding: 0px;
699
+ }
700
+
701
+ .about-header .wrap.klawoo-form td.es-emm-image img {
702
+ width: auto;
703
+ }
704
+
705
+ @media only screen and (max-width: 1362px){
706
+ .es-info h2{
707
+ font-size: 1.5em;
708
+ }
709
+ .es-info .es-about-line{
710
+ line-height: 1.4em;
711
+ }
712
+ .es-info .es-about-text{
713
+ font-size: 1.5em;
714
+ }
715
+ }
716
+
717
+ .es-emm-text .column {
718
+ padding: 0.5em;
719
+ /*border: 1px solid rgba(0, 0, 0, 0.1);*/
720
+ text-align: center;
721
+ color: rgba(0, 0, 0, 0.75);
722
+ margin: 0 auto;
723
+ /*border: 5px double #e0e0e0;*/
724
+ background: #f7f3c5;
725
+ }
726
+ .es-emm-text .column strong{
727
+ font-size: 1.2em;
728
+ color: #f55764;
729
+ }
730
+ .es-emm-text .column i.dashicons-facebook {
731
+ font-size: 2.5em;
732
+ line-height: 0.6em;
733
+ color: #28487D;
734
+ margin: 0.2em 0;
735
+ }
736
+ /**** Dashboard : end ***/
admin/css/jquery-ui.css ADDED
@@ -0,0 +1,1311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! jQuery UI - v1.12.1 - 2016-09-14
2
+ * http://jqueryui.com
3
+ * Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css
4
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=e9e9e9&bgTextureHeader=flat&borderColorHeader=dddddd&fcHeader=333333&iconColorHeader=444444&bgColorContent=ffffff&bgTextureContent=flat&borderColorContent=dddddd&fcContent=333333&iconColorContent=444444&bgColorDefault=f6f6f6&bgTextureDefault=flat&borderColorDefault=c5c5c5&fcDefault=454545&iconColorDefault=777777&bgColorHover=ededed&bgTextureHover=flat&borderColorHover=cccccc&fcHover=2b2b2b&iconColorHover=555555&bgColorActive=007fff&bgTextureActive=flat&borderColorActive=003eff&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=fffa90&bgTextureHighlight=flat&borderColorHighlight=dad55e&fcHighlight=777620&iconColorHighlight=777620&bgColorError=fddfdf&bgTextureError=flat&borderColorError=f1a899&fcError=5f3f3f&iconColorError=cc0000&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px
5
+ * Copyright jQuery Foundation and other contributors; Licensed MIT */
6
+
7
+ /* Layout helpers
8
+ ----------------------------------*/
9
+ .ui-helper-hidden {
10
+ display: none;
11
+ }
12
+ .ui-helper-hidden-accessible {
13
+ border: 0;
14
+ clip: rect(0 0 0 0);
15
+ height: 1px;
16
+ margin: -1px;
17
+ overflow: hidden;
18
+ padding: 0;
19
+ position: absolute;
20
+ width: 1px;
21
+ }
22
+ .ui-helper-reset {
23
+ margin: 0;
24
+ padding: 0;
25
+ border: 0;
26
+ outline: 0;
27
+ line-height: 1.3;
28
+ text-decoration: none;
29
+ font-size: 100%;
30
+ list-style: none;
31
+ }
32
+ .ui-helper-clearfix:before,
33
+ .ui-helper-clearfix:after {
34
+ content: "";
35
+ display: table;
36
+ border-collapse: collapse;
37
+ }
38
+ .ui-helper-clearfix:after {
39
+ clear: both;
40
+ }
41
+ .ui-helper-zfix {
42
+ width: 100%;
43
+ height: 100%;
44
+ top: 0;
45
+ left: 0;
46
+ position: absolute;
47
+ opacity: 0;
48
+ filter:Alpha(Opacity=0); /* support: IE8 */
49
+ }
50
+
51
+ .ui-front {
52
+ z-index: 100;
53
+ }
54
+
55
+
56
+ /* Interaction Cues
57
+ ----------------------------------*/
58
+ .ui-state-disabled {
59
+ cursor: default !important;
60
+ pointer-events: none;
61
+ }
62
+
63
+
64
+ /* Icons
65
+ ----------------------------------*/
66
+ .ui-icon {
67
+ display: inline-block;
68
+ vertical-align: middle;
69
+ margin-top: -.25em;
70
+ position: relative;
71
+ text-indent: -99999px;
72
+ overflow: hidden;
73
+ background-repeat: no-repeat;
74
+ }
75
+
76
+ .ui-widget-icon-block {
77
+ left: 50%;
78
+ margin-left: -8px;
79
+ display: block;
80
+ }
81
+
82
+ /* Misc visuals
83
+ ----------------------------------*/
84
+
85
+ /* Overlays */
86
+ .ui-widget-overlay {
87
+ position: fixed;
88
+ top: 0;
89
+ left: 0;
90
+ width: 100%;
91
+ height: 100%;
92
+ }
93
+ .ui-accordion .ui-accordion-header {
94
+ display: block;
95
+ cursor: pointer;
96
+ position: relative;
97
+ margin: 2px 0 0 0;
98
+ padding: .5em .5em .5em .7em;
99
+ font-size: 100%;
100
+ }
101
+ .ui-accordion .ui-accordion-content {
102
+ padding: 1em 2.2em;
103
+ border-top: 0;
104
+ overflow: auto;
105
+ }
106
+ .ui-autocomplete {
107
+ position: absolute;
108
+ top: 0;
109
+ left: 0;
110
+ cursor: default;
111
+ }
112
+ .ui-menu {
113
+ list-style: none;
114
+ padding: 0;
115
+ margin: 0;
116
+ display: block;
117
+ outline: 0;
118
+ }
119
+ .ui-menu .ui-menu {
120
+ position: absolute;
121
+ }
122
+ .ui-menu .ui-menu-item {
123
+ margin: 0;
124
+ cursor: pointer;
125
+ /* support: IE10, see #8844 */
126
+ list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
127
+ }
128
+ .ui-menu .ui-menu-item-wrapper {
129
+ position: relative;
130
+ padding: 3px 1em 3px .4em;
131
+ }
132
+ .ui-menu .ui-menu-divider {
133
+ margin: 5px 0;
134
+ height: 0;
135
+ font-size: 0;
136
+ line-height: 0;
137
+ border-width: 1px 0 0 0;
138
+ }
139
+ .ui-menu .ui-state-focus,
140
+ .ui-menu .ui-state-active {
141
+ margin: -1px;
142
+ }
143
+
144
+ /* icon support */
145
+ .ui-menu-icons {
146
+ position: relative;
147
+ }
148
+ .ui-menu-icons .ui-menu-item-wrapper {
149
+ padding-left: 2em;
150
+ }
151
+
152
+ /* left-aligned */
153
+ .ui-menu .ui-icon {
154
+ position: absolute;
155
+ top: 0;
156
+ bottom: 0;
157
+ left: .2em;
158
+ margin: auto 0;
159
+ }
160
+
161
+ /* right-aligned */
162
+ .ui-menu .ui-menu-icon {
163
+ left: auto;
164
+ right: 0;
165
+ }
166
+ .ui-button {
167
+ padding: .4em 1em;
168
+ display: inline-block;
169
+ position: relative;
170
+ line-height: normal;
171
+ margin-right: .1em;
172
+ cursor: pointer;
173
+ vertical-align: middle;
174
+ text-align: center;
175
+ -webkit-user-select: none;
176
+ -moz-user-select: none;
177
+ -ms-user-select: none;
178
+ user-select: none;
179
+
180
+ /* Support: IE <= 11 */
181
+ overflow: visible;
182
+ }
183
+
184
+ .ui-button,
185
+ .ui-button:link,
186
+ .ui-button:visited,
187
+ .ui-button:hover,
188
+ .ui-button:active {
189
+ text-decoration: none;
190
+ }
191
+
192
+ /* to make room for the icon, a width needs to be set here */
193
+ .ui-button-icon-only {
194
+ width: 2em;
195
+ box-sizing: border-box;
196
+ text-indent: -9999px;
197
+ white-space: nowrap;
198
+ }
199
+
200
+ /* no icon support for input elements */
201
+ input.ui-button.ui-button-icon-only {
202
+ text-indent: 0;
203
+ }
204
+
205
+ /* button icon element(s) */
206
+ .ui-button-icon-only .ui-icon {
207
+ position: absolute;
208
+ top: 50%;
209
+ left: 50%;
210
+ margin-top: -8px;
211
+ margin-left: -8px;
212
+ }
213
+
214
+ .ui-button.ui-icon-notext .ui-icon {
215
+ padding: 0;
216
+ width: 2.1em;
217
+ height: 2.1em;
218
+ text-indent: -9999px;
219
+ white-space: nowrap;
220
+
221
+ }
222
+
223
+ input.ui-button.ui-icon-notext .ui-icon {
224
+ width: auto;
225
+ height: auto;
226
+ text-indent: 0;
227
+ white-space: normal;
228
+ padding: .4em 1em;
229
+ }
230
+
231
+ /* workarounds */
232
+ /* Support: Firefox 5 - 40 */
233
+ input.ui-button::-moz-focus-inner,
234
+ button.ui-button::-moz-focus-inner {
235
+ border: 0;
236
+ padding: 0;
237
+ }
238
+ .ui-controlgroup {
239
+ vertical-align: middle;
240
+ display: inline-block;
241
+ }
242
+ .ui-controlgroup > .ui-controlgroup-item {
243
+ float: left;
244
+ margin-left: 0;
245
+ margin-right: 0;
246
+ }
247
+ .ui-controlgroup > .ui-controlgroup-item:focus,
248
+ .ui-controlgroup > .ui-controlgroup-item.ui-visual-focus {
249
+ z-index: 9999;
250
+ }
251
+ .ui-controlgroup-vertical > .ui-controlgroup-item {
252
+ display: block;
253
+ float: none;
254
+ width: 100%;
255
+ margin-top: 0;
256
+ margin-bottom: 0;
257
+ text-align: left;
258
+ }
259
+ .ui-controlgroup-vertical .ui-controlgroup-item {
260
+ box-sizing: border-box;
261
+ }
262
+ .ui-controlgroup .ui-controlgroup-label {
263
+ padding: .4em 1em;
264
+ }
265
+ .ui-controlgroup .ui-controlgroup-label span {
266
+ font-size: 80%;
267
+ }
268
+ .ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item {
269
+ border-left: none;
270
+ }
271
+ .ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item {
272
+ border-top: none;
273
+ }
274
+ .ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content {
275
+ border-right: none;
276
+ }
277
+ .ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content {
278
+ border-bottom: none;
279
+ }
280
+
281
+ /* Spinner specific style fixes */
282
+ .ui-controlgroup-vertical .ui-spinner-input {
283
+
284
+ /* Support: IE8 only, Android < 4.4 only */
285
+ width: 75%;
286
+ width: calc( 100% - 2.4em );
287
+ }
288
+ .ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
289
+ border-top-style: solid;
290
+ }
291
+
292
+ .ui-checkboxradio-label .ui-icon-background {
293
+ box-shadow: inset 1px 1px 1px #ccc;
294
+ border-radius: .12em;
295
+ border: none;
296
+ }
297
+ .ui-checkboxradio-radio-label .ui-icon-background {
298
+ width: 16px;
299
+ height: 16px;
300
+ border-radius: 1em;
301
+ overflow: visible;
302
+ border: none;
303
+ }
304
+ .ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,
305
+ .ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon {
306
+ background-image: none;
307
+ width: 8px;
308
+ height: 8px;
309
+ border-width: 4px;
310
+ border-style: solid;
311
+ }
312
+ .ui-checkboxradio-disabled {
313
+ pointer-events: none;
314
+ }
315
+ .ui-datepicker {
316
+ width: 17em;
317
+ padding: .2em .2em 0;
318
+ display: none;
319
+ }
320
+ .ui-datepicker .ui-datepicker-header {
321
+ position: relative;
322
+ padding: .2em 0;
323
+ }
324
+ .ui-datepicker .ui-datepicker-prev,
325
+ .ui-datepicker .ui-datepicker-next {
326
+ position: absolute;
327
+ top: 2px;
328
+ width: 1.8em;
329
+ height: 1.8em;
330
+ }
331
+ .ui-datepicker .ui-datepicker-prev-hover,
332
+ .ui-datepicker .ui-datepicker-next-hover {
333
+ top: 1px;
334
+ }
335
+ .ui-datepicker .ui-datepicker-prev {
336
+ left: 2px;
337
+ }
338
+ .ui-datepicker .ui-datepicker-next {
339
+ right: 2px;
340
+ }
341
+ .ui-datepicker .ui-datepicker-prev-hover {
342
+ left: 1px;
343
+ }
344
+ .ui-datepicker .ui-datepicker-next-hover {
345
+ right: 1px;
346
+ }
347
+ .ui-datepicker .ui-datepicker-prev span,
348
+ .ui-datepicker .ui-datepicker-next span {
349
+ display: block;
350
+ position: absolute;
351
+ left: 50%;
352
+ margin-left: -8px;
353
+ top: 50%;
354
+ margin-top: -8px;
355
+ }
356
+ .ui-datepicker .ui-datepicker-title {
357
+ margin: 0 2.3em;
358
+ line-height: 1.8em;
359
+ text-align: center;
360
+ }
361
+ .ui-datepicker .ui-datepicker-title select {
362
+ font-size: 1em;
363
+ margin: 1px 0;
364
+ }
365
+ .ui-datepicker select.ui-datepicker-month,
366
+ .ui-datepicker select.ui-datepicker-year {
367
+ width: 45%;
368
+ }
369
+ .ui-datepicker table {
370
+ width: 100%;
371
+ font-size: .9em;
372
+ border-collapse: collapse;
373
+ margin: 0 0 .4em;
374
+ }
375
+ .ui-datepicker th {
376
+ padding: .7em .3em;
377
+ text-align: center;
378
+ font-weight: bold;
379
+ border: 0;
380
+ }
381
+ .ui-datepicker td {
382
+ border: 0;
383
+ padding: 1px;
384
+ }
385
+ .ui-datepicker td span,
386
+ .ui-datepicker td a {
387
+ display: block;
388
+ padding: .2em;
389
+ text-align: right;
390
+ text-decoration: none;
391
+ }
392
+ .ui-datepicker .ui-datepicker-buttonpane {
393
+ background-image: none;
394
+ margin: .7em 0 0 0;
395
+ padding: 0 .2em;
396
+ border-left: 0;
397
+ border-right: 0;
398
+ border-bottom: 0;
399
+ }
400
+ .ui-datepicker .ui-datepicker-buttonpane button {
401
+ float: right;
402
+ margin: .5em .2em .4em;
403
+ cursor: pointer;
404
+ padding: .2em .6em .3em .6em;
405
+ width: auto;
406
+ overflow: visible;
407
+ }
408
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
409
+ float: left;
410
+ }
411
+
412
+ /* with multiple calendars */
413
+ .ui-datepicker.ui-datepicker-multi {
414
+ width: auto;
415
+ }
416
+ .ui-datepicker-multi .ui-datepicker-group {
417
+ float: left;
418
+ }
419
+ .ui-datepicker-multi .ui-datepicker-group table {
420
+ width: 95%;
421
+ margin: 0 auto .4em;
422
+ }
423
+ .ui-datepicker-multi-2 .ui-datepicker-group {
424
+ width: 50%;
425
+ }
426
+ .ui-datepicker-multi-3 .ui-datepicker-group {
427
+ width: 33.3%;
428
+ }
429
+ .ui-datepicker-multi-4 .ui-datepicker-group {
430
+ width: 25%;
431
+ }
432
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
433
+ .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
434
+ border-left-width: 0;
435
+ }
436
+ .ui-datepicker-multi .ui-datepicker-buttonpane {
437
+ clear: left;
438
+ }
439
+ .ui-datepicker-row-break {
440
+ clear: both;
441
+ width: 100%;
442
+ font-size: 0;
443
+ }
444
+
445
+ /* RTL support */
446
+ .ui-datepicker-rtl {
447
+ direction: rtl;
448
+ }
449
+ .ui-datepicker-rtl .ui-datepicker-prev {
450
+ right: 2px;
451
+ left: auto;
452
+ }
453
+ .ui-datepicker-rtl .ui-datepicker-next {
454
+ left: 2px;
455
+ right: auto;
456
+ }
457
+ .ui-datepicker-rtl .ui-datepicker-prev:hover {
458
+ right: 1px;
459
+ left: auto;
460
+ }
461
+ .ui-datepicker-rtl .ui-datepicker-next:hover {
462
+ left: 1px;
463
+ right: auto;
464
+ }
465
+ .ui-datepicker-rtl .ui-datepicker-buttonpane {
466
+ clear: right;
467
+ }
468
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button {
469
+ float: left;
470
+ }
471
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
472
+ .ui-datepicker-rtl .ui-datepicker-group {
473
+ float: right;
474
+ }
475
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
476
+ .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
477
+ border-right-width: 0;
478
+ border-left-width: 1px;
479
+ }
480
+
481
+ /* Icons */
482
+ .ui-datepicker .ui-icon {
483
+ display: block;
484
+ text-indent: -99999px;
485
+ overflow: hidden;
486
+ background-repeat: no-repeat;
487
+ left: .5em;
488
+ top: .3em;
489
+ }
490
+ .ui-dialog {
491
+ position: absolute;
492
+ top: 0;
493
+ left: 0;
494
+ padding: .2em;
495
+ outline: 0;
496
+ }
497
+ .ui-dialog .ui-dialog-titlebar {
498
+ padding: .4em 1em;
499
+ position: relative;
500
+ }
501
+ .ui-dialog .ui-dialog-title {
502
+ float: left;
503
+ margin: .1em 0;
504
+ white-space: nowrap;
505
+ width: 90%;
506
+ overflow: hidden;
507
+ text-overflow: ellipsis;
508
+ }
509
+ .ui-dialog .ui-dialog-titlebar-close {
510
+ position: absolute;
511
+ right: .3em;
512
+ top: 50%;
513
+ width: 20px;
514
+ margin: -10px 0 0 0;
515
+ padding: 1px;
516
+ height: 20px;
517
+ }
518
+ .ui-dialog .ui-dialog-content {
519
+ position: relative;
520
+ border: 0;
521
+ padding: .5em 1em;
522
+ background: none;
523
+ overflow: auto;
524
+ }
525
+ .ui-dialog .ui-dialog-buttonpane {
526
+ text-align: left;
527
+ border-width: 1px 0 0 0;
528
+ background-image: none;
529
+ margin-top: .5em;
530
+ padding: .3em 1em .5em .4em;
531
+ }
532
+ .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
533
+ float: right;
534
+ }
535
+ .ui-dialog .ui-dialog-buttonpane button {
536
+ margin: .5em .4em .5em 0;
537
+ cursor: pointer;
538
+ }
539
+ .ui-dialog .ui-resizable-n {
540
+ height: 2px;
541
+ top: 0;
542
+ }
543
+ .ui-dialog .ui-resizable-e {
544
+ width: 2px;
545
+ right: 0;
546
+ }
547
+ .ui-dialog .ui-resizable-s {
548
+ height: 2px;
549
+ bottom: 0;
550
+ }
551
+ .ui-dialog .ui-resizable-w {
552
+ width: 2px;
553
+ left: 0;
554
+ }
555
+ .ui-dialog .ui-resizable-se,
556
+ .ui-dialog .ui-resizable-sw,
557
+ .ui-dialog .ui-resizable-ne,
558
+ .ui-dialog .ui-resizable-nw {
559
+ width: 7px;
560
+ height: 7px;
561
+ }
562
+ .ui-dialog .ui-resizable-se {
563
+ right: 0;
564
+ bottom: 0;
565
+ }
566
+ .ui-dialog .ui-resizable-sw {
567
+ left: 0;
568
+ bottom: 0;
569
+ }
570
+ .ui-dialog .ui-resizable-ne {
571
+ right: 0;
572
+ top: 0;
573
+ }
574
+ .ui-dialog .ui-resizable-nw {
575
+ left: 0;
576
+ top: 0;
577
+ }
578
+ .ui-draggable .ui-dialog-titlebar {
579
+ cursor: move;
580
+ }
581
+ .ui-draggable-handle {
582
+ -ms-touch-action: none;
583
+ touch-action: none;
584
+ }
585
+ .ui-resizable {
586
+ position: relative;
587
+ }
588
+ .ui-resizable-handle {
589
+ position: absolute;
590
+ font-size: 0.1px;
591
+ display: block;
592
+ -ms-touch-action: none;
593
+ touch-action: none;
594
+ }
595
+ .ui-resizable-disabled .ui-resizable-handle,
596
+ .ui-resizable-autohide .ui-resizable-handle {
597
+ display: none;
598
+ }
599
+ .ui-resizable-n {
600
+ cursor: n-resize;
601
+ height: 7px;
602
+ width: 100%;
603
+ top: -5px;
604
+ left: 0;
605
+ }
606
+ .ui-resizable-s {
607
+ cursor: s-resize;
608
+ height: 7px;
609
+ width: 100%;
610
+ bottom: -5px;
611
+ left: 0;
612
+ }
613
+ .ui-resizable-e {
614
+ cursor: e-resize;
615
+ width: 7px;
616
+ right: -5px;
617
+ top: 0;
618
+ height: 100%;
619
+ }
620
+ .ui-resizable-w {
621
+ cursor: w-resize;
622
+ width: 7px;
623
+ left: -5px;
624
+ top: 0;
625
+ height: 100%;
626
+ }
627
+ .ui-resizable-se {
628
+ cursor: se-resize;
629
+ width: 12px;
630
+ height: 12px;
631
+ right: 1px;
632
+ bottom: 1px;
633
+ }
634
+ .ui-resizable-sw {
635
+ cursor: sw-resize;
636
+ width: 9px;
637
+ height: 9px;
638
+ left: -5px;
639
+ bottom: -5px;
640
+ }
641
+ .ui-resizable-nw {
642
+ cursor: nw-resize;
643
+ width: 9px;
644
+ height: 9px;
645
+ left: -5px;
646
+ top: -5px;
647
+ }
648
+ .ui-resizable-ne {
649
+ cursor: ne-resize;
650
+ width: 9px;
651
+ height: 9px;
652
+ right: -5px;
653
+ top: -5px;
654
+ }
655
+ .ui-progressbar {
656
+ height: 2em;
657
+ text-align: left;
658
+ overflow: hidden;
659
+ }
660
+ .ui-progressbar .ui-progressbar-value {
661
+ margin: -1px;
662
+ height: 100%;
663
+ }
664
+ .ui-progressbar .ui-progressbar-overlay {
665
+ background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
666
+ height: 100%;
667
+ filter: alpha(opacity=25); /* support: IE8 */
668
+ opacity: 0.25;
669
+ }
670
+ .ui-progressbar-indeterminate .ui-progressbar-value {
671
+ background-image: none;
672
+ }
673
+ .ui-selectable {
674
+ -ms-touch-action: none;
675
+ touch-action: none;
676
+ }
677
+ .ui-selectable-helper {
678
+ position: absolute;
679
+ z-index: 100;
680
+ border: 1px dotted black;
681
+ }
682
+ .ui-selectmenu-menu {
683
+ padding: 0;
684
+ margin: 0;
685
+ position: absolute;
686
+ top: 0;
687
+ left: 0;
688
+ display: none;
689
+ }
690
+ .ui-selectmenu-menu .ui-menu {
691
+ overflow: auto;
692
+ overflow-x: hidden;
693
+ padding-bottom: 1px;
694
+ }
695
+ .ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
696
+ font-size: 1em;
697
+ font-weight: bold;
698
+ line-height: 1.5;
699
+ padding: 2px 0.4em;
700
+ margin: 0.5em 0 0 0;
701
+ height: auto;
702
+ border: 0;
703
+ }
704
+ .ui-selectmenu-open {
705
+ display: block;
706
+ }
707
+ .ui-selectmenu-text {
708
+ display: block;
709
+ margin-right: 20px;
710
+ overflow: hidden;
711
+ text-overflow: ellipsis;
712
+ }
713
+ .ui-selectmenu-button.ui-button {
714
+ text-align: left;
715
+ white-space: nowrap;
716
+ width: 14em;
717
+ }
718
+ .ui-selectmenu-icon.ui-icon {
719
+ float: right;
720
+ margin-top: 0;
721
+ }
722
+ .ui-slider {
723
+ position: relative;
724
+ text-align: left;
725
+ }
726
+ .ui-slider .ui-slider-handle {
727
+ position: absolute;
728
+ z-index: 2;
729
+ width: 1.2em;
730
+ height: 1.2em;
731
+ cursor: default;
732
+ -ms-touch-action: none;
733
+ touch-action: none;
734
+ }
735
+ .ui-slider .ui-slider-range {
736
+ position: absolute;
737
+ z-index: 1;
738
+ font-size: .7em;
739
+ display: block;
740
+ border: 0;
741
+ background-position: 0 0;
742
+ }
743
+
744
+ /* support: IE8 - See #6727 */
745
+ .ui-slider.ui-state-disabled .ui-slider-handle,
746
+ .ui-slider.ui-state-disabled .ui-slider-range {
747
+ filter: inherit;
748
+ }
749
+
750
+ .ui-slider-horizontal {
751
+ height: .8em;
752
+ }
753
+ .ui-slider-horizontal .ui-slider-handle {
754
+ top: -.3em;
755
+ margin-left: -.6em;
756
+ }
757
+ .ui-slider-horizontal .ui-slider-range {
758
+ top: 0;
759
+ height: 100%;
760
+ }
761
+ .ui-slider-horizontal .ui-slider-range-min {
762
+ left: 0;
763
+ }
764
+ .ui-slider-horizontal .ui-slider-range-max {
765
+ right: 0;
766
+ }
767
+
768
+ .ui-slider-vertical {
769
+ width: .8em;
770
+ height: 100px;
771
+ }
772
+ .ui-slider-vertical .ui-slider-handle {
773
+ left: -.3em;
774
+ margin-left: 0;
775
+ margin-bottom: -.6em;
776
+ }
777
+ .ui-slider-vertical .ui-slider-range {
778
+ left: 0;
779
+ width: 100%;
780
+ }
781
+ .ui-slider-vertical .ui-slider-range-min {
782
+ bottom: 0;
783
+ }
784
+ .ui-slider-vertical .ui-slider-range-max {
785
+ top: 0;
786
+ }
787
+ .ui-sortable-handle {
788
+ -ms-touch-action: none;
789
+ touch-action: none;
790
+ }
791
+ .ui-spinner {
792
+ position: relative;
793
+ display: inline-block;
794
+ overflow: hidden;
795
+ padding: 0;
796
+ vertical-align: middle;
797
+ }
798
+ .ui-spinner-input {
799
+ border: none;
800
+ background: none;
801
+ color: inherit;
802
+ padding: .222em 0;
803
+ margin: .2em 0;
804
+ vertical-align: middle;
805
+ margin-left: .4em;
806
+ margin-right: 2em;
807
+ }
808
+ .ui-spinner-button {
809
+ width: 1.6em;
810
+ height: 50%;
811
+ font-size: .5em;
812
+ padding: 0;
813
+ margin: 0;
814
+ text-align: center;
815
+ position: absolute;
816
+ cursor: default;
817
+ display: block;
818
+ overflow: hidden;
819
+ right: 0;
820
+ }
821
+ /* more specificity required here to override default borders */
822
+ .ui-spinner a.ui-spinner-button {
823
+ border-top-style: none;
824
+ border-bottom-style: none;
825
+ border-right-style: none;
826
+ }
827
+ .ui-spinner-up {
828
+ top: 0;
829
+ }
830
+ .ui-spinner-down {
831
+ bottom: 0;
832
+ }
833
+ .ui-tabs {
834
+ position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
835
+ padding: .2em;
836
+ }
837
+ .ui-tabs .ui-tabs-nav {
838
+ margin: 0;
839
+ padding: .2em .2em 0;
840
+ }
841
+ .ui-tabs .ui-tabs-nav li {
842
+ list-style: none;
843
+ float: left;
844
+ position: relative;
845
+ top: 0;
846
+ margin: 1px .2em 0 0;
847
+ border-bottom-width: 0;
848
+ padding: 0;
849
+ white-space: nowrap;
850
+ }
851
+ .ui-tabs .ui-tabs-nav .ui-tabs-anchor {
852
+ float: left;
853
+ padding: .5em 1em;
854
+ text-decoration: none;
855
+ }
856
+ .ui-tabs .ui-tabs-nav li.ui-tabs-active {
857
+ margin-bottom: -1px;
858
+ padding-bottom: 1px;
859
+ }
860
+ .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
861
+ .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
862
+ .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
863
+ cursor: text;
864
+ }
865
+ .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
866
+ cursor: pointer;
867
+ }
868
+ .ui-tabs .ui-tabs-panel {
869
+ display: block;
870
+ border-width: 0;
871
+ padding: 1em 1.4em;
872
+ background: none;
873
+ }
874
+ .ui-tooltip {
875
+ padding: 8px;
876
+ position: absolute;
877
+ z-index: 9999;
878
+ max-width: 300px;
879
+ }
880
+ body .ui-tooltip {
881
+ border-width: 2px;
882
+ }
883
+ /* Component containers
884
+ ----------------------------------*/
885
+ .ui-widget {
886
+ font-family: Arial,Helvetica,sans-serif;
887
+ font-size: 1em;
888
+ }
889
+ .ui-widget .ui-widget {
890
+ font-size: 1em;
891
+ }
892
+ .ui-widget input,
893
+ .ui-widget select,
894
+ .ui-widget textarea,
895
+ .ui-widget button {
896
+ font-family: Arial,Helvetica,sans-serif;
897
+ font-size: 1em;
898
+ }
899
+ .ui-widget.ui-widget-content {
900
+ border: 1px solid #c5c5c5;
901
+ }
902
+ .ui-widget-content {
903
+ border: 1px solid #dddddd;
904
+ background: #ffffff;
905
+ color: #333333;
906
+ }
907
+ .ui-widget-content a {
908
+ color: #333333;
909
+ }
910
+ .ui-widget-header {
911
+ border: 1px solid #dddddd;
912
+ background: #e9e9e9;
913
+ color: #333333;
914
+ font-weight: bold;
915
+ }
916
+ .ui-widget-header a {
917
+ color: #333333;
918
+ }
919
+
920
+ /* Interaction states
921
+ ----------------------------------*/
922
+ .ui-state-default,
923
+ .ui-widget-content .ui-state-default,
924
+ .ui-widget-header .ui-state-default,
925
+ .ui-button,
926
+
927
+ /* We use html here because we need a greater specificity to make sure disabled
928
+ works properly when clicked or hovered */
929
+ html .ui-button.ui-state-disabled:hover,
930
+ html .ui-button.ui-state-disabled:active {
931
+ border: 1px solid #c5c5c5;
932
+ background: #f6f6f6;
933
+ font-weight: normal;
934
+ color: #454545;
935
+ }
936
+ .ui-state-default a,
937
+ .ui-state-default a:link,
938
+ .ui-state-default a:visited,
939
+ a.ui-button,
940
+ a:link.ui-button,
941
+ a:visited.ui-button,
942
+ .ui-button {
943
+ color: #454545;
944
+ text-decoration: none;
945
+ }
946
+ .ui-state-hover,
947
+ .ui-widget-content .ui-state-hover,
948
+ .ui-widget-header .ui-state-hover,
949
+ .ui-state-focus,
950
+ .ui-widget-content .ui-state-focus,
951
+ .ui-widget-header .ui-state-focus,
952
+ .ui-button:hover,
953
+ .ui-button:focus {
954
+ border: 1px solid #cccccc;
955
+ background: #ededed;
956
+ font-weight: normal;
957
+ color: #2b2b2b;
958
+ }
959
+ .ui-state-hover a,
960
+ .ui-state-hover a:hover,
961
+ .ui-state-hover a:link,
962
+ .ui-state-hover a:visited,
963
+ .ui-state-focus a,
964
+ .ui-state-focus a:hover,
965
+ .ui-state-focus a:link,
966
+ .ui-state-focus a:visited,
967
+ a.ui-button:hover,
968
+ a.ui-button:focus {
969
+ color: #2b2b2b;
970
+ text-decoration: none;
971
+ }
972
+
973
+ .ui-visual-focus {
974
+ box-shadow: 0 0 3px 1px rgb(94, 158, 214);
975
+ }
976
+ .ui-state-active,
977
+ .ui-widget-content .ui-state-active,
978
+ .ui-widget-header .ui-state-active,
979
+ a.ui-button:active,
980
+ .ui-button:active,
981
+ .ui-button.ui-state-active:hover {
982
+ border: 1px solid #003eff;
983
+ background: #007fff;
984
+ font-weight: normal;
985
+ color: #ffffff;
986
+ }
987
+ .ui-icon-background,
988
+ .ui-state-active .ui-icon-background {
989
+ border: #003eff;
990
+ background-color: #ffffff;
991
+ }
992
+ .ui-state-active a,
993
+ .ui-state-active a:link,
994
+ .ui-state-active a:visited {
995
+ color: #ffffff;
996
+ text-decoration: none;
997
+ }
998
+
999
+ /* Interaction Cues
1000
+ ----------------------------------*/
1001
+ .ui-state-highlight,
1002
+ .ui-widget-content .ui-state-highlight,
1003
+ .ui-widget-header .ui-state-highlight {
1004
+ border: 1px solid #dad55e;
1005
+ background: #fffa90;
1006
+ color: #777620;
1007
+ }
1008
+ .ui-state-checked {
1009
+ border: 1px solid #dad55e;
1010
+ background: #fffa90;
1011
+ }
1012
+ .ui-state-highlight a,
1013
+ .ui-widget-content .ui-state-highlight a,
1014
+ .ui-widget-header .ui-state-highlight a {
1015
+ color: #777620;
1016
+ }
1017
+ .ui-state-error,
1018
+ .ui-widget-content .ui-state-error,
1019
+ .ui-widget-header .ui-state-error {
1020
+ border: 1px solid #f1a899;
1021
+ background: #fddfdf;
1022
+ color: #5f3f3f;
1023
+ }
1024
+ .ui-state-error a,
1025
+ .ui-widget-content .ui-state-error a,
1026
+ .ui-widget-header .ui-state-error a {
1027
+ color: #5f3f3f;
1028
+ }
1029
+ .ui-state-error-text,
1030
+ .ui-widget-content .ui-state-error-text,
1031
+ .ui-widget-header .ui-state-error-text {
1032
+ color: #5f3f3f;
1033
+ }
1034
+ .ui-priority-primary,
1035
+ .ui-widget-content .ui-priority-primary,
1036
+ .ui-widget-header .ui-priority-primary {
1037
+ font-weight: bold;
1038
+ }
1039
+ .ui-priority-secondary,
1040
+ .ui-widget-content .ui-priority-secondary,
1041
+ .ui-widget-header .ui-priority-secondary {
1042
+ opacity: .7;
1043
+ filter:Alpha(Opacity=70); /* support: IE8 */
1044
+ font-weight: normal;
1045
+ }
1046
+ .ui-state-disabled,
1047
+ .ui-widget-content .ui-state-disabled,
1048
+ .ui-widget-header .ui-state-disabled {
1049
+ opacity: .35;
1050
+ filter:Alpha(Opacity=35); /* support: IE8 */
1051
+ background-image: none;
1052
+ }
1053
+ .ui-state-disabled .ui-icon {
1054
+ filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
1055
+ }
1056
+
1057
+ /* Icons
1058
+ ----------------------------------*/
1059
+
1060
+ /* states and images */
1061
+ .ui-icon {
1062
+ width: 16px;
1063
+ height: 16px;
1064
+ }
1065
+ .ui-icon,
1066
+ .ui-widget-content .ui-icon {
1067
+ background-image: url("images/ui-icons_444444_256x240.png");
1068
+ }
1069
+ .ui-widget-header .ui-icon {
1070
+ background-image: url("images/ui-icons_444444_256x240.png");
1071
+ }
1072
+ .ui-state-hover .ui-icon,
1073
+ .ui-state-focus .ui-icon,
1074
+ .ui-button:hover .ui-icon,
1075
+ .ui-button:focus .ui-icon {
1076
+ background-image: url("images/ui-icons_555555_256x240.png");
1077
+ }
1078
+ .ui-state-active .ui-icon,
1079
+ .ui-button:active .ui-icon {
1080
+ background-image: url("images/ui-icons_ffffff_256x240.png");
1081
+ }
1082
+ .ui-state-highlight .ui-icon,
1083
+ .ui-button .ui-state-highlight.ui-icon {
1084
+ background-image: url("images/ui-icons_777620_256x240.png");
1085
+ }
1086
+ .ui-state-error .ui-icon,
1087
+ .ui-state-error-text .ui-icon {
1088
+ background-image: url("images/ui-icons_cc0000_256x240.png");
1089
+ }
1090
+ .ui-button .ui-icon {
1091
+ background-image: url("images/ui-icons_777777_256x240.png");
1092
+ }
1093
+
1094
+ /* positioning */
1095
+ .ui-icon-blank { background-position: 16px 16px; }
1096
+ .ui-icon-caret-1-n { background-position: 0 0; }
1097
+ .ui-icon-caret-1-ne { background-position: -16px 0; }
1098
+ .ui-icon-caret-1-e { background-position: -32px 0; }
1099
+ .ui-icon-caret-1-se { background-position: -48px 0; }
1100
+ .ui-icon-caret-1-s { background-position: -65px 0; }
1101
+ .ui-icon-caret-1-sw { background-position: -80px 0; }
1102
+ .ui-icon-caret-1-w { background-position: -96px 0; }
1103
+ .ui-icon-caret-1-nw { background-position: -112px 0; }
1104
+ .ui-icon-caret-2-n-s { background-position: -128px 0; }
1105
+ .ui-icon-caret-2-e-w { background-position: -144px 0; }
1106
+ .ui-icon-triangle-1-n { background-position: 0 -16px; }
1107
+ .ui-icon-triangle-1-ne { background-position: -16px -16px; }
1108
+ .ui-icon-triangle-1-e { background-position: -32px -16px; }
1109
+ .ui-icon-triangle-1-se { background-position: -48px -16px; }
1110
+ .ui-icon-triangle-1-s { background-position: -65px -16px; }
1111
+ .ui-icon-triangle-1-sw { background-position: -80px -16px; }
1112
+ .ui-icon-triangle-1-w { background-position: -96px -16px; }
1113
+ .ui-icon-triangle-1-nw { background-position: -112px -16px; }
1114
+ .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
1115
+ .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
1116
+ .ui-icon-arrow-1-n { background-position: 0 -32px; }
1117
+ .ui-icon-arrow-1-ne { background-position: -16px -32px; }
1118
+ .ui-icon-arrow-1-e { background-position: -32px -32px; }
1119
+ .ui-icon-arrow-1-se { background-position: -48px -32px; }
1120
+ .ui-icon-arrow-1-s { background-position: -65px -32px; }
1121
+ .ui-icon-arrow-1-sw { background-position: -80px -32px; }
1122
+ .ui-icon-arrow-1-w { background-position: -96px -32px; }
1123
+ .ui-icon-arrow-1-nw { background-position: -112px -32px; }
1124
+ .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
1125
+ .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
1126
+ .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
1127
+ .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
1128
+ .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
1129
+ .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
1130
+ .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
1131
+ .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
1132
+ .ui-icon-arrowthick-1-n { background-position: 1px -48px; }
1133
+ .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
1134
+ .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
1135
+ .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
1136
+ .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
1137
+ .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
1138
+ .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
1139
+ .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
1140
+ .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
1141
+ .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
1142
+ .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
1143
+ .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
1144
+ .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
1145
+ .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
1146
+ .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
1147
+ .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
1148
+ .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
1149
+ .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
1150
+ .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
1151
+ .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
1152
+ .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
1153
+ .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
1154
+ .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
1155
+ .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
1156
+ .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
1157
+ .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
1158
+ .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
1159
+ .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
1160
+ .ui-icon-arrow-4 { background-position: 0 -80px; }
1161
+ .ui-icon-arrow-4-diag { background-position: -16px -80px; }
1162
+ .ui-icon-extlink { background-position: -32px -80px; }
1163
+ .ui-icon-newwin { background-position: -48px -80px; }
1164
+ .ui-icon-refresh { background-position: -64px -80px; }
1165
+ .ui-icon-shuffle { background-position: -80px -80px; }
1166
+ .ui-icon-transfer-e-w { background-position: -96px -80px; }
1167
+ .ui-icon-transferthick-e-w { background-position: -112px -80px; }
1168
+ .ui-icon-folder-collapsed { background-position: 0 -96px; }
1169
+ .ui-icon-folder-open { background-position: -16px -96px; }
1170
+ .ui-icon-document { background-position: -32px -96px; }
1171
+ .ui-icon-document-b { background-position: -48px -96px; }
1172
+ .ui-icon-note { background-position: -64px -96px; }
1173
+ .ui-icon-mail-closed { background-position: -80px -96px; }
1174
+ .ui-icon-mail-open { background-position: -96px -96px; }
1175
+ .ui-icon-suitcase { background-position: -112px -96px; }
1176
+ .ui-icon-comment { background-position: -128px -96px; }
1177
+ .ui-icon-person { background-position: -144px -96px; }
1178
+ .ui-icon-print { background-position: -160px -96px; }
1179
+ .ui-icon-trash { background-position: -176px -96px; }
1180
+ .ui-icon-locked { background-position: -192px -96px; }
1181
+ .ui-icon-unlocked { background-position: -208px -96px; }
1182
+ .ui-icon-bookmark { background-position: -224px -96px; }
1183
+ .ui-icon-tag { background-position: -240px -96px; }
1184
+ .ui-icon-home { background-position: 0 -112px; }
1185
+ .ui-icon-flag { background-position: -16px -112px; }
1186
+ .ui-icon-calendar { background-position: -32px -112px; }
1187
+ .ui-icon-cart { background-position: -48px -112px; }
1188
+ .ui-icon-pencil { background-position: -64px -112px; }
1189
+ .ui-icon-clock { background-position: -80px -112px; }
1190
+ .ui-icon-disk { background-position: -96px -112px; }
1191
+ .ui-icon-calculator { background-position: -112px -112px; }
1192
+ .ui-icon-zoomin { background-position: -128px -112px; }
1193
+ .ui-icon-zoomout { background-position: -144px -112px; }
1194
+ .ui-icon-search { background-position: -160px -112px; }
1195
+ .ui-icon-wrench { background-position: -176px -112px; }
1196
+ .ui-icon-gear { background-position: -192px -112px; }
1197
+ .ui-icon-heart { background-position: -208px -112px; }
1198
+ .ui-icon-star { background-position: -224px -112px; }
1199
+ .ui-icon-link { background-position: -240px -112px; }
1200
+ .ui-icon-cancel { background-position: 0 -128px; }
1201
+ .ui-icon-plus { background-position: -16px -128px; }
1202
+ .ui-icon-plusthick { background-position: -32px -128px; }
1203
+ .ui-icon-minus { background-position: -48px -128px; }
1204
+ .ui-icon-minusthick { background-position: -64px -128px; }
1205
+ .ui-icon-close { background-position: -80px -128px; }
1206
+ .ui-icon-closethick { background-position: -96px -128px; }
1207
+ .ui-icon-key { background-position: -112px -128px; }
1208
+ .ui-icon-lightbulb { background-position: -128px -128px; }
1209
+ .ui-icon-scissors { background-position: -144px -128px; }
1210
+ .ui-icon-clipboard { background-position: -160px -128px; }
1211
+ .ui-icon-copy { background-position: -176px -128px; }
1212
+ .ui-icon-contact { background-position: -192px -128px; }
1213
+ .ui-icon-image { background-position: -208px -128px; }
1214
+ .ui-icon-video { background-position: -224px -128px; }
1215
+ .ui-icon-script { background-position: -240px -128px; }
1216
+ .ui-icon-alert { background-position: 0 -144px; }
1217
+ .ui-icon-info { background-position: -16px -144px; }
1218
+ .ui-icon-notice { background-position: -32px -144px; }
1219
+ .ui-icon-help { background-position: -48px -144px; }
1220
+ .ui-icon-check { background-position: -64px -144px; }
1221
+ .ui-icon-bullet { background-position: -80px -144px; }
1222
+ .ui-icon-radio-on { background-position: -96px -144px; }
1223
+ .ui-icon-radio-off { background-position: -112px -144px; }
1224
+ .ui-icon-pin-w { background-position: -128px -144px; }
1225
+ .ui-icon-pin-s { background-position: -144px -144px; }
1226
+ .ui-icon-play { background-position: 0 -160px; }
1227
+ .ui-icon-pause { background-position: -16px -160px; }
1228
+ .ui-icon-seek-next { background-position: -32px -160px; }
1229
+ .ui-icon-seek-prev { background-position: -48px -160px; }
1230
+ .ui-icon-seek-end { background-position: -64px -160px; }
1231
+ .ui-icon-seek-start { background-position: -80px -160px; }
1232
+ /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
1233
+ .ui-icon-seek-first { background-position: -80px -160px; }
1234
+ .ui-icon-stop { background-position: -96px -160px; }
1235
+ .ui-icon-eject { background-position: -112px -160px; }
1236
+ .ui-icon-volume-off { background-position: -128px -160px; }
1237
+ .ui-icon-volume-on { background-position: -144px -160px; }
1238
+ .ui-icon-power { background-position: 0 -176px; }
1239
+ .ui-icon-signal-diag { background-position: -16px -176px; }
1240
+ .ui-icon-signal { background-position: -32px -176px; }
1241
+ .ui-icon-battery-0 { background-position: -48px -176px; }
1242
+ .ui-icon-battery-1 { background-position: -64px -176px; }
1243
+ .ui-icon-battery-2 { background-position: -80px -176px; }
1244
+ .ui-icon-battery-3 { background-position: -96px -176px; }
1245
+ .ui-icon-circle-plus { background-position: 0 -192px; }
1246
+ .ui-icon-circle-minus { background-position: -16px -192px; }
1247
+ .ui-icon-circle-close { background-position: -32px -192px; }
1248
+ .ui-icon-circle-triangle-e { background-position: -48px -192px; }
1249
+ .ui-icon-circle-triangle-s { background-position: -64px -192px; }
1250
+ .ui-icon-circle-triangle-w { background-position: -80px -192px; }
1251
+ .ui-icon-circle-triangle-n { background-position: -96px -192px; }
1252
+ .ui-icon-circle-arrow-e { background-position: -112px -192px; }
1253
+ .ui-icon-circle-arrow-s { background-position: -128px -192px; }
1254
+ .ui-icon-circle-arrow-w { background-position: -144px -192px; }
1255
+ .ui-icon-circle-arrow-n { background-position: -160px -192px; }
1256
+ .ui-icon-circle-zoomin { background-position: -176px -192px; }
1257
+ .ui-icon-circle-zoomout { background-position: -192px -192px; }
1258
+ .ui-icon-circle-check { background-position: -208px -192px; }
1259
+ .ui-icon-circlesmall-plus { background-position: 0 -208px; }
1260
+ .ui-icon-circlesmall-minus { background-position: -16px -208px; }
1261
+ .ui-icon-circlesmall-close { background-position: -32px -208px; }
1262
+ .ui-icon-squaresmall-plus { background-position: -48px -208px; }
1263
+ .ui-icon-squaresmall-minus { background-position: -64px -208px; }
1264
+ .ui-icon-squaresmall-close { background-position: -80px -208px; }
1265
+ .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
1266
+ .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
1267
+ .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
1268
+ .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
1269
+ .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
1270
+ .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
1271
+
1272
+
1273
+ /* Misc visuals
1274
+ ----------------------------------*/
1275
+
1276
+ /* Corner radius */
1277
+ .ui-corner-all,
1278
+ .ui-corner-top,
1279
+ .ui-corner-left,
1280
+ .ui-corner-tl {
1281
+ border-top-left-radius: 3px;
1282
+ }
1283
+ .ui-corner-all,
1284
+ .ui-corner-top,
1285
+ .ui-corner-right,
1286
+ .ui-corner-tr {
1287
+ border-top-right-radius: 3px;
1288
+ }
1289
+ .ui-corner-all,
1290
+ .ui-corner-bottom,
1291
+ .ui-corner-left,
1292
+ .ui-corner-bl {
1293
+ border-bottom-left-radius: 3px;
1294
+ }
1295
+ .ui-corner-all,
1296
+ .ui-corner-bottom,
1297
+ .ui-corner-right,
1298
+ .ui-corner-br {
1299
+ border-bottom-right-radius: 3px;
1300
+ }
1301
+
1302
+ /* Overlays */
1303
+ .ui-widget-overlay {
1304
+ background: #aaaaaa;
1305
+ opacity: .3;
1306
+ filter: Alpha(Opacity=30); /* support: IE8 */
1307
+ }
1308
+ .ui-widget-shadow {
1309
+ -webkit-box-shadow: 0px 0px 5px #666666;
1310
+ box-shadow: 0px 0px 5px #666666;
1311
+ }
admin/css/select2.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
admin/images/bg1.png ADDED
Binary file
admin/images/bg2.jpg ADDED
Binary file
admin/images/bg3.png ADDED
Binary file
{images → admin/images}/email-marketing-mastery.png RENAMED
File without changes
{images → admin/images}/envelope.png RENAMED
File without changes
{images → admin/images}/es-esaf-integration.png RENAMED
File without changes
{images → admin/images}/es-ig-integration.png RENAMED
File without changes
{images → admin/images}/es-logo-128x128.png RENAMED
File without changes
{images → admin/images}/es-logo-64x64.png RENAMED
File without changes
{images → admin/images}/es-rm-integration.png RENAMED
File without changes
admin/js/email-subscribers-admin.js ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function ($) {
2
+
3
+ $(document).ready(
4
+ function () {
5
+ $(document).on('change', '.es_visible', function() {
6
+ if($('.es_visible:checked').length >= 1){
7
+ $('.es_required').prop('disabled', false);
8
+ }else{
9
+ $('.es_required').prop('disabled', true);
10
+ }
11
+ });
12
+ $('.es_visible').change();
13
+
14
+ $('#tabs').tabs().addClass('ui-tabs-vertical ui-helper-clearfix');
15
+
16
+ var defaultHeight = $('div#tabs div#menu-tab-content div#tabs-1').height() + 30;
17
+ $('div#tabs div#menu-tab-listing ul').height(defaultHeight);
18
+
19
+ // Set Tab Height
20
+ $('.ui-tabs-anchor').click(function () {
21
+ var tab = $(this).attr('href');
22
+ var tabHight = $('div#tabs div#menu-tab-content div' + tab).height() + 30;
23
+ $('div#tabs div#menu-tab-listing ul').height(tabHight);
24
+ });
25
+
26
+ if (jQuery('.statusesselect').length) {
27
+ var statusselect = jQuery('.statusesselect')[0].outerHTML;
28
+ }
29
+
30
+ if (jQuery('.groupsselect').length) {
31
+ var groupselect = jQuery('.groupsselect')[0].outerHTML;
32
+ }
33
+
34
+ jQuery(".es-audience-view .bulkactions #bulk-action-selector-top").after(statusselect);
35
+ jQuery(".es-audience-view .bulkactions #bulk-action-selector-top").after(groupselect);
36
+
37
+ //jQuery(".es-audience-view .bulkactions #bulk-action-selector-bottom").after(statusselect);
38
+ // jQuery(".es-audience-view .bulkactions #bulk-action-selector-bottom").after(groupselect);
39
+
40
+ jQuery("#bulk-action-selector-top").change(function () {
41
+ if (jQuery('option:selected', this).attr('value') == 'bulk_list_update') {
42
+ jQuery('.groupsselect').eq(1).show();
43
+ jQuery('.statusesselect').eq(1).hide();
44
+ } else if (jQuery('option:selected', this).attr('value') == 'bulk_status_update') {
45
+ jQuery('.statusesselect').eq(1).show();
46
+ jQuery('.groupsselect').eq(1).hide();
47
+ } else {
48
+ jQuery('.statusesselect').hide();
49
+ jQuery('.groupsselect').hide();
50
+ }
51
+ });
52
+
53
+ jQuery('.es-audience-view .tablenav.bottom #bulk-action-selector-bottom').hide();
54
+ jQuery('.es-audience-view .tablenav.bottom #doaction2').hide();
55
+ jQuery(document).on( 'change', "#base_template_id", function(){
56
+ var img = jQuery('option:selected', this).data('img')
57
+ jQuery('.es-templ-img').html(img);
58
+ });
59
+
60
+ var removeSubmenu = [ 'ig-es-broadcast', 'ig-es-lists', 'ig-es-post-notifications' ];
61
+ $.each(removeSubmenu, function(key, id) {
62
+ $("#" + id).parent('a').parent('li').hide();
63
+ });
64
+ });
65
+
66
+
67
+ // Get the element with id="defaultOpen" and click on it
68
+
69
+
70
+ })(jQuery);
71
+
72
+ function checkDelete() {
73
+ return confirm('Are you sure?');
74
+ }
admin/js/jquery-1.12.4.js ADDED
@@ -0,0 +1,11008 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery JavaScript Library v1.12.4
3
+ * http://jquery.com/
4
+ *
5
+ * Includes Sizzle.js
6
+ * http://sizzlejs.com/
7
+ *
8
+ * Copyright jQuery Foundation and other contributors
9
+ * Released under the MIT license
10
+ * http://jquery.org/license
11
+ *
12
+ * Date: 2016-05-20T17:17Z
13
+ */
14
+
15
+ (function( global, factory ) {
16
+
17
+ if ( typeof module === "object" && typeof module.exports === "object" ) {
18
+ // For CommonJS and CommonJS-like environments where a proper `window`
19
+ // is present, execute the factory and get jQuery.
20
+ // For environments that do not have a `window` with a `document`
21
+ // (such as Node.js), expose a factory as module.exports.
22
+ // This accentuates the need for the creation of a real `window`.
23
+ // e.g. var jQuery = require("jquery")(window);
24
+ // See ticket #14549 for more info.
25
+ module.exports = global.document ?
26
+ factory( global, true ) :
27
+ function( w ) {
28
+ if ( !w.document ) {
29
+ throw new Error( "jQuery requires a window with a document" );
30
+ }
31
+ return factory( w );
32
+ };
33
+ } else {
34
+ factory( global );
35
+ }
36
+
37
+ // Pass this if window is not defined yet
38
+ }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
39
+
40
+ // Support: Firefox 18+
41
+ // Can't be in strict mode, several libs including ASP.NET trace
42
+ // the stack via arguments.caller.callee and Firefox dies if
43
+ // you try to trace through "use strict" call chains. (#13335)
44
+ //"use strict";
45
+ var deletedIds = [];
46
+
47
+ var document = window.document;
48
+
49
+ var slice = deletedIds.slice;
50
+
51
+ var concat = deletedIds.concat;
52
+
53
+ var push = deletedIds.push;
54
+
55
+ var indexOf = deletedIds.indexOf;
56
+
57
+ var class2type = {};
58
+
59
+ var toString = class2type.toString;
60
+
61
+ var hasOwn = class2type.hasOwnProperty;
62
+
63
+ var support = {};
64
+
65
+
66
+
67
+ var
68
+ version = "1.12.4",
69
+
70
+ // Define a local copy of jQuery
71
+ jQuery = function( selector, context ) {
72
+
73
+ // The jQuery object is actually just the init constructor 'enhanced'
74
+ // Need init if jQuery is called (just allow error to be thrown if not included)
75
+ return new jQuery.fn.init( selector, context );
76
+ },
77
+
78
+ // Support: Android<4.1, IE<9
79
+ // Make sure we trim BOM and NBSP
80
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
81
+
82
+ // Matches dashed string for camelizing
83
+ rmsPrefix = /^-ms-/,
84
+ rdashAlpha = /-([\da-z])/gi,
85
+
86
+ // Used by jQuery.camelCase as callback to replace()
87
+ fcamelCase = function( all, letter ) {
88
+ return letter.toUpperCase();
89
+ };
90
+
91
+ jQuery.fn = jQuery.prototype = {
92
+
93
+ // The current version of jQuery being used
94
+ jquery: version,
95
+
96
+ constructor: jQuery,
97
+
98
+ // Start with an empty selector
99
+ selector: "",
100
+
101
+ // The default length of a jQuery object is 0
102
+ length: 0,
103
+
104
+ toArray: function() {
105
+ return slice.call( this );
106
+ },
107
+
108
+ // Get the Nth element in the matched element set OR
109
+ // Get the whole matched element set as a clean array
110
+ get: function( num ) {
111
+ return num != null ?
112
+
113
+ // Return just the one element from the set
114
+ ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
115
+
116
+ // Return all the elements in a clean array
117
+ slice.call( this );
118
+ },
119
+
120
+ // Take an array of elements and push it onto the stack
121
+ // (returning the new matched element set)
122
+ pushStack: function( elems ) {
123
+
124
+ // Build a new jQuery matched element set
125
+ var ret = jQuery.merge( this.constructor(), elems );
126
+
127
+ // Add the old object onto the stack (as a reference)
128
+ ret.prevObject = this;
129
+ ret.context = this.context;
130
+
131
+ // Return the newly-formed element set
132
+ return ret;
133
+ },
134
+
135
+ // Execute a callback for every element in the matched set.
136
+ each: function( callback ) {
137
+ return jQuery.each( this, callback );
138
+ },
139
+
140
+ map: function( callback ) {
141
+ return this.pushStack( jQuery.map( this, function( elem, i ) {
142
+ return callback.call( elem, i, elem );
143
+ } ) );
144
+ },
145
+
146
+ slice: function() {
147
+ return this.pushStack( slice.apply( this, arguments ) );
148
+ },
149
+
150
+ first: function() {
151
+ return this.eq( 0 );
152
+ },
153
+
154
+ last: function() {
155
+ return this.eq( -1 );
156
+ },
157
+
158
+ eq: function( i ) {
159
+ var len = this.length,
160
+ j = +i + ( i < 0 ? len : 0 );
161
+ return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
162
+ },
163
+
164
+ end: function() {
165
+ return this.prevObject || this.constructor();
166
+ },
167
+
168
+ // For internal use only.
169
+ // Behaves like an Array's method, not like a jQuery method.
170
+ push: push,
171
+ sort: deletedIds.sort,
172
+ splice: deletedIds.splice
173
+ };
174
+
175
+ jQuery.extend = jQuery.fn.extend = function() {
176
+ var src, copyIsArray, copy, name, options, clone,
177
+ target = arguments[ 0 ] || {},
178
+ i = 1,
179
+ length = arguments.length,
180
+ deep = false;
181
+
182
+ // Handle a deep copy situation
183
+ if ( typeof target === "boolean" ) {
184
+ deep = target;
185
+
186
+ // skip the boolean and the target
187
+ target = arguments[ i ] || {};
188
+ i++;
189
+ }
190
+
191
+ // Handle case when target is a string or something (possible in deep copy)
192
+ if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
193
+ target = {};
194
+ }
195
+
196
+ // extend jQuery itself if only one argument is passed
197
+ if ( i === length ) {
198
+ target = this;
199
+ i--;
200
+ }
201
+
202
+ for ( ; i < length; i++ ) {
203
+
204
+ // Only deal with non-null/undefined values
205
+ if ( ( options = arguments[ i ] ) != null ) {
206
+
207
+ // Extend the base object
208
+ for ( name in options ) {
209
+ src = target[ name ];
210
+ copy = options[ name ];
211
+
212
+ // Prevent never-ending loop
213
+ if ( target === copy ) {
214
+ continue;
215
+ }
216
+
217
+ // Recurse if we're merging plain objects or arrays
218
+ if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
219
+ ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
220
+
221
+ if ( copyIsArray ) {
222
+ copyIsArray = false;
223
+ clone = src && jQuery.isArray( src ) ? src : [];
224
+
225
+ } else {
226
+ clone = src && jQuery.isPlainObject( src ) ? src : {};
227
+ }
228
+
229
+ // Never move original objects, clone them
230
+ target[ name ] = jQuery.extend( deep, clone, copy );
231
+
232
+ // Don't bring in undefined values
233
+ } else if ( copy !== undefined ) {
234
+ target[ name ] = copy;
235
+ }
236
+ }
237
+ }
238
+ }
239
+
240
+ // Return the modified object
241
+ return target;
242
+ };
243
+
244
+ jQuery.extend( {
245
+
246
+ // Unique for each copy of jQuery on the page
247
+ expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
248
+
249
+ // Assume jQuery is ready without the ready module
250
+ isReady: true,
251
+
252
+ error: function( msg ) {
253
+ throw new Error( msg );
254
+ },
255
+
256
+ noop: function() {},
257
+
258
+ // See test/unit/core.js for details concerning isFunction.
259
+ // Since version 1.3, DOM methods and functions like alert
260
+ // aren't supported. They return false on IE (#2968).
261
+ isFunction: function( obj ) {
262
+ return jQuery.type( obj ) === "function";
263
+ },
264
+
265
+ isArray: Array.isArray || function( obj ) {
266
+ return jQuery.type( obj ) === "array";
267
+ },
268
+
269
+ isWindow: function( obj ) {
270
+ /* jshint eqeqeq: false */
271
+ return obj != null && obj == obj.window;
272
+ },
273
+
274
+ isNumeric: function( obj ) {
275
+
276
+ // parseFloat NaNs numeric-cast false positives (null|true|false|"")
277
+ // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
278
+ // subtraction forces infinities to NaN
279
+ // adding 1 corrects loss of precision from parseFloat (#15100)
280
+ var realStringObj = obj && obj.toString();
281
+ return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
282
+ },
283
+
284
+ isEmptyObject: function( obj ) {
285
+ var name;
286
+ for ( name in obj ) {
287
+ return false;
288
+ }
289
+ return true;
290
+ },
291
+
292
+ isPlainObject: function( obj ) {
293
+ var key;
294
+
295
+ // Must be an Object.
296
+ // Because of IE, we also have to check the presence of the constructor property.
297
+ // Make sure that DOM nodes and window objects don't pass through, as well
298
+ if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
299
+ return false;
300
+ }
301
+
302
+ try {
303
+
304
+ // Not own constructor property must be Object
305
+ if ( obj.constructor &&
306
+ !hasOwn.call( obj, "constructor" ) &&
307
+ !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
308
+ return false;
309
+ }
310
+ } catch ( e ) {
311
+
312
+ // IE8,9 Will throw exceptions on certain host objects #9897
313
+ return false;
314
+ }
315
+
316
+ // Support: IE<9
317
+ // Handle iteration over inherited properties before own properties.
318
+ if ( !support.ownFirst ) {
319
+ for ( key in obj ) {
320
+ return hasOwn.call( obj, key );
321
+ }
322
+ }
323
+
324
+ // Own properties are enumerated firstly, so to speed up,
325
+ // if last one is own, then all properties are own.
326
+ for ( key in obj ) {}
327
+
328
+ return key === undefined || hasOwn.call( obj, key );
329
+ },
330
+
331
+ type: function( obj ) {
332
+ if ( obj == null ) {
333
+ return obj + "";
334
+ }
335
+ return typeof obj === "object" || typeof obj === "function" ?
336
+ class2type[ toString.call( obj ) ] || "object" :
337
+ typeof obj;
338
+ },
339
+
340
+ // Workarounds based on findings by Jim Driscoll
341
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
342
+ globalEval: function( data ) {
343
+ if ( data && jQuery.trim( data ) ) {
344
+
345
+ // We use execScript on Internet Explorer
346
+ // We use an anonymous function so that context is window
347
+ // rather than jQuery in Firefox
348
+ ( window.execScript || function( data ) {
349
+ window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
350
+ } )( data );
351
+ }
352
+ },
353
+
354
+ // Convert dashed to camelCase; used by the css and data modules
355
+ // Microsoft forgot to hump their vendor prefix (#9572)
356
+ camelCase: function( string ) {
357
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
358
+ },
359
+
360
+ nodeName: function( elem, name ) {
361
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
362
+ },
363
+
364
+ each: function( obj, callback ) {
365
+ var length, i = 0;
366
+
367
+ if ( isArrayLike( obj ) ) {
368
+ length = obj.length;
369
+ for ( ; i < length; i++ ) {
370
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
371
+ break;
372
+ }
373
+ }
374
+ } else {
375
+ for ( i in obj ) {
376
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
377
+ break;
378
+ }
379
+ }
380
+ }
381
+
382
+ return obj;
383
+ },
384
+
385
+ // Support: Android<4.1, IE<9
386
+ trim: function( text ) {
387
+ return text == null ?
388
+ "" :
389
+ ( text + "" ).replace( rtrim, "" );
390
+ },
391
+
392
+ // results is for internal usage only
393
+ makeArray: function( arr, results ) {
394
+ var ret = results || [];
395
+
396
+ if ( arr != null ) {
397
+ if ( isArrayLike( Object( arr ) ) ) {
398
+ jQuery.merge( ret,
399
+ typeof arr === "string" ?
400
+ [ arr ] : arr
401
+ );
402
+ } else {
403
+ push.call( ret, arr );
404
+ }
405
+ }
406
+
407
+ return ret;
408
+ },
409
+
410
+ inArray: function( elem, arr, i ) {
411
+ var len;
412
+
413
+ if ( arr ) {
414
+ if ( indexOf ) {
415
+ return indexOf.call( arr, elem, i );
416
+ }
417
+
418
+ len = arr.length;
419
+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
420
+
421
+ for ( ; i < len; i++ ) {
422
+
423
+ // Skip accessing in sparse arrays
424
+ if ( i in arr && arr[ i ] === elem ) {
425
+ return i;
426
+ }
427
+ }
428
+ }
429
+
430
+ return -1;
431
+ },
432
+
433
+ merge: function( first, second ) {
434
+ var len = +second.length,
435
+ j = 0,
436
+ i = first.length;
437
+
438
+ while ( j < len ) {
439
+ first[ i++ ] = second[ j++ ];
440
+ }
441
+
442
+ // Support: IE<9
443
+ // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
444
+ if ( len !== len ) {
445
+ while ( second[ j ] !== undefined ) {
446
+ first[ i++ ] = second[ j++ ];
447
+ }
448
+ }
449
+
450
+ first.length = i;
451
+
452
+ return first;
453
+ },
454
+
455
+ grep: function( elems, callback, invert ) {
456
+ var callbackInverse,
457
+ matches = [],
458
+ i = 0,
459
+ length = elems.length,
460
+ callbackExpect = !invert;
461
+
462
+ // Go through the array, only saving the items
463
+ // that pass the validator function
464
+ for ( ; i < length; i++ ) {
465
+ callbackInverse = !callback( elems[ i ], i );
466
+ if ( callbackInverse !== callbackExpect ) {
467
+ matches.push( elems[ i ] );
468
+ }
469
+ }
470
+
471
+ return matches;
472
+ },
473
+
474
+ // arg is for internal usage only
475
+ map: function( elems, callback, arg ) {
476
+ var length, value,
477
+ i = 0,
478
+ ret = [];
479
+
480
+ // Go through the array, translating each of the items to their new values
481
+ if ( isArrayLike( elems ) ) {
482
+ length = elems.length;
483
+ for ( ; i < length; i++ ) {
484
+ value = callback( elems[ i ], i, arg );
485
+
486
+ if ( value != null ) {
487
+ ret.push( value );
488
+ }
489
+ }
490
+
491
+ // Go through every key on the object,
492
+ } else {
493
+ for ( i in elems ) {
494
+ value = callback( elems[ i ], i, arg );
495
+
496
+ if ( value != null ) {
497
+ ret.push( value );
498
+ }
499
+ }
500
+ }
501
+
502
+ // Flatten any nested arrays
503
+ return concat.apply( [], ret );
504
+ },
505
+
506
+ // A global GUID counter for objects
507
+ guid: 1,
508
+
509
+ // Bind a function to a context, optionally partially applying any
510
+ // arguments.
511
+ proxy: function( fn, context ) {
512
+ var args, proxy, tmp;
513
+
514
+ if ( typeof context === "string" ) {
515
+ tmp = fn[ context ];
516
+ context = fn;
517
+ fn = tmp;
518
+ }
519
+
520
+ // Quick check to determine if target is callable, in the spec
521
+ // this throws a TypeError, but we will just return undefined.
522
+ if ( !jQuery.isFunction( fn ) ) {
523
+ return undefined;
524
+ }
525
+
526
+ // Simulated bind
527
+ args = slice.call( arguments, 2 );
528
+ proxy = function() {
529
+ return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
530
+ };
531
+
532
+ // Set the guid of unique handler to the same of original handler, so it can be removed
533
+ proxy.guid = fn.guid = fn.guid || jQuery.guid++;
534
+
535
+ return proxy;
536
+ },
537
+
538
+ now: function() {
539
+ return +( new Date() );
540
+ },
541
+
542
+ // jQuery.support is not used in Core but other projects attach their
543
+ // properties to it so it needs to exist.
544
+ support: support
545
+ } );
546
+
547
+ // JSHint would error on this code due to the Symbol not being defined in ES5.
548
+ // Defining this global in .jshintrc would create a danger of using the global
549
+ // unguarded in another place, it seems safer to just disable JSHint for these
550
+ // three lines.
551
+ /* jshint ignore: start */
552
+ if ( typeof Symbol === "function" ) {
553
+ jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ];
554
+ }
555
+ /* jshint ignore: end */
556
+
557
+ // Populate the class2type map
558
+ jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
559
+ function( i, name ) {
560
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
561
+ } );
562
+
563
+ function isArrayLike( obj ) {
564
+
565
+ // Support: iOS 8.2 (not reproducible in simulator)
566
+ // `in` check used to prevent JIT error (gh-2145)
567
+ // hasOwn isn't used here due to false negatives
568
+ // regarding Nodelist length in IE
569
+ var length = !!obj && "length" in obj && obj.length,
570
+ type = jQuery.type( obj );
571
+
572
+ if ( type === "function" || jQuery.isWindow( obj ) ) {
573
+ return false;
574
+ }
575
+
576
+ return type === "array" || length === 0 ||
577
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj;
578
+ }
579
+ var Sizzle =
580
+ /*!
581
+ * Sizzle CSS Selector Engine v2.2.1
582
+ * http://sizzlejs.com/
583
+ *
584
+ * Copyright jQuery Foundation and other contributors
585
+ * Released under the MIT license
586
+ * http://jquery.org/license
587
+ *
588
+ * Date: 2015-10-17
589
+ */
590
+ (function( window ) {
591
+
592
+ var i,
593
+ support,
594
+ Expr,
595
+ getText,
596
+ isXML,
597
+ tokenize,
598
+ compile,
599
+ select,
600
+ outermostContext,
601
+ sortInput,
602
+ hasDuplicate,
603
+
604
+ // Local document vars
605
+ setDocument,
606
+ document,
607
+ docElem,
608
+ documentIsHTML,
609
+ rbuggyQSA,
610
+ rbuggyMatches,
611
+ matches,
612
+ contains,
613
+
614
+ // Instance-specific data
615
+ expando = "sizzle" + 1 * new Date(),
616
+ preferredDoc = window.document,
617
+ dirruns = 0,
618
+ done = 0,
619
+ classCache = createCache(),
620
+ tokenCache = createCache(),
621
+ compilerCache = createCache(),
622
+ sortOrder = function( a, b ) {
623
+ if ( a === b ) {
624
+ hasDuplicate = true;
625
+ }
626
+ return 0;
627
+ },
628
+
629
+ // General-purpose constants
630
+ MAX_NEGATIVE = 1 << 31,
631
+
632
+ // Instance methods
633
+ hasOwn = ({}).hasOwnProperty,
634
+ arr = [],
635
+ pop = arr.pop,
636
+ push_native = arr.push,
637
+ push = arr.push,
638
+ slice = arr.slice,
639
+ // Use a stripped-down indexOf as it's faster than native
640
+ // http://jsperf.com/thor-indexof-vs-for/5
641
+ indexOf = function( list, elem ) {
642
+ var i = 0,
643
+ len = list.length;
644
+ for ( ; i < len; i++ ) {
645
+ if ( list[i] === elem ) {
646
+ return i;
647
+ }
648
+ }
649
+ return -1;
650
+ },
651
+
652
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
653
+
654
+ // Regular expressions
655
+
656
+ // http://www.w3.org/TR/css3-selectors/#whitespace
657
+ whitespace = "[\\x20\\t\\r\\n\\f]",
658
+
659
+ // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
660
+ identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
661
+
662
+ // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
663
+ attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
664
+ // Operator (capture 2)
665
+ "*([*^$|!~]?=)" + whitespace +
666
+ // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
667
+ "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
668
+ "*\\]",
669
+
670
+ pseudos = ":(" + identifier + ")(?:\\((" +
671
+ // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
672
+ // 1. quoted (capture 3; capture 4 or capture 5)
673
+ "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
674
+ // 2. simple (capture 6)
675
+ "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
676
+ // 3. anything else (capture 2)
677
+ ".*" +
678
+ ")\\)|)",
679
+
680
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
681
+ rwhitespace = new RegExp( whitespace + "+", "g" ),
682
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
683
+
684
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
685
+ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
686
+
687
+ rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
688
+
689
+ rpseudo = new RegExp( pseudos ),
690
+ ridentifier = new RegExp( "^" + identifier + "$" ),
691
+
692
+ matchExpr = {
693
+ "ID": new RegExp( "^#(" + identifier + ")" ),
694
+ "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
695
+ "TAG": new RegExp( "^(" + identifier + "|[*])" ),
696
+ "ATTR": new RegExp( "^" + attributes ),
697
+ "PSEUDO": new RegExp( "^" + pseudos ),
698
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
699
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
700
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
701
+ "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
702
+ // For use in libraries implementing .is()
703
+ // We use this for POS matching in `select`
704
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
705
+ whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
706
+ },
707
+
708
+ rinputs = /^(?:input|select|textarea|button)$/i,
709
+ rheader = /^h\d$/i,
710
+
711
+ rnative = /^[^{]+\{\s*\[native \w/,
712
+
713
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
714
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
715
+
716
+ rsibling = /[+~]/,
717
+ rescape = /'|\\/g,
718
+
719
+ // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
720
+ runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
721
+ funescape = function( _, escaped, escapedWhitespace ) {
722
+ var high = "0x" + escaped - 0x10000;
723
+ // NaN means non-codepoint
724
+ // Support: Firefox<24
725
+ // Workaround erroneous numeric interpretation of +"0x"
726
+ return high !== high || escapedWhitespace ?
727
+ escaped :
728
+ high < 0 ?
729
+ // BMP codepoint
730
+ String.fromCharCode( high + 0x10000 ) :
731
+ // Supplemental Plane codepoint (surrogate pair)
732
+ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
733
+ },
734
+
735
+ // Used for iframes
736
+ // See setDocument()
737
+ // Removing the function wrapper causes a "Permission Denied"
738
+ // error in IE
739
+ unloadHandler = function() {
740
+ setDocument();
741
+ };
742
+
743
+ // Optimize for push.apply( _, NodeList )
744
+ try {
745
+ push.apply(
746
+ (arr = slice.call( preferredDoc.childNodes )),
747
+ preferredDoc.childNodes
748
+ );
749
+ // Support: Android<4.0
750
+ // Detect silently failing push.apply
751
+ arr[ preferredDoc.childNodes.length ].nodeType;
752
+ } catch ( e ) {
753
+ push = { apply: arr.length ?
754
+
755
+ // Leverage slice if possible
756
+ function( target, els ) {
757
+ push_native.apply( target, slice.call(els) );
758
+ } :
759
+
760
+ // Support: IE<9
761
+ // Otherwise append directly
762
+ function( target, els ) {
763
+ var j = target.length,
764
+ i = 0;
765
+ // Can't trust NodeList.length
766
+ while ( (target[j++] = els[i++]) ) {}
767
+ target.length = j - 1;
768
+ }
769
+ };
770
+ }
771
+
772
+ function Sizzle( selector, context, results, seed ) {
773
+ var m, i, elem, nid, nidselect, match, groups, newSelector,
774
+ newContext = context && context.ownerDocument,
775
+
776
+ // nodeType defaults to 9, since context defaults to document
777
+ nodeType = context ? context.nodeType : 9;
778
+
779
+ results = results || [];
780
+
781
+ // Return early from calls with invalid selector or context
782
+ if ( typeof selector !== "string" || !selector ||
783
+ nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
784
+
785
+ return results;
786
+ }
787
+
788
+ // Try to shortcut find operations (as opposed to filters) in HTML documents
789
+ if ( !seed ) {
790
+
791
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
792
+ setDocument( context );
793
+ }
794
+ context = context || document;
795
+
796
+ if ( documentIsHTML ) {
797
+
798
+ // If the selector is sufficiently simple, try using a "get*By*" DOM method
799
+ // (excepting DocumentFragment context, where the methods don't exist)
800
+ if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
801
+
802
+ // ID selector
803
+ if ( (m = match[1]) ) {
804
+
805
+ // Document context
806
+ if ( nodeType === 9 ) {
807
+ if ( (elem = context.getElementById( m )) ) {
808
+
809
+ // Support: IE, Opera, Webkit
810
+ // TODO: identify versions
811
+ // getElementById can match elements by name instead of ID
812
+ if ( elem.id === m ) {
813
+ results.push( elem );
814
+ return results;
815
+ }
816
+ } else {
817
+ return results;
818
+ }
819
+
820
+ // Element context
821
+ } else {
822
+
823
+ // Support: IE, Opera, Webkit
824
+ // TODO: identify versions
825
+ // getElementById can match elements by name instead of ID
826
+ if ( newContext && (elem = newContext.getElementById( m )) &&
827
+ contains( context, elem ) &&
828
+ elem.id === m ) {
829
+
830
+ results.push( elem );
831
+ return results;
832
+ }
833
+ }
834
+
835
+ // Type selector
836
+ } else if ( match[2] ) {
837
+ push.apply( results, context.getElementsByTagName( selector ) );
838
+ return results;
839
+
840
+ // Class selector
841
+ } else if ( (m = match[3]) && support.getElementsByClassName &&
842
+ context.getElementsByClassName ) {
843
+
844
+ push.apply( results, context.getElementsByClassName( m ) );
845
+ return results;
846
+ }
847
+ }
848
+
849
+ // Take advantage of querySelectorAll
850
+ if ( support.qsa &&
851
+ !compilerCache[ selector + " " ] &&
852
+ (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
853
+
854
+ if ( nodeType !== 1 ) {
855
+ newContext = context;
856
+ newSelector = selector;
857
+
858
+ // qSA looks outside Element context, which is not what we want
859
+ // Thanks to Andrew Dupont for this workaround technique
860
+ // Support: IE <=8
861
+ // Exclude object elements
862
+ } else if ( context.nodeName.toLowerCase() !== "object" ) {
863
+
864
+ // Capture the context ID, setting it first if necessary
865
+ if ( (nid = context.getAttribute( "id" )) ) {
866
+ nid = nid.replace( rescape, "\\$&" );
867
+ } else {
868
+ context.setAttribute( "id", (nid = expando) );
869
+ }
870
+
871
+ // Prefix every selector in the list
872
+ groups = tokenize( selector );
873
+ i = groups.length;
874
+ nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
875
+ while ( i-- ) {
876
+ groups[i] = nidselect + " " + toSelector( groups[i] );
877
+ }
878
+ newSelector = groups.join( "," );
879
+
880
+ // Expand context for sibling selectors
881
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
882
+ context;
883
+ }
884
+
885
+ if ( newSelector ) {
886
+ try {
887
+ push.apply( results,
888
+ newContext.querySelectorAll( newSelector )
889
+ );
890
+ return results;
891
+ } catch ( qsaError ) {
892
+ } finally {
893
+ if ( nid === expando ) {
894
+ context.removeAttribute( "id" );
895
+ }
896
+ }
897
+ }
898
+ }
899
+ }
900
+ }
901
+
902
+ // All others
903
+ return select( selector.replace( rtrim, "$1" ), context, results, seed );
904
+ }
905
+
906
+ /**
907
+ * Create key-value caches of limited size
908
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
909
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
910
+ * deleting the oldest entry
911
+ */
912
+ function createCache() {
913
+ var keys = [];
914
+
915
+ function cache( key, value ) {
916
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
917
+ if ( keys.push( key + " " ) > Expr.cacheLength ) {
918
+ // Only keep the most recent entries
919
+ delete cache[ keys.shift() ];
920
+ }
921
+ return (cache[ key + " " ] = value);
922
+ }
923
+ return cache;
924
+ }
925
+
926
+ /**
927
+ * Mark a function for special use by Sizzle
928
+ * @param {Function} fn The function to mark
929
+ */
930
+ function markFunction( fn ) {
931
+ fn[ expando ] = true;
932
+ return fn;
933
+ }
934
+
935
+ /**
936
+ * Support testing using an element
937
+ * @param {Function} fn Passed the created div and expects a boolean result
938
+ */
939
+ function assert( fn ) {
940
+ var div = document.createElement("div");
941
+
942
+ try {
943
+ return !!fn( div );
944
+ } catch (e) {
945
+ return false;
946
+ } finally {
947
+ // Remove from its parent by default
948
+ if ( div.parentNode ) {
949
+ div.parentNode.removeChild( div );
950
+ }
951
+ // release memory in IE
952
+ div = null;
953
+ }
954
+ }
955
+
956
+ /**
957
+ * Adds the same handler for all of the specified attrs
958
+ * @param {String} attrs Pipe-separated list of attributes
959
+ * @param {Function} handler The method that will be applied
960
+ */
961
+ function addHandle( attrs, handler ) {
962
+ var arr = attrs.split("|"),
963
+ i = arr.length;
964
+
965
+ while ( i-- ) {
966
+ Expr.attrHandle[ arr[i] ] = handler;
967
+ }
968
+ }
969
+
970
+ /**
971
+ * Checks document order of two siblings
972
+ * @param {Element} a
973
+ * @param {Element} b
974
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
975
+ */
976
+ function siblingCheck( a, b ) {
977
+ var cur = b && a,
978
+ diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
979
+ ( ~b.sourceIndex || MAX_NEGATIVE ) -
980
+ ( ~a.sourceIndex || MAX_NEGATIVE );
981
+
982
+ // Use IE sourceIndex if available on both nodes
983
+ if ( diff ) {
984
+ return diff;
985
+ }
986
+
987
+ // Check if b follows a
988
+ if ( cur ) {
989
+ while ( (cur = cur.nextSibling) ) {
990
+ if ( cur === b ) {
991
+ return -1;
992
+ }
993
+ }
994
+ }
995
+
996
+ return a ? 1 : -1;
997
+ }
998
+
999
+ /**
1000
+ * Returns a function to use in pseudos for input types
1001
+ * @param {String} type
1002
+ */
1003
+ function createInputPseudo( type ) {
1004
+ return function( elem ) {
1005
+ var name = elem.nodeName.toLowerCase();
1006
+ return name === "input" && elem.type === type;
1007
+ };
1008
+ }
1009
+
1010
+ /**
1011
+ * Returns a function to use in pseudos for buttons
1012
+ * @param {String} type
1013
+ */
1014
+ function createButtonPseudo( type ) {
1015
+ return function( elem ) {
1016
+ var name = elem.nodeName.toLowerCase();
1017
+ return (name === "input" || name === "button") && elem.type === type;
1018
+ };
1019
+ }
1020
+
1021
+ /**
1022
+ * Returns a function to use in pseudos for positionals
1023
+ * @param {Function} fn
1024
+ */
1025
+ function createPositionalPseudo( fn ) {
1026
+ return markFunction(function( argument ) {
1027
+ argument = +argument;
1028
+ return markFunction(function( seed, matches ) {
1029
+ var j,
1030
+ matchIndexes = fn( [], seed.length, argument ),
1031
+ i = matchIndexes.length;
1032
+
1033
+ // Match elements found at the specified indexes
1034
+ while ( i-- ) {
1035
+ if ( seed[ (j = matchIndexes[i]) ] ) {
1036
+ seed[j] = !(matches[j] = seed[j]);
1037
+ }
1038
+ }
1039
+ });
1040
+ });
1041
+ }
1042
+
1043
+ /**
1044
+ * Checks a node for validity as a Sizzle context
1045
+ * @param {Element|Object=} context
1046
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1047
+ */
1048
+ function testContext( context ) {
1049
+ return context && typeof context.getElementsByTagName !== "undefined" && context;
1050
+ }
1051
+
1052
+ // Expose support vars for convenience
1053
+ support = Sizzle.support = {};
1054
+
1055
+ /**
1056
+ * Detects XML nodes
1057
+ * @param {Element|Object} elem An element or a document
1058
+ * @returns {Boolean} True iff elem is a non-HTML XML node
1059
+ */
1060
+ isXML = Sizzle.isXML = function( elem ) {
1061
+ // documentElement is verified for cases where it doesn't yet exist
1062
+ // (such as loading iframes in IE - #4833)
1063
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1064
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
1065
+ };
1066
+
1067
+ /**
1068
+ * Sets document-related variables once based on the current document
1069
+ * @param {Element|Object} [doc] An element or document object to use to set the document
1070
+ * @returns {Object} Returns the current document
1071
+ */
1072
+ setDocument = Sizzle.setDocument = function( node ) {
1073
+ var hasCompare, parent,
1074
+ doc = node ? node.ownerDocument || node : preferredDoc;
1075
+
1076
+ // Return early if doc is invalid or already selected
1077
+ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1078
+ return document;
1079
+ }
1080
+
1081
+ // Update global variables
1082
+ document = doc;
1083
+ docElem = document.documentElement;
1084
+ documentIsHTML = !isXML( document );
1085
+
1086
+ // Support: IE 9-11, Edge
1087
+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1088
+ if ( (parent = document.defaultView) && parent.top !== parent ) {
1089
+ // Support: IE 11
1090
+ if ( parent.addEventListener ) {
1091
+ parent.addEventListener( "unload", unloadHandler, false );
1092
+
1093
+ // Support: IE 9 - 10 only
1094
+ } else if ( parent.attachEvent ) {
1095
+ parent.attachEvent( "onunload", unloadHandler );
1096
+ }
1097
+ }
1098
+
1099
+ /* Attributes
1100
+ ---------------------------------------------------------------------- */
1101
+
1102
+ // Support: IE<8
1103
+ // Verify that getAttribute really returns attributes and not properties
1104
+ // (excepting IE8 booleans)
1105
+ support.attributes = assert(function( div ) {
1106
+ div.className = "i";
1107
+ return !div.getAttribute("className");
1108
+ });
1109
+
1110
+ /* getElement(s)By*
1111
+ ---------------------------------------------------------------------- */
1112
+
1113
+ // Check if getElementsByTagName("*") returns only elements
1114
+ support.getElementsByTagName = assert(function( div ) {
1115
+ div.appendChild( document.createComment("") );
1116
+ return !div.getElementsByTagName("*").length;
1117
+ });
1118
+
1119
+ // Support: IE<9
1120
+ support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1121
+
1122
+ // Support: IE<10
1123
+ // Check if getElementById returns elements by name
1124
+ // The broken getElementById methods don't pick up programatically-set names,
1125
+ // so use a roundabout getElementsByName test
1126
+ support.getById = assert(function( div ) {
1127
+ docElem.appendChild( div ).id = expando;
1128
+ return !document.getElementsByName || !document.getElementsByName( expando ).length;
1129
+ });
1130
+
1131
+ // ID find and filter
1132
+ if ( support.getById ) {
1133
+ Expr.find["ID"] = function( id, context ) {
1134
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1135
+ var m = context.getElementById( id );
1136
+ return m ? [ m ] : [];
1137
+ }
1138
+ };
1139
+ Expr.filter["ID"] = function( id ) {
1140
+ var attrId = id.replace( runescape, funescape );
1141
+ return function( elem ) {
1142
+ return elem.getAttribute("id") === attrId;
1143
+ };
1144
+ };
1145
+ } else {
1146
+ // Support: IE6/7
1147
+ // getElementById is not reliable as a find shortcut
1148
+ delete Expr.find["ID"];
1149
+
1150
+ Expr.filter["ID"] = function( id ) {
1151
+ var attrId = id.replace( runescape, funescape );
1152
+ return function( elem ) {
1153
+ var node = typeof elem.getAttributeNode !== "undefined" &&
1154
+ elem.getAttributeNode("id");
1155
+ return node && node.value === attrId;
1156
+ };
1157
+ };
1158
+ }
1159
+
1160
+ // Tag
1161
+ Expr.find["TAG"] = support.getElementsByTagName ?
1162
+ function( tag, context ) {
1163
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
1164
+ return context.getElementsByTagName( tag );
1165
+
1166
+ // DocumentFragment nodes don't have gEBTN
1167
+ } else if ( support.qsa ) {
1168
+ return context.querySelectorAll( tag );
1169
+ }
1170
+ } :
1171
+
1172
+ function( tag, context ) {
1173
+ var elem,
1174
+ tmp = [],
1175
+ i = 0,
1176
+ // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1177
+ results = context.getElementsByTagName( tag );
1178
+
1179
+ // Filter out possible comments
1180
+ if ( tag === "*" ) {
1181
+ while ( (elem = results[i++]) ) {
1182
+ if ( elem.nodeType === 1 ) {
1183
+ tmp.push( elem );
1184
+ }
1185
+ }
1186
+
1187
+ return tmp;
1188
+ }
1189
+ return results;
1190
+ };
1191
+
1192
+ // Class
1193
+ Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1194
+ if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1195
+ return context.getElementsByClassName( className );
1196
+ }
1197
+ };
1198
+
1199
+ /* QSA/matchesSelector
1200
+ ---------------------------------------------------------------------- */
1201
+
1202
+ // QSA and matchesSelector support
1203
+
1204
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1205
+ rbuggyMatches = [];
1206
+
1207
+ // qSa(:focus) reports false when true (Chrome 21)
1208
+ // We allow this because of a bug in IE8/9 that throws an error
1209
+ // whenever `document.activeElement` is accessed on an iframe
1210
+ // So, we allow :focus to pass through QSA all the time to avoid the IE error
1211
+ // See http://bugs.jquery.com/ticket/13378
1212
+ rbuggyQSA = [];
1213
+
1214
+ if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1215
+ // Build QSA regex
1216
+ // Regex strategy adopted from Diego Perini
1217
+ assert(function( div ) {
1218
+ // Select is set to empty string on purpose
1219
+ // This is to test IE's treatment of not explicitly
1220
+ // setting a boolean content attribute,
1221
+ // since its presence should be enough
1222
+ // http://bugs.jquery.com/ticket/12359
1223
+ docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1224
+ "<select id='" + expando + "-\r\\' msallowcapture=''>" +
1225
+ "<option selected=''></option></select>";
1226
+
1227
+ // Support: IE8, Opera 11-12.16
1228
+ // Nothing should be selected when empty strings follow ^= or $= or *=
1229
+ // The test attribute must be unknown in Opera but "safe" for WinRT
1230
+ // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1231
+ if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1232
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1233
+ }
1234
+
1235
+ // Support: IE8
1236
+ // Boolean attributes and "value" are not treated correctly
1237
+ if ( !div.querySelectorAll("[selected]").length ) {
1238
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1239
+ }
1240
+
1241
+ // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1242
+ if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1243
+ rbuggyQSA.push("~=");
1244
+ }
1245
+
1246
+ // Webkit/Opera - :checked should return selected option elements
1247
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1248
+ // IE8 throws error here and will not see later tests
1249
+ if ( !div.querySelectorAll(":checked").length ) {
1250
+ rbuggyQSA.push(":checked");
1251
+ }
1252
+
1253
+ // Support: Safari 8+, iOS 8+
1254
+ // https://bugs.webkit.org/show_bug.cgi?id=136851
1255
+ // In-page `selector#id sibing-combinator selector` fails
1256
+ if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1257
+ rbuggyQSA.push(".#.+[+~]");
1258
+ }
1259
+ });
1260
+
1261
+ assert(function( div ) {
1262
+ // Support: Windows 8 Native Apps
1263
+ // The type and name attributes are restricted during .innerHTML assignment
1264
+ var input = document.createElement("input");
1265
+ input.setAttribute( "type", "hidden" );
1266
+ div.appendChild( input ).setAttribute( "name", "D" );
1267
+
1268
+ // Support: IE8
1269
+ // Enforce case-sensitivity of name attribute
1270
+ if ( div.querySelectorAll("[name=d]").length ) {
1271
+ rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1272
+ }
1273
+
1274
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1275
+ // IE8 throws error here and will not see later tests
1276
+ if ( !div.querySelectorAll(":enabled").length ) {
1277
+ rbuggyQSA.push( ":enabled", ":disabled" );
1278
+ }
1279
+
1280
+ // Opera 10-11 does not throw on post-comma invalid pseudos
1281
+ div.querySelectorAll("*,:x");
1282
+ rbuggyQSA.push(",.*:");
1283
+ });
1284
+ }
1285
+
1286
+ if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1287
+ docElem.webkitMatchesSelector ||
1288
+ docElem.mozMatchesSelector ||
1289
+ docElem.oMatchesSelector ||
1290
+ docElem.msMatchesSelector) )) ) {
1291
+
1292
+ assert(function( div ) {
1293
+ // Check to see if it's possible to do matchesSelector
1294
+ // on a disconnected node (IE 9)
1295
+ support.disconnectedMatch = matches.call( div, "div" );
1296
+
1297
+ // This should fail with an exception
1298
+ // Gecko does not error, returns false instead
1299
+ matches.call( div, "[s!='']:x" );
1300
+ rbuggyMatches.push( "!=", pseudos );
1301
+ });
1302
+ }
1303
+
1304
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1305
+ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1306
+
1307
+ /* Contains
1308
+ ---------------------------------------------------------------------- */
1309
+ hasCompare = rnative.test( docElem.compareDocumentPosition );
1310
+
1311
+ // Element contains another
1312
+ // Purposefully self-exclusive
1313
+ // As in, an element does not contain itself
1314
+ contains = hasCompare || rnative.test( docElem.contains ) ?
1315
+ function( a, b ) {
1316
+ var adown = a.nodeType === 9 ? a.documentElement : a,
1317
+ bup = b && b.parentNode;
1318
+ return a === bup || !!( bup && bup.nodeType === 1 && (
1319
+ adown.contains ?
1320
+ adown.contains( bup ) :
1321
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1322
+ ));
1323
+ } :
1324
+ function( a, b ) {
1325
+ if ( b ) {
1326
+ while ( (b = b.parentNode) ) {
1327
+ if ( b === a ) {
1328
+ return true;
1329
+ }
1330
+ }
1331
+ }
1332
+ return false;
1333
+ };
1334
+
1335
+ /* Sorting
1336
+ ---------------------------------------------------------------------- */
1337
+
1338
+ // Document order sorting
1339
+ sortOrder = hasCompare ?
1340
+ function( a, b ) {
1341
+
1342
+ // Flag for duplicate removal
1343
+ if ( a === b ) {
1344
+ hasDuplicate = true;
1345
+ return 0;
1346
+ }
1347
+
1348
+ // Sort on method existence if only one input has compareDocumentPosition
1349
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1350
+ if ( compare ) {
1351
+ return compare;
1352
+ }
1353
+
1354
+ // Calculate position if both inputs belong to the same document
1355
+ compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1356
+ a.compareDocumentPosition( b ) :
1357
+
1358
+ // Otherwise we know they are disconnected
1359
+ 1;
1360
+
1361
+ // Disconnected nodes
1362
+ if ( compare & 1 ||
1363
+ (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1364
+
1365
+ // Choose the first element that is related to our preferred document
1366
+ if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1367
+ return -1;
1368
+ }
1369
+ if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1370
+ return 1;
1371
+ }
1372
+
1373
+ // Maintain original order
1374
+ return sortInput ?
1375
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1376
+ 0;
1377
+ }
1378
+
1379
+ return compare & 4 ? -1 : 1;
1380
+ } :
1381
+ function( a, b ) {
1382
+ // Exit early if the nodes are identical
1383
+ if ( a === b ) {
1384
+ hasDuplicate = true;
1385
+ return 0;
1386
+ }
1387
+
1388
+ var cur,
1389
+ i = 0,
1390
+ aup = a.parentNode,
1391
+ bup = b.parentNode,
1392
+ ap = [ a ],
1393
+ bp = [ b ];
1394
+
1395
+ // Parentless nodes are either documents or disconnected
1396
+ if ( !aup || !bup ) {
1397
+ return a === document ? -1 :
1398
+ b === document ? 1 :
1399
+ aup ? -1 :
1400
+ bup ? 1 :
1401
+ sortInput ?
1402
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1403
+ 0;
1404
+
1405
+ // If the nodes are siblings, we can do a quick check
1406
+ } else if ( aup === bup ) {
1407
+ return siblingCheck( a, b );
1408
+ }
1409
+
1410
+ // Otherwise we need full lists of their ancestors for comparison
1411
+ cur = a;
1412
+ while ( (cur = cur.parentNode) ) {
1413
+ ap.unshift( cur );
1414
+ }
1415
+ cur = b;
1416
+ while ( (cur = cur.parentNode) ) {
1417
+ bp.unshift( cur );
1418
+ }
1419
+
1420
+ // Walk down the tree looking for a discrepancy
1421
+ while ( ap[i] === bp[i] ) {
1422
+ i++;
1423
+ }
1424
+
1425
+ return i ?
1426
+ // Do a sibling check if the nodes have a common ancestor
1427
+ siblingCheck( ap[i], bp[i] ) :
1428
+
1429
+ // Otherwise nodes in our document sort first
1430
+ ap[i] === preferredDoc ? -1 :
1431
+ bp[i] === preferredDoc ? 1 :
1432
+ 0;
1433
+ };
1434
+
1435
+ return document;
1436
+ };
1437
+
1438
+ Sizzle.matches = function( expr, elements ) {
1439
+ return Sizzle( expr, null, null, elements );
1440
+ };
1441
+
1442
+ Sizzle.matchesSelector = function( elem, expr ) {
1443
+ // Set document vars if needed
1444
+ if ( ( elem.ownerDocument || elem ) !== document ) {
1445
+ setDocument( elem );
1446
+ }
1447
+
1448
+ // Make sure that attribute selectors are quoted
1449
+ expr = expr.replace( rattributeQuotes, "='$1']" );
1450
+
1451
+ if ( support.matchesSelector && documentIsHTML &&
1452
+ !compilerCache[ expr + " " ] &&
1453
+ ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1454
+ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1455
+
1456
+ try {
1457
+ var ret = matches.call( elem, expr );
1458
+
1459
+ // IE 9's matchesSelector returns false on disconnected nodes
1460
+ if ( ret || support.disconnectedMatch ||
1461
+ // As well, disconnected nodes are said to be in a document
1462
+ // fragment in IE 9
1463
+ elem.document && elem.document.nodeType !== 11 ) {
1464
+ return ret;
1465
+ }
1466
+ } catch (e) {}
1467
+ }
1468
+
1469
+ return Sizzle( expr, document, null, [ elem ] ).length > 0;
1470
+ };
1471
+
1472
+ Sizzle.contains = function( context, elem ) {
1473
+ // Set document vars if needed
1474
+ if ( ( context.ownerDocument || context ) !== document ) {
1475
+ setDocument( context );
1476
+ }
1477
+ return contains( context, elem );
1478
+ };
1479
+
1480
+ Sizzle.attr = function( elem, name ) {
1481
+ // Set document vars if needed
1482
+ if ( ( elem.ownerDocument || elem ) !== document ) {
1483
+ setDocument( elem );
1484
+ }
1485
+
1486
+ var fn = Expr.attrHandle[ name.toLowerCase() ],
1487
+ // Don't get fooled by Object.prototype properties (jQuery #13807)
1488
+ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1489
+ fn( elem, name, !documentIsHTML ) :
1490
+ undefined;
1491
+
1492
+ return val !== undefined ?
1493
+ val :
1494
+ support.attributes || !documentIsHTML ?
1495
+ elem.getAttribute( name ) :
1496
+ (val = elem.getAttributeNode(name)) && val.specified ?
1497
+ val.value :
1498
+ null;
1499
+ };
1500
+
1501
+ Sizzle.error = function( msg ) {
1502
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
1503
+ };
1504
+
1505
+ /**
1506
+ * Document sorting and removing duplicates
1507
+ * @param {ArrayLike} results
1508
+ */
1509
+ Sizzle.uniqueSort = function( results ) {
1510
+ var elem,
1511
+ duplicates = [],
1512
+ j = 0,
1513
+ i = 0;
1514
+
1515
+ // Unless we *know* we can detect duplicates, assume their presence
1516
+ hasDuplicate = !support.detectDuplicates;
1517
+ sortInput = !support.sortStable && results.slice( 0 );
1518
+ results.sort( sortOrder );
1519
+
1520
+ if ( hasDuplicate ) {
1521
+ while ( (elem = results[i++]) ) {
1522
+ if ( elem === results[ i ] ) {
1523
+ j = duplicates.push( i );
1524
+ }
1525
+ }
1526
+ while ( j-- ) {
1527
+ results.splice( duplicates[ j ], 1 );
1528
+ }
1529
+ }
1530
+
1531
+ // Clear input after sorting to release objects
1532
+ // See https://github.com/jquery/sizzle/pull/225
1533
+ sortInput = null;
1534
+
1535
+ return results;
1536
+ };
1537
+
1538
+ /**
1539
+ * Utility function for retrieving the text value of an array of DOM nodes
1540
+ * @param {Array|Element} elem
1541
+ */
1542
+ getText = Sizzle.getText = function( elem ) {
1543
+ var node,
1544
+ ret = "",
1545
+ i = 0,
1546
+ nodeType = elem.nodeType;
1547
+
1548
+ if ( !nodeType ) {
1549
+ // If no nodeType, this is expected to be an array
1550
+ while ( (node = elem[i++]) ) {
1551
+ // Do not traverse comment nodes
1552
+ ret += getText( node );
1553
+ }
1554
+ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1555
+ // Use textContent for elements
1556
+ // innerText usage removed for consistency of new lines (jQuery #11153)
1557
+ if ( typeof elem.textContent === "string" ) {
1558
+ return elem.textContent;
1559
+ } else {
1560
+ // Traverse its children
1561
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1562
+ ret += getText( elem );
1563
+ }
1564
+ }
1565
+ } else if ( nodeType === 3 || nodeType === 4 ) {
1566
+ return elem.nodeValue;
1567
+ }
1568
+ // Do not include comment or processing instruction nodes
1569
+
1570
+ return ret;
1571
+ };
1572
+
1573
+ Expr = Sizzle.selectors = {
1574
+
1575
+ // Can be adjusted by the user
1576
+ cacheLength: 50,
1577
+
1578
+ createPseudo: markFunction,
1579
+
1580
+ match: matchExpr,
1581
+
1582
+ attrHandle: {},
1583
+
1584
+ find: {},
1585
+
1586
+ relative: {
1587
+ ">": { dir: "parentNode", first: true },
1588
+ " ": { dir: "parentNode" },
1589
+ "+": { dir: "previousSibling", first: true },
1590
+ "~": { dir: "previousSibling" }
1591
+ },
1592
+
1593
+ preFilter: {
1594
+ "ATTR": function( match ) {
1595
+ match[1] = match[1].replace( runescape, funescape );
1596
+
1597
+ // Move the given value to match[3] whether quoted or unquoted
1598
+ match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1599
+
1600
+ if ( match[2] === "~=" ) {
1601
+ match[3] = " " + match[3] + " ";
1602
+ }
1603
+
1604
+ return match.slice( 0, 4 );
1605
+ },
1606
+
1607
+ "CHILD": function( match ) {
1608
+ /* matches from matchExpr["CHILD"]
1609
+ 1 type (only|nth|...)
1610
+ 2 what (child|of-type)
1611
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1612
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
1613
+ 5 sign of xn-component
1614
+ 6 x of xn-component
1615
+ 7 sign of y-component
1616
+ 8 y of y-component
1617
+ */
1618
+ match[1] = match[1].toLowerCase();
1619
+
1620
+ if ( match[1].slice( 0, 3 ) === "nth" ) {
1621
+ // nth-* requires argument
1622
+ if ( !match[3] ) {
1623
+ Sizzle.error( match[0] );
1624
+ }
1625
+
1626
+ // numeric x and y parameters for Expr.filter.CHILD
1627
+ // remember that false/true cast respectively to 0/1
1628
+ match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1629
+ match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1630
+
1631
+ // other types prohibit arguments
1632
+ } else if ( match[3] ) {
1633
+ Sizzle.error( match[0] );
1634
+ }
1635
+
1636
+ return match;
1637
+ },
1638
+
1639
+ "PSEUDO": function( match ) {
1640
+ var excess,
1641
+ unquoted = !match[6] && match[2];
1642
+
1643
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
1644
+ return null;
1645
+ }
1646
+
1647
+ // Accept quoted arguments as-is
1648
+ if ( match[3] ) {
1649
+ match[2] = match[4] || match[5] || "";
1650
+
1651
+ // Strip excess characters from unquoted arguments
1652
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
1653
+ // Get excess from tokenize (recursively)
1654
+ (excess = tokenize( unquoted, true )) &&
1655
+ // advance to the next closing parenthesis
1656
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1657
+
1658
+ // excess is a negative index
1659
+ match[0] = match[0].slice( 0, excess );
1660
+ match[2] = unquoted.slice( 0, excess );
1661
+ }
1662
+
1663
+ // Return only captures needed by the pseudo filter method (type and argument)
1664
+ return match.slice( 0, 3 );
1665
+ }
1666
+ },
1667
+
1668
+ filter: {
1669
+
1670
+ "TAG": function( nodeNameSelector ) {
1671
+ var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1672
+ return nodeNameSelector === "*" ?
1673
+ function() { return true; } :
1674
+ function( elem ) {
1675
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1676
+ };
1677
+ },
1678
+
1679
+ "CLASS": function( className ) {
1680
+ var pattern = classCache[ className + " " ];
1681
+
1682
+ return pattern ||
1683
+ (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1684
+ classCache( className, function( elem ) {
1685
+ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1686
+ });
1687
+ },
1688
+
1689
+ "ATTR": function( name, operator, check ) {
1690
+ return function( elem ) {
1691
+ var result = Sizzle.attr( elem, name );
1692
+
1693
+ if ( result == null ) {
1694
+ return operator === "!=";
1695
+ }
1696
+ if ( !operator ) {
1697
+ return true;
1698
+ }
1699
+
1700
+ result += "";
1701
+
1702
+ return operator === "=" ? result === check :
1703
+ operator === "!=" ? result !== check :
1704
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
1705
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
1706
+ operator === "$=" ? check && result.slice( -check.length ) === check :
1707
+ operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1708
+ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1709
+ false;
1710
+ };
1711
+ },
1712
+
1713
+ "CHILD": function( type, what, argument, first, last ) {
1714
+ var simple = type.slice( 0, 3 ) !== "nth",
1715
+ forward = type.slice( -4 ) !== "last",
1716
+ ofType = what === "of-type";
1717
+
1718
+ return first === 1 && last === 0 ?
1719
+
1720
+ // Shortcut for :nth-*(n)
1721
+ function( elem ) {
1722
+ return !!elem.parentNode;
1723
+ } :
1724
+
1725
+ function( elem, context, xml ) {
1726
+ var cache, uniqueCache, outerCache, node, nodeIndex, start,
1727
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
1728
+ parent = elem.parentNode,
1729
+ name = ofType && elem.nodeName.toLowerCase(),
1730
+ useCache = !xml && !ofType,
1731
+ diff = false;
1732
+
1733
+ if ( parent ) {
1734
+
1735
+ // :(first|last|only)-(child|of-type)
1736
+ if ( simple ) {
1737
+ while ( dir ) {
1738
+ node = elem;
1739
+ while ( (node = node[ dir ]) ) {
1740
+ if ( ofType ?
1741
+ node.nodeName.toLowerCase() === name :
1742
+ node.nodeType === 1 ) {
1743
+
1744
+ return false;
1745
+ }
1746
+ }
1747
+ // Reverse direction for :only-* (if we haven't yet done so)
1748
+ start = dir = type === "only" && !start && "nextSibling";
1749
+ }
1750
+ return true;
1751
+ }
1752
+
1753
+ start = [ forward ? parent.firstChild : parent.lastChild ];
1754
+
1755
+ // non-xml :nth-child(...) stores cache data on `parent`
1756
+ if ( forward && useCache ) {
1757
+
1758
+ // Seek `elem` from a previously-cached index
1759
+
1760
+ // ...in a gzip-friendly way
1761
+ node = parent;
1762
+ outerCache = node[ expando ] || (node[ expando ] = {});
1763
+
1764
+ // Support: IE <9 only
1765
+ // Defend against cloned attroperties (jQuery gh-1709)
1766
+ uniqueCache = outerCache[ node.uniqueID ] ||
1767
+ (outerCache[ node.uniqueID ] = {});
1768
+
1769
+ cache = uniqueCache[ type ] || [];
1770
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1771
+ diff = nodeIndex && cache[ 2 ];
1772
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
1773
+
1774
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
1775
+
1776
+ // Fallback to seeking `elem` from the start
1777
+ (diff = nodeIndex = 0) || start.pop()) ) {
1778
+
1779
+ // When found, cache indexes on `parent` and break
1780
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
1781
+ uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1782
+ break;
1783
+ }
1784
+ }
1785
+
1786
+ } else {
1787
+ // Use previously-cached element index if available
1788
+ if ( useCache ) {
1789
+ // ...in a gzip-friendly way
1790
+ node = elem;
1791
+ outerCache = node[ expando ] || (node[ expando ] = {});
1792
+
1793
+ // Support: IE <9 only
1794
+ // Defend against cloned attroperties (jQuery gh-1709)
1795
+ uniqueCache = outerCache[ node.uniqueID ] ||
1796
+ (outerCache[ node.uniqueID ] = {});
1797
+
1798
+ cache = uniqueCache[ type ] || [];
1799
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1800
+ diff = nodeIndex;
1801
+ }
1802
+
1803
+ // xml :nth-child(...)
1804
+ // or :nth-last-child(...) or :nth(-last)?-of-type(...)
1805
+ if ( diff === false ) {
1806
+ // Use the same loop as above to seek `elem` from the start
1807
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
1808
+ (diff = nodeIndex = 0) || start.pop()) ) {
1809
+
1810
+ if ( ( ofType ?
1811
+ node.nodeName.toLowerCase() === name :
1812
+ node.nodeType === 1 ) &&
1813
+ ++diff ) {
1814
+
1815
+ // Cache the index of each encountered element
1816
+ if ( useCache ) {
1817
+ outerCache = node[ expando ] || (node[ expando ] = {});
1818
+
1819
+ // Support: IE <9 only
1820
+ // Defend against cloned attroperties (jQuery gh-1709)
1821
+ uniqueCache = outerCache[ node.uniqueID ] ||
1822
+ (outerCache[ node.uniqueID ] = {});
1823
+
1824
+ uniqueCache[ type ] = [ dirruns, diff ];
1825
+ }
1826
+
1827
+ if ( node === elem ) {
1828
+ break;
1829
+ }
1830
+ }
1831
+ }
1832
+ }
1833
+ }
1834
+
1835
+ // Incorporate the offset, then check against cycle size
1836
+ diff -= last;
1837
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
1838
+ }
1839
+ };
1840
+ },
1841
+
1842
+ "PSEUDO": function( pseudo, argument ) {
1843
+ // pseudo-class names are case-insensitive
1844
+ // http://www.w3.org/TR/selectors/#pseudo-classes
1845
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1846
+ // Remember that setFilters inherits from pseudos
1847
+ var args,
1848
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1849
+ Sizzle.error( "unsupported pseudo: " + pseudo );
1850
+
1851
+ // The user may use createPseudo to indicate that
1852
+ // arguments are needed to create the filter function
1853
+ // just as Sizzle does
1854
+ if ( fn[ expando ] ) {
1855
+ return fn( argument );
1856
+ }
1857
+
1858
+ // But maintain support for old signatures
1859
+ if ( fn.length > 1 ) {
1860
+ args = [ pseudo, pseudo, "", argument ];
1861
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1862
+ markFunction(function( seed, matches ) {
1863
+ var idx,
1864
+ matched = fn( seed, argument ),
1865
+ i = matched.length;
1866
+ while ( i-- ) {
1867
+ idx = indexOf( seed, matched[i] );
1868
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
1869
+ }
1870
+ }) :
1871
+ function( elem ) {
1872
+ return fn( elem, 0, args );
1873
+ };
1874
+ }
1875
+
1876
+ return fn;
1877
+ }
1878
+ },
1879
+
1880
+ pseudos: {
1881
+ // Potentially complex pseudos
1882
+ "not": markFunction(function( selector ) {
1883
+ // Trim the selector passed to compile
1884
+ // to avoid treating leading and trailing
1885
+ // spaces as combinators
1886
+ var input = [],
1887
+ results = [],
1888
+ matcher = compile( selector.replace( rtrim, "$1" ) );
1889
+
1890
+ return matcher[ expando ] ?
1891
+ markFunction(function( seed, matches, context, xml ) {
1892
+ var elem,
1893
+ unmatched = matcher( seed, null, xml, [] ),
1894
+ i = seed.length;
1895
+
1896
+ // Match elements unmatched by `matcher`
1897
+ while ( i-- ) {
1898
+ if ( (elem = unmatched[i]) ) {
1899
+ seed[i] = !(matches[i] = elem);
1900
+ }
1901
+ }
1902
+ }) :
1903
+ function( elem, context, xml ) {
1904
+ input[0] = elem;
1905
+ matcher( input, null, xml, results );
1906
+ // Don't keep the element (issue #299)
1907
+ input[0] = null;
1908
+ return !results.pop();
1909
+ };
1910
+ }),
1911
+
1912
+ "has": markFunction(function( selector ) {
1913
+ return function( elem ) {
1914
+ return Sizzle( selector, elem ).length > 0;
1915
+ };
1916
+ }),
1917
+
1918
+ "contains": markFunction(function( text ) {
1919
+ text = text.replace( runescape, funescape );
1920
+ return function( elem ) {
1921
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1922
+ };
1923
+ }),
1924
+
1925
+ // "Whether an element is represented by a :lang() selector
1926
+ // is based solely on the element's language value
1927
+ // being equal to the identifier C,
1928
+ // or beginning with the identifier C immediately followed by "-".
1929
+ // The matching of C against the element's language value is performed case-insensitively.
1930
+ // The identifier C does not have to be a valid language name."
1931
+ // http://www.w3.org/TR/selectors/#lang-pseudo
1932
+ "lang": markFunction( function( lang ) {
1933
+ // lang value must be a valid identifier
1934
+ if ( !ridentifier.test(lang || "") ) {
1935
+ Sizzle.error( "unsupported lang: " + lang );
1936
+ }
1937
+ lang = lang.replace( runescape, funescape ).toLowerCase();
1938
+ return function( elem ) {
1939
+ var elemLang;
1940
+ do {
1941
+ if ( (elemLang = documentIsHTML ?
1942
+ elem.lang :
1943
+ elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1944
+
1945
+ elemLang = elemLang.toLowerCase();
1946
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1947
+ }
1948
+ } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1949
+ return false;
1950
+ };
1951
+ }),
1952
+
1953
+ // Miscellaneous
1954
+ "target": function( elem ) {
1955
+ var hash = window.location && window.location.hash;
1956
+ return hash && hash.slice( 1 ) === elem.id;
1957
+ },
1958
+
1959
+ "root": function( elem ) {
1960
+ return elem === docElem;
1961
+ },
1962
+
1963
+ "focus": function( elem ) {
1964
+ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1965
+ },
1966
+
1967
+ // Boolean properties
1968
+ "enabled": function( elem ) {
1969
+ return elem.disabled === false;
1970
+ },
1971
+
1972
+ "disabled": function( elem ) {
1973
+ return elem.disabled === true;
1974
+ },
1975
+
1976
+ "checked": function( elem ) {
1977
+ // In CSS3, :checked should return both checked and selected elements
1978
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1979
+ var nodeName = elem.nodeName.toLowerCase();
1980
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1981
+ },
1982
+
1983
+ "selected": function( elem ) {
1984
+ // Accessing this property makes selected-by-default
1985
+ // options in Safari work properly
1986
+ if ( elem.parentNode ) {
1987
+ elem.parentNode.selectedIndex;
1988
+ }
1989
+
1990
+ return elem.selected === true;
1991
+ },
1992
+
1993
+ // Contents
1994
+ "empty": function( elem ) {
1995
+ // http://www.w3.org/TR/selectors/#empty-pseudo
1996
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1997
+ // but not by others (comment: 8; processing instruction: 7; etc.)
1998
+ // nodeType < 6 works because attributes (2) do not appear as children
1999
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2000
+ if ( elem.nodeType < 6 ) {
2001
+ return false;
2002
+ }
2003
+ }
2004
+ return true;
2005
+ },
2006
+
2007
+ "parent": function( elem ) {
2008
+ return !Expr.pseudos["empty"]( elem );
2009
+ },
2010
+
2011
+ // Element/input types
2012
+ "header": function( elem ) {
2013
+ return rheader.test( elem.nodeName );
2014
+ },
2015
+
2016
+ "input": function( elem ) {
2017
+ return rinputs.test( elem.nodeName );
2018
+ },
2019
+
2020
+ "button": function( elem ) {
2021
+ var name = elem.nodeName.toLowerCase();
2022
+ return name === "input" && elem.type === "button" || name === "button";
2023
+ },
2024
+
2025
+ "text": function( elem ) {
2026
+ var attr;
2027
+ return elem.nodeName.toLowerCase() === "input" &&
2028
+ elem.type === "text" &&
2029
+
2030
+ // Support: IE<8
2031
+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2032
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2033
+ },
2034
+
2035
+ // Position-in-collection
2036
+ "first": createPositionalPseudo(function() {
2037
+ return [ 0 ];
2038
+ }),
2039
+
2040
+ "last": createPositionalPseudo(function( matchIndexes, length ) {
2041
+ return [ length - 1 ];
2042
+ }),
2043
+
2044
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2045
+ return [ argument < 0 ? argument + length : argument ];
2046
+ }),
2047
+
2048
+ "even": createPositionalPseudo(function( matchIndexes, length ) {
2049
+ var i = 0;
2050
+ for ( ; i < length; i += 2 ) {
2051
+ matchIndexes.push( i );
2052
+ }
2053
+ return matchIndexes;
2054
+ }),
2055
+
2056
+ "odd": createPositionalPseudo(function( matchIndexes, length ) {
2057
+ var i = 1;
2058
+ for ( ; i < length; i += 2 ) {
2059
+ matchIndexes.push( i );
2060
+ }
2061
+ return matchIndexes;
2062
+ }),
2063
+
2064
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2065
+ var i = argument < 0 ? argument + length : argument;
2066
+ for ( ; --i >= 0; ) {
2067
+ matchIndexes.push( i );
2068
+ }
2069
+ return matchIndexes;
2070
+ }),
2071
+
2072
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2073
+ var i = argument < 0 ? argument + length : argument;
2074
+ for ( ; ++i < length; ) {
2075
+ matchIndexes.push( i );
2076
+ }
2077
+ return matchIndexes;
2078
+ })
2079
+ }
2080
+ };
2081
+
2082
+ Expr.pseudos["nth"] = Expr.pseudos["eq"];
2083
+
2084
+ // Add button/input type pseudos
2085
+ for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2086
+ Expr.pseudos[ i ] = createInputPseudo( i );
2087
+ }
2088
+ for ( i in { submit: true, reset: true } ) {
2089
+ Expr.pseudos[ i ] = createButtonPseudo( i );
2090
+ }
2091
+
2092
+ // Easy API for creating new setFilters
2093
+ function setFilters() {}
2094
+ setFilters.prototype = Expr.filters = Expr.pseudos;
2095
+ Expr.setFilters = new setFilters();
2096
+
2097
+ tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2098
+ var matched, match, tokens, type,
2099
+ soFar, groups, preFilters,
2100
+ cached = tokenCache[ selector + " " ];
2101
+
2102
+ if ( cached ) {
2103
+ return parseOnly ? 0 : cached.slice( 0 );
2104
+ }
2105
+
2106
+ soFar = selector;
2107
+ groups = [];
2108
+ preFilters = Expr.preFilter;
2109
+
2110
+ while ( soFar ) {
2111
+
2112
+ // Comma and first run
2113
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
2114
+ if ( match ) {
2115
+ // Don't consume trailing commas as valid
2116
+ soFar = soFar.slice( match[0].length ) || soFar;
2117
+ }
2118
+ groups.push( (tokens = []) );
2119
+ }
2120
+
2121
+ matched = false;
2122
+
2123
+ // Combinators
2124
+ if ( (match = rcombinators.exec( soFar )) ) {
2125
+ matched = match.shift();
2126
+ tokens.push({
2127
+ value: matched,
2128
+ // Cast descendant combinators to space
2129
+ type: match[0].replace( rtrim, " " )
2130
+ });
2131
+ soFar = soFar.slice( matched.length );
2132
+ }
2133
+
2134
+ // Filters
2135
+ for ( type in Expr.filter ) {
2136
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2137
+ (match = preFilters[ type ]( match ))) ) {
2138
+ matched = match.shift();
2139
+ tokens.push({
2140
+ value: matched,
2141
+ type: type,
2142
+ matches: match
2143
+ });
2144
+ soFar = soFar.slice( matched.length );
2145
+ }
2146
+ }
2147
+
2148
+ if ( !matched ) {
2149
+ break;
2150
+ }
2151
+ }
2152
+
2153
+ // Return the length of the invalid excess
2154
+ // if we're just parsing
2155
+ // Otherwise, throw an error or return tokens
2156
+ return parseOnly ?
2157
+ soFar.length :
2158
+ soFar ?
2159
+ Sizzle.error( selector ) :
2160
+ // Cache the tokens
2161
+ tokenCache( selector, groups ).slice( 0 );
2162
+ };
2163
+
2164
+ function toSelector( tokens ) {
2165
+ var i = 0,
2166
+ len = tokens.length,
2167
+ selector = "";
2168
+ for ( ; i < len; i++ ) {
2169
+ selector += tokens[i].value;
2170
+ }
2171
+ return selector;
2172
+ }
2173
+
2174
+ function addCombinator( matcher, combinator, base ) {
2175
+ var dir = combinator.dir,
2176
+ checkNonElements = base && dir === "parentNode",
2177
+ doneName = done++;
2178
+
2179
+ return combinator.first ?
2180
+ // Check against closest ancestor/preceding element
2181
+ function( elem, context, xml ) {
2182
+ while ( (elem = elem[ dir ]) ) {
2183
+ if ( elem.nodeType === 1 || checkNonElements ) {
2184
+ return matcher( elem, context, xml );
2185
+ }
2186
+ }
2187
+ } :
2188
+
2189
+ // Check against all ancestor/preceding elements
2190
+ function( elem, context, xml ) {
2191
+ var oldCache, uniqueCache, outerCache,
2192
+ newCache = [ dirruns, doneName ];
2193
+
2194
+ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2195
+ if ( xml ) {
2196
+ while ( (elem = elem[ dir ]) ) {
2197
+ if ( elem.nodeType === 1 || checkNonElements ) {
2198
+ if ( matcher( elem, context, xml ) ) {
2199
+ return true;
2200
+ }
2201
+ }
2202
+ }
2203
+ } else {
2204
+ while ( (elem = elem[ dir ]) ) {
2205
+ if ( elem.nodeType === 1 || checkNonElements ) {
2206
+ outerCache = elem[ expando ] || (elem[ expando ] = {});
2207
+
2208
+ // Support: IE <9 only
2209
+ // Defend against cloned attroperties (jQuery gh-1709)
2210
+ uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2211
+
2212
+ if ( (oldCache = uniqueCache[ dir ]) &&
2213
+ oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2214
+
2215
+ // Assign to newCache so results back-propagate to previous elements
2216
+ return (newCache[ 2 ] = oldCache[ 2 ]);
2217
+ } else {
2218
+ // Reuse newcache so results back-propagate to previous elements
2219
+ uniqueCache[ dir ] = newCache;
2220
+
2221
+ // A match means we're done; a fail means we have to keep checking
2222
+ if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2223
+ return true;
2224
+ }
2225
+ }
2226
+ }
2227
+ }
2228
+ }
2229
+ };
2230
+ }
2231
+
2232
+ function elementMatcher( matchers ) {
2233
+ return matchers.length > 1 ?
2234
+ function( elem, context, xml ) {
2235
+ var i = matchers.length;
2236
+ while ( i-- ) {
2237
+ if ( !matchers[i]( elem, context, xml ) ) {
2238
+ return false;
2239
+ }
2240
+ }
2241
+ return true;
2242
+ } :
2243
+ matchers[0];
2244
+ }
2245
+
2246
+ function multipleContexts( selector, contexts, results ) {
2247
+ var i = 0,
2248
+ len = contexts.length;
2249
+ for ( ; i < len; i++ ) {
2250
+ Sizzle( selector, contexts[i], results );
2251
+ }
2252
+ return results;
2253
+ }
2254
+
2255
+ function condense( unmatched, map, filter, context, xml ) {
2256
+ var elem,
2257
+ newUnmatched = [],
2258
+ i = 0,
2259
+ len = unmatched.length,
2260
+ mapped = map != null;
2261
+
2262
+ for ( ; i < len; i++ ) {
2263
+ if ( (elem = unmatched[i]) ) {
2264
+ if ( !filter || filter( elem, context, xml ) ) {
2265
+ newUnmatched.push( elem );
2266
+ if ( mapped ) {
2267
+ map.push( i );
2268
+ }
2269
+ }
2270
+ }
2271
+ }
2272
+
2273
+ return newUnmatched;
2274
+ }
2275
+
2276
+ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2277
+ if ( postFilter && !postFilter[ expando ] ) {
2278
+ postFilter = setMatcher( postFilter );
2279
+ }
2280
+ if ( postFinder && !postFinder[ expando ] ) {
2281
+ postFinder = setMatcher( postFinder, postSelector );
2282
+ }
2283
+ return markFunction(function( seed, results, context, xml ) {
2284
+ var temp, i, elem,
2285
+ preMap = [],
2286
+ postMap = [],
2287
+ preexisting = results.length,
2288
+
2289
+ // Get initial elements from seed or context
2290
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2291
+
2292
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
2293
+ matcherIn = preFilter && ( seed || !selector ) ?
2294
+ condense( elems, preMap, preFilter, context, xml ) :
2295
+ elems,
2296
+
2297
+ matcherOut = matcher ?
2298
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2299
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2300
+
2301
+ // ...intermediate processing is necessary
2302
+ [] :
2303
+
2304
+ // ...otherwise use results directly
2305
+ results :
2306
+ matcherIn;
2307
+
2308
+ // Find primary matches
2309
+ if ( matcher ) {
2310
+ matcher( matcherIn, matcherOut, context, xml );
2311
+ }
2312
+
2313
+ // Apply postFilter
2314
+ if ( postFilter ) {
2315
+ temp = condense( matcherOut, postMap );
2316
+ postFilter( temp, [], context, xml );
2317
+
2318
+ // Un-match failing elements by moving them back to matcherIn
2319
+ i = temp.length;
2320
+ while ( i-- ) {
2321
+ if ( (elem = temp[i]) ) {
2322
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2323
+ }
2324
+ }
2325
+ }
2326
+
2327
+ if ( seed ) {
2328
+ if ( postFinder || preFilter ) {
2329
+ if ( postFinder ) {
2330
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
2331
+ temp = [];
2332
+ i = matcherOut.length;
2333
+ while ( i-- ) {
2334
+ if ( (elem = matcherOut[i]) ) {
2335
+ // Restore matcherIn since elem is not yet a final match
2336
+ temp.push( (matcherIn[i] = elem) );
2337
+ }
2338
+ }
2339
+ postFinder( null, (matcherOut = []), temp, xml );
2340
+ }
2341
+
2342
+ // Move matched elements from seed to results to keep them synchronized
2343
+ i = matcherOut.length;
2344
+ while ( i-- ) {
2345
+ if ( (elem = matcherOut[i]) &&
2346
+ (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2347
+
2348
+ seed[temp] = !(results[temp] = elem);
2349
+ }
2350
+ }
2351
+ }
2352
+
2353
+ // Add elements to results, through postFinder if defined
2354
+ } else {
2355
+ matcherOut = condense(
2356
+ matcherOut === results ?
2357
+ matcherOut.splice( preexisting, matcherOut.length ) :
2358
+ matcherOut
2359
+ );
2360
+ if ( postFinder ) {
2361
+ postFinder( null, results, matcherOut, xml );
2362
+ } else {
2363
+ push.apply( results, matcherOut );
2364
+ }
2365
+ }
2366
+ });
2367
+ }
2368
+
2369
+ function matcherFromTokens( tokens ) {
2370
+ var checkContext, matcher, j,
2371
+ len = tokens.length,
2372
+ leadingRelative = Expr.relative[ tokens[0].type ],
2373
+ implicitRelative = leadingRelative || Expr.relative[" "],
2374
+ i = leadingRelative ? 1 : 0,
2375
+
2376
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
2377
+ matchContext = addCombinator( function( elem ) {
2378
+ return elem === checkContext;
2379
+ }, implicitRelative, true ),
2380
+ matchAnyContext = addCombinator( function( elem ) {
2381
+ return indexOf( checkContext, elem ) > -1;
2382
+ }, implicitRelative, true ),
2383
+ matchers = [ function( elem, context, xml ) {
2384
+ var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2385
+ (checkContext = context).nodeType ?
2386
+ matchContext( elem, context, xml ) :
2387
+ matchAnyContext( elem, context, xml ) );
2388
+ // Avoid hanging onto element (issue #299)
2389
+ checkContext = null;
2390
+ return ret;
2391
+ } ];
2392
+
2393
+ for ( ; i < len; i++ ) {
2394
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2395
+ matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2396
+ } else {
2397
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2398
+
2399
+ // Return special upon seeing a positional matcher
2400
+ if ( matcher[ expando ] ) {
2401
+ // Find the next relative operator (if any) for proper handling
2402
+ j = ++i;
2403
+ for ( ; j < len; j++ ) {
2404
+ if ( Expr.relative[ tokens[j].type ] ) {
2405
+ break;
2406
+ }
2407
+ }
2408
+ return setMatcher(
2409
+ i > 1 && elementMatcher( matchers ),
2410
+ i > 1 && toSelector(
2411
+ // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2412
+ tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2413
+ ).replace( rtrim, "$1" ),
2414
+ matcher,
2415
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
2416
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2417
+ j < len && toSelector( tokens )
2418
+ );
2419
+ }
2420
+ matchers.push( matcher );
2421
+ }
2422
+ }
2423
+
2424
+ return elementMatcher( matchers );
2425
+ }
2426
+
2427
+ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2428
+ var bySet = setMatchers.length > 0,
2429
+ byElement = elementMatchers.length > 0,
2430
+ superMatcher = function( seed, context, xml, results, outermost ) {
2431
+ var elem, j, matcher,
2432
+ matchedCount = 0,
2433
+ i = "0",
2434
+ unmatched = seed && [],
2435
+ setMatched = [],
2436
+ contextBackup = outermostContext,
2437
+ // We must always have either seed elements or outermost context
2438
+ elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2439
+ // Use integer dirruns iff this is the outermost matcher
2440
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2441
+ len = elems.length;
2442
+
2443
+ if ( outermost ) {
2444
+ outermostContext = context === document || context || outermost;
2445
+ }
2446
+
2447
+ // Add elements passing elementMatchers directly to results
2448
+ // Support: IE<9, Safari
2449
+ // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2450
+ for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2451
+ if ( byElement && elem ) {
2452
+ j = 0;
2453
+ if ( !context && elem.ownerDocument !== document ) {
2454
+ setDocument( elem );
2455
+ xml = !documentIsHTML;
2456
+ }
2457
+ while ( (matcher = elementMatchers[j++]) ) {
2458
+ if ( matcher( elem, context || document, xml) ) {
2459
+ results.push( elem );
2460
+ break;
2461
+ }
2462
+ }
2463
+ if ( outermost ) {
2464
+ dirruns = dirrunsUnique;
2465
+ }
2466
+ }
2467
+
2468
+ // Track unmatched elements for set filters
2469
+ if ( bySet ) {
2470
+ // They will have gone through all possible matchers
2471
+ if ( (elem = !matcher && elem) ) {
2472
+ matchedCount--;
2473
+ }
2474
+
2475
+ // Lengthen the array for every element, matched or not
2476
+ if ( seed ) {
2477
+ unmatched.push( elem );
2478
+ }
2479
+ }
2480
+ }
2481
+
2482
+ // `i` is now the count of elements visited above, and adding it to `matchedCount`
2483
+ // makes the latter nonnegative.
2484
+ matchedCount += i;
2485
+
2486
+ // Apply set filters to unmatched elements
2487
+ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2488
+ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2489
+ // no element matchers and no seed.
2490
+ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2491
+ // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2492
+ // numerically zero.
2493
+ if ( bySet && i !== matchedCount ) {
2494
+ j = 0;
2495
+ while ( (matcher = setMatchers[j++]) ) {
2496
+ matcher( unmatched, setMatched, context, xml );
2497
+ }
2498
+
2499
+ if ( seed ) {
2500
+ // Reintegrate element matches to eliminate the need for sorting
2501
+ if ( matchedCount > 0 ) {
2502
+ while ( i-- ) {
2503
+ if ( !(unmatched[i] || setMatched[i]) ) {
2504
+ setMatched[i] = pop.call( results );
2505
+ }
2506
+ }
2507
+ }
2508
+
2509
+ // Discard index placeholder values to get only actual matches
2510
+ setMatched = condense( setMatched );
2511
+ }
2512
+
2513
+ // Add matches to results
2514
+ push.apply( results, setMatched );
2515
+
2516
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
2517
+ if ( outermost && !seed && setMatched.length > 0 &&
2518
+ ( matchedCount + setMatchers.length ) > 1 ) {
2519
+
2520
+ Sizzle.uniqueSort( results );
2521
+ }
2522
+ }
2523
+
2524
+ // Override manipulation of globals by nested matchers
2525
+ if ( outermost ) {
2526
+ dirruns = dirrunsUnique;
2527
+ outermostContext = contextBackup;
2528
+ }
2529
+
2530
+ return unmatched;
2531
+ };
2532
+
2533
+ return bySet ?
2534
+ markFunction( superMatcher ) :
2535
+ superMatcher;
2536
+ }
2537
+
2538
+ compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2539
+ var i,
2540
+ setMatchers = [],
2541
+ elementMatchers = [],
2542
+ cached = compilerCache[ selector + " " ];
2543
+
2544
+ if ( !cached ) {
2545
+ // Generate a function of recursive functions that can be used to check each element
2546
+ if ( !match ) {
2547
+ match = tokenize( selector );
2548
+ }
2549
+ i = match.length;
2550
+ while ( i-- ) {
2551
+ cached = matcherFromTokens( match[i] );
2552
+ if ( cached[ expando ] ) {
2553
+ setMatchers.push( cached );
2554
+ } else {
2555
+ elementMatchers.push( cached );
2556
+ }
2557
+ }
2558
+
2559
+ // Cache the compiled function
2560
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2561
+
2562
+ // Save selector and tokenization
2563
+ cached.selector = selector;
2564
+ }
2565
+ return cached;
2566
+ };
2567
+
2568
+ /**
2569
+ * A low-level selection function that works with Sizzle's compiled
2570
+ * selector functions
2571
+ * @param {String|Function} selector A selector or a pre-compiled
2572
+ * selector function built with Sizzle.compile
2573
+ * @param {Element} context
2574
+ * @param {Array} [results]
2575
+ * @param {Array} [seed] A set of elements to match against
2576
+ */
2577
+ select = Sizzle.select = function( selector, context, results, seed ) {
2578
+ var i, tokens, token, type, find,
2579
+ compiled = typeof selector === "function" && selector,
2580
+ match = !seed && tokenize( (selector = compiled.selector || selector) );
2581
+
2582
+ results = results || [];
2583
+
2584
+ // Try to minimize operations if there is only one selector in the list and no seed
2585
+ // (the latter of which guarantees us context)
2586
+ if ( match.length === 1 ) {
2587
+
2588
+ // Reduce context if the leading compound selector is an ID
2589
+ tokens = match[0] = match[0].slice( 0 );
2590
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2591
+ support.getById && context.nodeType === 9 && documentIsHTML &&
2592
+ Expr.relative[ tokens[1].type ] ) {
2593
+
2594
+ context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2595
+ if ( !context ) {
2596
+ return results;
2597
+
2598
+ // Precompiled matchers will still verify ancestry, so step up a level
2599
+ } else if ( compiled ) {
2600
+ context = context.parentNode;
2601
+ }
2602
+
2603
+ selector = selector.slice( tokens.shift().value.length );
2604
+ }
2605
+
2606
+ // Fetch a seed set for right-to-left matching
2607
+ i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2608
+ while ( i-- ) {
2609
+ token = tokens[i];
2610
+
2611
+ // Abort if we hit a combinator
2612
+ if ( Expr.relative[ (type = token.type) ] ) {
2613
+ break;
2614
+ }
2615
+ if ( (find = Expr.find[ type ]) ) {
2616
+ // Search, expanding context for leading sibling combinators
2617
+ if ( (seed = find(
2618
+ token.matches[0].replace( runescape, funescape ),
2619
+ rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2620
+ )) ) {
2621
+
2622
+ // If seed is empty or no tokens remain, we can return early
2623
+ tokens.splice( i, 1 );
2624
+ selector = seed.length && toSelector( tokens );
2625
+ if ( !selector ) {
2626
+ push.apply( results, seed );
2627
+ return results;
2628
+ }
2629
+
2630
+ break;
2631
+ }
2632
+ }
2633
+ }
2634
+ }
2635
+
2636
+ // Compile and execute a filtering function if one is not provided
2637
+ // Provide `match` to avoid retokenization if we modified the selector above
2638
+ ( compiled || compile( selector, match ) )(
2639
+ seed,
2640
+ context,
2641
+ !documentIsHTML,
2642
+ results,
2643
+ !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2644
+ );
2645
+ return results;
2646
+ };
2647
+
2648
+ // One-time assignments
2649
+
2650
+ // Sort stability
2651
+ support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2652
+
2653
+ // Support: Chrome 14-35+
2654
+ // Always assume duplicates if they aren't passed to the comparison function
2655
+ support.detectDuplicates = !!hasDuplicate;
2656
+
2657
+ // Initialize against the default document
2658
+ setDocument();
2659
+
2660
+ // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2661
+ // Detached nodes confoundingly follow *each other*
2662
+ support.sortDetached = assert(function( div1 ) {
2663
+ // Should return 1, but returns 4 (following)
2664
+ return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2665
+ });
2666
+
2667
+ // Support: IE<8
2668
+ // Prevent attribute/property "interpolation"
2669
+ // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2670
+ if ( !assert(function( div ) {
2671
+ div.innerHTML = "<a href='#'></a>";
2672
+ return div.firstChild.getAttribute("href") === "#" ;
2673
+ }) ) {
2674
+ addHandle( "type|href|height|width", function( elem, name, isXML ) {
2675
+ if ( !isXML ) {
2676
+ return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2677
+ }
2678
+ });
2679
+ }
2680
+
2681
+ // Support: IE<9
2682
+ // Use defaultValue in place of getAttribute("value")
2683
+ if ( !support.attributes || !assert(function( div ) {
2684
+ div.innerHTML = "<input/>";
2685
+ div.firstChild.setAttribute( "value", "" );
2686
+ return div.firstChild.getAttribute( "value" ) === "";
2687
+ }) ) {
2688
+ addHandle( "value", function( elem, name, isXML ) {
2689
+ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2690
+ return elem.defaultValue;
2691
+ }
2692
+ });
2693
+ }
2694
+
2695
+ // Support: IE<9
2696
+ // Use getAttributeNode to fetch booleans when getAttribute lies
2697
+ if ( !assert(function( div ) {
2698
+ return div.getAttribute("disabled") == null;
2699
+ }) ) {
2700
+ addHandle( booleans, function( elem, name, isXML ) {
2701
+ var val;
2702
+ if ( !isXML ) {
2703
+ return elem[ name ] === true ? name.toLowerCase() :
2704
+ (val = elem.getAttributeNode( name )) && val.specified ?
2705
+ val.value :
2706
+ null;
2707
+ }
2708
+ });
2709
+ }
2710
+
2711
+ return Sizzle;
2712
+
2713
+ })( window );
2714
+
2715
+
2716
+
2717
+ jQuery.find = Sizzle;
2718
+ jQuery.expr = Sizzle.selectors;
2719
+ jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2720
+ jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2721
+ jQuery.text = Sizzle.getText;
2722
+ jQuery.isXMLDoc = Sizzle.isXML;
2723
+ jQuery.contains = Sizzle.contains;
2724
+
2725
+
2726
+
2727
+ var dir = function( elem, dir, until ) {
2728
+ var matched = [],
2729
+ truncate = until !== undefined;
2730
+
2731
+ while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2732
+ if ( elem.nodeType === 1 ) {
2733
+ if ( truncate && jQuery( elem ).is( until ) ) {
2734
+ break;
2735
+ }
2736
+ matched.push( elem );
2737
+ }
2738
+ }
2739
+ return matched;
2740
+ };
2741
+
2742
+
2743
+ var siblings = function( n, elem ) {
2744
+ var matched = [];
2745
+
2746
+ for ( ; n; n = n.nextSibling ) {
2747
+ if ( n.nodeType === 1 && n !== elem ) {
2748
+ matched.push( n );
2749
+ }
2750
+ }
2751
+
2752
+ return matched;
2753
+ };
2754
+
2755
+
2756
+ var rneedsContext = jQuery.expr.match.needsContext;
2757
+
2758
+ var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
2759
+
2760
+
2761
+
2762
+ var risSimple = /^.[^:#\[\.,]*$/;
2763
+
2764
+ // Implement the identical functionality for filter and not
2765
+ function winnow( elements, qualifier, not ) {
2766
+ if ( jQuery.isFunction( qualifier ) ) {
2767
+ return jQuery.grep( elements, function( elem, i ) {
2768
+ /* jshint -W018 */
2769
+ return !!qualifier.call( elem, i, elem ) !== not;
2770
+ } );
2771
+
2772
+ }
2773
+
2774
+ if ( qualifier.nodeType ) {
2775
+ return jQuery.grep( elements, function( elem ) {
2776
+ return ( elem === qualifier ) !== not;
2777
+ } );
2778
+
2779
+ }
2780
+
2781
+ if ( typeof qualifier === "string" ) {
2782
+ if ( risSimple.test( qualifier ) ) {
2783
+ return jQuery.filter( qualifier, elements, not );
2784
+ }
2785
+
2786
+ qualifier = jQuery.filter( qualifier, elements );
2787
+ }
2788
+
2789
+ return jQuery.grep( elements, function( elem ) {
2790
+ return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not;
2791
+ } );
2792
+ }
2793
+
2794
+ jQuery.filter = function( expr, elems, not ) {
2795
+ var elem = elems[ 0 ];
2796
+
2797
+ if ( not ) {
2798
+ expr = ":not(" + expr + ")";
2799
+ }
2800
+
2801
+ return elems.length === 1 && elem.nodeType === 1 ?
2802
+ jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2803
+ jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2804
+ return elem.nodeType === 1;
2805
+ } ) );
2806
+ };
2807
+
2808
+ jQuery.fn.extend( {
2809
+ find: function( selector ) {
2810
+ var i,
2811
+ ret = [],
2812
+ self = this,
2813
+ len = self.length;
2814
+
2815
+ if ( typeof selector !== "string" ) {
2816
+ return this.pushStack( jQuery( selector ).filter( function() {
2817
+ for ( i = 0; i < len; i++ ) {
2818
+ if ( jQuery.contains( self[ i ], this ) ) {
2819
+ return true;
2820
+ }
2821
+ }
2822
+ } ) );
2823
+ }
2824
+
2825
+ for ( i = 0; i < len; i++ ) {
2826
+ jQuery.find( selector, self[ i ], ret );
2827
+ }
2828
+
2829
+ // Needed because $( selector, context ) becomes $( context ).find( selector )
2830
+ ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2831
+ ret.selector = this.selector ? this.selector + " " + selector : selector;
2832
+ return ret;
2833
+ },
2834
+ filter: function( selector ) {
2835
+ return this.pushStack( winnow( this, selector || [], false ) );
2836
+ },
2837
+ not: function( selector ) {
2838
+ return this.pushStack( winnow( this, selector || [], true ) );
2839
+ },
2840
+ is: function( selector ) {
2841
+ return !!winnow(
2842
+ this,
2843
+
2844
+ // If this is a positional/relative selector, check membership in the returned set
2845
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
2846
+ typeof selector === "string" && rneedsContext.test( selector ) ?
2847
+ jQuery( selector ) :
2848
+ selector || [],
2849
+ false
2850
+ ).length;
2851
+ }
2852
+ } );
2853
+
2854
+
2855
+ // Initialize a jQuery object
2856
+
2857
+
2858
+ // A central reference to the root jQuery(document)
2859
+ var rootjQuery,
2860
+
2861
+ // A simple way to check for HTML strings
2862
+ // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2863
+ // Strict HTML recognition (#11290: must start with <)
2864
+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2865
+
2866
+ init = jQuery.fn.init = function( selector, context, root ) {
2867
+ var match, elem;
2868
+
2869
+ // HANDLE: $(""), $(null), $(undefined), $(false)
2870
+ if ( !selector ) {
2871
+ return this;
2872
+ }
2873
+
2874
+ // init accepts an alternate rootjQuery
2875
+ // so migrate can support jQuery.sub (gh-2101)
2876
+ root = root || rootjQuery;
2877
+
2878
+ // Handle HTML strings
2879
+ if ( typeof selector === "string" ) {
2880
+ if ( selector.charAt( 0 ) === "<" &&
2881
+ selector.charAt( selector.length - 1 ) === ">" &&
2882
+ selector.length >= 3 ) {
2883
+
2884
+ // Assume that strings that start and end with <> are HTML and skip the regex check
2885
+ match = [ null, selector, null ];
2886
+
2887
+ } else {
2888
+ match = rquickExpr.exec( selector );
2889
+ }
2890
+
2891
+ // Match html or make sure no context is specified for #id
2892
+ if ( match && ( match[ 1 ] || !context ) ) {
2893
+
2894
+ // HANDLE: $(html) -> $(array)
2895
+ if ( match[ 1 ] ) {
2896
+ context = context instanceof jQuery ? context[ 0 ] : context;
2897
+
2898
+ // scripts is true for back-compat
2899
+ // Intentionally let the error be thrown if parseHTML is not present
2900
+ jQuery.merge( this, jQuery.parseHTML(
2901
+ match[ 1 ],
2902
+ context && context.nodeType ? context.ownerDocument || context : document,
2903
+ true
2904
+ ) );
2905
+
2906
+ // HANDLE: $(html, props)
2907
+ if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
2908
+ for ( match in context ) {
2909
+
2910
+ // Properties of context are called as methods if possible
2911
+ if ( jQuery.isFunction( this[ match ] ) ) {
2912
+ this[ match ]( context[ match ] );
2913
+
2914
+ // ...and otherwise set as attributes
2915
+ } else {
2916
+ this.attr( match, context[ match ] );
2917
+ }
2918
+ }
2919
+ }
2920
+
2921
+ return this;
2922
+
2923
+ // HANDLE: $(#id)
2924
+ } else {
2925
+ elem = document.getElementById( match[ 2 ] );
2926
+
2927
+ // Check parentNode to catch when Blackberry 4.6 returns
2928
+ // nodes that are no longer in the document #6963
2929
+ if ( elem && elem.parentNode ) {
2930
+
2931
+ // Handle the case where IE and Opera return items
2932
+ // by name instead of ID
2933
+ if ( elem.id !== match[ 2 ] ) {
2934
+ return rootjQuery.find( selector );
2935
+ }
2936
+
2937
+ // Otherwise, we inject the element directly into the jQuery object
2938
+ this.length = 1;
2939
+ this[ 0 ] = elem;
2940
+ }
2941
+
2942
+ this.context = document;
2943
+ this.selector = selector;
2944
+ return this;
2945
+ }
2946
+
2947
+ // HANDLE: $(expr, $(...))
2948
+ } else if ( !context || context.jquery ) {
2949
+ return ( context || root ).find( selector );
2950
+
2951
+ // HANDLE: $(expr, context)
2952
+ // (which is just equivalent to: $(context).find(expr)
2953
+ } else {
2954
+ return this.constructor( context ).find( selector );
2955
+ }
2956
+
2957
+ // HANDLE: $(DOMElement)
2958
+ } else if ( selector.nodeType ) {
2959
+ this.context = this[ 0 ] = selector;
2960
+ this.length = 1;
2961
+ return this;
2962
+
2963
+ // HANDLE: $(function)
2964
+ // Shortcut for document ready
2965
+ } else if ( jQuery.isFunction( selector ) ) {
2966
+ return typeof root.ready !== "undefined" ?
2967
+ root.ready( selector ) :
2968
+
2969
+ // Execute immediately if ready is not present
2970
+ selector( jQuery );
2971
+ }
2972
+
2973
+ if ( selector.selector !== undefined ) {
2974
+ this.selector = selector.selector;
2975
+ this.context = selector.context;
2976
+ }
2977
+
2978
+ return jQuery.makeArray( selector, this );
2979
+ };
2980
+
2981
+ // Give the init function the jQuery prototype for later instantiation
2982
+ init.prototype = jQuery.fn;
2983
+
2984
+ // Initialize central reference
2985
+ rootjQuery = jQuery( document );
2986
+
2987
+
2988
+ var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2989
+
2990
+ // methods guaranteed to produce a unique set when starting from a unique set
2991
+ guaranteedUnique = {
2992
+ children: true,
2993
+ contents: true,
2994
+ next: true,
2995
+ prev: true
2996
+ };
2997
+
2998
+ jQuery.fn.extend( {
2999
+ has: function( target ) {
3000
+ var i,
3001
+ targets = jQuery( target, this ),
3002
+ len = targets.length;
3003
+
3004
+ return this.filter( function() {
3005
+ for ( i = 0; i < len; i++ ) {
3006
+ if ( jQuery.contains( this, targets[ i ] ) ) {
3007
+ return true;
3008
+ }
3009
+ }
3010
+ } );
3011
+ },
3012
+
3013
+ closest: function( selectors, context ) {
3014
+ var cur,
3015
+ i = 0,
3016
+ l = this.length,
3017
+ matched = [],
3018
+ pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
3019
+ jQuery( selectors, context || this.context ) :
3020
+ 0;
3021
+
3022
+ for ( ; i < l; i++ ) {
3023
+ for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3024
+
3025
+ // Always skip document fragments
3026
+ if ( cur.nodeType < 11 && ( pos ?
3027
+ pos.index( cur ) > -1 :
3028
+
3029
+ // Don't pass non-elements to Sizzle
3030
+ cur.nodeType === 1 &&
3031
+ jQuery.find.matchesSelector( cur, selectors ) ) ) {
3032
+
3033
+ matched.push( cur );
3034
+ break;
3035
+ }
3036
+ }
3037
+ }
3038
+
3039
+ return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3040
+ },
3041
+
3042
+ // Determine the position of an element within
3043
+ // the matched set of elements
3044
+ index: function( elem ) {
3045
+
3046
+ // No argument, return index in parent
3047
+ if ( !elem ) {
3048
+ return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3049
+ }
3050
+
3051
+ // index in selector
3052
+ if ( typeof elem === "string" ) {
3053
+ return jQuery.inArray( this[ 0 ], jQuery( elem ) );
3054
+ }
3055
+
3056
+ // Locate the position of the desired element
3057
+ return jQuery.inArray(
3058
+
3059
+ // If it receives a jQuery object, the first element is used
3060
+ elem.jquery ? elem[ 0 ] : elem, this );
3061
+ },
3062
+
3063
+ add: function( selector, context ) {
3064
+ return this.pushStack(
3065
+ jQuery.uniqueSort(
3066
+ jQuery.merge( this.get(), jQuery( selector, context ) )
3067
+ )
3068
+ );
3069
+ },
3070
+
3071
+ addBack: function( selector ) {
3072
+ return this.add( selector == null ?
3073
+ this.prevObject : this.prevObject.filter( selector )
3074
+ );
3075
+ }
3076
+ } );
3077
+
3078
+ function sibling( cur, dir ) {
3079
+ do {
3080
+ cur = cur[ dir ];
3081
+ } while ( cur && cur.nodeType !== 1 );
3082
+
3083
+ return cur;
3084
+ }
3085
+
3086
+ jQuery.each( {
3087
+ parent: function( elem ) {
3088
+ var parent = elem.parentNode;
3089
+ return parent && parent.nodeType !== 11 ? parent : null;
3090
+ },
3091
+ parents: function( elem ) {
3092
+ return dir( elem, "parentNode" );
3093
+ },
3094
+ parentsUntil: function( elem, i, until ) {
3095
+ return dir( elem, "parentNode", until );
3096
+ },
3097
+ next: function( elem ) {
3098
+ return sibling( elem, "nextSibling" );
3099
+ },
3100
+ prev: function( elem ) {
3101
+ return sibling( elem, "previousSibling" );
3102
+ },
3103
+ nextAll: function( elem ) {
3104
+ return dir( elem, "nextSibling" );
3105
+ },
3106
+ prevAll: function( elem ) {
3107
+ return dir( elem, "previousSibling" );
3108
+ },
3109
+ nextUntil: function( elem, i, until ) {
3110
+ return dir( elem, "nextSibling", until );
3111
+ },
3112
+ prevUntil: function( elem, i, until ) {
3113
+ return dir( elem, "previousSibling", until );
3114
+ },
3115
+ siblings: function( elem ) {
3116
+ return siblings( ( elem.parentNode || {} ).firstChild, elem );
3117
+ },
3118
+ children: function( elem ) {
3119
+ return siblings( elem.firstChild );
3120
+ },
3121
+ contents: function( elem ) {
3122
+ return jQuery.nodeName( elem, "iframe" ) ?
3123
+ elem.contentDocument || elem.contentWindow.document :
3124
+ jQuery.merge( [], elem.childNodes );
3125
+ }
3126
+ }, function( name, fn ) {
3127
+ jQuery.fn[ name ] = function( until, selector ) {
3128
+ var ret = jQuery.map( this, fn, until );
3129
+
3130
+ if ( name.slice( -5 ) !== "Until" ) {
3131
+ selector = until;
3132
+ }
3133
+
3134
+ if ( selector && typeof selector === "string" ) {
3135
+ ret = jQuery.filter( selector, ret );
3136
+ }
3137
+
3138
+ if ( this.length > 1 ) {
3139
+
3140
+ // Remove duplicates
3141
+ if ( !guaranteedUnique[ name ] ) {
3142
+ ret = jQuery.uniqueSort( ret );
3143
+ }
3144
+
3145
+ // Reverse order for parents* and prev-derivatives
3146
+ if ( rparentsprev.test( name ) ) {
3147
+ ret = ret.reverse();
3148
+ }
3149
+ }
3150
+
3151
+ return this.pushStack( ret );
3152
+ };
3153
+ } );
3154
+ var rnotwhite = ( /\S+/g );
3155
+
3156
+
3157
+
3158
+ // Convert String-formatted options into Object-formatted ones
3159
+ function createOptions( options ) {
3160
+ var object = {};
3161
+ jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3162
+ object[ flag ] = true;
3163
+ } );
3164
+ return object;
3165
+ }
3166
+
3167
+ /*
3168
+ * Create a callback list using the following parameters:
3169
+ *
3170
+ * options: an optional list of space-separated options that will change how
3171
+ * the callback list behaves or a more traditional option object
3172
+ *
3173
+ * By default a callback list will act like an event callback list and can be
3174
+ * "fired" multiple times.
3175
+ *
3176
+ * Possible options:
3177
+ *
3178
+ * once: will ensure the callback list can only be fired once (like a Deferred)
3179
+ *
3180
+ * memory: will keep track of previous values and will call any callback added
3181
+ * after the list has been fired right away with the latest "memorized"
3182
+ * values (like a Deferred)
3183
+ *
3184
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
3185
+ *
3186
+ * stopOnFalse: interrupt callings when a callback returns false
3187
+ *
3188
+ */
3189
+ jQuery.Callbacks = function( options ) {
3190
+
3191
+ // Convert options from String-formatted to Object-formatted if needed
3192
+ // (we check in cache first)
3193
+ options = typeof options === "string" ?
3194
+ createOptions( options ) :
3195
+ jQuery.extend( {}, options );
3196
+
3197
+ var // Flag to know if list is currently firing
3198
+ firing,
3199
+
3200
+ // Last fire value for non-forgettable lists
3201
+ memory,
3202
+
3203
+ // Flag to know if list was already fired
3204
+ fired,
3205
+
3206
+ // Flag to prevent firing
3207
+ locked,
3208
+
3209
+ // Actual callback list
3210
+ list = [],
3211
+
3212
+ // Queue of execution data for repeatable lists
3213
+ queue = [],
3214
+
3215
+ // Index of currently firing callback (modified by add/remove as needed)
3216
+ firingIndex = -1,
3217
+
3218
+ // Fire callbacks
3219
+ fire = function() {
3220
+
3221
+ // Enforce single-firing
3222
+ locked = options.once;
3223
+
3224
+ // Execute callbacks for all pending executions,
3225
+ // respecting firingIndex overrides and runtime changes
3226
+ fired = firing = true;
3227
+ for ( ; queue.length; firingIndex = -1 ) {
3228
+ memory = queue.shift();
3229
+ while ( ++firingIndex < list.length ) {
3230
+
3231
+ // Run callback and check for early termination
3232
+ if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3233
+ options.stopOnFalse ) {
3234
+
3235
+ // Jump to end and forget the data so .add doesn't re-fire
3236
+ firingIndex = list.length;
3237
+ memory = false;
3238
+ }
3239
+ }
3240
+ }
3241
+
3242
+ // Forget the data if we're done with it
3243
+ if ( !options.memory ) {
3244
+ memory = false;
3245
+ }
3246
+
3247
+ firing = false;
3248
+
3249
+ // Clean up if we're done firing for good
3250
+ if ( locked ) {
3251
+
3252
+ // Keep an empty list if we have data for future add calls
3253
+ if ( memory ) {
3254
+ list = [];
3255
+
3256
+ // Otherwise, this object is spent
3257
+ } else {
3258
+ list = "";
3259
+ }
3260
+ }
3261
+ },
3262
+
3263
+ // Actual Callbacks object
3264
+ self = {
3265
+
3266
+ // Add a callback or a collection of callbacks to the list
3267
+ add: function() {
3268
+ if ( list ) {
3269
+
3270
+ // If we have memory from a past run, we should fire after adding
3271
+ if ( memory && !firing ) {
3272
+ firingIndex = list.length - 1;
3273
+ queue.push( memory );
3274
+ }
3275
+
3276
+ ( function add( args ) {
3277
+ jQuery.each( args, function( _, arg ) {
3278
+ if ( jQuery.isFunction( arg ) ) {
3279
+ if ( !options.unique || !self.has( arg ) ) {
3280
+ list.push( arg );
3281
+ }
3282
+ } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3283
+
3284
+ // Inspect recursively
3285
+ add( arg );
3286
+ }
3287
+ } );
3288
+ } )( arguments );
3289
+
3290
+ if ( memory && !firing ) {
3291
+ fire();
3292
+ }
3293
+ }
3294
+ return this;
3295
+ },
3296
+
3297
+ // Remove a callback from the list
3298
+ remove: function() {
3299
+ jQuery.each( arguments, function( _, arg ) {
3300
+ var index;
3301
+ while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3302
+ list.splice( index, 1 );
3303
+
3304
+ // Handle firing indexes
3305
+ if ( index <= firingIndex ) {
3306
+ firingIndex--;
3307
+ }
3308
+ }
3309
+ } );
3310
+ return this;
3311
+ },
3312
+
3313
+ // Check if a given callback is in the list.
3314
+ // If no argument is given, return whether or not list has callbacks attached.
3315
+ has: function( fn ) {
3316
+ return fn ?
3317
+ jQuery.inArray( fn, list ) > -1 :
3318
+ list.length > 0;
3319
+ },
3320
+
3321
+ // Remove all callbacks from the list
3322
+ empty: function() {
3323
+ if ( list ) {
3324
+ list = [];
3325
+ }
3326
+ return this;
3327
+ },
3328
+
3329
+ // Disable .fire and .add
3330
+ // Abort any current/pending executions
3331
+ // Clear all callbacks and values
3332
+ disable: function() {
3333
+ locked = queue = [];
3334
+ list = memory = "";
3335
+ return this;
3336
+ },
3337
+ disabled: function() {
3338
+ return !list;
3339
+ },
3340
+
3341
+ // Disable .fire
3342
+ // Also disable .add unless we have memory (since it would have no effect)
3343
+ // Abort any pending executions
3344
+ lock: function() {
3345
+ locked = true;
3346
+ if ( !memory ) {
3347
+ self.disable();
3348
+ }
3349
+ return this;
3350
+ },
3351
+ locked: function() {
3352
+ return !!locked;
3353
+ },
3354
+
3355
+ // Call all callbacks with the given context and arguments
3356
+ fireWith: function( context, args ) {
3357
+ if ( !locked ) {
3358
+ args = args || [];
3359
+ args = [ context, args.slice ? args.slice() : args ];
3360
+ queue.push( args );
3361
+ if ( !firing ) {
3362
+ fire();
3363
+ }
3364
+ }
3365
+ return this;
3366
+ },
3367
+
3368
+ // Call all the callbacks with the given arguments
3369
+ fire: function() {
3370
+ self.fireWith( this, arguments );
3371
+ return this;
3372
+ },
3373
+
3374
+ // To know if the callbacks have already been called at least once
3375
+ fired: function() {
3376
+ return !!fired;
3377
+ }
3378
+ };
3379
+
3380
+ return self;
3381
+ };
3382
+
3383
+
3384
+ jQuery.extend( {
3385
+
3386
+ Deferred: function( func ) {
3387
+ var tuples = [
3388
+
3389
+ // action, add listener, listener list, final state
3390
+ [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
3391
+ [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
3392
+ [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
3393
+ ],
3394
+ state = "pending",
3395
+ promise = {
3396
+ state: function() {
3397
+ return state;
3398
+ },
3399
+ always: function() {
3400
+ deferred.done( arguments ).fail( arguments );
3401
+ return this;
3402
+ },
3403
+ then: function( /* fnDone, fnFail, fnProgress */ ) {
3404
+ var fns = arguments;
3405
+ return jQuery.Deferred( function( newDefer ) {
3406
+ jQuery.each( tuples, function( i, tuple ) {
3407
+ var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3408
+
3409
+ // deferred[ done | fail | progress ] for forwarding actions to newDefer
3410
+ deferred[ tuple[ 1 ] ]( function() {
3411
+ var returned = fn && fn.apply( this, arguments );
3412
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
3413
+ returned.promise()
3414
+ .progress( newDefer.notify )
3415
+ .done( newDefer.resolve )
3416
+ .fail( newDefer.reject );
3417
+ } else {
3418
+ newDefer[ tuple[ 0 ] + "With" ](
3419
+ this === promise ? newDefer.promise() : this,
3420
+ fn ? [ returned ] : arguments
3421
+ );
3422
+ }
3423
+ } );
3424
+ } );
3425
+ fns = null;
3426
+ } ).promise();
3427
+ },
3428
+
3429
+ // Get a promise for this deferred
3430
+ // If obj is provided, the promise aspect is added to the object
3431
+ promise: function( obj ) {
3432
+ return obj != null ? jQuery.extend( obj, promise ) : promise;
3433
+ }
3434
+ },
3435
+ deferred = {};
3436
+
3437
+ // Keep pipe for back-compat
3438
+ promise.pipe = promise.then;
3439
+
3440
+ // Add list-specific methods
3441
+ jQuery.each( tuples, function( i, tuple ) {
3442
+ var list = tuple[ 2 ],
3443
+ stateString = tuple[ 3 ];
3444
+
3445
+ // promise[ done | fail | progress ] = list.add
3446
+ promise[ tuple[ 1 ] ] = list.add;
3447
+
3448
+ // Handle state
3449
+ if ( stateString ) {
3450
+ list.add( function() {
3451
+
3452
+ // state = [ resolved | rejected ]
3453
+ state = stateString;
3454
+
3455
+ // [ reject_list | resolve_list ].disable; progress_list.lock
3456
+ }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3457
+ }
3458
+
3459
+ // deferred[ resolve | reject | notify ]
3460
+ deferred[ tuple[ 0 ] ] = function() {
3461
+ deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
3462
+ return this;
3463
+ };
3464
+ deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3465
+ } );
3466
+
3467
+ // Make the deferred a promise
3468
+ promise.promise( deferred );
3469
+
3470
+ // Call given func if any
3471
+ if ( func ) {
3472
+ func.call( deferred, deferred );
3473
+ }
3474
+
3475
+ // All done!
3476
+ return deferred;
3477
+ },
3478
+
3479
+ // Deferred helper
3480
+ when: function( subordinate /* , ..., subordinateN */ ) {
3481
+ var i = 0,
3482
+ resolveValues = slice.call( arguments ),
3483
+ length = resolveValues.length,
3484
+
3485
+ // the count of uncompleted subordinates
3486
+ remaining = length !== 1 ||
3487
+ ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3488
+
3489
+ // the master Deferred.
3490
+ // If resolveValues consist of only a single Deferred, just use that.
3491
+ deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3492
+
3493
+ // Update function for both resolve and progress values
3494
+ updateFunc = function( i, contexts, values ) {
3495
+ return function( value ) {
3496
+ contexts[ i ] = this;
3497
+ values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3498
+ if ( values === progressValues ) {
3499
+ deferred.notifyWith( contexts, values );
3500
+
3501
+ } else if ( !( --remaining ) ) {
3502
+ deferred.resolveWith( contexts, values );
3503
+ }
3504
+ };
3505
+ },
3506
+
3507
+ progressValues, progressContexts, resolveContexts;
3508
+
3509
+ // add listeners to Deferred subordinates; treat others as resolved
3510
+ if ( length > 1 ) {
3511
+ progressValues = new Array( length );
3512
+ progressContexts = new Array( length );
3513
+ resolveContexts = new Array( length );
3514
+ for ( ; i < length; i++ ) {
3515
+ if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3516
+ resolveValues[ i ].promise()
3517
+ .progress( updateFunc( i, progressContexts, progressValues ) )
3518
+ .done( updateFunc( i, resolveContexts, resolveValues ) )
3519
+ .fail( deferred.reject );
3520
+ } else {
3521
+ --remaining;
3522
+ }
3523
+ }
3524
+ }
3525
+
3526
+ // if we're not waiting on anything, resolve the master
3527
+ if ( !remaining ) {
3528
+ deferred.resolveWith( resolveContexts, resolveValues );
3529
+ }
3530
+
3531
+ return deferred.promise();
3532
+ }
3533
+ } );
3534
+
3535
+
3536
+ // The deferred used on DOM ready
3537
+ var readyList;
3538
+
3539
+ jQuery.fn.ready = function( fn ) {
3540
+
3541
+ // Add the callback
3542
+ jQuery.ready.promise().done( fn );
3543
+
3544
+ return this;
3545
+ };
3546
+
3547
+ jQuery.extend( {
3548
+
3549
+ // Is the DOM ready to be used? Set to true once it occurs.
3550
+ isReady: false,
3551
+
3552
+ // A counter to track how many items to wait for before
3553
+ // the ready event fires. See #6781
3554
+ readyWait: 1,
3555
+
3556
+ // Hold (or release) the ready event
3557
+ holdReady: function( hold ) {
3558
+ if ( hold ) {
3559
+ jQuery.readyWait++;
3560
+ } else {
3561
+ jQuery.ready( true );
3562
+ }
3563
+ },
3564
+
3565
+ // Handle when the DOM is ready
3566
+ ready: function( wait ) {
3567
+
3568
+ // Abort if there are pending holds or we're already ready
3569
+ if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3570
+ return;
3571
+ }
3572
+
3573
+ // Remember that the DOM is ready
3574
+ jQuery.isReady = true;
3575
+
3576
+ // If a normal DOM Ready event fired, decrement, and wait if need be
3577
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
3578
+ return;
3579
+ }
3580
+
3581
+ // If there are functions bound, to execute
3582
+ readyList.resolveWith( document, [ jQuery ] );
3583
+
3584
+ // Trigger any bound ready events
3585
+ if ( jQuery.fn.triggerHandler ) {
3586
+ jQuery( document ).triggerHandler( "ready" );
3587
+ jQuery( document ).off( "ready" );
3588
+ }
3589
+ }
3590
+ } );
3591
+
3592
+ /**
3593
+ * Clean-up method for dom ready events
3594
+ */
3595
+ function detach() {
3596
+ if ( document.addEventListener ) {
3597
+ document.removeEventListener( "DOMContentLoaded", completed );
3598
+ window.removeEventListener( "load", completed );
3599
+
3600
+ } else {
3601
+ document.detachEvent( "onreadystatechange", completed );
3602
+ window.detachEvent( "onload", completed );
3603
+ }
3604
+ }
3605
+
3606
+ /**
3607
+ * The ready event handler and self cleanup method
3608
+ */
3609
+ function completed() {
3610
+
3611
+ // readyState === "complete" is good enough for us to call the dom ready in oldIE
3612
+ if ( document.addEventListener ||
3613
+ window.event.type === "load" ||
3614
+ document.readyState === "complete" ) {
3615
+
3616
+ detach();
3617
+ jQuery.ready();
3618
+ }
3619
+ }
3620
+
3621
+ jQuery.ready.promise = function( obj ) {
3622
+ if ( !readyList ) {
3623
+
3624
+ readyList = jQuery.Deferred();
3625
+
3626
+ // Catch cases where $(document).ready() is called
3627
+ // after the browser event has already occurred.
3628
+ // Support: IE6-10
3629
+ // Older IE sometimes signals "interactive" too soon
3630
+ if ( document.readyState === "complete" ||
3631
+ ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3632
+
3633
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
3634
+ window.setTimeout( jQuery.ready );
3635
+
3636
+ // Standards-based browsers support DOMContentLoaded
3637
+ } else if ( document.addEventListener ) {
3638
+
3639
+ // Use the handy event callback
3640
+ document.addEventListener( "DOMContentLoaded", completed );
3641
+
3642
+ // A fallback to window.onload, that will always work
3643
+ window.addEventListener( "load", completed );
3644
+
3645
+ // If IE event model is used
3646
+ } else {
3647
+
3648
+ // Ensure firing before onload, maybe late but safe also for iframes
3649
+ document.attachEvent( "onreadystatechange", completed );
3650
+
3651
+ // A fallback to window.onload, that will always work
3652
+ window.attachEvent( "onload", completed );
3653
+
3654
+ // If IE and not a frame
3655
+ // continually check to see if the document is ready
3656
+ var top = false;
3657
+
3658
+ try {
3659
+ top = window.frameElement == null && document.documentElement;
3660
+ } catch ( e ) {}
3661
+
3662
+ if ( top && top.doScroll ) {
3663
+ ( function doScrollCheck() {
3664
+ if ( !jQuery.isReady ) {
3665
+
3666
+ try {
3667
+
3668
+ // Use the trick by Diego Perini
3669
+ // http://javascript.nwbox.com/IEContentLoaded/
3670
+ top.doScroll( "left" );
3671
+ } catch ( e ) {
3672
+ return window.setTimeout( doScrollCheck, 50 );
3673
+ }
3674
+
3675
+ // detach all dom ready events
3676
+ detach();
3677
+
3678
+ // and execute any waiting functions
3679
+ jQuery.ready();
3680
+ }
3681
+ } )();
3682
+ }
3683
+ }
3684
+ }
3685
+ return readyList.promise( obj );
3686
+ };
3687
+
3688
+ // Kick off the DOM ready check even if the user does not
3689
+ jQuery.ready.promise();
3690
+
3691
+
3692
+
3693
+
3694
+ // Support: IE<9
3695
+ // Iteration over object's inherited properties before its own
3696
+ var i;
3697
+ for ( i in jQuery( support ) ) {
3698
+ break;
3699
+ }
3700
+ support.ownFirst = i === "0";
3701
+
3702
+ // Note: most support tests are defined in their respective modules.
3703
+ // false until the test is run
3704
+ support.inlineBlockNeedsLayout = false;
3705
+
3706
+ // Execute ASAP in case we need to set body.style.zoom
3707
+ jQuery( function() {
3708
+
3709
+ // Minified: var a,b,c,d
3710
+ var val, div, body, container;
3711
+
3712
+ body = document.getElementsByTagName( "body" )[ 0 ];
3713
+ if ( !body || !body.style ) {
3714
+
3715
+ // Return for frameset docs that don't have a body
3716
+ return;
3717
+ }
3718
+
3719
+ // Setup
3720
+ div = document.createElement( "div" );
3721
+ container = document.createElement( "div" );
3722
+ container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
3723
+ body.appendChild( container ).appendChild( div );
3724
+
3725
+ if ( typeof div.style.zoom !== "undefined" ) {
3726
+
3727
+ // Support: IE<8
3728
+ // Check if natively block-level elements act like inline-block
3729
+ // elements when setting their display to 'inline' and giving
3730
+ // them layout
3731
+ div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
3732
+
3733
+ support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
3734
+ if ( val ) {
3735
+
3736
+ // Prevent IE 6 from affecting layout for positioned elements #11048
3737
+ // Prevent IE from shrinking the body in IE 7 mode #12869
3738
+ // Support: IE<8
3739
+ body.style.zoom = 1;
3740
+ }
3741
+ }
3742
+
3743
+ body.removeChild( container );
3744
+ } );
3745
+
3746
+
3747
+ ( function() {
3748
+ var div = document.createElement( "div" );
3749
+
3750
+ // Support: IE<9
3751
+ support.deleteExpando = true;
3752
+ try {
3753
+ delete div.test;
3754
+ } catch ( e ) {
3755
+ support.deleteExpando = false;
3756
+ }
3757
+
3758
+ // Null elements to avoid leaks in IE.
3759
+ div = null;
3760
+ } )();
3761
+ var acceptData = function( elem ) {
3762
+ var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ],
3763
+ nodeType = +elem.nodeType || 1;
3764
+
3765
+ // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
3766
+ return nodeType !== 1 && nodeType !== 9 ?
3767
+ false :
3768
+
3769
+ // Nodes accept data unless otherwise specified; rejection can be conditional
3770
+ !noData || noData !== true && elem.getAttribute( "classid" ) === noData;
3771
+ };
3772
+
3773
+
3774
+
3775
+
3776
+ var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3777
+ rmultiDash = /([A-Z])/g;
3778
+
3779
+ function dataAttr( elem, key, data ) {
3780
+
3781
+ // If nothing was found internally, try to fetch any
3782
+ // data from the HTML5 data-* attribute
3783
+ if ( data === undefined && elem.nodeType === 1 ) {
3784
+
3785
+ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3786
+
3787
+ data = elem.getAttribute( name );
3788
+
3789
+ if ( typeof data === "string" ) {
3790
+ try {
3791
+ data = data === "true" ? true :
3792
+ data === "false" ? false :
3793
+ data === "null" ? null :
3794
+
3795
+ // Only convert to a number if it doesn't change the string
3796
+ +data + "" === data ? +data :
3797
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
3798
+ data;
3799
+ } catch ( e ) {}
3800
+
3801
+ // Make sure we set the data so it isn't changed later
3802
+ jQuery.data( elem, key, data );
3803
+
3804
+ } else {
3805
+ data = undefined;
3806
+ }
3807
+ }
3808
+
3809
+ return data;
3810
+ }
3811
+
3812
+ // checks a cache object for emptiness
3813
+ function isEmptyDataObject( obj ) {
3814
+ var name;
3815
+ for ( name in obj ) {
3816
+
3817
+ // if the public data object is empty, the private is still empty
3818
+ if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) {
3819
+ continue;
3820
+ }
3821
+ if ( name !== "toJSON" ) {
3822
+ return false;
3823
+ }
3824
+ }
3825
+
3826
+ return true;
3827
+ }
3828
+
3829
+ function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
3830
+ if ( !acceptData( elem ) ) {
3831
+ return;
3832
+ }
3833
+
3834
+ var ret, thisCache,
3835
+ internalKey = jQuery.expando,
3836
+
3837
+ // We have to handle DOM nodes and JS objects differently because IE6-7
3838
+ // can't GC object references properly across the DOM-JS boundary
3839
+ isNode = elem.nodeType,
3840
+
3841
+ // Only DOM nodes need the global jQuery cache; JS object data is
3842
+ // attached directly to the object so GC can occur automatically
3843
+ cache = isNode ? jQuery.cache : elem,
3844
+
3845
+ // Only defining an ID for JS objects if its cache already exists allows
3846
+ // the code to shortcut on the same path as a DOM node with no cache
3847
+ id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
3848
+
3849
+ // Avoid doing any more work than we need to when trying to get data on an
3850
+ // object that has no data at all
3851
+ if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) &&
3852
+ data === undefined && typeof name === "string" ) {
3853
+ return;
3854
+ }
3855
+
3856
+ if ( !id ) {
3857
+
3858
+ // Only DOM nodes need a new unique ID for each element since their data
3859
+ // ends up in the global cache
3860
+ if ( isNode ) {
3861
+ id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
3862
+ } else {
3863
+ id = internalKey;
3864
+ }
3865
+ }
3866
+
3867
+ if ( !cache[ id ] ) {
3868
+
3869
+ // Avoid exposing jQuery metadata on plain JS objects when the object
3870
+ // is serialized using JSON.stringify
3871
+ cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
3872
+ }
3873
+
3874
+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
3875
+ // shallow copied over onto the existing cache
3876
+ if ( typeof name === "object" || typeof name === "function" ) {
3877
+ if ( pvt ) {
3878
+ cache[ id ] = jQuery.extend( cache[ id ], name );
3879
+ } else {
3880
+ cache[ id ].data = jQuery.extend( cache[ id ].data, name );
3881
+ }
3882
+ }
3883
+
3884
+ thisCache = cache[ id ];
3885
+
3886
+ // jQuery data() is stored in a separate object inside the object's internal data
3887
+ // cache in order to avoid key collisions between internal data and user-defined
3888
+ // data.
3889
+ if ( !pvt ) {
3890
+ if ( !thisCache.data ) {
3891
+ thisCache.data = {};
3892
+ }
3893
+
3894
+ thisCache = thisCache.data;
3895
+ }
3896
+
3897
+ if ( data !== undefined ) {
3898
+ thisCache[ jQuery.camelCase( name ) ] = data;
3899
+ }
3900
+
3901
+ // Check for both converted-to-camel and non-converted data property names
3902
+ // If a data property was specified
3903
+ if ( typeof name === "string" ) {
3904
+
3905
+ // First Try to find as-is property data
3906
+ ret = thisCache[ name ];
3907
+
3908
+ // Test for null|undefined property data
3909
+ if ( ret == null ) {
3910
+
3911
+ // Try to find the camelCased property
3912
+ ret = thisCache[ jQuery.camelCase( name ) ];
3913
+ }
3914
+ } else {
3915
+ ret = thisCache;
3916
+ }
3917
+
3918
+ return ret;
3919
+ }
3920
+
3921
+ function internalRemoveData( elem, name, pvt ) {
3922
+ if ( !acceptData( elem ) ) {
3923
+ return;
3924
+ }
3925
+
3926
+ var thisCache, i,
3927
+ isNode = elem.nodeType,
3928
+
3929
+ // See jQuery.data for more information
3930
+ cache = isNode ? jQuery.cache : elem,
3931
+ id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
3932
+
3933
+ // If there is already no cache entry for this object, there is no
3934
+ // purpose in continuing
3935
+ if ( !cache[ id ] ) {
3936
+ return;
3937
+ }
3938
+
3939
+ if ( name ) {
3940
+
3941
+ thisCache = pvt ? cache[ id ] : cache[ id ].data;
3942
+
3943
+ if ( thisCache ) {
3944
+
3945
+ // Support array or space separated string names for data keys
3946
+ if ( !jQuery.isArray( name ) ) {
3947
+
3948
+ // try the string as a key before any manipulation
3949
+ if ( name in thisCache ) {
3950
+ name = [ name ];
3951
+ } else {
3952
+
3953
+ // split the camel cased version by spaces unless a key with the spaces exists
3954
+ name = jQuery.camelCase( name );
3955
+ if ( name in thisCache ) {
3956
+ name = [ name ];
3957
+ } else {
3958
+ name = name.split( " " );
3959
+ }
3960
+ }
3961
+ } else {
3962
+
3963
+ // If "name" is an array of keys...
3964
+ // When data is initially created, via ("key", "val") signature,
3965
+ // keys will be converted to camelCase.
3966
+ // Since there is no way to tell _how_ a key was added, remove
3967
+ // both plain key and camelCase key. #12786
3968
+ // This will only penalize the array argument path.
3969
+ name = name.concat( jQuery.map( name, jQuery.camelCase ) );
3970
+ }
3971
+
3972
+ i = name.length;
3973
+ while ( i-- ) {
3974
+ delete thisCache[ name[ i ] ];
3975
+ }
3976
+
3977
+ // If there is no data left in the cache, we want to continue
3978
+ // and let the cache object itself get destroyed
3979
+ if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) {
3980
+ return;
3981
+ }
3982
+ }
3983
+ }
3984
+
3985
+ // See jQuery.data for more information
3986
+ if ( !pvt ) {
3987
+ delete cache[ id ].data;
3988
+
3989
+ // Don't destroy the parent cache unless the internal data object
3990
+ // had been the only thing left in it
3991
+ if ( !isEmptyDataObject( cache[ id ] ) ) {
3992
+ return;
3993
+ }
3994
+ }
3995
+
3996
+ // Destroy the cache
3997
+ if ( isNode ) {
3998
+ jQuery.cleanData( [ elem ], true );
3999
+
4000
+ // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
4001
+ /* jshint eqeqeq: false */
4002
+ } else if ( support.deleteExpando || cache != cache.window ) {
4003
+ /* jshint eqeqeq: true */
4004
+ delete cache[ id ];
4005
+
4006
+ // When all else fails, undefined
4007
+ } else {
4008
+ cache[ id ] = undefined;
4009
+ }
4010
+ }
4011
+
4012
+ jQuery.extend( {
4013
+ cache: {},
4014
+
4015
+ // The following elements (space-suffixed to avoid Object.prototype collisions)
4016
+ // throw uncatchable exceptions if you attempt to set expando properties
4017
+ noData: {
4018
+ "applet ": true,
4019
+ "embed ": true,
4020
+
4021
+ // ...but Flash objects (which have this classid) *can* handle expandos
4022
+ "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
4023
+ },
4024
+
4025
+ hasData: function( elem ) {
4026
+ elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ];
4027
+ return !!elem && !isEmptyDataObject( elem );
4028
+ },
4029
+
4030
+ data: function( elem, name, data ) {
4031
+ return internalData( elem, name, data );
4032
+ },
4033
+
4034
+ removeData: function( elem, name ) {
4035
+ return internalRemoveData( elem, name );
4036
+ },
4037
+
4038
+ // For internal use only.
4039
+ _data: function( elem, name, data ) {
4040
+ return internalData( elem, name, data, true );
4041
+ },
4042
+
4043
+ _removeData: function( elem, name ) {
4044
+ return internalRemoveData( elem, name, true );
4045
+ }
4046
+ } );
4047
+
4048
+ jQuery.fn.extend( {
4049
+ data: function( key, value ) {
4050
+ var i, name, data,
4051
+ elem = this[ 0 ],
4052
+ attrs = elem && elem.attributes;
4053
+
4054
+ // Special expections of .data basically thwart jQuery.access,
4055
+ // so implement the relevant behavior ourselves
4056
+
4057
+ // Gets all values
4058
+ if ( key === undefined ) {
4059
+ if ( this.length ) {
4060
+ data = jQuery.data( elem );
4061
+
4062
+ if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
4063
+ i = attrs.length;
4064
+ while ( i-- ) {
4065
+
4066
+ // Support: IE11+
4067
+ // The attrs elements can be null (#14894)
4068
+ if ( attrs[ i ] ) {
4069
+ name = attrs[ i ].name;
4070
+ if ( name.indexOf( "data-" ) === 0 ) {
4071
+ name = jQuery.camelCase( name.slice( 5 ) );
4072
+ dataAttr( elem, name, data[ name ] );
4073
+ }
4074
+ }
4075
+ }
4076
+ jQuery._data( elem, "parsedAttrs", true );
4077
+ }
4078
+ }
4079
+
4080
+ return data;
4081
+ }
4082
+
4083
+ // Sets multiple values
4084
+ if ( typeof key === "object" ) {
4085
+ return this.each( function() {
4086
+ jQuery.data( this, key );
4087
+ } );
4088
+ }
4089
+
4090
+ return arguments.length > 1 ?
4091
+
4092
+ // Sets one value
4093
+ this.each( function() {
4094
+ jQuery.data( this, key, value );
4095
+ } ) :
4096
+
4097
+ // Gets one value
4098
+ // Try to fetch any internally stored data first
4099
+ elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
4100
+ },
4101
+
4102
+ removeData: function( key ) {
4103
+ return this.each( function() {
4104
+ jQuery.removeData( this, key );
4105
+ } );
4106
+ }
4107
+ } );
4108
+
4109
+
4110
+ jQuery.extend( {
4111
+ queue: function( elem, type, data ) {
4112
+ var queue;
4113
+
4114
+ if ( elem ) {
4115
+ type = ( type || "fx" ) + "queue";
4116
+ queue = jQuery._data( elem, type );
4117
+
4118
+ // Speed up dequeue by getting out quickly if this is just a lookup
4119
+ if ( data ) {
4120
+ if ( !queue || jQuery.isArray( data ) ) {
4121
+ queue = jQuery._data( elem, type, jQuery.makeArray( data ) );
4122
+ } else {
4123
+ queue.push( data );
4124
+ }
4125
+ }
4126
+ return queue || [];
4127
+ }
4128
+ },
4129
+
4130
+ dequeue: function( elem, type ) {
4131
+ type = type || "fx";
4132
+
4133
+ var queue = jQuery.queue( elem, type ),
4134
+ startLength = queue.length,
4135
+ fn = queue.shift(),
4136
+ hooks = jQuery._queueHooks( elem, type ),
4137
+ next = function() {
4138
+ jQuery.dequeue( elem, type );
4139
+ };
4140
+
4141
+ // If the fx queue is dequeued, always remove the progress sentinel
4142
+ if ( fn === "inprogress" ) {
4143
+ fn = queue.shift();
4144
+ startLength--;
4145
+ }
4146
+
4147
+ if ( fn ) {
4148
+
4149
+ // Add a progress sentinel to prevent the fx queue from being
4150
+ // automatically dequeued
4151
+ if ( type === "fx" ) {
4152
+ queue.unshift( "inprogress" );
4153
+ }
4154
+
4155
+ // clear up the last queue stop function
4156
+ delete hooks.stop;
4157
+ fn.call( elem, next, hooks );
4158
+ }
4159
+
4160
+ if ( !startLength && hooks ) {
4161
+ hooks.empty.fire();
4162
+ }
4163
+ },
4164
+
4165
+ // not intended for public consumption - generates a queueHooks object,
4166
+ // or returns the current one
4167
+ _queueHooks: function( elem, type ) {
4168
+ var key = type + "queueHooks";
4169
+ return jQuery._data( elem, key ) || jQuery._data( elem, key, {
4170
+ empty: jQuery.Callbacks( "once memory" ).add( function() {
4171
+ jQuery._removeData( elem, type + "queue" );
4172
+ jQuery._removeData( elem, key );
4173
+ } )
4174
+ } );
4175
+ }
4176
+ } );
4177
+
4178
+ jQuery.fn.extend( {
4179
+ queue: function( type, data ) {
4180
+ var setter = 2;
4181
+
4182
+ if ( typeof type !== "string" ) {
4183
+ data = type;
4184
+ type = "fx";
4185
+ setter--;
4186
+ }
4187
+
4188
+ if ( arguments.length < setter ) {
4189
+ return jQuery.queue( this[ 0 ], type );
4190
+ }
4191
+
4192
+ return data === undefined ?
4193
+ this :
4194
+ this.each( function() {
4195
+ var queue = jQuery.queue( this, type, data );
4196
+
4197
+ // ensure a hooks for this queue
4198
+ jQuery._queueHooks( this, type );
4199
+
4200
+ if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4201
+ jQuery.dequeue( this, type );
4202
+ }
4203
+ } );
4204
+ },
4205
+ dequeue: function( type ) {
4206
+ return this.each( function() {
4207
+ jQuery.dequeue( this, type );
4208
+ } );
4209
+ },
4210
+ clearQueue: function( type ) {
4211
+ return this.queue( type || "fx", [] );
4212
+ },
4213
+
4214
+ // Get a promise resolved when queues of a certain type
4215
+ // are emptied (fx is the type by default)
4216
+ promise: function( type, obj ) {
4217
+ var tmp,
4218
+ count = 1,
4219
+ defer = jQuery.Deferred(),
4220
+ elements = this,
4221
+ i = this.length,
4222
+ resolve = function() {
4223
+ if ( !( --count ) ) {
4224
+ defer.resolveWith( elements, [ elements ] );
4225
+ }
4226
+ };
4227
+
4228
+ if ( typeof type !== "string" ) {
4229
+ obj = type;
4230
+ type = undefined;
4231
+ }
4232
+ type = type || "fx";
4233
+
4234
+ while ( i-- ) {
4235
+ tmp = jQuery._data( elements[ i ], type + "queueHooks" );
4236
+ if ( tmp && tmp.empty ) {
4237
+ count++;
4238
+ tmp.empty.add( resolve );
4239
+ }
4240
+ }
4241
+ resolve();
4242
+ return defer.promise( obj );
4243
+ }
4244
+ } );
4245
+
4246
+
4247
+ ( function() {
4248
+ var shrinkWrapBlocksVal;
4249
+
4250
+ support.shrinkWrapBlocks = function() {
4251
+ if ( shrinkWrapBlocksVal != null ) {
4252
+ return shrinkWrapBlocksVal;
4253
+ }
4254
+
4255
+ // Will be changed later if needed.
4256
+ shrinkWrapBlocksVal = false;
4257
+
4258
+ // Minified: var b,c,d
4259
+ var div, body, container;
4260
+
4261
+ body = document.getElementsByTagName( "body" )[ 0 ];
4262
+ if ( !body || !body.style ) {
4263
+
4264
+ // Test fired too early or in an unsupported environment, exit.
4265
+ return;
4266
+ }
4267
+
4268
+ // Setup
4269
+ div = document.createElement( "div" );
4270
+ container = document.createElement( "div" );
4271
+ container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
4272
+ body.appendChild( container ).appendChild( div );
4273
+
4274
+ // Support: IE6
4275
+ // Check if elements with layout shrink-wrap their children
4276
+ if ( typeof div.style.zoom !== "undefined" ) {
4277
+
4278
+ // Reset CSS: box-sizing; display; margin; border
4279
+ div.style.cssText =
4280
+
4281
+ // Support: Firefox<29, Android 2.3
4282
+ // Vendor-prefix box-sizing
4283
+ "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
4284
+ "box-sizing:content-box;display:block;margin:0;border:0;" +
4285
+ "padding:1px;width:1px;zoom:1";
4286
+ div.appendChild( document.createElement( "div" ) ).style.width = "5px";
4287
+ shrinkWrapBlocksVal = div.offsetWidth !== 3;
4288
+ }
4289
+
4290
+ body.removeChild( container );
4291
+
4292
+ return shrinkWrapBlocksVal;
4293
+ };
4294
+
4295
+ } )();
4296
+ var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4297
+
4298
+ var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4299
+
4300
+
4301
+ var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4302
+
4303
+ var isHidden = function( elem, el ) {
4304
+
4305
+ // isHidden might be called from jQuery#filter function;
4306
+ // in that case, element will be second argument
4307
+ elem = el || elem;
4308
+ return jQuery.css( elem, "display" ) === "none" ||
4309
+ !jQuery.contains( elem.ownerDocument, elem );
4310
+ };
4311
+
4312
+
4313
+
4314
+ function adjustCSS( elem, prop, valueParts, tween ) {
4315
+ var adjusted,
4316
+ scale = 1,
4317
+ maxIterations = 20,
4318
+ currentValue = tween ?
4319
+ function() { return tween.cur(); } :
4320
+ function() { return jQuery.css( elem, prop, "" ); },
4321
+ initial = currentValue(),
4322
+ unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4323
+
4324
+ // Starting value computation is required for potential unit mismatches
4325
+ initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4326
+ rcssNum.exec( jQuery.css( elem, prop ) );
4327
+
4328
+ if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4329
+
4330
+ // Trust units reported by jQuery.css
4331
+ unit = unit || initialInUnit[ 3 ];
4332
+
4333
+ // Make sure we update the tween properties later on
4334
+ valueParts = valueParts || [];
4335
+
4336
+ // Iteratively approximate from a nonzero starting point
4337
+ initialInUnit = +initial || 1;
4338
+
4339
+ do {
4340
+
4341
+ // If previous iteration zeroed out, double until we get *something*.
4342
+ // Use string for doubling so we don't accidentally see scale as unchanged below
4343
+ scale = scale || ".5";
4344
+
4345
+ // Adjust and apply
4346
+ initialInUnit = initialInUnit / scale;
4347
+ jQuery.style( elem, prop, initialInUnit + unit );
4348
+
4349
+ // Update scale, tolerating zero or NaN from tween.cur()
4350
+ // Break the loop if scale is unchanged or perfect, or if we've just had enough.
4351
+ } while (
4352
+ scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4353
+ );
4354
+ }
4355
+
4356
+ if ( valueParts ) {
4357
+ initialInUnit = +initialInUnit || +initial || 0;
4358
+
4359
+ // Apply relative offset (+=/-=) if specified
4360
+ adjusted = valueParts[ 1 ] ?
4361
+ initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4362
+ +valueParts[ 2 ];
4363
+ if ( tween ) {
4364
+ tween.unit = unit;
4365
+ tween.start = initialInUnit;
4366
+ tween.end = adjusted;
4367
+ }
4368
+ }
4369
+ return adjusted;
4370
+ }
4371
+
4372
+
4373
+ // Multifunctional method to get and set values of a collection
4374
+ // The value/s can optionally be executed if it's a function
4375
+ var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4376
+ var i = 0,
4377
+ length = elems.length,
4378
+ bulk = key == null;
4379
+
4380
+ // Sets many values
4381
+ if ( jQuery.type( key ) === "object" ) {
4382
+ chainable = true;
4383
+ for ( i in key ) {
4384
+ access( elems, fn, i, key[ i ], true, emptyGet, raw );
4385
+ }
4386
+
4387
+ // Sets one value
4388
+ } else if ( value !== undefined ) {
4389
+ chainable = true;
4390
+
4391
+ if ( !jQuery.isFunction( value ) ) {
4392
+ raw = true;
4393
+ }
4394
+
4395
+ if ( bulk ) {
4396
+
4397
+ // Bulk operations run against the entire set
4398
+ if ( raw ) {
4399
+ fn.call( elems, value );
4400
+ fn = null;
4401
+
4402
+ // ...except when executing function values
4403
+ } else {
4404
+ bulk = fn;
4405
+ fn = function( elem, key, value ) {
4406
+ return bulk.call( jQuery( elem ), value );
4407
+ };
4408
+ }
4409
+ }
4410
+
4411
+ if ( fn ) {
4412
+ for ( ; i < length; i++ ) {
4413
+ fn(
4414
+ elems[ i ],
4415
+ key,
4416
+ raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) )
4417
+ );
4418
+ }
4419
+ }
4420
+ }
4421
+
4422
+ return chainable ?
4423
+ elems :
4424
+
4425
+ // Gets
4426
+ bulk ?
4427
+ fn.call( elems ) :
4428
+ length ? fn( elems[ 0 ], key ) : emptyGet;
4429
+ };
4430
+ var rcheckableType = ( /^(?:checkbox|radio)$/i );
4431
+
4432
+ var rtagName = ( /<([\w:-]+)/ );
4433
+
4434
+ var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4435
+
4436
+ var rleadingWhitespace = ( /^\s+/ );
4437
+
4438
+ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" +
4439
+ "details|dialog|figcaption|figure|footer|header|hgroup|main|" +
4440
+ "mark|meter|nav|output|picture|progress|section|summary|template|time|video";
4441
+
4442
+
4443
+
4444
+ function createSafeFragment( document ) {
4445
+ var list = nodeNames.split( "|" ),
4446
+ safeFrag = document.createDocumentFragment();
4447
+
4448
+ if ( safeFrag.createElement ) {
4449
+ while ( list.length ) {
4450
+ safeFrag.createElement(
4451
+ list.pop()
4452
+ );
4453
+ }
4454
+ }
4455
+ return safeFrag;
4456
+ }
4457
+
4458
+
4459
+ ( function() {
4460
+ var div = document.createElement( "div" ),
4461
+ fragment = document.createDocumentFragment(),
4462
+ input = document.createElement( "input" );
4463
+
4464
+ // Setup
4465
+ div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
4466
+
4467
+ // IE strips leading whitespace when .innerHTML is used
4468
+ support.leadingWhitespace = div.firstChild.nodeType === 3;
4469
+
4470
+ // Make sure that tbody elements aren't automatically inserted
4471
+ // IE will insert them into empty tables
4472
+ support.tbody = !div.getElementsByTagName( "tbody" ).length;
4473
+
4474
+ // Make sure that link elements get serialized correctly by innerHTML
4475
+ // This requires a wrapper element in IE
4476
+ support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
4477
+
4478
+ // Makes sure cloning an html5 element does not cause problems
4479
+ // Where outerHTML is undefined, this still works
4480
+ support.html5Clone =
4481
+ document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
4482
+
4483
+ // Check if a disconnected checkbox will retain its checked
4484
+ // value of true after appended to the DOM (IE6/7)
4485
+ input.type = "checkbox";
4486
+ input.checked = true;
4487
+ fragment.appendChild( input );
4488
+ support.appendChecked = input.checked;
4489
+
4490
+ // Make sure textarea (and checkbox) defaultValue is properly cloned
4491
+ // Support: IE6-IE11+
4492
+ div.innerHTML = "<textarea>x</textarea>";
4493
+ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4494
+
4495
+ // #11217 - WebKit loses check when the name is after the checked attribute
4496
+ fragment.appendChild( div );
4497
+
4498
+ // Support: Windows Web Apps (WWA)
4499
+ // `name` and `type` must use .setAttribute for WWA (#14901)
4500
+ input = document.createElement( "input" );
4501
+ input.setAttribute( "type", "radio" );
4502
+ input.setAttribute( "checked", "checked" );
4503
+ input.setAttribute( "name", "t" );
4504
+
4505
+ div.appendChild( input );
4506
+
4507
+ // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
4508
+ // old WebKit doesn't clone checked state correctly in fragments
4509
+ support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4510
+
4511
+ // Support: IE<9
4512
+ // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+
4513
+ support.noCloneEvent = !!div.addEventListener;
4514
+
4515
+ // Support: IE<9
4516
+ // Since attributes and properties are the same in IE,
4517
+ // cleanData must set properties to undefined rather than use removeAttribute
4518
+ div[ jQuery.expando ] = 1;
4519
+ support.attributes = !div.getAttribute( jQuery.expando );
4520
+ } )();
4521
+
4522
+
4523
+ // We have to close these tags to support XHTML (#13200)
4524
+ var wrapMap = {
4525
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
4526
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
4527
+ area: [ 1, "<map>", "</map>" ],
4528
+
4529
+ // Support: IE8
4530
+ param: [ 1, "<object>", "</object>" ],
4531
+ thead: [ 1, "<table>", "</table>" ],
4532
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4533
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4534
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4535
+
4536
+ // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
4537
+ // unless wrapped in a div with non-breaking characters in front of it.
4538
+ _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
4539
+ };
4540
+
4541
+ // Support: IE8-IE9
4542
+ wrapMap.optgroup = wrapMap.option;
4543
+
4544
+ wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4545
+ wrapMap.th = wrapMap.td;
4546
+
4547
+
4548
+ function getAll( context, tag ) {
4549
+ var elems, elem,
4550
+ i = 0,
4551
+ found = typeof context.getElementsByTagName !== "undefined" ?
4552
+ context.getElementsByTagName( tag || "*" ) :
4553
+ typeof context.querySelectorAll !== "undefined" ?
4554
+ context.querySelectorAll( tag || "*" ) :
4555
+ undefined;
4556
+
4557
+ if ( !found ) {
4558
+ for ( found = [], elems = context.childNodes || context;
4559
+ ( elem = elems[ i ] ) != null;
4560
+ i++
4561
+ ) {
4562
+ if ( !tag || jQuery.nodeName( elem, tag ) ) {
4563
+ found.push( elem );
4564
+ } else {
4565
+ jQuery.merge( found, getAll( elem, tag ) );
4566
+ }
4567
+ }
4568
+ }
4569
+
4570
+ return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
4571
+ jQuery.merge( [ context ], found ) :
4572
+ found;
4573
+ }
4574
+
4575
+
4576
+ // Mark scripts as having already been evaluated
4577
+ function setGlobalEval( elems, refElements ) {
4578
+ var elem,
4579
+ i = 0;
4580
+ for ( ; ( elem = elems[ i ] ) != null; i++ ) {
4581
+ jQuery._data(
4582
+ elem,
4583
+ "globalEval",
4584
+ !refElements || jQuery._data( refElements[ i ], "globalEval" )
4585
+ );
4586
+ }
4587
+ }
4588
+
4589
+
4590
+ var rhtml = /<|&#?\w+;/,
4591
+ rtbody = /<tbody/i;
4592
+
4593
+ function fixDefaultChecked( elem ) {
4594
+ if ( rcheckableType.test( elem.type ) ) {
4595
+ elem.defaultChecked = elem.checked;
4596
+ }
4597
+ }
4598
+
4599
+ function buildFragment( elems, context, scripts, selection, ignored ) {
4600
+ var j, elem, contains,
4601
+ tmp, tag, tbody, wrap,
4602
+ l = elems.length,
4603
+
4604
+ // Ensure a safe fragment
4605
+ safe = createSafeFragment( context ),
4606
+
4607
+ nodes = [],
4608
+ i = 0;
4609
+
4610
+ for ( ; i < l; i++ ) {
4611
+ elem = elems[ i ];
4612
+
4613
+ if ( elem || elem === 0 ) {
4614
+
4615
+ // Add nodes directly
4616
+ if ( jQuery.type( elem ) === "object" ) {
4617
+ jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4618
+
4619
+ // Convert non-html into a text node
4620
+ } else if ( !rhtml.test( elem ) ) {
4621
+ nodes.push( context.createTextNode( elem ) );
4622
+
4623
+ // Convert html into DOM nodes
4624
+ } else {
4625
+ tmp = tmp || safe.appendChild( context.createElement( "div" ) );
4626
+
4627
+ // Deserialize a standard representation
4628
+ tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4629
+ wrap = wrapMap[ tag ] || wrapMap._default;
4630
+
4631
+ tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4632
+
4633
+ // Descend through wrappers to the right content
4634
+ j = wrap[ 0 ];
4635
+ while ( j-- ) {
4636
+ tmp = tmp.lastChild;
4637
+ }
4638
+
4639
+ // Manually add leading whitespace removed by IE
4640
+ if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
4641
+ nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[ 0 ] ) );
4642
+ }
4643
+
4644
+ // Remove IE's autoinserted <tbody> from table fragments
4645
+ if ( !support.tbody ) {
4646
+
4647
+ // String was a <table>, *may* have spurious <tbody>
4648
+ elem = tag === "table" && !rtbody.test( elem ) ?
4649
+ tmp.firstChild :
4650
+
4651
+ // String was a bare <thead> or <tfoot>
4652
+ wrap[ 1 ] === "<table>" && !rtbody.test( elem ) ?
4653
+ tmp :
4654
+ 0;
4655
+
4656
+ j = elem && elem.childNodes.length;
4657
+ while ( j-- ) {
4658
+ if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) &&
4659
+ !tbody.childNodes.length ) {
4660
+
4661
+ elem.removeChild( tbody );
4662
+ }
4663
+ }
4664
+ }
4665
+
4666
+ jQuery.merge( nodes, tmp.childNodes );
4667
+
4668
+ // Fix #12392 for WebKit and IE > 9
4669
+ tmp.textContent = "";
4670
+
4671
+ // Fix #12392 for oldIE
4672
+ while ( tmp.firstChild ) {
4673
+ tmp.removeChild( tmp.firstChild );
4674
+ }
4675
+
4676
+ // Remember the top-level container for proper cleanup
4677
+ tmp = safe.lastChild;
4678
+ }
4679
+ }
4680
+ }
4681
+
4682
+ // Fix #11356: Clear elements from fragment
4683
+ if ( tmp ) {
4684
+ safe.removeChild( tmp );
4685
+ }
4686
+
4687
+ // Reset defaultChecked for any radios and checkboxes
4688
+ // about to be appended to the DOM in IE 6/7 (#8060)
4689
+ if ( !support.appendChecked ) {
4690
+ jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
4691
+ }
4692
+
4693
+ i = 0;
4694
+ while ( ( elem = nodes[ i++ ] ) ) {
4695
+
4696
+ // Skip elements already in the context collection (trac-4087)
4697
+ if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4698
+ if ( ignored ) {
4699
+ ignored.push( elem );
4700
+ }
4701
+
4702
+ continue;
4703
+ }
4704
+
4705
+ contains = jQuery.contains( elem.ownerDocument, elem );
4706
+
4707
+ // Append to fragment
4708
+ tmp = getAll( safe.appendChild( elem ), "script" );
4709
+
4710
+ // Preserve script evaluation history
4711
+ if ( contains ) {
4712
+ setGlobalEval( tmp );
4713
+ }
4714
+
4715
+ // Capture executables
4716
+ if ( scripts ) {
4717
+ j = 0;
4718
+ while ( ( elem = tmp[ j++ ] ) ) {
4719
+ if ( rscriptType.test( elem.type || "" ) ) {
4720
+ scripts.push( elem );
4721
+ }
4722
+ }
4723
+ }
4724
+ }
4725
+
4726
+ tmp = null;
4727
+
4728
+ return safe;
4729
+ }
4730
+
4731
+
4732
+ ( function() {
4733
+ var i, eventName,
4734
+ div = document.createElement( "div" );
4735
+
4736
+ // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events)
4737
+ for ( i in { submit: true, change: true, focusin: true } ) {
4738
+ eventName = "on" + i;
4739
+
4740
+ if ( !( support[ i ] = eventName in window ) ) {
4741
+
4742
+ // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
4743
+ div.setAttribute( eventName, "t" );
4744
+ support[ i ] = div.attributes[ eventName ].expando === false;
4745
+ }
4746
+ }
4747
+
4748
+ // Null elements to avoid leaks in IE.
4749
+ div = null;
4750
+ } )();
4751
+
4752
+
4753
+ var rformElems = /^(?:input|select|textarea)$/i,
4754
+ rkeyEvent = /^key/,
4755
+ rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4756
+ rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4757
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4758
+
4759
+ function returnTrue() {
4760
+ return true;
4761
+ }
4762
+
4763
+ function returnFalse() {
4764
+ return false;
4765
+ }
4766
+
4767
+ // Support: IE9
4768
+ // See #13393 for more info
4769
+ function safeActiveElement() {
4770
+ try {
4771
+ return document.activeElement;
4772
+ } catch ( err ) { }
4773
+ }
4774
+
4775
+ function on( elem, types, selector, data, fn, one ) {
4776
+ var origFn, type;
4777
+
4778
+ // Types can be a map of types/handlers
4779
+ if ( typeof types === "object" ) {
4780
+
4781
+ // ( types-Object, selector, data )
4782
+ if ( typeof selector !== "string" ) {
4783
+
4784
+ // ( types-Object, data )
4785
+ data = data || selector;
4786
+ selector = undefined;
4787
+ }
4788
+ for ( type in types ) {
4789
+ on( elem, type, selector, data, types[ type ], one );
4790
+ }
4791
+ return elem;
4792
+ }
4793
+
4794
+ if ( data == null && fn == null ) {
4795
+
4796
+ // ( types, fn )
4797
+ fn = selector;
4798
+ data = selector = undefined;
4799
+ } else if ( fn == null ) {
4800
+ if ( typeof selector === "string" ) {
4801
+
4802
+ // ( types, selector, fn )
4803
+ fn = data;
4804
+ data = undefined;
4805
+ } else {
4806
+
4807
+ // ( types, data, fn )
4808
+ fn = data;
4809
+ data = selector;
4810
+ selector = undefined;
4811
+ }
4812
+ }
4813
+ if ( fn === false ) {
4814
+ fn = returnFalse;
4815
+ } else if ( !fn ) {
4816
+ return elem;
4817
+ }
4818
+
4819
+ if ( one === 1 ) {
4820
+ origFn = fn;
4821
+ fn = function( event ) {
4822
+
4823
+ // Can use an empty set, since event contains the info
4824
+ jQuery().off( event );
4825
+ return origFn.apply( this, arguments );
4826
+ };
4827
+
4828
+ // Use same guid so caller can remove using origFn
4829
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4830
+ }
4831
+ return elem.each( function() {
4832
+ jQuery.event.add( this, types, fn, data, selector );
4833
+ } );
4834
+ }
4835
+
4836
+ /*
4837
+ * Helper functions for managing events -- not part of the public interface.
4838
+ * Props to Dean Edwards' addEvent library for many of the ideas.
4839
+ */
4840
+ jQuery.event = {
4841
+
4842
+ global: {},
4843
+
4844
+ add: function( elem, types, handler, data, selector ) {
4845
+ var tmp, events, t, handleObjIn,
4846
+ special, eventHandle, handleObj,
4847
+ handlers, type, namespaces, origType,
4848
+ elemData = jQuery._data( elem );
4849
+
4850
+ // Don't attach events to noData or text/comment nodes (but allow plain objects)
4851
+ if ( !elemData ) {
4852
+ return;
4853
+ }
4854
+
4855
+ // Caller can pass in an object of custom data in lieu of the handler
4856
+ if ( handler.handler ) {
4857
+ handleObjIn = handler;
4858
+ handler = handleObjIn.handler;
4859
+ selector = handleObjIn.selector;
4860
+ }
4861
+
4862
+ // Make sure that the handler has a unique ID, used to find/remove it later
4863
+ if ( !handler.guid ) {
4864
+ handler.guid = jQuery.guid++;
4865
+ }
4866
+
4867
+ // Init the element's event structure and main handler, if this is the first
4868
+ if ( !( events = elemData.events ) ) {
4869
+ events = elemData.events = {};
4870
+ }
4871
+ if ( !( eventHandle = elemData.handle ) ) {
4872
+ eventHandle = elemData.handle = function( e ) {
4873
+
4874
+ // Discard the second event of a jQuery.event.trigger() and
4875
+ // when an event is called after a page has unloaded
4876
+ return typeof jQuery !== "undefined" &&
4877
+ ( !e || jQuery.event.triggered !== e.type ) ?
4878
+ jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
4879
+ undefined;
4880
+ };
4881
+
4882
+ // Add elem as a property of the handle fn to prevent a memory leak
4883
+ // with IE non-native events
4884
+ eventHandle.elem = elem;
4885
+ }
4886
+
4887
+ // Handle multiple events separated by a space
4888
+ types = ( types || "" ).match( rnotwhite ) || [ "" ];
4889
+ t = types.length;
4890
+ while ( t-- ) {
4891
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
4892
+ type = origType = tmp[ 1 ];
4893
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4894
+
4895
+ // There *must* be a type, no attaching namespace-only handlers
4896
+ if ( !type ) {
4897
+ continue;
4898
+ }
4899
+
4900
+ // If event changes its type, use the special event handlers for the changed type
4901
+ special = jQuery.event.special[ type ] || {};
4902
+
4903
+ // If selector defined, determine special event api type, otherwise given type
4904
+ type = ( selector ? special.delegateType : special.bindType ) || type;
4905
+
4906
+ // Update special based on newly reset type
4907
+ special = jQuery.event.special[ type ] || {};
4908
+
4909
+ // handleObj is passed to all event handlers
4910
+ handleObj = jQuery.extend( {
4911
+ type: type,
4912
+ origType: origType,
4913
+ data: data,
4914
+ handler: handler,
4915
+ guid: handler.guid,
4916
+ selector: selector,
4917
+ needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4918
+ namespace: namespaces.join( "." )
4919
+ }, handleObjIn );
4920
+
4921
+ // Init the event handler queue if we're the first
4922
+ if ( !( handlers = events[ type ] ) ) {
4923
+ handlers = events[ type ] = [];
4924
+ handlers.delegateCount = 0;
4925
+
4926
+ // Only use addEventListener/attachEvent if the special events handler returns false
4927
+ if ( !special.setup ||
4928
+ special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4929
+
4930
+ // Bind the global event handler to the element
4931
+ if ( elem.addEventListener ) {
4932
+ elem.addEventListener( type, eventHandle, false );
4933
+
4934
+ } else if ( elem.attachEvent ) {
4935
+ elem.attachEvent( "on" + type, eventHandle );
4936
+ }
4937
+ }
4938
+ }
4939
+
4940
+ if ( special.add ) {
4941
+ special.add.call( elem, handleObj );
4942
+
4943
+ if ( !handleObj.handler.guid ) {
4944
+ handleObj.handler.guid = handler.guid;
4945
+ }
4946
+ }
4947
+
4948
+ // Add to the element's handler list, delegates in front
4949
+ if ( selector ) {
4950
+ handlers.splice( handlers.delegateCount++, 0, handleObj );
4951
+ } else {
4952
+ handlers.push( handleObj );
4953
+ }
4954
+
4955
+ // Keep track of which events have ever been used, for event optimization
4956
+ jQuery.event.global[ type ] = true;
4957
+ }
4958
+
4959
+ // Nullify elem to prevent memory leaks in IE
4960
+ elem = null;
4961
+ },
4962
+
4963
+ // Detach an event or set of events from an element
4964
+ remove: function( elem, types, handler, selector, mappedTypes ) {
4965
+ var j, handleObj, tmp,
4966
+ origCount, t, events,
4967
+ special, handlers, type,
4968
+ namespaces, origType,
4969
+ elemData = jQuery.hasData( elem ) && jQuery._data( elem );
4970
+
4971
+ if ( !elemData || !( events = elemData.events ) ) {
4972
+ return;
4973
+ }
4974
+
4975
+ // Once for each type.namespace in types; type may be omitted
4976
+ types = ( types || "" ).match( rnotwhite ) || [ "" ];
4977
+ t = types.length;
4978
+ while ( t-- ) {
4979
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
4980
+ type = origType = tmp[ 1 ];
4981
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4982
+
4983
+ // Unbind all events (on this namespace, if provided) for the element
4984
+ if ( !type ) {
4985
+ for ( type in events ) {
4986
+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4987
+ }
4988
+ continue;
4989
+ }
4990
+
4991
+ special = jQuery.event.special[ type ] || {};
4992
+ type = ( selector ? special.delegateType : special.bindType ) || type;
4993
+ handlers = events[ type ] || [];
4994
+ tmp = tmp[ 2 ] &&
4995
+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
4996
+
4997
+ // Remove matching events
4998
+ origCount = j = handlers.length;
4999
+ while ( j-- ) {
5000
+ handleObj = handlers[ j ];
5001
+
5002
+ if ( ( mappedTypes || origType === handleObj.origType ) &&
5003
+ ( !handler || handler.guid === handleObj.guid ) &&
5004
+ ( !tmp || tmp.test( handleObj.namespace ) ) &&
5005
+ ( !selector || selector === handleObj.selector ||
5006
+ selector === "**" && handleObj.selector ) ) {
5007
+ handlers.splice( j, 1 );
5008
+
5009
+ if ( handleObj.selector ) {
5010
+ handlers.delegateCount--;
5011
+ }
5012
+ if ( special.remove ) {
5013
+ special.remove.call( elem, handleObj );
5014
+ }
5015
+ }
5016
+ }
5017
+
5018
+ // Remove generic event handler if we removed something and no more handlers exist
5019
+ // (avoids potential for endless recursion during removal of special event handlers)
5020
+ if ( origCount && !handlers.length ) {
5021
+ if ( !special.teardown ||
5022
+ special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5023
+
5024
+ jQuery.removeEvent( elem, type, elemData.handle );
5025
+ }
5026
+
5027
+ delete events[ type ];
5028
+ }
5029
+ }
5030
+
5031
+ // Remove the expando if it's no longer used
5032
+ if ( jQuery.isEmptyObject( events ) ) {
5033
+ delete elemData.handle;
5034
+
5035
+ // removeData also checks for emptiness and clears the expando if empty
5036
+ // so use it instead of delete
5037
+ jQuery._removeData( elem, "events" );
5038
+ }
5039
+ },
5040
+
5041
+ trigger: function( event, data, elem, onlyHandlers ) {
5042
+ var handle, ontype, cur,
5043
+ bubbleType, special, tmp, i,
5044
+ eventPath = [ elem || document ],
5045
+ type = hasOwn.call( event, "type" ) ? event.type : event,
5046
+ namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
5047
+
5048
+ cur = tmp = elem = elem || document;
5049
+
5050
+ // Don't do events on text and comment nodes
5051
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
5052
+ return;
5053
+ }
5054
+
5055
+ // focus/blur morphs to focusin/out; ensure we're not firing them right now
5056
+ if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
5057
+ return;
5058
+ }
5059
+
5060
+ if ( type.indexOf( "." ) > -1 ) {
5061
+
5062
+ // Namespaced trigger; create a regexp to match event type in handle()
5063
+ namespaces = type.split( "." );
5064
+ type = namespaces.shift();
5065
+ namespaces.sort();
5066
+ }
5067
+ ontype = type.indexOf( ":" ) < 0 && "on" + type;
5068
+
5069
+ // Caller can pass in a jQuery.Event object, Object, or just an event type string
5070
+ event = event[ jQuery.expando ] ?
5071
+ event :
5072
+ new jQuery.Event( type, typeof event === "object" && event );
5073
+
5074
+ // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
5075
+ event.isTrigger = onlyHandlers ? 2 : 3;
5076
+ event.namespace = namespaces.join( "." );
5077
+ event.rnamespace = event.namespace ?
5078
+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
5079
+ null;
5080
+
5081
+ // Clean up the event in case it is being reused
5082
+ event.result = undefined;
5083
+ if ( !event.target ) {
5084
+ event.target = elem;
5085
+ }
5086
+
5087
+ // Clone any incoming data and prepend the event, creating the handler arg list
5088
+ data = data == null ?
5089
+ [ event ] :
5090
+ jQuery.makeArray( data, [ event ] );
5091
+
5092
+ // Allow special events to draw outside the lines
5093
+ special = jQuery.event.special[ type ] || {};
5094
+ if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
5095
+ return;
5096
+ }
5097
+
5098
+ // Determine event propagation path in advance, per W3C events spec (#9951)
5099
+ // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
5100
+ if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
5101
+
5102
+ bubbleType = special.delegateType || type;
5103
+ if ( !rfocusMorph.test( bubbleType + type ) ) {
5104
+ cur = cur.parentNode;
5105
+ }
5106
+ for ( ; cur; cur = cur.parentNode ) {
5107
+ eventPath.push( cur );
5108
+ tmp = cur;
5109
+ }
5110
+
5111
+ // Only add window if we got to document (e.g., not plain obj or detached DOM)
5112
+ if ( tmp === ( elem.ownerDocument || document ) ) {
5113
+ eventPath.push( tmp.defaultView || tmp.parentWindow || window );
5114
+ }
5115
+ }
5116
+
5117
+ // Fire handlers on the event path
5118
+ i = 0;
5119
+ while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
5120
+
5121
+ event.type = i > 1 ?
5122
+ bubbleType :
5123
+ special.bindType || type;
5124
+
5125
+ // jQuery handler
5126
+ handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] &&
5127
+ jQuery._data( cur, "handle" );
5128
+
5129
+ if ( handle ) {
5130
+ handle.apply( cur, data );
5131
+ }
5132
+
5133
+ // Native handler
5134
+ handle = ontype && cur[ ontype ];
5135
+ if ( handle && handle.apply && acceptData( cur ) ) {
5136
+ event.result = handle.apply( cur, data );
5137
+ if ( event.result === false ) {
5138
+ event.preventDefault();
5139
+ }
5140
+ }
5141
+ }
5142
+ event.type = type;
5143
+
5144
+ // If nobody prevented the default action, do it now
5145
+ if ( !onlyHandlers && !event.isDefaultPrevented() ) {
5146
+
5147
+ if (
5148
+ ( !special._default ||
5149
+ special._default.apply( eventPath.pop(), data ) === false
5150
+ ) && acceptData( elem )
5151
+ ) {
5152
+
5153
+ // Call a native DOM method on the target with the same name name as the event.
5154
+ // Can't use an .isFunction() check here because IE6/7 fails that test.
5155
+ // Don't do default actions on window, that's where global variables be (#6170)
5156
+ if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
5157
+
5158
+ // Don't re-trigger an onFOO event when we call its FOO() method
5159
+ tmp = elem[ ontype ];
5160
+
5161
+ if ( tmp ) {
5162
+ elem[ ontype ] = null;
5163
+ }
5164
+
5165
+ // Prevent re-triggering of the same event, since we already bubbled it above
5166
+ jQuery.event.triggered = type;
5167
+ try {
5168
+ elem[ type ]();
5169
+ } catch ( e ) {
5170
+
5171
+ // IE<9 dies on focus/blur to hidden element (#1486,#12518)
5172
+ // only reproducible on winXP IE8 native, not IE9 in IE8 mode
5173
+ }
5174
+ jQuery.event.triggered = undefined;
5175
+
5176
+ if ( tmp ) {
5177
+ elem[ ontype ] = tmp;
5178
+ }
5179
+ }
5180
+ }
5181
+ }
5182
+
5183
+ return event.result;
5184
+ },
5185
+
5186
+ dispatch: function( event ) {
5187
+
5188
+ // Make a writable jQuery.Event from the native event object
5189
+ event = jQuery.event.fix( event );
5190
+
5191
+ var i, j, ret, matched, handleObj,
5192
+ handlerQueue = [],
5193
+ args = slice.call( arguments ),
5194
+ handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
5195
+ special = jQuery.event.special[ event.type ] || {};
5196
+
5197
+ // Use the fix-ed jQuery.Event rather than the (read-only) native event
5198
+ args[ 0 ] = event;
5199
+ event.delegateTarget = this;
5200
+
5201
+ // Call the preDispatch hook for the mapped type, and let it bail if desired
5202
+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5203
+ return;
5204
+ }
5205
+
5206
+ // Determine handlers
5207
+ handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5208
+
5209
+ // Run delegates first; they may want to stop propagation beneath us
5210
+ i = 0;
5211
+ while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5212
+ event.currentTarget = matched.elem;
5213
+
5214
+ j = 0;
5215
+ while ( ( handleObj = matched.handlers[ j++ ] ) &&
5216
+ !event.isImmediatePropagationStopped() ) {
5217
+
5218
+ // Triggered event must either 1) have no namespace, or 2) have namespace(s)
5219
+ // a subset or equal to those in the bound event (both can have no namespace).
5220
+ if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
5221
+
5222
+ event.handleObj = handleObj;
5223
+ event.data = handleObj.data;
5224
+
5225
+ ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5226
+ handleObj.handler ).apply( matched.elem, args );
5227
+
5228
+ if ( ret !== undefined ) {
5229
+ if ( ( event.result = ret ) === false ) {
5230
+ event.preventDefault();
5231
+ event.stopPropagation();
5232
+ }
5233
+ }
5234
+ }
5235
+ }
5236
+ }
5237
+
5238
+ // Call the postDispatch hook for the mapped type
5239
+ if ( special.postDispatch ) {
5240
+ special.postDispatch.call( this, event );
5241
+ }
5242
+
5243
+ return event.result;
5244
+ },
5245
+
5246
+ handlers: function( event, handlers ) {
5247
+ var i, matches, sel, handleObj,
5248
+ handlerQueue = [],
5249
+ delegateCount = handlers.delegateCount,
5250
+ cur = event.target;
5251
+
5252
+ // Support (at least): Chrome, IE9
5253
+ // Find delegate handlers
5254
+ // Black-hole SVG <use> instance trees (#13180)
5255
+ //
5256
+ // Support: Firefox<=42+
5257
+ // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
5258
+ if ( delegateCount && cur.nodeType &&
5259
+ ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
5260
+
5261
+ /* jshint eqeqeq: false */
5262
+ for ( ; cur != this; cur = cur.parentNode || this ) {
5263
+ /* jshint eqeqeq: true */
5264
+
5265
+ // Don't check non-elements (#13208)
5266
+ // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5267
+ if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
5268
+ matches = [];
5269
+ for ( i = 0; i < delegateCount; i++ ) {
5270
+ handleObj = handlers[ i ];
5271
+
5272
+ // Don't conflict with Object.prototype properties (#13203)
5273
+ sel = handleObj.selector + " ";
5274
+
5275
+ if ( matches[ sel ] === undefined ) {
5276
+ matches[ sel ] = handleObj.needsContext ?
5277
+ jQuery( sel, this ).index( cur ) > -1 :
5278
+ jQuery.find( sel, this, null, [ cur ] ).length;
5279
+ }
5280
+ if ( matches[ sel ] ) {
5281
+ matches.push( handleObj );
5282
+ }
5283
+ }
5284
+ if ( matches.length ) {
5285
+ handlerQueue.push( { elem: cur, handlers: matches } );
5286
+ }
5287
+ }
5288
+ }
5289
+ }
5290
+
5291
+ // Add the remaining (directly-bound) handlers
5292
+ if ( delegateCount < handlers.length ) {
5293
+ handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
5294
+ }
5295
+
5296
+ return handlerQueue;
5297
+ },
5298
+
5299
+ fix: function( event ) {
5300
+ if ( event[ jQuery.expando ] ) {
5301
+ return event;
5302
+ }
5303
+
5304
+ // Create a writable copy of the event object and normalize some properties
5305
+ var i, prop, copy,
5306
+ type = event.type,
5307
+ originalEvent = event,
5308
+ fixHook = this.fixHooks[ type ];
5309
+
5310
+ if ( !fixHook ) {
5311
+ this.fixHooks[ type ] = fixHook =
5312
+ rmouseEvent.test( type ) ? this.mouseHooks :
5313
+ rkeyEvent.test( type ) ? this.keyHooks :
5314
+ {};
5315
+ }
5316
+ copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
5317
+
5318
+ event = new jQuery.Event( originalEvent );
5319
+
5320
+ i = copy.length;
5321
+ while ( i-- ) {
5322
+ prop = copy[ i ];
5323
+ event[ prop ] = originalEvent[ prop ];
5324
+ }
5325
+
5326
+ // Support: IE<9
5327
+ // Fix target property (#1925)
5328
+ if ( !event.target ) {
5329
+ event.target = originalEvent.srcElement || document;
5330
+ }
5331
+
5332
+ // Support: Safari 6-8+
5333
+ // Target should not be a text node (#504, #13143)
5334
+ if ( event.target.nodeType === 3 ) {
5335
+ event.target = event.target.parentNode;
5336
+ }
5337
+
5338
+ // Support: IE<9
5339
+ // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
5340
+ event.metaKey = !!event.metaKey;
5341
+
5342
+ return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
5343
+ },
5344
+
5345
+ // Includes some event props shared by KeyEvent and MouseEvent
5346
+ props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
5347
+ "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
5348
+
5349
+ fixHooks: {},
5350
+
5351
+ keyHooks: {
5352
+ props: "char charCode key keyCode".split( " " ),
5353
+ filter: function( event, original ) {
5354
+
5355
+ // Add which for key events
5356
+ if ( event.which == null ) {
5357
+ event.which = original.charCode != null ? original.charCode : original.keyCode;
5358
+ }
5359
+
5360
+ return event;
5361
+ }
5362
+ },
5363
+
5364
+ mouseHooks: {
5365
+ props: ( "button buttons clientX clientY fromElement offsetX offsetY " +
5366
+ "pageX pageY screenX screenY toElement" ).split( " " ),
5367
+ filter: function( event, original ) {
5368
+ var body, eventDoc, doc,
5369
+ button = original.button,
5370
+ fromElement = original.fromElement;
5371
+
5372
+ // Calculate pageX/Y if missing and clientX/Y available
5373
+ if ( event.pageX == null && original.clientX != null ) {
5374
+ eventDoc = event.target.ownerDocument || document;
5375
+ doc = eventDoc.documentElement;
5376
+ body = eventDoc.body;
5377
+
5378
+ event.pageX = original.clientX +
5379
+ ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
5380
+ ( doc && doc.clientLeft || body && body.clientLeft || 0 );
5381
+ event.pageY = original.clientY +
5382
+ ( doc && doc.scrollTop || body && body.scrollTop || 0 ) -
5383
+ ( doc && doc.clientTop || body && body.clientTop || 0 );
5384
+ }
5385
+
5386
+ // Add relatedTarget, if necessary
5387
+ if ( !event.relatedTarget && fromElement ) {
5388
+ event.relatedTarget = fromElement === event.target ?
5389
+ original.toElement :
5390
+ fromElement;
5391
+ }
5392
+
5393
+ // Add which for click: 1 === left; 2 === middle; 3 === right
5394
+ // Note: button is not normalized, so don't use it
5395
+ if ( !event.which && button !== undefined ) {
5396
+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
5397
+ }
5398
+
5399
+ return event;
5400
+ }
5401
+ },
5402
+
5403
+ special: {
5404
+ load: {
5405
+
5406
+ // Prevent triggered image.load events from bubbling to window.load
5407
+ noBubble: true
5408
+ },
5409
+ focus: {
5410
+
5411
+ // Fire native event if possible so blur/focus sequence is correct
5412
+ trigger: function() {
5413
+ if ( this !== safeActiveElement() && this.focus ) {
5414
+ try {
5415
+ this.focus();
5416
+ return false;
5417
+ } catch ( e ) {
5418
+
5419
+ // Support: IE<9
5420
+ // If we error on focus to hidden element (#1486, #12518),
5421
+ // let .trigger() run the handlers
5422
+ }
5423
+ }
5424
+ },
5425
+ delegateType: "focusin"
5426
+ },
5427
+ blur: {
5428
+ trigger: function() {
5429
+ if ( this === safeActiveElement() && this.blur ) {
5430
+ this.blur();
5431
+ return false;
5432
+ }
5433
+ },
5434
+ delegateType: "focusout"
5435
+ },
5436
+ click: {
5437
+
5438
+ // For checkbox, fire native event so checked state will be right
5439
+ trigger: function() {
5440
+ if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
5441
+ this.click();
5442
+ return false;
5443
+ }
5444
+ },
5445
+
5446
+ // For cross-browser consistency, don't fire native .click() on links
5447
+ _default: function( event ) {
5448
+ return jQuery.nodeName( event.target, "a" );
5449
+ }
5450
+ },
5451
+
5452
+ beforeunload: {
5453
+ postDispatch: function( event ) {
5454
+
5455
+ // Support: Firefox 20+
5456
+ // Firefox doesn't alert if the returnValue field is not set.
5457
+ if ( event.result !== undefined && event.originalEvent ) {
5458
+ event.originalEvent.returnValue = event.result;
5459
+ }
5460
+ }
5461
+ }
5462
+ },
5463
+
5464
+ // Piggyback on a donor event to simulate a different one
5465
+ simulate: function( type, elem, event ) {
5466
+ var e = jQuery.extend(
5467
+ new jQuery.Event(),
5468
+ event,
5469
+ {
5470
+ type: type,
5471
+ isSimulated: true
5472
+
5473
+ // Previously, `originalEvent: {}` was set here, so stopPropagation call
5474
+ // would not be triggered on donor event, since in our own
5475
+ // jQuery.event.stopPropagation function we had a check for existence of
5476
+ // originalEvent.stopPropagation method, so, consequently it would be a noop.
5477
+ //
5478
+ // Guard for simulated events was moved to jQuery.event.stopPropagation function
5479
+ // since `originalEvent` should point to the original event for the
5480
+ // constancy with other events and for more focused logic
5481
+ }
5482
+ );
5483
+
5484
+ jQuery.event.trigger( e, null, elem );
5485
+
5486
+ if ( e.isDefaultPrevented() ) {
5487
+ event.preventDefault();
5488
+ }
5489
+ }
5490
+ };
5491
+
5492
+ jQuery.removeEvent = document.removeEventListener ?
5493
+ function( elem, type, handle ) {
5494
+
5495
+ // This "if" is needed for plain objects
5496
+ if ( elem.removeEventListener ) {
5497
+ elem.removeEventListener( type, handle );
5498
+ }
5499
+ } :
5500
+ function( elem, type, handle ) {
5501
+ var name = "on" + type;
5502
+
5503
+ if ( elem.detachEvent ) {
5504
+
5505
+ // #8545, #7054, preventing memory leaks for custom events in IE6-8
5506
+ // detachEvent needed property on element, by name of that event,
5507
+ // to properly expose it to GC
5508
+ if ( typeof elem[ name ] === "undefined" ) {
5509
+ elem[ name ] = null;
5510
+ }
5511
+
5512
+ elem.detachEvent( name, handle );
5513
+ }
5514
+ };
5515
+
5516
+ jQuery.Event = function( src, props ) {
5517
+
5518
+ // Allow instantiation without the 'new' keyword
5519
+ if ( !( this instanceof jQuery.Event ) ) {
5520
+ return new jQuery.Event( src, props );
5521
+ }
5522
+
5523
+ // Event object
5524
+ if ( src && src.type ) {
5525
+ this.originalEvent = src;
5526
+ this.type = src.type;
5527
+
5528
+ // Events bubbling up the document may have been marked as prevented
5529
+ // by a handler lower down the tree; reflect the correct value.
5530
+ this.isDefaultPrevented = src.defaultPrevented ||
5531
+ src.defaultPrevented === undefined &&
5532
+
5533
+ // Support: IE < 9, Android < 4.0
5534
+ src.returnValue === false ?
5535
+ returnTrue :
5536
+ returnFalse;
5537
+
5538
+ // Event type
5539
+ } else {
5540
+ this.type = src;
5541
+ }
5542
+
5543
+ // Put explicitly provided properties onto the event object
5544
+ if ( props ) {
5545
+ jQuery.extend( this, props );
5546
+ }
5547
+
5548
+ // Create a timestamp if incoming event doesn't have one
5549
+ this.timeStamp = src && src.timeStamp || jQuery.now();
5550
+
5551
+ // Mark it as fixed
5552
+ this[ jQuery.expando ] = true;
5553
+ };
5554
+
5555
+ // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5556
+ // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5557
+ jQuery.Event.prototype = {
5558
+ constructor: jQuery.Event,
5559
+ isDefaultPrevented: returnFalse,
5560
+ isPropagationStopped: returnFalse,
5561
+ isImmediatePropagationStopped: returnFalse,
5562
+
5563
+ preventDefault: function() {
5564
+ var e = this.originalEvent;
5565
+
5566
+ this.isDefaultPrevented = returnTrue;
5567
+ if ( !e ) {
5568
+ return;
5569
+ }
5570
+
5571
+ // If preventDefault exists, run it on the original event
5572
+ if ( e.preventDefault ) {
5573
+ e.preventDefault();
5574
+
5575
+ // Support: IE
5576
+ // Otherwise set the returnValue property of the original event to false
5577
+ } else {
5578
+ e.returnValue = false;
5579
+ }
5580
+ },
5581
+ stopPropagation: function() {
5582
+ var e = this.originalEvent;
5583
+
5584
+ this.isPropagationStopped = returnTrue;
5585
+
5586
+ if ( !e || this.isSimulated ) {
5587
+ return;
5588
+ }
5589
+
5590
+ // If stopPropagation exists, run it on the original event
5591
+ if ( e.stopPropagation ) {
5592
+ e.stopPropagation();
5593
+ }
5594
+
5595
+ // Support: IE
5596
+ // Set the cancelBubble property of the original event to true
5597
+ e.cancelBubble = true;
5598
+ },
5599
+ stopImmediatePropagation: function() {
5600
+ var e = this.originalEvent;
5601
+
5602
+ this.isImmediatePropagationStopped = returnTrue;
5603
+
5604
+ if ( e && e.stopImmediatePropagation ) {
5605
+ e.stopImmediatePropagation();
5606
+ }
5607
+
5608
+ this.stopPropagation();
5609
+ }
5610
+ };
5611
+
5612
+ // Create mouseenter/leave events using mouseover/out and event-time checks
5613
+ // so that event delegation works in jQuery.
5614
+ // Do the same for pointerenter/pointerleave and pointerover/pointerout
5615
+ //
5616
+ // Support: Safari 7 only
5617
+ // Safari sends mouseenter too often; see:
5618
+ // https://code.google.com/p/chromium/issues/detail?id=470258
5619
+ // for the description of the bug (it existed in older Chrome versions as well).
5620
+ jQuery.each( {
5621
+ mouseenter: "mouseover",
5622
+ mouseleave: "mouseout",
5623
+ pointerenter: "pointerover",
5624
+ pointerleave: "pointerout"
5625
+ }, function( orig, fix ) {
5626
+ jQuery.event.special[ orig ] = {
5627
+ delegateType: fix,
5628
+ bindType: fix,
5629
+
5630
+ handle: function( event ) {
5631
+ var ret,
5632
+ target = this,
5633
+ related = event.relatedTarget,
5634
+ handleObj = event.handleObj;
5635
+
5636
+ // For mouseenter/leave call the handler if related is outside the target.
5637
+ // NB: No relatedTarget if the mouse left/entered the browser window
5638
+ if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5639
+ event.type = handleObj.origType;
5640
+ ret = handleObj.handler.apply( this, arguments );
5641
+ event.type = fix;
5642
+ }
5643
+ return ret;
5644
+ }
5645
+ };
5646
+ } );
5647
+
5648
+ // IE submit delegation
5649
+ if ( !support.submit ) {
5650
+
5651
+ jQuery.event.special.submit = {
5652
+ setup: function() {
5653
+
5654
+ // Only need this for delegated form submit events
5655
+ if ( jQuery.nodeName( this, "form" ) ) {
5656
+ return false;
5657
+ }
5658
+
5659
+ // Lazy-add a submit handler when a descendant form may potentially be submitted
5660
+ jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
5661
+
5662
+ // Node name check avoids a VML-related crash in IE (#9807)
5663
+ var elem = e.target,
5664
+ form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ?
5665
+
5666
+ // Support: IE <=8
5667
+ // We use jQuery.prop instead of elem.form
5668
+ // to allow fixing the IE8 delegated submit issue (gh-2332)
5669
+ // by 3rd party polyfills/workarounds.
5670
+ jQuery.prop( elem, "form" ) :
5671
+ undefined;
5672
+
5673
+ if ( form && !jQuery._data( form, "submit" ) ) {
5674
+ jQuery.event.add( form, "submit._submit", function( event ) {
5675
+ event._submitBubble = true;
5676
+ } );
5677
+ jQuery._data( form, "submit", true );
5678
+ }
5679
+ } );
5680
+
5681
+ // return undefined since we don't need an event listener
5682
+ },
5683
+
5684
+ postDispatch: function( event ) {
5685
+
5686
+ // If form was submitted by the user, bubble the event up the tree
5687
+ if ( event._submitBubble ) {
5688
+ delete event._submitBubble;
5689
+ if ( this.parentNode && !event.isTrigger ) {
5690
+ jQuery.event.simulate( "submit", this.parentNode, event );
5691
+ }
5692
+ }
5693
+ },
5694
+
5695
+ teardown: function() {
5696
+
5697
+ // Only need this for delegated form submit events
5698
+ if ( jQuery.nodeName( this, "form" ) ) {
5699
+ return false;
5700
+ }
5701
+
5702
+ // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
5703
+ jQuery.event.remove( this, "._submit" );
5704
+ }
5705
+ };
5706
+ }
5707
+
5708
+ // IE change delegation and checkbox/radio fix
5709
+ if ( !support.change ) {
5710
+
5711
+ jQuery.event.special.change = {
5712
+
5713
+ setup: function() {
5714
+
5715
+ if ( rformElems.test( this.nodeName ) ) {
5716
+
5717
+ // IE doesn't fire change on a check/radio until blur; trigger it on click
5718
+ // after a propertychange. Eat the blur-change in special.change.handle.
5719
+ // This still fires onchange a second time for check/radio after blur.
5720
+ if ( this.type === "checkbox" || this.type === "radio" ) {
5721
+ jQuery.event.add( this, "propertychange._change", function( event ) {
5722
+ if ( event.originalEvent.propertyName === "checked" ) {
5723
+ this._justChanged = true;
5724
+ }
5725
+ } );
5726
+ jQuery.event.add( this, "click._change", function( event ) {
5727
+ if ( this._justChanged && !event.isTrigger ) {
5728
+ this._justChanged = false;
5729
+ }
5730
+
5731
+ // Allow triggered, simulated change events (#11500)
5732
+ jQuery.event.simulate( "change", this, event );
5733
+ } );
5734
+ }
5735
+ return false;
5736
+ }
5737
+
5738
+ // Delegated event; lazy-add a change handler on descendant inputs
5739
+ jQuery.event.add( this, "beforeactivate._change", function( e ) {
5740
+ var elem = e.target;
5741
+
5742
+ if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) {
5743
+ jQuery.event.add( elem, "change._change", function( event ) {
5744
+ if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
5745
+ jQuery.event.simulate( "change", this.parentNode, event );
5746
+ }
5747
+ } );
5748
+ jQuery._data( elem, "change", true );
5749
+ }
5750
+ } );
5751
+ },
5752
+
5753
+ handle: function( event ) {
5754
+ var elem = event.target;
5755
+
5756
+ // Swallow native change events from checkbox/radio, we already triggered them above
5757
+ if ( this !== elem || event.isSimulated || event.isTrigger ||
5758
+ ( elem.type !== "radio" && elem.type !== "checkbox" ) ) {
5759
+
5760
+ return event.handleObj.handler.apply( this, arguments );
5761
+ }
5762
+ },
5763
+
5764
+ teardown: function() {
5765
+ jQuery.event.remove( this, "._change" );
5766
+
5767
+ return !rformElems.test( this.nodeName );
5768
+ }
5769
+ };
5770
+ }
5771
+
5772
+ // Support: Firefox
5773
+ // Firefox doesn't have focus(in | out) events
5774
+ // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
5775
+ //
5776
+ // Support: Chrome, Safari
5777
+ // focus(in | out) events fire after focus & blur events,
5778
+ // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
5779
+ // Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
5780
+ if ( !support.focusin ) {
5781
+ jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
5782
+
5783
+ // Attach a single capturing handler on the document while someone wants focusin/focusout
5784
+ var handler = function( event ) {
5785
+ jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
5786
+ };
5787
+
5788
+ jQuery.event.special[ fix ] = {
5789
+ setup: function() {
5790
+ var doc = this.ownerDocument || this,
5791
+ attaches = jQuery._data( doc, fix );
5792
+
5793
+ if ( !attaches ) {
5794
+ doc.addEventListener( orig, handler, true );
5795
+ }
5796
+ jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
5797
+ },
5798
+ teardown: function() {
5799
+ var doc = this.ownerDocument || this,
5800
+ attaches = jQuery._data( doc, fix ) - 1;
5801
+
5802
+ if ( !attaches ) {
5803
+ doc.removeEventListener( orig, handler, true );
5804
+ jQuery._removeData( doc, fix );
5805
+ } else {
5806
+ jQuery._data( doc, fix, attaches );
5807
+ }
5808
+ }
5809
+ };
5810
+ } );
5811
+ }
5812
+
5813
+ jQuery.fn.extend( {
5814
+
5815
+ on: function( types, selector, data, fn ) {
5816
+ return on( this, types, selector, data, fn );
5817
+ },
5818
+ one: function( types, selector, data, fn ) {
5819
+ return on( this, types, selector, data, fn, 1 );
5820
+ },
5821
+ off: function( types, selector, fn ) {
5822
+ var handleObj, type;
5823
+ if ( types && types.preventDefault && types.handleObj ) {
5824
+
5825
+ // ( event ) dispatched jQuery.Event
5826
+ handleObj = types.handleObj;
5827
+ jQuery( types.delegateTarget ).off(
5828
+ handleObj.namespace ?
5829
+ handleObj.origType + "." + handleObj.namespace :
5830
+ handleObj.origType,
5831
+ handleObj.selector,
5832
+ handleObj.handler
5833
+ );
5834
+ return this;
5835
+ }
5836
+ if ( typeof types === "object" ) {
5837
+
5838
+ // ( types-object [, selector] )
5839
+ for ( type in types ) {
5840
+ this.off( type, selector, types[ type ] );
5841
+ }
5842
+ return this;
5843
+ }
5844
+ if ( selector === false || typeof selector === "function" ) {
5845
+
5846
+ // ( types [, fn] )
5847
+ fn = selector;
5848
+ selector = undefined;
5849
+ }
5850
+ if ( fn === false ) {
5851
+ fn = returnFalse;
5852
+ }
5853
+ return this.each( function() {
5854
+ jQuery.event.remove( this, types, fn, selector );
5855
+ } );
5856
+ },
5857
+
5858
+ trigger: function( type, data ) {
5859
+ return this.each( function() {
5860
+ jQuery.event.trigger( type, data, this );
5861
+ } );
5862
+ },
5863
+ triggerHandler: function( type, data ) {
5864
+ var elem = this[ 0 ];
5865
+ if ( elem ) {
5866
+ return jQuery.event.trigger( type, data, elem, true );
5867
+ }
5868
+ }
5869
+ } );
5870
+
5871
+
5872
+ var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5873
+ rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ),
5874
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
5875
+
5876
+ // Support: IE 10-11, Edge 10240+
5877
+ // In IE/Edge using regex groups here causes severe slowdowns.
5878
+ // See https://connect.microsoft.com/IE/feedback/details/1736512/
5879
+ rnoInnerhtml = /<script|<style|<link/i,
5880
+
5881
+ // checked="checked" or checked
5882
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5883
+ rscriptTypeMasked = /^true\/(.*)/,
5884
+ rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
5885
+ safeFragment = createSafeFragment( document ),
5886
+ fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) );
5887
+
5888
+ // Support: IE<8
5889
+ // Manipulating tables requires a tbody
5890
+ function manipulationTarget( elem, content ) {
5891
+ return jQuery.nodeName( elem, "table" ) &&
5892
+ jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5893
+
5894
+ elem.getElementsByTagName( "tbody" )[ 0 ] ||
5895
+ elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
5896
+ elem;
5897
+ }
5898
+
5899
+ // Replace/restore the type attribute of script elements for safe DOM manipulation
5900
+ function disableScript( elem ) {
5901
+ elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type;
5902
+ return elem;
5903
+ }
5904
+ function restoreScript( elem ) {
5905
+ var match = rscriptTypeMasked.exec( elem.type );
5906
+ if ( match ) {
5907
+ elem.type = match[ 1 ];
5908
+ } else {
5909
+ elem.removeAttribute( "type" );
5910
+ }
5911
+ return elem;
5912
+ }
5913
+
5914
+ function cloneCopyEvent( src, dest ) {
5915
+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5916
+ return;
5917
+ }
5918
+
5919
+ var type, i, l,
5920
+ oldData = jQuery._data( src ),
5921
+ curData = jQuery._data( dest, oldData ),
5922
+ events = oldData.events;
5923
+
5924
+ if ( events ) {
5925
+ delete curData.handle;
5926
+ curData.events = {};
5927
+
5928
+ for ( type in events ) {
5929
+ for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5930
+ jQuery.event.add( dest, type, events[ type ][ i ] );
5931
+ }
5932
+ }
5933
+ }
5934
+
5935
+ // make the cloned public data object a copy from the original
5936
+ if ( curData.data ) {
5937
+ curData.data = jQuery.extend( {}, curData.data );
5938
+ }
5939
+ }
5940
+
5941
+ function fixCloneNodeIssues( src, dest ) {
5942
+ var nodeName, e, data;
5943
+
5944
+ // We do not need to do anything for non-Elements
5945
+ if ( dest.nodeType !== 1 ) {
5946
+ return;
5947
+ }
5948
+
5949
+ nodeName = dest.nodeName.toLowerCase();
5950
+
5951
+ // IE6-8 copies events bound via attachEvent when using cloneNode.
5952
+ if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
5953
+ data = jQuery._data( dest );
5954
+
5955
+ for ( e in data.events ) {
5956
+ jQuery.removeEvent( dest, e, data.handle );
5957
+ }
5958
+
5959
+ // Event data gets referenced instead of copied if the expando gets copied too
5960
+ dest.removeAttribute( jQuery.expando );
5961
+ }
5962
+
5963
+ // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
5964
+ if ( nodeName === "script" && dest.text !== src.text ) {
5965
+ disableScript( dest ).text = src.text;
5966
+ restoreScript( dest );
5967
+
5968
+ // IE6-10 improperly clones children of object elements using classid.
5969
+ // IE10 throws NoModificationAllowedError if parent is null, #12132.
5970
+ } else if ( nodeName === "object" ) {
5971
+ if ( dest.parentNode ) {
5972
+ dest.outerHTML = src.outerHTML;
5973
+ }
5974
+
5975
+ // This path appears unavoidable for IE9. When cloning an object
5976
+ // element in IE9, the outerHTML strategy above is not sufficient.
5977
+ // If the src has innerHTML and the destination does not,
5978
+ // copy the src.innerHTML into the dest.innerHTML. #10324
5979
+ if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) {
5980
+ dest.innerHTML = src.innerHTML;
5981
+ }
5982
+
5983
+ } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5984
+
5985
+ // IE6-8 fails to persist the checked state of a cloned checkbox
5986
+ // or radio button. Worse, IE6-7 fail to give the cloned element
5987
+ // a checked appearance if the defaultChecked value isn't also set
5988
+
5989
+ dest.defaultChecked = dest.checked = src.checked;
5990
+
5991
+ // IE6-7 get confused and end up setting the value of a cloned
5992
+ // checkbox/radio button to an empty string instead of "on"
5993
+ if ( dest.value !== src.value ) {
5994
+ dest.value = src.value;
5995
+ }
5996
+
5997
+ // IE6-8 fails to return the selected option to the default selected
5998
+ // state when cloning options
5999
+ } else if ( nodeName === "option" ) {
6000
+ dest.defaultSelected = dest.selected = src.defaultSelected;
6001
+
6002
+ // IE6-8 fails to set the defaultValue to the correct value when
6003
+ // cloning other types of input fields
6004
+ } else if ( nodeName === "input" || nodeName === "textarea" ) {
6005
+ dest.defaultValue = src.defaultValue;
6006
+ }
6007
+ }
6008
+
6009
+ function domManip( collection, args, callback, ignored ) {
6010
+
6011
+ // Flatten any nested arrays
6012
+ args = concat.apply( [], args );
6013
+
6014
+ var first, node, hasScripts,
6015
+ scripts, doc, fragment,
6016
+ i = 0,
6017
+ l = collection.length,
6018
+ iNoClone = l - 1,
6019
+ value = args[ 0 ],
6020
+ isFunction = jQuery.isFunction( value );
6021
+
6022
+ // We can't cloneNode fragments that contain checked, in WebKit
6023
+ if ( isFunction ||
6024
+ ( l > 1 && typeof value === "string" &&
6025
+ !support.checkClone && rchecked.test( value ) ) ) {
6026
+ return collection.each( function( index ) {
6027
+ var self = collection.eq( index );
6028
+ if ( isFunction ) {
6029
+ args[ 0 ] = value.call( this, index, self.html() );
6030
+ }
6031
+ domManip( self, args, callback, ignored );
6032
+ } );
6033
+ }
6034
+
6035
+ if ( l ) {
6036
+ fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
6037
+ first = fragment.firstChild;
6038
+
6039
+ if ( fragment.childNodes.length === 1 ) {
6040
+ fragment = first;
6041
+ }
6042
+
6043
+ // Require either new content or an interest in ignored elements to invoke the callback
6044
+ if ( first || ignored ) {
6045
+ scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
6046
+ hasScripts = scripts.length;
6047
+
6048
+ // Use the original fragment for the last item
6049
+ // instead of the first because it can end up
6050
+ // being emptied incorrectly in certain situations (#8070).
6051
+ for ( ; i < l; i++ ) {
6052
+ node = fragment;
6053
+
6054
+ if ( i !== iNoClone ) {
6055
+ node = jQuery.clone( node, true, true );
6056
+
6057
+ // Keep references to cloned scripts for later restoration
6058
+ if ( hasScripts ) {
6059
+
6060
+ // Support: Android<4.1, PhantomJS<2
6061
+ // push.apply(_, arraylike) throws on ancient WebKit
6062
+ jQuery.merge( scripts, getAll( node, "script" ) );
6063
+ }
6064
+ }
6065
+
6066
+ callback.call( collection[ i ], node, i );
6067
+ }
6068
+
6069
+ if ( hasScripts ) {
6070
+ doc = scripts[ scripts.length - 1 ].ownerDocument;
6071
+
6072
+ // Reenable scripts
6073
+ jQuery.map( scripts, restoreScript );
6074
+
6075
+ // Evaluate executable scripts on first document insertion
6076
+ for ( i = 0; i < hasScripts; i++ ) {
6077
+ node = scripts[ i ];
6078
+ if ( rscriptType.test( node.type || "" ) &&
6079
+ !jQuery._data( node, "globalEval" ) &&
6080
+ jQuery.contains( doc, node ) ) {
6081
+
6082
+ if ( node.src ) {
6083
+
6084
+ // Optional AJAX dependency, but won't run scripts if not present
6085
+ if ( jQuery._evalUrl ) {
6086
+ jQuery._evalUrl( node.src );
6087
+ }
6088
+ } else {
6089
+ jQuery.globalEval(
6090
+ ( node.text || node.textContent || node.innerHTML || "" )
6091
+ .replace( rcleanScript, "" )
6092
+ );
6093
+ }
6094
+ }
6095
+ }
6096
+ }
6097
+
6098
+ // Fix #11809: Avoid leaking memory
6099
+ fragment = first = null;
6100
+ }
6101
+ }
6102
+
6103
+ return collection;
6104
+ }
6105
+
6106
+ function remove( elem, selector, keepData ) {
6107
+ var node,
6108
+ elems = selector ? jQuery.filter( selector, elem ) : elem,
6109
+ i = 0;
6110
+
6111
+ for ( ; ( node = elems[ i ] ) != null; i++ ) {
6112
+
6113
+ if ( !keepData && node.nodeType === 1 ) {
6114
+ jQuery.cleanData( getAll( node ) );
6115
+ }
6116
+
6117
+ if ( node.parentNode ) {
6118
+ if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
6119
+ setGlobalEval( getAll( node, "script" ) );
6120
+ }
6121
+ node.parentNode.removeChild( node );
6122
+ }
6123
+ }
6124
+
6125
+ return elem;
6126
+ }
6127
+
6128
+ jQuery.extend( {
6129
+ htmlPrefilter: function( html ) {
6130
+ return html.replace( rxhtmlTag, "<$1></$2>" );
6131
+ },
6132
+
6133
+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6134
+ var destElements, node, clone, i, srcElements,
6135
+ inPage = jQuery.contains( elem.ownerDocument, elem );
6136
+
6137
+ if ( support.html5Clone || jQuery.isXMLDoc( elem ) ||
6138
+ !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
6139
+
6140
+ clone = elem.cloneNode( true );
6141
+
6142
+ // IE<=8 does not properly clone detached, unknown element nodes
6143
+ } else {
6144
+ fragmentDiv.innerHTML = elem.outerHTML;
6145
+ fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
6146
+ }
6147
+
6148
+ if ( ( !support.noCloneEvent || !support.noCloneChecked ) &&
6149
+ ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
6150
+
6151
+ // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
6152
+ destElements = getAll( clone );
6153
+ srcElements = getAll( elem );
6154
+
6155
+ // Fix all IE cloning issues
6156
+ for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) {
6157
+
6158
+ // Ensure that the destination node is not null; Fixes #9587
6159
+ if ( destElements[ i ] ) {
6160
+ fixCloneNodeIssues( node, destElements[ i ] );
6161
+ }
6162
+ }
6163
+ }
6164
+
6165
+ // Copy the events from the original to the clone
6166
+ if ( dataAndEvents ) {
6167
+ if ( deepDataAndEvents ) {
6168
+ srcElements = srcElements || getAll( elem );
6169
+ destElements = destElements || getAll( clone );
6170
+
6171
+ for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) {
6172
+ cloneCopyEvent( node, destElements[ i ] );
6173
+ }
6174
+ } else {
6175
+ cloneCopyEvent( elem, clone );
6176
+ }
6177
+ }
6178
+
6179
+ // Preserve script evaluation history
6180
+ destElements = getAll( clone, "script" );
6181
+ if ( destElements.length > 0 ) {
6182
+ setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
6183
+ }
6184
+
6185
+ destElements = srcElements = node = null;
6186
+
6187
+ // Return the cloned set
6188
+ return clone;
6189
+ },
6190
+
6191
+ cleanData: function( elems, /* internal */ forceAcceptData ) {
6192
+ var elem, type, id, data,
6193
+ i = 0,
6194
+ internalKey = jQuery.expando,
6195
+ cache = jQuery.cache,
6196
+ attributes = support.attributes,
6197
+ special = jQuery.event.special;
6198
+
6199
+ for ( ; ( elem = elems[ i ] ) != null; i++ ) {
6200
+ if ( forceAcceptData || acceptData( elem ) ) {
6201
+
6202
+ id = elem[ internalKey ];
6203
+ data = id && cache[ id ];
6204
+
6205
+ if ( data ) {
6206
+ if ( data.events ) {
6207
+ for ( type in data.events ) {
6208
+ if ( special[ type ] ) {
6209
+ jQuery.event.remove( elem, type );
6210
+
6211
+ // This is a shortcut to avoid jQuery.event.remove's overhead
6212
+ } else {
6213
+ jQuery.removeEvent( elem, type, data.handle );
6214
+ }
6215
+ }
6216
+ }
6217
+
6218
+ // Remove cache only if it was not already removed by jQuery.event.remove
6219
+ if ( cache[ id ] ) {
6220
+
6221
+ delete cache[ id ];
6222
+
6223
+ // Support: IE<9
6224
+ // IE does not allow us to delete expando properties from nodes
6225
+ // IE creates expando attributes along with the property
6226
+ // IE does not have a removeAttribute function on Document nodes
6227
+ if ( !attributes && typeof elem.removeAttribute !== "undefined" ) {
6228
+ elem.removeAttribute( internalKey );
6229
+
6230
+ // Webkit & Blink performance suffers when deleting properties
6231
+ // from DOM nodes, so set to undefined instead
6232
+ // https://code.google.com/p/chromium/issues/detail?id=378607
6233
+ } else {
6234
+ elem[ internalKey ] = undefined;
6235
+ }
6236
+
6237
+ deletedIds.push( id );
6238
+ }
6239
+ }
6240
+ }
6241
+ }
6242
+ }
6243
+ } );
6244
+
6245
+ jQuery.fn.extend( {
6246
+
6247
+ // Keep domManip exposed until 3.0 (gh-2225)
6248
+ domManip: domManip,
6249
+
6250
+ detach: function( selector ) {
6251
+ return remove( this, selector, true );
6252
+ },
6253
+
6254
+ remove: function( selector ) {
6255
+ return remove( this, selector );
6256
+ },
6257
+
6258
+ text: function( value ) {
6259
+ return access( this, function( value ) {
6260
+ return value === undefined ?
6261
+ jQuery.text( this ) :
6262
+ this.empty().append(
6263
+ ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value )
6264
+ );
6265
+ }, null, value, arguments.length );
6266
+ },
6267
+
6268
+ append: function() {
6269
+ return domManip( this, arguments, function( elem ) {
6270
+ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6271
+ var target = manipulationTarget( this, elem );
6272
+ target.appendChild( elem );
6273
+ }
6274
+ } );
6275
+ },
6276
+
6277
+ prepend: function() {
6278
+ return domManip( this, arguments, function( elem ) {
6279
+ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6280
+ var target = manipulationTarget( this, elem );
6281
+ target.insertBefore( elem, target.firstChild );
6282
+ }
6283
+ } );
6284
+ },
6285
+
6286
+ before: function() {
6287
+ return domManip( this, arguments, function( elem ) {
6288
+ if ( this.parentNode ) {
6289
+ this.parentNode.insertBefore( elem, this );
6290
+ }
6291
+ } );
6292
+ },
6293
+
6294
+ after: function() {
6295
+ return domManip( this, arguments, function( elem ) {
6296
+ if ( this.parentNode ) {
6297
+ this.parentNode.insertBefore( elem, this.nextSibling );
6298
+ }
6299
+ } );
6300
+ },
6301
+
6302
+ empty: function() {
6303
+ var elem,
6304
+ i = 0;
6305
+
6306
+ for ( ; ( elem = this[ i ] ) != null; i++ ) {
6307
+
6308
+ // Remove element nodes and prevent memory leaks
6309
+ if ( elem.nodeType === 1 ) {
6310
+ jQuery.cleanData( getAll( elem, false ) );
6311
+ }
6312
+
6313
+ // Remove any remaining nodes
6314
+ while ( elem.firstChild ) {
6315
+ elem.removeChild( elem.firstChild );
6316
+ }
6317
+
6318
+ // If this is a select, ensure that it displays empty (#12336)
6319
+ // Support: IE<9
6320
+ if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
6321
+ elem.options.length = 0;
6322
+ }
6323
+ }
6324
+
6325
+ return this;
6326
+ },
6327
+
6328
+ clone: function( dataAndEvents, deepDataAndEvents ) {
6329
+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6330
+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6331
+
6332
+ return this.map( function() {
6333
+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6334
+ } );
6335
+ },
6336
+
6337
+ html: function( value ) {
6338
+ return access( this, function( value ) {
6339
+ var elem = this[ 0 ] || {},
6340
+ i = 0,
6341
+ l = this.length;
6342
+
6343
+ if ( value === undefined ) {
6344
+ return elem.nodeType === 1 ?
6345
+ elem.innerHTML.replace( rinlinejQuery, "" ) :
6346
+ undefined;
6347
+ }
6348
+
6349
+ // See if we can take a shortcut and just use innerHTML
6350
+ if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
6351
+ ( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
6352
+ ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
6353
+ !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
6354
+
6355
+ value = jQuery.htmlPrefilter( value );
6356
+
6357
+ try {
6358
+ for ( ; i < l; i++ ) {
6359
+
6360
+ // Remove element nodes and prevent memory leaks
6361
+ elem = this[ i ] || {};
6362
+ if ( elem.nodeType === 1 ) {
6363
+ jQuery.cleanData( getAll( elem, false ) );
6364
+ elem.innerHTML = value;
6365
+ }
6366
+ }
6367
+
6368
+ elem = 0;
6369
+
6370
+ // If using innerHTML throws an exception, use the fallback method
6371
+ } catch ( e ) {}
6372
+ }
6373
+
6374
+ if ( elem ) {
6375
+ this.empty().append( value );
6376
+ }
6377
+ }, null, value, arguments.length );
6378
+ },
6379
+
6380
+ replaceWith: function() {
6381
+ var ignored = [];
6382
+
6383
+ // Make the changes, replacing each non-ignored context element with the new content
6384
+ return domManip( this, arguments, function( elem ) {
6385
+ var parent = this.parentNode;
6386
+
6387
+ if ( jQuery.inArray( this, ignored ) < 0 ) {
6388
+ jQuery.cleanData( getAll( this ) );
6389
+ if ( parent ) {
6390
+ parent.replaceChild( elem, this );
6391
+ }
6392
+ }
6393
+
6394
+ // Force callback invocation
6395
+ }, ignored );
6396
+ }
6397
+ } );
6398
+
6399
+ jQuery.each( {
6400
+ appendTo: "append",
6401
+ prependTo: "prepend",
6402
+ insertBefore: "before",
6403
+ insertAfter: "after",
6404
+ replaceAll: "replaceWith"
6405
+ }, function( name, original ) {
6406
+ jQuery.fn[ name ] = function( selector ) {
6407
+ var elems,
6408
+ i = 0,
6409
+ ret = [],
6410
+ insert = jQuery( selector ),
6411
+ last = insert.length - 1;
6412
+
6413
+ for ( ; i <= last; i++ ) {
6414
+ elems = i === last ? this : this.clone( true );
6415
+ jQuery( insert[ i ] )[ original ]( elems );
6416
+
6417
+ // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
6418
+ push.apply( ret, elems.get() );
6419
+ }
6420
+
6421
+ return this.pushStack( ret );
6422
+ };
6423
+ } );
6424
+
6425
+
6426
+ var iframe,
6427
+ elemdisplay = {
6428
+
6429
+ // Support: Firefox
6430
+ // We have to pre-define these values for FF (#10227)
6431
+ HTML: "block",
6432
+ BODY: "block"
6433
+ };
6434
+
6435
+ /**
6436
+ * Retrieve the actual display of a element
6437
+ * @param {String} name nodeName of the element
6438
+ * @param {Object} doc Document object
6439
+ */
6440
+
6441
+ // Called only from within defaultDisplay
6442
+ function actualDisplay( name, doc ) {
6443
+ var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
6444
+
6445
+ display = jQuery.css( elem[ 0 ], "display" );
6446
+
6447
+ // We don't have any data stored on the element,
6448
+ // so use "detach" method as fast way to get rid of the element
6449
+ elem.detach();
6450
+
6451
+ return display;
6452
+ }
6453
+
6454
+ /**
6455
+ * Try to determine the default display value of an element
6456
+ * @param {String} nodeName
6457
+ */
6458
+ function defaultDisplay( nodeName ) {
6459
+ var doc = document,
6460
+ display = elemdisplay[ nodeName ];
6461
+
6462
+ if ( !display ) {
6463
+ display = actualDisplay( nodeName, doc );
6464
+
6465
+ // If the simple way fails, read from inside an iframe
6466
+ if ( display === "none" || !display ) {
6467
+
6468
+ // Use the already-created iframe if possible
6469
+ iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
6470
+ .appendTo( doc.documentElement );
6471
+
6472
+ // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
6473
+ doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
6474
+
6475
+ // Support: IE
6476
+ doc.write();
6477
+ doc.close();
6478
+
6479
+ display = actualDisplay( nodeName, doc );
6480
+ iframe.detach();
6481
+ }
6482
+
6483
+ // Store the correct default display
6484
+ elemdisplay[ nodeName ] = display;
6485
+ }
6486
+
6487
+ return display;
6488
+ }
6489
+ var rmargin = ( /^margin/ );
6490
+
6491
+ var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6492
+
6493
+ var swap = function( elem, options, callback, args ) {
6494
+ var ret, name,
6495
+ old = {};
6496
+
6497
+ // Remember the old values, and insert the new ones
6498
+ for ( name in options ) {
6499
+ old[ name ] = elem.style[ name ];
6500
+ elem.style[ name ] = options[ name ];
6501
+ }
6502
+
6503
+ ret = callback.apply( elem, args || [] );
6504
+
6505
+ // Revert the old values
6506
+ for ( name in options ) {
6507
+ elem.style[ name ] = old[ name ];
6508
+ }
6509
+
6510
+ return ret;
6511
+ };
6512
+
6513
+
6514
+ var documentElement = document.documentElement;
6515
+
6516
+
6517
+
6518
+ ( function() {
6519
+ var pixelPositionVal, pixelMarginRightVal, boxSizingReliableVal,
6520
+ reliableHiddenOffsetsVal, reliableMarginRightVal, reliableMarginLeftVal,
6521
+ container = document.createElement( "div" ),
6522
+ div = document.createElement( "div" );
6523
+
6524
+ // Finish early in limited (non-browser) environments
6525
+ if ( !div.style ) {
6526
+ return;
6527
+ }
6528
+
6529
+ div.style.cssText = "float:left;opacity:.5";
6530
+
6531
+ // Support: IE<9
6532
+ // Make sure that element opacity exists (as opposed to filter)
6533
+ support.opacity = div.style.opacity === "0.5";
6534
+
6535
+ // Verify style float existence
6536
+ // (IE uses styleFloat instead of cssFloat)
6537
+ support.cssFloat = !!div.style.cssFloat;
6538
+
6539
+ div.style.backgroundClip = "content-box";
6540
+ div.cloneNode( true ).style.backgroundClip = "";
6541
+ support.clearCloneStyle = div.style.backgroundClip === "content-box";
6542
+
6543
+ container = document.createElement( "div" );
6544
+ container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
6545
+ "padding:0;margin-top:1px;position:absolute";
6546
+ div.innerHTML = "";
6547
+ container.appendChild( div );
6548
+
6549
+ // Support: Firefox<29, Android 2.3
6550
+ // Vendor-prefix box-sizing
6551
+ support.boxSizing = div.style.boxSizing === "" || div.style.MozBoxSizing === "" ||
6552
+ div.style.WebkitBoxSizing === "";
6553
+
6554
+ jQuery.extend( support, {
6555
+ reliableHiddenOffsets: function() {
6556
+ if ( pixelPositionVal == null ) {
6557
+ computeStyleTests();
6558
+ }
6559
+ return reliableHiddenOffsetsVal;
6560
+ },
6561
+
6562
+ boxSizingReliable: function() {
6563
+
6564
+ // We're checking for pixelPositionVal here instead of boxSizingReliableVal
6565
+ // since that compresses better and they're computed together anyway.
6566
+ if ( pixelPositionVal == null ) {
6567
+ computeStyleTests();
6568
+ }
6569
+ return boxSizingReliableVal;
6570
+ },
6571
+
6572
+ pixelMarginRight: function() {
6573
+
6574
+ // Support: Android 4.0-4.3
6575
+ if ( pixelPositionVal == null ) {
6576
+ computeStyleTests();
6577
+ }
6578
+ return pixelMarginRightVal;
6579
+ },
6580
+
6581
+ pixelPosition: function() {
6582
+ if ( pixelPositionVal == null ) {
6583
+ computeStyleTests();
6584
+ }
6585
+ return pixelPositionVal;
6586
+ },
6587
+
6588
+ reliableMarginRight: function() {
6589
+
6590
+ // Support: Android 2.3
6591
+ if ( pixelPositionVal == null ) {
6592
+ computeStyleTests();
6593
+ }
6594
+ return reliableMarginRightVal;
6595
+ },
6596
+
6597
+ reliableMarginLeft: function() {
6598
+
6599
+ // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
6600
+ if ( pixelPositionVal == null ) {
6601
+ computeStyleTests();
6602
+ }
6603
+ return reliableMarginLeftVal;
6604
+ }
6605
+ } );
6606
+
6607
+ function computeStyleTests() {
6608
+ var contents, divStyle,
6609
+ documentElement = document.documentElement;
6610
+
6611
+ // Setup
6612
+ documentElement.appendChild( container );
6613
+
6614
+ div.style.cssText =
6615
+
6616
+ // Support: Android 2.3
6617
+ // Vendor-prefix box-sizing
6618
+ "-webkit-box-sizing:border-box;box-sizing:border-box;" +
6619
+ "position:relative;display:block;" +
6620
+ "margin:auto;border:1px;padding:1px;" +
6621
+ "top:1%;width:50%";
6622
+
6623
+ // Support: IE<9
6624
+ // Assume reasonable values in the absence of getComputedStyle
6625
+ pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false;
6626
+ pixelMarginRightVal = reliableMarginRightVal = true;
6627
+
6628
+ // Check for getComputedStyle so that this code is not run in IE<9.
6629
+ if ( window.getComputedStyle ) {
6630
+ divStyle = window.getComputedStyle( div );
6631
+ pixelPositionVal = ( divStyle || {} ).top !== "1%";
6632
+ reliableMarginLeftVal = ( divStyle || {} ).marginLeft === "2px";
6633
+ boxSizingReliableVal = ( divStyle || { width: "4px" } ).width === "4px";
6634
+
6635
+ // Support: Android 4.0 - 4.3 only
6636
+ // Some styles come back with percentage values, even though they shouldn't
6637
+ div.style.marginRight = "50%";
6638
+ pixelMarginRightVal = ( divStyle || { marginRight: "4px" } ).marginRight === "4px";
6639
+
6640
+ // Support: Android 2.3 only
6641
+ // Div with explicit width and no margin-right incorrectly
6642
+ // gets computed margin-right based on width of container (#3333)
6643
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6644
+ contents = div.appendChild( document.createElement( "div" ) );
6645
+
6646
+ // Reset CSS: box-sizing; display; margin; border; padding
6647
+ contents.style.cssText = div.style.cssText =
6648
+
6649
+ // Support: Android 2.3
6650
+ // Vendor-prefix box-sizing
6651
+ "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
6652
+ "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
6653
+ contents.style.marginRight = contents.style.width = "0";
6654
+ div.style.width = "1px";
6655
+
6656
+ reliableMarginRightVal =
6657
+ !parseFloat( ( window.getComputedStyle( contents ) || {} ).marginRight );
6658
+
6659
+ div.removeChild( contents );
6660
+ }
6661
+
6662
+ // Support: IE6-8
6663
+ // First check that getClientRects works as expected
6664
+ // Check if table cells still have offsetWidth/Height when they are set
6665
+ // to display:none and there are still other visible table cells in a
6666
+ // table row; if so, offsetWidth/Height are not reliable for use when
6667
+ // determining if an element has been hidden directly using
6668
+ // display:none (it is still safe to use offsets if a parent element is
6669
+ // hidden; don safety goggles and see bug #4512 for more information).
6670
+ div.style.display = "none";
6671
+ reliableHiddenOffsetsVal = div.getClientRects().length === 0;
6672
+ if ( reliableHiddenOffsetsVal ) {
6673
+ div.style.display = "";
6674
+ div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
6675
+ div.childNodes[ 0 ].style.borderCollapse = "separate";
6676
+ contents = div.getElementsByTagName( "td" );
6677
+ contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
6678
+ reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6679
+ if ( reliableHiddenOffsetsVal ) {
6680
+ contents[ 0 ].style.display = "";
6681
+ contents[ 1 ].style.display = "none";
6682
+ reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6683
+ }
6684
+ }
6685
+
6686
+ // Teardown
6687
+ documentElement.removeChild( container );
6688
+ }
6689
+
6690
+ } )();
6691
+
6692
+
6693
+ var getStyles, curCSS,
6694
+ rposition = /^(top|right|bottom|left)$/;
6695
+
6696
+ if ( window.getComputedStyle ) {
6697
+ getStyles = function( elem ) {
6698
+
6699
+ // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
6700
+ // IE throws on elements created in popups
6701
+ // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6702
+ var view = elem.ownerDocument.defaultView;
6703
+
6704
+ if ( !view || !view.opener ) {
6705
+ view = window;
6706
+ }
6707
+
6708
+ return view.getComputedStyle( elem );
6709
+ };
6710
+
6711
+ curCSS = function( elem, name, computed ) {
6712
+ var width, minWidth, maxWidth, ret,
6713
+ style = elem.style;
6714
+
6715
+ computed = computed || getStyles( elem );
6716
+
6717
+ // getPropertyValue is only needed for .css('filter') in IE9, see #12537
6718
+ ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
6719
+
6720
+ // Support: Opera 12.1x only
6721
+ // Fall back to style even without computed
6722
+ // computed is undefined for elems on document fragments
6723
+ if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
6724
+ ret = jQuery.style( elem, name );
6725
+ }
6726
+
6727
+ if ( computed ) {
6728
+
6729
+ // A tribute to the "awesome hack by Dean Edwards"
6730
+ // Chrome < 17 and Safari 5.0 uses "computed value"
6731
+ // instead of "used value" for margin-right
6732
+ // Safari 5.1.7 (at least) returns percentage for a larger set of values,
6733
+ // but width seems to be reliably pixels
6734
+ // this is against the CSSOM draft spec:
6735
+ // http://dev.w3.org/csswg/cssom/#resolved-values
6736
+ if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6737
+
6738
+ // Remember the original values
6739
+ width = style.width;
6740
+ minWidth = style.minWidth;
6741
+ maxWidth = style.maxWidth;
6742
+
6743
+ // Put in the new values to get a computed value out
6744
+ style.minWidth = style.maxWidth = style.width = ret;
6745
+ ret = computed.width;
6746
+
6747
+ // Revert the changed values
6748
+ style.width = width;
6749
+ style.minWidth = minWidth;
6750
+ style.maxWidth = maxWidth;
6751
+ }
6752
+ }
6753
+
6754
+ // Support: IE
6755
+ // IE returns zIndex value as an integer.
6756
+ return ret === undefined ?
6757
+ ret :
6758
+ ret + "";
6759
+ };
6760
+ } else if ( documentElement.currentStyle ) {
6761
+ getStyles = function( elem ) {
6762
+ return elem.currentStyle;
6763
+ };
6764
+
6765
+ curCSS = function( elem, name, computed ) {
6766
+ var left, rs, rsLeft, ret,
6767
+ style = elem.style;
6768
+
6769
+ computed = computed || getStyles( elem );
6770
+ ret = computed ? computed[ name ] : undefined;
6771
+
6772
+ // Avoid setting ret to empty string here
6773
+ // so we don't default to auto
6774
+ if ( ret == null && style && style[ name ] ) {
6775
+ ret = style[ name ];
6776
+ }
6777
+
6778
+ // From the awesome hack by Dean Edwards
6779
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6780
+
6781
+ // If we're not dealing with a regular pixel number
6782
+ // but a number that has a weird ending, we need to convert it to pixels
6783
+ // but not position css attributes, as those are
6784
+ // proportional to the parent element instead
6785
+ // and we can't measure the parent instead because it
6786
+ // might trigger a "stacking dolls" problem
6787
+ if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6788
+
6789
+ // Remember the original values
6790
+ left = style.left;
6791
+ rs = elem.runtimeStyle;
6792
+ rsLeft = rs && rs.left;
6793
+
6794
+ // Put in the new values to get a computed value out
6795
+ if ( rsLeft ) {
6796
+ rs.left = elem.currentStyle.left;
6797
+ }
6798
+ style.left = name === "fontSize" ? "1em" : ret;
6799
+ ret = style.pixelLeft + "px";
6800
+
6801
+ // Revert the changed values
6802
+ style.left = left;
6803
+ if ( rsLeft ) {
6804
+ rs.left = rsLeft;
6805
+ }
6806
+ }
6807
+
6808
+ // Support: IE
6809
+ // IE returns zIndex value as an integer.
6810
+ return ret === undefined ?
6811
+ ret :
6812
+ ret + "" || "auto";
6813
+ };
6814
+ }
6815
+
6816
+
6817
+
6818
+
6819
+ function addGetHookIf( conditionFn, hookFn ) {
6820
+
6821
+ // Define the hook, we'll check on the first run if it's really needed.
6822
+ return {
6823
+ get: function() {
6824
+ if ( conditionFn() ) {
6825
+
6826
+ // Hook not needed (or it's not possible to use it due
6827
+ // to missing dependency), remove it.
6828
+ delete this.get;
6829
+ return;
6830
+ }
6831
+
6832
+ // Hook needed; redefine it so that the support test is not executed again.
6833
+ return ( this.get = hookFn ).apply( this, arguments );
6834
+ }
6835
+ };
6836
+ }
6837
+
6838
+
6839
+ var
6840
+
6841
+ ralpha = /alpha\([^)]*\)/i,
6842
+ ropacity = /opacity\s*=\s*([^)]*)/i,
6843
+
6844
+ // swappable if display is none or starts with table except
6845
+ // "table", "table-cell", or "table-caption"
6846
+ // see here for display values:
6847
+ // https://developer.mozilla.org/en-US/docs/CSS/display
6848
+ rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6849
+ rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
6850
+
6851
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6852
+ cssNormalTransform = {
6853
+ letterSpacing: "0",
6854
+ fontWeight: "400"
6855
+ },
6856
+
6857
+ cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
6858
+ emptyStyle = document.createElement( "div" ).style;
6859
+
6860
+
6861
+ // return a css property mapped to a potentially vendor prefixed property
6862
+ function vendorPropName( name ) {
6863
+
6864
+ // shortcut for names that are not vendor prefixed
6865
+ if ( name in emptyStyle ) {
6866
+ return name;
6867
+ }
6868
+
6869
+ // check for vendor prefixed names
6870
+ var capName = name.charAt( 0 ).toUpperCase() + name.slice( 1 ),
6871
+ i = cssPrefixes.length;
6872
+
6873
+ while ( i-- ) {
6874
+ name = cssPrefixes[ i ] + capName;
6875
+ if ( name in emptyStyle ) {
6876
+ return name;
6877
+ }
6878
+ }
6879
+ }
6880
+
6881
+ function showHide( elements, show ) {
6882
+ var display, elem, hidden,
6883
+ values = [],
6884
+ index = 0,
6885
+ length = elements.length;
6886
+
6887
+ for ( ; index < length; index++ ) {
6888
+ elem = elements[ index ];
6889
+ if ( !elem.style ) {
6890
+ continue;
6891
+ }
6892
+
6893
+ values[ index ] = jQuery._data( elem, "olddisplay" );
6894
+ display = elem.style.display;
6895
+ if ( show ) {
6896
+
6897
+ // Reset the inline display of this element to learn if it is
6898
+ // being hidden by cascaded rules or not
6899
+ if ( !values[ index ] && display === "none" ) {
6900
+ elem.style.display = "";
6901
+ }
6902
+
6903
+ // Set elements which have been overridden with display: none
6904
+ // in a stylesheet to whatever the default browser style is
6905
+ // for such an element
6906
+ if ( elem.style.display === "" && isHidden( elem ) ) {
6907
+ values[ index ] =
6908
+ jQuery._data( elem, "olddisplay", defaultDisplay( elem.nodeName ) );
6909
+ }
6910
+ } else {
6911
+ hidden = isHidden( elem );
6912
+
6913
+ if ( display && display !== "none" || !hidden ) {
6914
+ jQuery._data(
6915
+ elem,
6916
+ "olddisplay",
6917
+ hidden ? display : jQuery.css( elem, "display" )
6918
+ );
6919
+ }
6920
+ }
6921
+ }
6922
+
6923
+ // Set the display of most of the elements in a second loop
6924
+ // to avoid the constant reflow
6925
+ for ( index = 0; index < length; index++ ) {
6926
+ elem = elements[ index ];
6927
+ if ( !elem.style ) {
6928
+ continue;
6929
+ }
6930
+ if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6931
+ elem.style.display = show ? values[ index ] || "" : "none";
6932
+ }
6933
+ }
6934
+
6935
+ return elements;
6936
+ }
6937
+
6938
+ function setPositiveNumber( elem, value, subtract ) {
6939
+ var matches = rnumsplit.exec( value );
6940
+ return matches ?
6941
+
6942
+ // Guard against undefined "subtract", e.g., when used as in cssHooks
6943
+ Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6944
+ value;
6945
+ }
6946
+
6947
+ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6948
+ var i = extra === ( isBorderBox ? "border" : "content" ) ?
6949
+
6950
+ // If we already have the right measurement, avoid augmentation
6951
+ 4 :
6952
+
6953
+ // Otherwise initialize for horizontal or vertical properties
6954
+ name === "width" ? 1 : 0,
6955
+
6956
+ val = 0;
6957
+
6958
+ for ( ; i < 4; i += 2 ) {
6959
+
6960
+ // both box models exclude margin, so add it if we want it
6961
+ if ( extra === "margin" ) {
6962
+ val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6963
+ }
6964
+
6965
+ if ( isBorderBox ) {
6966
+
6967
+ // border-box includes padding, so remove it if we want content
6968
+ if ( extra === "content" ) {
6969
+ val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6970
+ }
6971
+
6972
+ // at this point, extra isn't border nor margin, so remove border
6973
+ if ( extra !== "margin" ) {
6974
+ val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6975
+ }
6976
+ } else {
6977
+
6978
+ // at this point, extra isn't content, so add padding
6979
+ val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6980
+
6981
+ // at this point, extra isn't content nor padding, so add border
6982
+ if ( extra !== "padding" ) {
6983
+ val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6984
+ }
6985
+ }
6986
+ }
6987
+
6988
+ return val;
6989
+ }
6990
+
6991
+ function getWidthOrHeight( elem, name, extra ) {
6992
+
6993
+ // Start with offset property, which is equivalent to the border-box value
6994
+ var valueIsBorderBox = true,
6995
+ val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6996
+ styles = getStyles( elem ),
6997
+ isBorderBox = support.boxSizing &&
6998
+ jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6999
+
7000
+ // some non-html elements return undefined for offsetWidth, so check for null/undefined
7001
+ // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
7002
+ // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
7003
+ if ( val <= 0 || val == null ) {
7004
+
7005
+ // Fall back to computed then uncomputed css if necessary
7006
+ val = curCSS( elem, name, styles );
7007
+ if ( val < 0 || val == null ) {
7008
+ val = elem.style[ name ];
7009
+ }
7010
+
7011
+ // Computed unit is not pixels. Stop here and return.
7012
+ if ( rnumnonpx.test( val ) ) {
7013
+ return val;
7014
+ }
7015
+
7016
+ // we need the check for style in case a browser which returns unreliable values
7017
+ // for getComputedStyle silently falls back to the reliable elem.style
7018
+ valueIsBorderBox = isBorderBox &&
7019
+ ( support.boxSizingReliable() || val === elem.style[ name ] );
7020
+
7021
+ // Normalize "", auto, and prepare for extra
7022
+ val = parseFloat( val ) || 0;
7023
+ }
7024
+
7025
+ // use the active box-sizing model to add/subtract irrelevant styles
7026
+ return ( val +
7027
+ augmentWidthOrHeight(
7028
+ elem,
7029
+ name,
7030
+ extra || ( isBorderBox ? "border" : "content" ),
7031
+ valueIsBorderBox,
7032
+ styles
7033
+ )
7034
+ ) + "px";
7035
+ }
7036
+
7037
+ jQuery.extend( {
7038
+
7039
+ // Add in style property hooks for overriding the default
7040
+ // behavior of getting and setting a style property
7041
+ cssHooks: {
7042
+ opacity: {
7043
+ get: function( elem, computed ) {
7044
+ if ( computed ) {
7045
+
7046
+ // We should always get a number back from opacity
7047
+ var ret = curCSS( elem, "opacity" );
7048
+ return ret === "" ? "1" : ret;
7049
+ }
7050
+ }
7051
+ }
7052
+ },
7053
+
7054
+ // Don't automatically add "px" to these possibly-unitless properties
7055
+ cssNumber: {
7056
+ "animationIterationCount": true,
7057
+ "columnCount": true,
7058
+ "fillOpacity": true,
7059
+ "flexGrow": true,
7060
+ "flexShrink": true,
7061
+ "fontWeight": true,
7062
+ "lineHeight": true,
7063
+ "opacity": true,
7064
+ "order": true,
7065
+ "orphans": true,
7066
+ "widows": true,
7067
+ "zIndex": true,
7068
+ "zoom": true
7069
+ },
7070
+
7071
+ // Add in properties whose names you wish to fix before
7072
+ // setting or getting the value
7073
+ cssProps: {
7074
+
7075
+ // normalize float css property
7076
+ "float": support.cssFloat ? "cssFloat" : "styleFloat"
7077
+ },
7078
+
7079
+ // Get and set the style property on a DOM Node
7080
+ style: function( elem, name, value, extra ) {
7081
+
7082
+ // Don't set styles on text and comment nodes
7083
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
7084
+ return;
7085
+ }
7086
+
7087
+ // Make sure that we're working with the right name
7088
+ var ret, type, hooks,
7089
+ origName = jQuery.camelCase( name ),
7090
+ style = elem.style;
7091
+
7092
+ name = jQuery.cssProps[ origName ] ||
7093
+ ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
7094
+
7095
+ // gets hook for the prefixed version
7096
+ // followed by the unprefixed version
7097
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7098
+
7099
+ // Check if we're setting a value
7100
+ if ( value !== undefined ) {
7101
+ type = typeof value;
7102
+
7103
+ // Convert "+=" or "-=" to relative numbers (#7345)
7104
+ if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
7105
+ value = adjustCSS( elem, name, ret );
7106
+
7107
+ // Fixes bug #9237
7108
+ type = "number";
7109
+ }
7110
+
7111
+ // Make sure that null and NaN values aren't set. See: #7116
7112
+ if ( value == null || value !== value ) {
7113
+ return;
7114
+ }
7115
+
7116
+ // If a number was passed in, add the unit (except for certain CSS properties)
7117
+ if ( type === "number" ) {
7118
+ value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
7119
+ }
7120
+
7121
+ // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
7122
+ // but it would mean to define eight
7123
+ // (for every problematic property) identical functions
7124
+ if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
7125
+ style[ name ] = "inherit";
7126
+ }
7127
+
7128
+ // If a hook was provided, use that value, otherwise just set the specified value
7129
+ if ( !hooks || !( "set" in hooks ) ||
7130
+ ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
7131
+
7132
+ // Support: IE
7133
+ // Swallow errors from 'invalid' CSS values (#5509)
7134
+ try {
7135
+ style[ name ] = value;
7136
+ } catch ( e ) {}
7137
+ }
7138
+
7139
+ } else {
7140
+
7141
+ // If a hook was provided get the non-computed value from there
7142
+ if ( hooks && "get" in hooks &&
7143
+ ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
7144
+
7145
+ return ret;
7146
+ }
7147
+
7148
+ // Otherwise just get the value from the style object
7149
+ return style[ name ];
7150
+ }
7151
+ },
7152
+
7153
+ css: function( elem, name, extra, styles ) {
7154
+ var num, val, hooks,
7155
+ origName = jQuery.camelCase( name );
7156
+
7157
+ // Make sure that we're working with the right name
7158
+ name = jQuery.cssProps[ origName ] ||
7159
+ ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
7160
+
7161
+ // gets hook for the prefixed version
7162
+ // followed by the unprefixed version
7163
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7164
+
7165
+ // If a hook was provided get the computed value from there
7166
+ if ( hooks && "get" in hooks ) {
7167
+ val = hooks.get( elem, true, extra );
7168
+ }
7169
+
7170
+ // Otherwise, if a way to get the computed value exists, use that
7171
+ if ( val === undefined ) {
7172
+ val = curCSS( elem, name, styles );
7173
+ }
7174
+
7175
+ //convert "normal" to computed value
7176
+ if ( val === "normal" && name in cssNormalTransform ) {
7177
+ val = cssNormalTransform[ name ];
7178
+ }
7179
+
7180
+ // Return, converting to number if forced or a qualifier was provided and val looks numeric
7181
+ if ( extra === "" || extra ) {
7182
+ num = parseFloat( val );
7183
+ return extra === true || isFinite( num ) ? num || 0 : val;
7184
+ }
7185
+ return val;
7186
+ }
7187
+ } );
7188
+
7189
+ jQuery.each( [ "height", "width" ], function( i, name ) {
7190
+ jQuery.cssHooks[ name ] = {
7191
+ get: function( elem, computed, extra ) {
7192
+ if ( computed ) {
7193
+
7194
+ // certain elements can have dimension info if we invisibly show them
7195
+ // however, it must have a current display style that would benefit from this
7196
+ return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
7197
+ elem.offsetWidth === 0 ?
7198
+ swap( elem, cssShow, function() {
7199
+ return getWidthOrHeight( elem, name, extra );
7200
+ } ) :
7201
+ getWidthOrHeight( elem, name, extra );
7202
+ }
7203
+ },
7204
+
7205
+ set: function( elem, value, extra ) {
7206
+ var styles = extra && getStyles( elem );
7207
+ return setPositiveNumber( elem, value, extra ?
7208
+ augmentWidthOrHeight(
7209
+ elem,
7210
+ name,
7211
+ extra,
7212
+ support.boxSizing &&
7213
+ jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7214
+ styles
7215
+ ) : 0
7216
+ );
7217
+ }
7218
+ };
7219
+ } );
7220
+
7221
+ if ( !support.opacity ) {
7222
+ jQuery.cssHooks.opacity = {
7223
+ get: function( elem, computed ) {
7224
+
7225
+ // IE uses filters for opacity
7226
+ return ropacity.test( ( computed && elem.currentStyle ?
7227
+ elem.currentStyle.filter :
7228
+ elem.style.filter ) || "" ) ?
7229
+ ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
7230
+ computed ? "1" : "";
7231
+ },
7232
+
7233
+ set: function( elem, value ) {
7234
+ var style = elem.style,
7235
+ currentStyle = elem.currentStyle,
7236
+ opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
7237
+ filter = currentStyle && currentStyle.filter || style.filter || "";
7238
+
7239
+ // IE has trouble with opacity if it does not have layout
7240
+ // Force it by setting the zoom level
7241
+ style.zoom = 1;
7242
+
7243
+ // if setting opacity to 1, and no other filters exist -
7244
+ // attempt to remove filter attribute #6652
7245
+ // if value === "", then remove inline opacity #12685
7246
+ if ( ( value >= 1 || value === "" ) &&
7247
+ jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
7248
+ style.removeAttribute ) {
7249
+
7250
+ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
7251
+ // if "filter:" is present at all, clearType is disabled, we want to avoid this
7252
+ // style.removeAttribute is IE Only, but so apparently is this code path...
7253
+ style.removeAttribute( "filter" );
7254
+
7255
+ // if there is no filter style applied in a css rule
7256
+ // or unset inline opacity, we are done
7257
+ if ( value === "" || currentStyle && !currentStyle.filter ) {
7258
+ return;
7259
+ }
7260
+ }
7261
+
7262
+ // otherwise, set new filter values
7263
+ style.filter = ralpha.test( filter ) ?
7264
+ filter.replace( ralpha, opacity ) :
7265
+ filter + " " + opacity;
7266
+ }
7267
+ };
7268
+ }
7269
+
7270
+ jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
7271
+ function( elem, computed ) {
7272
+ if ( computed ) {
7273
+ return swap( elem, { "display": "inline-block" },
7274
+ curCSS, [ elem, "marginRight" ] );
7275
+ }
7276
+ }
7277
+ );
7278
+
7279
+ jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
7280
+ function( elem, computed ) {
7281
+ if ( computed ) {
7282
+ return (
7283
+ parseFloat( curCSS( elem, "marginLeft" ) ) ||
7284
+
7285
+ // Support: IE<=11+
7286
+ // Running getBoundingClientRect on a disconnected node in IE throws an error
7287
+ // Support: IE8 only
7288
+ // getClientRects() errors on disconnected elems
7289
+ ( jQuery.contains( elem.ownerDocument, elem ) ?
7290
+ elem.getBoundingClientRect().left -
7291
+ swap( elem, { marginLeft: 0 }, function() {
7292
+ return elem.getBoundingClientRect().left;
7293
+ } ) :
7294
+ 0
7295
+ )
7296
+ ) + "px";
7297
+ }
7298
+ }
7299
+ );
7300
+
7301
+ // These hooks are used by animate to expand properties
7302
+ jQuery.each( {
7303
+ margin: "",
7304
+ padding: "",
7305
+ border: "Width"
7306
+ }, function( prefix, suffix ) {
7307
+ jQuery.cssHooks[ prefix + suffix ] = {
7308
+ expand: function( value ) {
7309
+ var i = 0,
7310
+ expanded = {},
7311
+
7312
+ // assumes a single number if not a string
7313
+ parts = typeof value === "string" ? value.split( " " ) : [ value ];
7314
+
7315
+ for ( ; i < 4; i++ ) {
7316
+ expanded[ prefix + cssExpand[ i ] + suffix ] =
7317
+ parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7318
+ }
7319
+
7320
+ return expanded;
7321
+ }
7322
+ };
7323
+
7324
+ if ( !rmargin.test( prefix ) ) {
7325
+ jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7326
+ }
7327
+ } );
7328
+
7329
+ jQuery.fn.extend( {
7330
+ css: function( name, value ) {
7331
+ return access( this, function( elem, name, value ) {
7332
+ var styles, len,
7333
+ map = {},
7334
+ i = 0;
7335
+
7336
+ if ( jQuery.isArray( name ) ) {
7337
+ styles = getStyles( elem );
7338
+ len = name.length;
7339
+
7340
+ for ( ; i < len; i++ ) {
7341
+ map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
7342
+ }
7343
+
7344
+ return map;
7345
+ }
7346
+
7347
+ return value !== undefined ?
7348
+ jQuery.style( elem, name, value ) :
7349
+ jQuery.css( elem, name );
7350
+ }, name, value, arguments.length > 1 );
7351
+ },
7352
+ show: function() {
7353
+ return showHide( this, true );
7354
+ },
7355
+ hide: function() {
7356
+ return showHide( this );
7357
+ },
7358
+ toggle: function( state ) {
7359
+ if ( typeof state === "boolean" ) {
7360
+ return state ? this.show() : this.hide();
7361
+ }
7362
+
7363
+ return this.each( function() {
7364
+ if ( isHidden( this ) ) {
7365
+ jQuery( this ).show();
7366
+ } else {
7367
+ jQuery( this ).hide();
7368
+ }
7369
+ } );
7370
+ }
7371
+ } );
7372
+
7373
+
7374
+ function Tween( elem, options, prop, end, easing ) {
7375
+ return new Tween.prototype.init( elem, options, prop, end, easing );
7376
+ }
7377
+ jQuery.Tween = Tween;
7378
+
7379
+ Tween.prototype = {
7380
+ constructor: Tween,
7381
+ init: function( elem, options, prop, end, easing, unit ) {
7382
+ this.elem = elem;
7383
+ this.prop = prop;
7384
+ this.easing = easing || jQuery.easing._default;
7385
+ this.options = options;
7386
+ this.start = this.now = this.cur();
7387
+ this.end = end;
7388
+ this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
7389
+ },
7390
+ cur: function() {
7391
+ var hooks = Tween.propHooks[ this.prop ];
7392
+
7393
+ return hooks && hooks.get ?
7394
+ hooks.get( this ) :
7395
+ Tween.propHooks._default.get( this );
7396
+ },
7397
+ run: function( percent ) {
7398
+ var eased,
7399
+ hooks = Tween.propHooks[ this.prop ];
7400
+
7401
+ if ( this.options.duration ) {
7402
+ this.pos = eased = jQuery.easing[ this.easing ](
7403
+ percent, this.options.duration * percent, 0, 1, this.options.duration
7404
+ );
7405
+ } else {
7406
+ this.pos = eased = percent;
7407
+ }
7408
+ this.now = ( this.end - this.start ) * eased + this.start;
7409
+
7410
+ if ( this.options.step ) {
7411
+ this.options.step.call( this.elem, this.now, this );
7412
+ }
7413
+
7414
+ if ( hooks && hooks.set ) {
7415
+ hooks.set( this );
7416
+ } else {
7417
+ Tween.propHooks._default.set( this );
7418
+ }
7419
+ return this;
7420
+ }
7421
+ };
7422
+
7423
+ Tween.prototype.init.prototype = Tween.prototype;
7424
+
7425
+ Tween.propHooks = {
7426
+ _default: {
7427
+ get: function( tween ) {
7428
+ var result;
7429
+
7430
+ // Use a property on the element directly when it is not a DOM element,
7431
+ // or when there is no matching style property that exists.
7432
+ if ( tween.elem.nodeType !== 1 ||
7433
+ tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
7434
+ return tween.elem[ tween.prop ];
7435
+ }
7436
+
7437
+ // passing an empty string as a 3rd parameter to .css will automatically
7438
+ // attempt a parseFloat and fallback to a string if the parse fails
7439
+ // so, simple values such as "10px" are parsed to Float.
7440
+ // complex values such as "rotate(1rad)" are returned as is.
7441
+ result = jQuery.css( tween.elem, tween.prop, "" );
7442
+
7443
+ // Empty strings, null, undefined and "auto" are converted to 0.
7444
+ return !result || result === "auto" ? 0 : result;
7445
+ },
7446
+ set: function( tween ) {
7447
+
7448
+ // use step hook for back compat - use cssHook if its there - use .style if its
7449
+ // available and use plain properties where available
7450
+ if ( jQuery.fx.step[ tween.prop ] ) {
7451
+ jQuery.fx.step[ tween.prop ]( tween );
7452
+ } else if ( tween.elem.nodeType === 1 &&
7453
+ ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
7454
+ jQuery.cssHooks[ tween.prop ] ) ) {
7455
+ jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7456
+ } else {
7457
+ tween.elem[ tween.prop ] = tween.now;
7458
+ }
7459
+ }
7460
+ }
7461
+ };
7462
+
7463
+ // Support: IE <=9
7464
+ // Panic based approach to setting things on disconnected nodes
7465
+
7466
+ Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7467
+ set: function( tween ) {
7468
+ if ( tween.elem.nodeType && tween.elem.parentNode ) {
7469
+ tween.elem[ tween.prop ] = tween.now;
7470
+ }
7471
+ }
7472
+ };
7473
+
7474
+ jQuery.easing = {
7475
+ linear: function( p ) {
7476
+ return p;
7477
+ },
7478
+ swing: function( p ) {
7479
+ return 0.5 - Math.cos( p * Math.PI ) / 2;
7480
+ },
7481
+ _default: "swing"
7482
+ };
7483
+
7484
+ jQuery.fx = Tween.prototype.init;
7485
+
7486
+ // Back Compat <1.8 extension point
7487
+ jQuery.fx.step = {};
7488
+
7489
+
7490
+
7491
+
7492
+ var
7493
+ fxNow, timerId,
7494
+ rfxtypes = /^(?:toggle|show|hide)$/,
7495
+ rrun = /queueHooks$/;
7496
+
7497
+ // Animations created synchronously will run synchronously
7498
+ function createFxNow() {
7499
+ window.setTimeout( function() {
7500
+ fxNow = undefined;
7501
+ } );
7502
+ return ( fxNow = jQuery.now() );
7503
+ }
7504
+
7505
+ // Generate parameters to create a standard animation
7506
+ function genFx( type, includeWidth ) {
7507
+ var which,
7508
+ attrs = { height: type },
7509
+ i = 0;
7510
+
7511
+ // if we include width, step value is 1 to do all cssExpand values,
7512
+ // if we don't include width, step value is 2 to skip over Left and Right
7513
+ includeWidth = includeWidth ? 1 : 0;
7514
+ for ( ; i < 4 ; i += 2 - includeWidth ) {
7515
+ which = cssExpand[ i ];
7516
+ attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7517
+ }
7518
+
7519
+ if ( includeWidth ) {
7520
+ attrs.opacity = attrs.width = type;
7521
+ }
7522
+
7523
+ return attrs;
7524
+ }
7525
+
7526
+ function createTween( value, prop, animation ) {
7527
+ var tween,
7528
+ collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
7529
+ index = 0,
7530
+ length = collection.length;
7531
+ for ( ; index < length; index++ ) {
7532
+ if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
7533
+
7534
+ // we're done with this property
7535
+ return tween;
7536
+ }
7537
+ }
7538
+ }
7539
+
7540
+ function defaultPrefilter( elem, props, opts ) {
7541
+ /* jshint validthis: true */
7542
+ var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
7543
+ anim = this,
7544
+ orig = {},
7545
+ style = elem.style,
7546
+ hidden = elem.nodeType && isHidden( elem ),
7547
+ dataShow = jQuery._data( elem, "fxshow" );
7548
+
7549
+ // handle queue: false promises
7550
+ if ( !opts.queue ) {
7551
+ hooks = jQuery._queueHooks( elem, "fx" );
7552
+ if ( hooks.unqueued == null ) {
7553
+ hooks.unqueued = 0;
7554
+ oldfire = hooks.empty.fire;
7555
+ hooks.empty.fire = function() {
7556
+ if ( !hooks.unqueued ) {
7557
+ oldfire();
7558
+ }
7559
+ };
7560
+ }
7561
+ hooks.unqueued++;
7562
+
7563
+ anim.always( function() {
7564
+
7565
+ // doing this makes sure that the complete handler will be called
7566
+ // before this completes
7567
+ anim.always( function() {
7568
+ hooks.unqueued--;
7569
+ if ( !jQuery.queue( elem, "fx" ).length ) {
7570
+ hooks.empty.fire();
7571
+ }
7572
+ } );
7573
+ } );
7574
+ }
7575
+
7576
+ // height/width overflow pass
7577
+ if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
7578
+
7579
+ // Make sure that nothing sneaks out
7580
+ // Record all 3 overflow attributes because IE does not
7581
+ // change the overflow attribute when overflowX and
7582
+ // overflowY are set to the same value
7583
+ opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7584
+
7585
+ // Set display property to inline-block for height/width
7586
+ // animations on inline elements that are having width/height animated
7587
+ display = jQuery.css( elem, "display" );
7588
+
7589
+ // Test default display if display is currently "none"
7590
+ checkDisplay = display === "none" ?
7591
+ jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
7592
+
7593
+ if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
7594
+
7595
+ // inline-level elements accept inline-block;
7596
+ // block-level elements need to be inline with layout
7597
+ if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
7598
+ style.display = "inline-block";
7599
+ } else {
7600
+ style.zoom = 1;
7601
+ }
7602
+ }
7603
+ }
7604
+
7605
+ if ( opts.overflow ) {
7606
+ style.overflow = "hidden";
7607
+ if ( !support.shrinkWrapBlocks() ) {
7608
+ anim.always( function() {
7609
+ style.overflow = opts.overflow[ 0 ];
7610
+ style.overflowX = opts.overflow[ 1 ];
7611
+ style.overflowY = opts.overflow[ 2 ];
7612
+ } );
7613
+ }
7614
+ }
7615
+
7616
+ // show/hide pass
7617
+ for ( prop in props ) {
7618
+ value = props[ prop ];
7619
+ if ( rfxtypes.exec( value ) ) {
7620
+ delete props[ prop ];
7621
+ toggle = toggle || value === "toggle";
7622
+ if ( value === ( hidden ? "hide" : "show" ) ) {
7623
+
7624
+ // If there is dataShow left over from a stopped hide or show
7625
+ // and we are going to proceed with show, we should pretend to be hidden
7626
+ if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7627
+ hidden = true;
7628
+ } else {
7629
+ continue;
7630
+ }
7631
+ }
7632
+ orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7633
+
7634
+ // Any non-fx value stops us from restoring the original display value
7635
+ } else {
7636
+ display = undefined;
7637
+ }
7638
+ }
7639
+
7640
+ if ( !jQuery.isEmptyObject( orig ) ) {
7641
+ if ( dataShow ) {
7642
+ if ( "hidden" in dataShow ) {
7643
+ hidden = dataShow.hidden;
7644
+ }
7645
+ } else {
7646
+ dataShow = jQuery._data( elem, "fxshow", {} );
7647
+ }
7648
+
7649
+ // store state if its toggle - enables .stop().toggle() to "reverse"
7650
+ if ( toggle ) {
7651
+ dataShow.hidden = !hidden;
7652
+ }
7653
+ if ( hidden ) {
7654
+ jQuery( elem ).show();
7655
+ } else {
7656
+ anim.done( function() {
7657
+ jQuery( elem ).hide();
7658
+ } );
7659
+ }
7660
+ anim.done( function() {
7661
+ var prop;
7662
+ jQuery._removeData( elem, "fxshow" );
7663
+ for ( prop in orig ) {
7664
+ jQuery.style( elem, prop, orig[ prop ] );
7665
+ }
7666
+ } );
7667
+ for ( prop in orig ) {
7668
+ tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7669
+
7670
+ if ( !( prop in dataShow ) ) {
7671
+ dataShow[ prop ] = tween.start;
7672
+ if ( hidden ) {
7673
+ tween.end = tween.start;
7674
+ tween.start = prop === "width" || prop === "height" ? 1 : 0;
7675
+ }
7676
+ }
7677
+ }
7678
+
7679
+ // If this is a noop like .hide().hide(), restore an overwritten display value
7680
+ } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
7681
+ style.display = display;
7682
+ }
7683
+ }
7684
+
7685
+ function propFilter( props, specialEasing ) {
7686
+ var index, name, easing, value, hooks;
7687
+
7688
+ // camelCase, specialEasing and expand cssHook pass
7689
+ for ( index in props ) {
7690
+ name = jQuery.camelCase( index );
7691
+ easing = specialEasing[ name ];
7692
+ value = props[ index ];
7693
+ if ( jQuery.isArray( value ) ) {
7694
+ easing = value[ 1 ];
7695
+ value = props[ index ] = value[ 0 ];
7696
+ }
7697
+
7698
+ if ( index !== name ) {
7699
+ props[ name ] = value;
7700
+ delete props[ index ];
7701
+ }
7702
+
7703
+ hooks = jQuery.cssHooks[ name ];
7704
+ if ( hooks && "expand" in hooks ) {
7705
+ value = hooks.expand( value );
7706
+ delete props[ name ];
7707
+
7708
+ // not quite $.extend, this wont overwrite keys already present.
7709
+ // also - reusing 'index' from above because we have the correct "name"
7710
+ for ( index in value ) {
7711
+ if ( !( index in props ) ) {
7712
+ props[ index ] = value[ index ];
7713
+ specialEasing[ index ] = easing;
7714
+ }
7715
+ }
7716
+ } else {
7717
+ specialEasing[ name ] = easing;
7718
+ }
7719
+ }
7720
+ }
7721
+
7722
+ function Animation( elem, properties, options ) {
7723
+ var result,
7724
+ stopped,
7725
+ index = 0,
7726
+ length = Animation.prefilters.length,
7727
+ deferred = jQuery.Deferred().always( function() {
7728
+
7729
+ // don't match elem in the :animated selector
7730
+ delete tick.elem;
7731
+ } ),
7732
+ tick = function() {
7733
+ if ( stopped ) {
7734
+ return false;
7735
+ }
7736
+ var currentTime = fxNow || createFxNow(),
7737
+ remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7738
+
7739
+ // Support: Android 2.3
7740
+ // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7741
+ temp = remaining / animation.duration || 0,
7742
+ percent = 1 - temp,
7743
+ index = 0,
7744
+ length = animation.tweens.length;
7745
+
7746
+ for ( ; index < length ; index++ ) {
7747
+ animation.tweens[ index ].run( percent );
7748
+ }
7749
+
7750
+ deferred.notifyWith( elem, [ animation, percent, remaining ] );
7751
+
7752
+ if ( percent < 1 && length ) {
7753
+ return remaining;
7754
+ } else {
7755
+ deferred.resolveWith( elem, [ animation ] );
7756
+ return false;
7757
+ }
7758
+ },
7759
+ animation = deferred.promise( {
7760
+ elem: elem,
7761
+ props: jQuery.extend( {}, properties ),
7762
+ opts: jQuery.extend( true, {
7763
+ specialEasing: {},
7764
+ easing: jQuery.easing._default
7765
+ }, options ),
7766
+ originalProperties: properties,
7767
+ originalOptions: options,
7768
+ startTime: fxNow || createFxNow(),
7769
+ duration: options.duration,
7770
+ tweens: [],
7771
+ createTween: function( prop, end ) {
7772
+ var tween = jQuery.Tween( elem, animation.opts, prop, end,
7773
+ animation.opts.specialEasing[ prop ] || animation.opts.easing );
7774
+ animation.tweens.push( tween );
7775
+ return tween;
7776
+ },
7777
+ stop: function( gotoEnd ) {
7778
+ var index = 0,
7779
+
7780
+ // if we are going to the end, we want to run all the tweens
7781
+ // otherwise we skip this part
7782
+ length = gotoEnd ? animation.tweens.length : 0;
7783
+ if ( stopped ) {
7784
+ return this;
7785
+ }
7786
+ stopped = true;
7787
+ for ( ; index < length ; index++ ) {
7788
+ animation.tweens[ index ].run( 1 );
7789
+ }
7790
+
7791
+ // resolve when we played the last frame
7792
+ // otherwise, reject
7793
+ if ( gotoEnd ) {
7794
+ deferred.notifyWith( elem, [ animation, 1, 0 ] );
7795
+ deferred.resolveWith( elem, [ animation, gotoEnd ] );
7796
+ } else {
7797
+ deferred.rejectWith( elem, [ animation, gotoEnd ] );
7798
+ }
7799
+ return this;
7800
+ }
7801
+ } ),
7802
+ props = animation.props;
7803
+
7804
+ propFilter( props, animation.opts.specialEasing );
7805
+
7806
+ for ( ; index < length ; index++ ) {
7807
+ result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7808
+ if ( result ) {
7809
+ if ( jQuery.isFunction( result.stop ) ) {
7810
+ jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7811
+ jQuery.proxy( result.stop, result );
7812
+ }
7813
+ return result;
7814
+ }
7815
+ }
7816
+
7817
+ jQuery.map( props, createTween, animation );
7818
+
7819
+ if ( jQuery.isFunction( animation.opts.start ) ) {
7820
+ animation.opts.start.call( elem, animation );
7821
+ }
7822
+
7823
+ jQuery.fx.timer(
7824
+ jQuery.extend( tick, {
7825
+ elem: elem,
7826
+ anim: animation,
7827
+ queue: animation.opts.queue
7828
+ } )
7829
+ );
7830
+
7831
+ // attach callbacks from options
7832
+ return animation.progress( animation.opts.progress )
7833
+ .done( animation.opts.done, animation.opts.complete )
7834
+ .fail( animation.opts.fail )
7835
+ .always( animation.opts.always );
7836
+ }
7837
+
7838
+ jQuery.Animation = jQuery.extend( Animation, {
7839
+
7840
+ tweeners: {
7841
+ "*": [ function( prop, value ) {
7842
+ var tween = this.createTween( prop, value );
7843
+ adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7844
+ return tween;
7845
+ } ]
7846
+ },
7847
+
7848
+ tweener: function( props, callback ) {
7849
+ if ( jQuery.isFunction( props ) ) {
7850
+ callback = props;
7851
+ props = [ "*" ];
7852
+ } else {
7853
+ props = props.match( rnotwhite );
7854
+ }
7855
+
7856
+ var prop,
7857
+ index = 0,
7858
+ length = props.length;
7859
+
7860
+ for ( ; index < length ; index++ ) {
7861
+ prop = props[ index ];
7862
+ Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7863
+ Animation.tweeners[ prop ].unshift( callback );
7864
+ }
7865
+ },
7866
+
7867
+ prefilters: [ defaultPrefilter ],
7868
+
7869
+ prefilter: function( callback, prepend ) {
7870
+ if ( prepend ) {
7871
+ Animation.prefilters.unshift( callback );
7872
+ } else {
7873
+ Animation.prefilters.push( callback );
7874
+ }
7875
+ }
7876
+ } );
7877
+
7878
+ jQuery.speed = function( speed, easing, fn ) {
7879
+ var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7880
+ complete: fn || !fn && easing ||
7881
+ jQuery.isFunction( speed ) && speed,
7882
+ duration: speed,
7883
+ easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
7884
+ };
7885
+
7886
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
7887
+ opt.duration in jQuery.fx.speeds ?
7888
+ jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
7889
+
7890
+ // normalize opt.queue - true/undefined/null -> "fx"
7891
+ if ( opt.queue == null || opt.queue === true ) {
7892
+ opt.queue = "fx";
7893
+ }
7894
+
7895
+ // Queueing
7896
+ opt.old = opt.complete;
7897
+
7898
+ opt.complete = function() {
7899
+ if ( jQuery.isFunction( opt.old ) ) {
7900
+ opt.old.call( this );
7901
+ }
7902
+
7903
+ if ( opt.queue ) {
7904
+ jQuery.dequeue( this, opt.queue );
7905
+ }
7906
+ };
7907
+
7908
+ return opt;
7909
+ };
7910
+
7911
+ jQuery.fn.extend( {
7912
+ fadeTo: function( speed, to, easing, callback ) {
7913
+
7914
+ // show any hidden elements after setting opacity to 0
7915
+ return this.filter( isHidden ).css( "opacity", 0 ).show()
7916
+
7917
+ // animate to the value specified
7918
+ .end().animate( { opacity: to }, speed, easing, callback );
7919
+ },
7920
+ animate: function( prop, speed, easing, callback ) {
7921
+ var empty = jQuery.isEmptyObject( prop ),
7922
+ optall = jQuery.speed( speed, easing, callback ),
7923
+ doAnimation = function() {
7924
+
7925
+ // Operate on a copy of prop so per-property easing won't be lost
7926
+ var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7927
+
7928
+ // Empty animations, or finishing resolves immediately
7929
+ if ( empty || jQuery._data( this, "finish" ) ) {
7930
+ anim.stop( true );
7931
+ }
7932
+ };
7933
+ doAnimation.finish = doAnimation;
7934
+
7935
+ return empty || optall.queue === false ?
7936
+ this.each( doAnimation ) :
7937
+ this.queue( optall.queue, doAnimation );
7938
+ },
7939
+ stop: function( type, clearQueue, gotoEnd ) {
7940
+ var stopQueue = function( hooks ) {
7941
+ var stop = hooks.stop;
7942
+ delete hooks.stop;
7943
+ stop( gotoEnd );
7944
+ };
7945
+
7946
+ if ( typeof type !== "string" ) {
7947
+ gotoEnd = clearQueue;
7948
+ clearQueue = type;
7949
+ type = undefined;
7950
+ }
7951
+ if ( clearQueue && type !== false ) {
7952
+ this.queue( type || "fx", [] );
7953
+ }
7954
+
7955
+ return this.each( function() {
7956
+ var dequeue = true,
7957
+ index = type != null && type + "queueHooks",
7958
+ timers = jQuery.timers,
7959
+ data = jQuery._data( this );
7960
+
7961
+ if ( index ) {
7962
+ if ( data[ index ] && data[ index ].stop ) {
7963
+ stopQueue( data[ index ] );
7964
+ }
7965
+ } else {
7966
+ for ( index in data ) {
7967
+ if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7968
+ stopQueue( data[ index ] );
7969
+ }
7970
+ }
7971
+ }
7972
+
7973
+ for ( index = timers.length; index--; ) {
7974
+ if ( timers[ index ].elem === this &&
7975
+ ( type == null || timers[ index ].queue === type ) ) {
7976
+
7977
+ timers[ index ].anim.stop( gotoEnd );
7978
+ dequeue = false;
7979
+ timers.splice( index, 1 );
7980
+ }
7981
+ }
7982
+
7983
+ // start the next in the queue if the last step wasn't forced
7984
+ // timers currently will call their complete callbacks, which will dequeue
7985
+ // but only if they were gotoEnd
7986
+ if ( dequeue || !gotoEnd ) {
7987
+ jQuery.dequeue( this, type );
7988
+ }
7989
+ } );
7990
+ },
7991
+ finish: function( type ) {
7992
+ if ( type !== false ) {
7993
+ type = type || "fx";
7994
+ }
7995
+ return this.each( function() {
7996
+ var index,
7997
+ data = jQuery._data( this ),
7998
+ queue = data[ type + "queue" ],
7999
+ hooks = data[ type + "queueHooks" ],
8000
+ timers = jQuery.timers,
8001
+ length = queue ? queue.length : 0;
8002
+
8003
+ // enable finishing flag on private data
8004
+ data.finish = true;
8005
+
8006
+ // empty the queue first
8007
+ jQuery.queue( this, type, [] );
8008
+
8009
+ if ( hooks && hooks.stop ) {
8010
+ hooks.stop.call( this, true );
8011
+ }
8012
+
8013
+ // look for any active animations, and finish them
8014
+ for ( index = timers.length; index--; ) {
8015
+ if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
8016
+ timers[ index ].anim.stop( true );
8017
+ timers.splice( index, 1 );
8018
+ }
8019
+ }
8020
+
8021
+ // look for any animations in the old queue and finish them
8022
+ for ( index = 0; index < length; index++ ) {
8023
+ if ( queue[ index ] && queue[ index ].finish ) {
8024
+ queue[ index ].finish.call( this );
8025
+ }
8026
+ }
8027
+
8028
+ // turn off finishing flag
8029
+ delete data.finish;
8030
+ } );
8031
+ }
8032
+ } );
8033
+
8034
+ jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
8035
+ var cssFn = jQuery.fn[ name ];
8036
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
8037
+ return speed == null || typeof speed === "boolean" ?
8038
+ cssFn.apply( this, arguments ) :
8039
+ this.animate( genFx( name, true ), speed, easing, callback );
8040
+ };
8041
+ } );
8042
+
8043
+ // Generate shortcuts for custom animations
8044
+ jQuery.each( {
8045
+ slideDown: genFx( "show" ),
8046
+ slideUp: genFx( "hide" ),
8047
+ slideToggle: genFx( "toggle" ),
8048
+ fadeIn: { opacity: "show" },
8049
+ fadeOut: { opacity: "hide" },
8050
+ fadeToggle: { opacity: "toggle" }
8051
+ }, function( name, props ) {
8052
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
8053
+ return this.animate( props, speed, easing, callback );
8054
+ };
8055
+ } );
8056
+
8057
+ jQuery.timers = [];
8058
+ jQuery.fx.tick = function() {
8059
+ var timer,
8060
+ timers = jQuery.timers,
8061
+ i = 0;
8062
+
8063
+ fxNow = jQuery.now();
8064
+
8065
+ for ( ; i < timers.length; i++ ) {
8066
+ timer = timers[ i ];
8067
+
8068
+ // Checks the timer has not already been removed
8069
+ if ( !timer() && timers[ i ] === timer ) {
8070
+ timers.splice( i--, 1 );
8071
+ }
8072
+ }
8073
+
8074
+ if ( !timers.length ) {
8075
+ jQuery.fx.stop();
8076
+ }
8077
+ fxNow = undefined;
8078
+ };
8079
+
8080
+ jQuery.fx.timer = function( timer ) {
8081
+ jQuery.timers.push( timer );
8082
+ if ( timer() ) {
8083
+ jQuery.fx.start();
8084
+ } else {
8085
+ jQuery.timers.pop();
8086
+ }
8087
+ };
8088
+
8089
+ jQuery.fx.interval = 13;
8090
+
8091
+ jQuery.fx.start = function() {
8092
+ if ( !timerId ) {
8093
+ timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
8094
+ }
8095
+ };
8096
+
8097
+ jQuery.fx.stop = function() {
8098
+ window.clearInterval( timerId );
8099
+ timerId = null;
8100
+ };
8101
+
8102
+ jQuery.fx.speeds = {
8103
+ slow: 600,
8104
+ fast: 200,
8105
+
8106
+ // Default speed
8107
+ _default: 400
8108
+ };
8109
+
8110
+
8111
+ // Based off of the plugin by Clint Helfers, with permission.
8112
+ // http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
8113
+ jQuery.fn.delay = function( time, type ) {
8114
+ time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
8115
+ type = type || "fx";
8116
+
8117
+ return this.queue( type, function( next, hooks ) {
8118
+ var timeout = window.setTimeout( next, time );
8119
+ hooks.stop = function() {
8120
+ window.clearTimeout( timeout );
8121
+ };
8122
+ } );
8123
+ };
8124
+
8125
+
8126
+ ( function() {
8127
+ var a,
8128
+ input = document.createElement( "input" ),
8129
+ div = document.createElement( "div" ),
8130
+ select = document.createElement( "select" ),
8131
+ opt = select.appendChild( document.createElement( "option" ) );
8132
+
8133
+ // Setup
8134
+ div = document.createElement( "div" );
8135
+ div.setAttribute( "className", "t" );
8136
+ div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
8137
+ a = div.getElementsByTagName( "a" )[ 0 ];
8138
+
8139
+ // Support: Windows Web Apps (WWA)
8140
+ // `type` must use .setAttribute for WWA (#14901)
8141
+ input.setAttribute( "type", "checkbox" );
8142
+ div.appendChild( input );
8143
+
8144
+ a = div.getElementsByTagName( "a" )[ 0 ];
8145
+
8146
+ // First batch of tests.
8147
+ a.style.cssText = "top:1px";
8148
+
8149
+ // Test setAttribute on camelCase class.
8150
+ // If it works, we need attrFixes when doing get/setAttribute (ie6/7)
8151
+ support.getSetAttribute = div.className !== "t";
8152
+
8153
+ // Get the style information from getAttribute
8154
+ // (IE uses .cssText instead)
8155
+ support.style = /top/.test( a.getAttribute( "style" ) );
8156
+
8157
+ // Make sure that URLs aren't manipulated
8158
+ // (IE normalizes it by default)
8159
+ support.hrefNormalized = a.getAttribute( "href" ) === "/a";
8160
+
8161
+ // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
8162
+ support.checkOn = !!input.value;
8163
+
8164
+ // Make sure that a selected-by-default option has a working selected property.
8165
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
8166
+ support.optSelected = opt.selected;
8167
+
8168
+ // Tests for enctype support on a form (#6743)
8169
+ support.enctype = !!document.createElement( "form" ).enctype;
8170
+
8171
+ // Make sure that the options inside disabled selects aren't marked as disabled
8172
+ // (WebKit marks them as disabled)
8173
+ select.disabled = true;
8174
+ support.optDisabled = !opt.disabled;
8175
+
8176
+ // Support: IE8 only
8177
+ // Check if we can trust getAttribute("value")
8178
+ input = document.createElement( "input" );
8179
+ input.setAttribute( "value", "" );
8180
+ support.input = input.getAttribute( "value" ) === "";
8181
+
8182
+ // Check if an input maintains its value after becoming a radio
8183
+ input.value = "t";
8184
+ input.setAttribute( "type", "radio" );
8185
+ support.radioValue = input.value === "t";
8186
+ } )();
8187
+
8188
+
8189
+ var rreturn = /\r/g,
8190
+ rspaces = /[\x20\t\r\n\f]+/g;
8191
+
8192
+ jQuery.fn.extend( {
8193
+ val: function( value ) {
8194
+ var hooks, ret, isFunction,
8195
+ elem = this[ 0 ];
8196
+
8197
+ if ( !arguments.length ) {
8198
+ if ( elem ) {
8199
+ hooks = jQuery.valHooks[ elem.type ] ||
8200
+ jQuery.valHooks[ elem.nodeName.toLowerCase() ];
8201
+
8202
+ if (
8203
+ hooks &&
8204
+ "get" in hooks &&
8205
+ ( ret = hooks.get( elem, "value" ) ) !== undefined
8206
+ ) {
8207
+ return ret;
8208
+ }
8209
+
8210
+ ret = elem.value;
8211
+
8212
+ return typeof ret === "string" ?
8213
+
8214
+ // handle most common string cases
8215
+ ret.replace( rreturn, "" ) :
8216
+
8217
+ // handle cases where value is null/undef or number
8218
+ ret == null ? "" : ret;
8219
+ }
8220
+
8221
+ return;
8222
+ }
8223
+
8224
+ isFunction = jQuery.isFunction( value );
8225
+
8226
+ return this.each( function( i ) {
8227
+ var val;
8228
+
8229
+ if ( this.nodeType !== 1 ) {
8230
+ return;
8231
+ }
8232
+
8233
+ if ( isFunction ) {
8234
+ val = value.call( this, i, jQuery( this ).val() );
8235
+ } else {
8236
+ val = value;
8237
+ }
8238
+
8239
+ // Treat null/undefined as ""; convert numbers to string
8240
+ if ( val == null ) {
8241
+ val = "";
8242
+ } else if ( typeof val === "number" ) {
8243
+ val += "";
8244
+ } else if ( jQuery.isArray( val ) ) {
8245
+ val = jQuery.map( val, function( value ) {
8246
+ return value == null ? "" : value + "";
8247
+ } );
8248
+ }
8249
+
8250
+ hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8251
+
8252
+ // If set returns undefined, fall back to normal setting
8253
+ if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8254
+ this.value = val;
8255
+ }
8256
+ } );
8257
+ }
8258
+ } );
8259
+
8260
+ jQuery.extend( {
8261
+ valHooks: {
8262
+ option: {
8263
+ get: function( elem ) {
8264
+ var val = jQuery.find.attr( elem, "value" );
8265
+ return val != null ?
8266
+ val :
8267
+
8268
+ // Support: IE10-11+
8269
+ // option.text throws exceptions (#14686, #14858)
8270
+ // Strip and collapse whitespace
8271
+ // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8272
+ jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
8273
+ }
8274
+ },
8275
+ select: {
8276
+ get: function( elem ) {
8277
+ var value, option,
8278
+ options = elem.options,
8279
+ index = elem.selectedIndex,
8280
+ one = elem.type === "select-one" || index < 0,
8281
+ values = one ? null : [],
8282
+ max = one ? index + 1 : options.length,
8283
+ i = index < 0 ?
8284
+ max :
8285
+ one ? index : 0;
8286
+
8287
+ // Loop through all the selected options
8288
+ for ( ; i < max; i++ ) {
8289
+ option = options[ i ];
8290
+
8291
+ // oldIE doesn't update selected after form reset (#2551)
8292
+ if ( ( option.selected || i === index ) &&
8293
+
8294
+ // Don't return options that are disabled or in a disabled optgroup
8295
+ ( support.optDisabled ?
8296
+ !option.disabled :
8297
+ option.getAttribute( "disabled" ) === null ) &&
8298
+ ( !option.parentNode.disabled ||
8299
+ !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
8300
+
8301
+ // Get the specific value for the option
8302
+ value = jQuery( option ).val();
8303
+
8304
+ // We don't need an array for one selects
8305
+ if ( one ) {
8306
+ return value;
8307
+ }
8308
+
8309
+ // Multi-Selects return an array
8310
+ values.push( value );
8311
+ }
8312
+ }
8313
+
8314
+ return values;
8315
+ },
8316
+
8317
+ set: function( elem, value ) {
8318
+ var optionSet, option,
8319
+ options = elem.options,
8320
+ values = jQuery.makeArray( value ),
8321
+ i = options.length;
8322
+
8323
+ while ( i-- ) {
8324
+ option = options[ i ];
8325
+
8326
+ if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) {
8327
+
8328
+ // Support: IE6
8329
+ // When new option element is added to select box we need to
8330
+ // force reflow of newly added node in order to workaround delay
8331
+ // of initialization properties
8332
+ try {
8333
+ option.selected = optionSet = true;
8334
+
8335
+ } catch ( _ ) {
8336
+
8337
+ // Will be executed only in IE6
8338
+ option.scrollHeight;
8339
+ }
8340
+
8341
+ } else {
8342
+ option.selected = false;
8343
+ }
8344
+ }
8345
+
8346
+ // Force browsers to behave consistently when non-matching value is set
8347
+ if ( !optionSet ) {
8348
+ elem.selectedIndex = -1;
8349
+ }
8350
+
8351
+ return options;
8352
+ }
8353
+ }
8354
+ }
8355
+ } );
8356
+
8357
+ // Radios and checkboxes getter/setter
8358
+ jQuery.each( [ "radio", "checkbox" ], function() {
8359
+ jQuery.valHooks[ this ] = {
8360
+ set: function( elem, value ) {
8361
+ if ( jQuery.isArray( value ) ) {
8362
+ return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8363
+ }
8364
+ }
8365
+ };
8366
+ if ( !support.checkOn ) {
8367
+ jQuery.valHooks[ this ].get = function( elem ) {
8368
+ return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8369
+ };
8370
+ }
8371
+ } );
8372
+
8373
+
8374
+
8375
+
8376
+ var nodeHook, boolHook,
8377
+ attrHandle = jQuery.expr.attrHandle,
8378
+ ruseDefault = /^(?:checked|selected)$/i,
8379
+ getSetAttribute = support.getSetAttribute,
8380
+ getSetInput = support.input;
8381
+
8382
+ jQuery.fn.extend( {
8383
+ attr: function( name, value ) {
8384
+ return access( this, jQuery.attr, name, value, arguments.length > 1 );
8385
+ },
8386
+
8387
+ removeAttr: function( name ) {
8388
+ return this.each( function() {
8389
+ jQuery.removeAttr( this, name );
8390
+ } );
8391
+ }
8392
+ } );
8393
+
8394
+ jQuery.extend( {
8395
+ attr: function( elem, name, value ) {
8396
+ var ret, hooks,
8397
+ nType = elem.nodeType;
8398
+
8399
+ // Don't get/set attributes on text, comment and attribute nodes
8400
+ if ( nType === 3 || nType === 8 || nType === 2 ) {
8401
+ return;
8402
+ }
8403
+
8404
+ // Fallback to prop when attributes are not supported
8405
+ if ( typeof elem.getAttribute === "undefined" ) {
8406
+ return jQuery.prop( elem, name, value );
8407
+ }
8408
+
8409
+ // All attributes are lowercase
8410
+ // Grab necessary hook if one is defined
8411
+ if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8412
+ name = name.toLowerCase();
8413
+ hooks = jQuery.attrHooks[ name ] ||
8414
+ ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
8415
+ }
8416
+
8417
+ if ( value !== undefined ) {
8418
+ if ( value === null ) {
8419
+ jQuery.removeAttr( elem, name );
8420
+ return;
8421
+ }
8422
+
8423
+ if ( hooks && "set" in hooks &&
8424
+ ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8425
+ return ret;
8426
+ }
8427
+
8428
+ elem.setAttribute( name, value + "" );
8429
+ return value;
8430
+ }
8431
+
8432
+ if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8433
+ return ret;
8434
+ }
8435
+
8436
+ ret = jQuery.find.attr( elem, name );
8437
+
8438
+ // Non-existent attributes return null, we normalize to undefined
8439
+ return ret == null ? undefined : ret;
8440
+ },
8441
+
8442
+ attrHooks: {
8443
+ type: {
8444
+ set: function( elem, value ) {
8445
+ if ( !support.radioValue && value === "radio" &&
8446
+ jQuery.nodeName( elem, "input" ) ) {
8447
+
8448
+ // Setting the type on a radio button after the value resets the value in IE8-9
8449
+ // Reset value to default in case type is set after value during creation
8450
+ var val = elem.value;
8451
+ elem.setAttribute( "type", value );
8452
+ if ( val ) {
8453
+ elem.value = val;
8454
+ }
8455
+ return value;
8456
+ }
8457
+ }
8458
+ }
8459
+ },
8460
+
8461
+ removeAttr: function( elem, value ) {
8462
+ var name, propName,
8463
+ i = 0,
8464
+ attrNames = value && value.match( rnotwhite );
8465
+
8466
+ if ( attrNames && elem.nodeType === 1 ) {
8467
+ while ( ( name = attrNames[ i++ ] ) ) {
8468
+ propName = jQuery.propFix[ name ] || name;
8469
+
8470
+ // Boolean attributes get special treatment (#10870)
8471
+ if ( jQuery.expr.match.bool.test( name ) ) {
8472
+
8473
+ // Set corresponding property to false
8474
+ if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8475
+ elem[ propName ] = false;
8476
+
8477
+ // Support: IE<9
8478
+ // Also clear defaultChecked/defaultSelected (if appropriate)
8479
+ } else {
8480
+ elem[ jQuery.camelCase( "default-" + name ) ] =
8481
+ elem[ propName ] = false;
8482
+ }
8483
+
8484
+ // See #9699 for explanation of this approach (setting first, then removal)
8485
+ } else {
8486
+ jQuery.attr( elem, name, "" );
8487
+ }
8488
+
8489
+ elem.removeAttribute( getSetAttribute ? name : propName );
8490
+ }
8491
+ }
8492
+ }
8493
+ } );
8494
+
8495
+ // Hooks for boolean attributes
8496
+ boolHook = {
8497
+ set: function( elem, value, name ) {
8498
+ if ( value === false ) {
8499
+
8500
+ // Remove boolean attributes when set to false
8501
+ jQuery.removeAttr( elem, name );
8502
+ } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8503
+
8504
+ // IE<8 needs the *property* name
8505
+ elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
8506
+
8507
+ } else {
8508
+
8509
+ // Support: IE<9
8510
+ // Use defaultChecked and defaultSelected for oldIE
8511
+ elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
8512
+ }
8513
+ return name;
8514
+ }
8515
+ };
8516
+
8517
+ jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
8518
+ var getter = attrHandle[ name ] || jQuery.find.attr;
8519
+
8520
+ if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8521
+ attrHandle[ name ] = function( elem, name, isXML ) {
8522
+ var ret, handle;
8523
+ if ( !isXML ) {
8524
+
8525
+ // Avoid an infinite loop by temporarily removing this function from the getter
8526
+ handle = attrHandle[ name ];
8527
+ attrHandle[ name ] = ret;
8528
+ ret = getter( elem, name, isXML ) != null ?
8529
+ name.toLowerCase() :
8530
+ null;
8531
+ attrHandle[ name ] = handle;
8532
+ }
8533
+ return ret;
8534
+ };
8535
+ } else {
8536
+ attrHandle[ name ] = function( elem, name, isXML ) {
8537
+ if ( !isXML ) {
8538
+ return elem[ jQuery.camelCase( "default-" + name ) ] ?
8539
+ name.toLowerCase() :
8540
+ null;
8541
+ }
8542
+ };
8543
+ }
8544
+ } );
8545
+
8546
+ // fix oldIE attroperties
8547
+ if ( !getSetInput || !getSetAttribute ) {
8548
+ jQuery.attrHooks.value = {
8549
+ set: function( elem, value, name ) {
8550
+ if ( jQuery.nodeName( elem, "input" ) ) {
8551
+
8552
+ // Does not return so that setAttribute is also used
8553
+ elem.defaultValue = value;
8554
+ } else {
8555
+
8556
+ // Use nodeHook if defined (#1954); otherwise setAttribute is fine
8557
+ return nodeHook && nodeHook.set( elem, value, name );
8558
+ }
8559
+ }
8560
+ };
8561
+ }
8562
+
8563
+ // IE6/7 do not support getting/setting some attributes with get/setAttribute
8564
+ if ( !getSetAttribute ) {
8565
+
8566
+ // Use this for any attribute in IE6/7
8567
+ // This fixes almost every IE6/7 issue
8568
+ nodeHook = {
8569
+ set: function( elem, value, name ) {
8570
+
8571
+ // Set the existing or create a new attribute node
8572
+ var ret = elem.getAttributeNode( name );
8573
+ if ( !ret ) {
8574
+ elem.setAttributeNode(
8575
+ ( ret = elem.ownerDocument.createAttribute( name ) )
8576
+ );
8577
+ }
8578
+
8579
+ ret.value = value += "";
8580
+
8581
+ // Break association with cloned elements by also using setAttribute (#9646)
8582
+ if ( name === "value" || value === elem.getAttribute( name ) ) {
8583
+ return value;
8584
+ }
8585
+ }
8586
+ };
8587
+
8588
+ // Some attributes are constructed with empty-string values when not defined
8589
+ attrHandle.id = attrHandle.name = attrHandle.coords =
8590
+ function( elem, name, isXML ) {
8591
+ var ret;
8592
+ if ( !isXML ) {
8593
+ return ( ret = elem.getAttributeNode( name ) ) && ret.value !== "" ?
8594
+ ret.value :
8595
+ null;
8596
+ }
8597
+ };
8598
+
8599
+ // Fixing value retrieval on a button requires this module
8600
+ jQuery.valHooks.button = {
8601
+ get: function( elem, name ) {
8602
+ var ret = elem.getAttributeNode( name );
8603
+ if ( ret && ret.specified ) {
8604
+ return ret.value;
8605
+ }
8606
+ },
8607
+ set: nodeHook.set
8608
+ };
8609
+
8610
+ // Set contenteditable to false on removals(#10429)
8611
+ // Setting to empty string throws an error as an invalid value
8612
+ jQuery.attrHooks.contenteditable = {
8613
+ set: function( elem, value, name ) {
8614
+ nodeHook.set( elem, value === "" ? false : value, name );
8615
+ }
8616
+ };
8617
+
8618
+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
8619
+ // This is for removals
8620
+ jQuery.each( [ "width", "height" ], function( i, name ) {
8621
+ jQuery.attrHooks[ name ] = {
8622
+ set: function( elem, value ) {
8623
+ if ( value === "" ) {
8624
+ elem.setAttribute( name, "auto" );
8625
+ return value;
8626
+ }
8627
+ }
8628
+ };
8629
+ } );
8630
+ }
8631
+
8632
+ if ( !support.style ) {
8633
+ jQuery.attrHooks.style = {
8634
+ get: function( elem ) {
8635
+
8636
+ // Return undefined in the case of empty string
8637
+ // Note: IE uppercases css property names, but if we were to .toLowerCase()
8638
+ // .cssText, that would destroy case sensitivity in URL's, like in "background"
8639
+ return elem.style.cssText || undefined;
8640
+ },
8641
+ set: function( elem, value ) {
8642
+ return ( elem.style.cssText = value + "" );
8643
+ }
8644
+ };
8645
+ }
8646
+
8647
+
8648
+
8649
+
8650
+ var rfocusable = /^(?:input|select|textarea|button|object)$/i,
8651
+ rclickable = /^(?:a|area)$/i;
8652
+
8653
+ jQuery.fn.extend( {
8654
+ prop: function( name, value ) {
8655
+ return access( this, jQuery.prop, name, value, arguments.length > 1 );
8656
+ },
8657
+
8658
+ removeProp: function( name ) {
8659
+ name = jQuery.propFix[ name ] || name;
8660
+ return this.each( function() {
8661
+
8662
+ // try/catch handles cases where IE balks (such as removing a property on window)
8663
+ try {
8664
+ this[ name ] = undefined;
8665
+ delete this[ name ];
8666
+ } catch ( e ) {}
8667
+ } );
8668
+ }
8669
+ } );
8670
+
8671
+ jQuery.extend( {
8672
+ prop: function( elem, name, value ) {
8673
+ var ret, hooks,
8674
+ nType = elem.nodeType;
8675
+
8676
+ // Don't get/set properties on text, comment and attribute nodes
8677
+ if ( nType === 3 || nType === 8 || nType === 2 ) {
8678
+ return;
8679
+ }
8680
+
8681
+ if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8682
+
8683
+ // Fix name and attach hooks
8684
+ name = jQuery.propFix[ name ] || name;
8685
+ hooks = jQuery.propHooks[ name ];
8686
+ }
8687
+
8688
+ if ( value !== undefined ) {
8689
+ if ( hooks && "set" in hooks &&
8690
+ ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8691
+ return ret;
8692
+ }
8693
+
8694
+ return ( elem[ name ] = value );
8695
+ }
8696
+
8697
+ if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8698
+ return ret;
8699
+ }
8700
+
8701
+ return elem[ name ];
8702
+ },
8703
+
8704
+ propHooks: {
8705
+ tabIndex: {
8706
+ get: function( elem ) {
8707
+
8708
+ // elem.tabIndex doesn't always return the
8709
+ // correct value when it hasn't been explicitly set
8710
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8711
+ // Use proper attribute retrieval(#12072)
8712
+ var tabindex = jQuery.find.attr( elem, "tabindex" );
8713
+
8714
+ return tabindex ?
8715
+ parseInt( tabindex, 10 ) :
8716
+ rfocusable.test( elem.nodeName ) ||
8717
+ rclickable.test( elem.nodeName ) && elem.href ?
8718
+ 0 :
8719
+ -1;
8720
+ }
8721
+ }
8722
+ },
8723
+
8724
+ propFix: {
8725
+ "for": "htmlFor",
8726
+ "class": "className"
8727
+ }
8728
+ } );
8729
+
8730
+ // Some attributes require a special call on IE
8731
+ // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
8732
+ if ( !support.hrefNormalized ) {
8733
+
8734
+ // href/src property should get the full normalized URL (#10299/#12915)
8735
+ jQuery.each( [ "href", "src" ], function( i, name ) {
8736
+ jQuery.propHooks[ name ] = {
8737
+ get: function( elem ) {
8738
+ return elem.getAttribute( name, 4 );
8739
+ }
8740
+ };
8741
+ } );
8742
+ }
8743
+
8744
+ // Support: Safari, IE9+
8745
+ // Accessing the selectedIndex property
8746
+ // forces the browser to respect setting selected
8747
+ // on the option
8748
+ // The getter ensures a default option is selected
8749
+ // when in an optgroup
8750
+ if ( !support.optSelected ) {
8751
+ jQuery.propHooks.selected = {
8752
+ get: function( elem ) {
8753
+ var parent = elem.parentNode;
8754
+
8755
+ if ( parent ) {
8756
+ parent.selectedIndex;
8757
+
8758
+ // Make sure that it also works with optgroups, see #5701
8759
+ if ( parent.parentNode ) {
8760
+ parent.parentNode.selectedIndex;
8761
+ }
8762
+ }
8763
+ return null;
8764
+ },
8765
+ set: function( elem ) {
8766
+ var parent = elem.parentNode;
8767
+ if ( parent ) {
8768
+ parent.selectedIndex;
8769
+
8770
+ if ( parent.parentNode ) {
8771
+ parent.parentNode.selectedIndex;
8772
+ }
8773
+ }
8774
+ }
8775
+ };
8776
+ }
8777
+
8778
+ jQuery.each( [
8779
+ "tabIndex",
8780
+ "readOnly",
8781
+ "maxLength",
8782
+ "cellSpacing",
8783
+ "cellPadding",
8784
+ "rowSpan",
8785
+ "colSpan",
8786
+ "useMap",
8787
+ "frameBorder",
8788
+ "contentEditable"
8789
+ ], function() {
8790
+ jQuery.propFix[ this.toLowerCase() ] = this;
8791
+ } );
8792
+
8793
+ // IE6/7 call enctype encoding
8794
+ if ( !support.enctype ) {
8795
+ jQuery.propFix.enctype = "encoding";
8796
+ }
8797
+
8798
+
8799
+
8800
+
8801
+ var rclass = /[\t\r\n\f]/g;
8802
+
8803
+ function getClass( elem ) {
8804
+ return jQuery.attr( elem, "class" ) || "";
8805
+ }
8806
+
8807
+ jQuery.fn.extend( {
8808
+ addClass: function( value ) {
8809
+ var classes, elem, cur, curValue, clazz, j, finalValue,
8810
+ i = 0;
8811
+
8812
+ if ( jQuery.isFunction( value ) ) {
8813
+ return this.each( function( j ) {
8814
+ jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
8815
+ } );
8816
+ }
8817
+
8818
+ if ( typeof value === "string" && value ) {
8819
+ classes = value.match( rnotwhite ) || [];
8820
+
8821
+ while ( ( elem = this[ i++ ] ) ) {
8822
+ curValue = getClass( elem );
8823
+ cur = elem.nodeType === 1 &&
8824
+ ( " " + curValue + " " ).replace( rclass, " " );
8825
+
8826
+ if ( cur ) {
8827
+ j = 0;
8828
+ while ( ( clazz = classes[ j++ ] ) ) {
8829
+ if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8830
+ cur += clazz + " ";
8831
+ }
8832
+ }
8833
+
8834
+ // only assign if different to avoid unneeded rendering.
8835
+ finalValue = jQuery.trim( cur );
8836
+ if ( curValue !== finalValue ) {
8837
+ jQuery.attr( elem, "class", finalValue );
8838
+ }
8839
+ }
8840
+ }
8841
+ }
8842
+
8843
+ return this;
8844
+ },
8845
+
8846
+ removeClass: function( value ) {
8847
+ var classes, elem, cur, curValue, clazz, j, finalValue,
8848
+ i = 0;
8849
+
8850
+ if ( jQuery.isFunction( value ) ) {
8851
+ return this.each( function( j ) {
8852
+ jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
8853
+ } );
8854
+ }
8855
+
8856
+ if ( !arguments.length ) {
8857
+ return this.attr( "class", "" );
8858
+ }
8859
+
8860
+ if ( typeof value === "string" && value ) {
8861
+ classes = value.match( rnotwhite ) || [];
8862
+
8863
+ while ( ( elem = this[ i++ ] ) ) {
8864
+ curValue = getClass( elem );
8865
+
8866
+ // This expression is here for better compressibility (see addClass)
8867
+ cur = elem.nodeType === 1 &&
8868
+ ( " " + curValue + " " ).replace( rclass, " " );
8869
+
8870
+ if ( cur ) {
8871
+ j = 0;
8872
+ while ( ( clazz = classes[ j++ ] ) ) {
8873
+
8874
+ // Remove *all* instances
8875
+ while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
8876
+ cur = cur.replace( " " + clazz + " ", " " );
8877
+ }
8878
+ }
8879
+
8880
+ // Only assign if different to avoid unneeded rendering.
8881
+ finalValue = jQuery.trim( cur );
8882
+ if ( curValue !== finalValue ) {
8883
+ jQuery.attr( elem, "class", finalValue );
8884
+ }
8885
+ }
8886
+ }
8887
+ }
8888
+
8889
+ return this;
8890
+ },
8891
+
8892
+ toggleClass: function( value, stateVal ) {
8893
+ var type = typeof value;
8894
+
8895
+ if ( typeof stateVal === "boolean" && type === "string" ) {
8896
+ return stateVal ? this.addClass( value ) : this.removeClass( value );
8897
+ }
8898
+
8899
+ if ( jQuery.isFunction( value ) ) {
8900
+ return this.each( function( i ) {
8901
+ jQuery( this ).toggleClass(
8902
+ value.call( this, i, getClass( this ), stateVal ),
8903
+ stateVal
8904
+ );
8905
+ } );
8906
+ }
8907
+
8908
+ return this.each( function() {
8909
+ var className, i, self, classNames;
8910
+
8911
+ if ( type === "string" ) {
8912
+
8913
+ // Toggle individual class names
8914
+ i = 0;
8915
+ self = jQuery( this );
8916
+ classNames = value.match( rnotwhite ) || [];
8917
+
8918
+ while ( ( className = classNames[ i++ ] ) ) {
8919
+
8920
+ // Check each className given, space separated list
8921
+ if ( self.hasClass( className ) ) {
8922
+ self.removeClass( className );
8923
+ } else {
8924
+ self.addClass( className );
8925
+ }
8926
+ }
8927
+
8928
+ // Toggle whole class name
8929
+ } else if ( value === undefined || type === "boolean" ) {
8930
+ className = getClass( this );
8931
+ if ( className ) {
8932
+
8933
+ // store className if set
8934
+ jQuery._data( this, "__className__", className );
8935
+ }
8936
+
8937
+ // If the element has a class name or if we're passed "false",
8938
+ // then remove the whole classname (if there was one, the above saved it).
8939
+ // Otherwise bring back whatever was previously saved (if anything),
8940
+ // falling back to the empty string if nothing was stored.
8941
+ jQuery.attr( this, "class",
8942
+ className || value === false ?
8943
+ "" :
8944
+ jQuery._data( this, "__className__" ) || ""
8945
+ );
8946
+ }
8947
+ } );
8948
+ },
8949
+
8950
+ hasClass: function( selector ) {
8951
+ var className, elem,
8952
+ i = 0;
8953
+
8954
+ className = " " + selector + " ";
8955
+ while ( ( elem = this[ i++ ] ) ) {
8956
+ if ( elem.nodeType === 1 &&
8957
+ ( " " + getClass( elem ) + " " ).replace( rclass, " " )
8958
+ .indexOf( className ) > -1
8959
+ ) {
8960
+ return true;
8961
+ }
8962
+ }
8963
+
8964
+ return false;
8965
+ }
8966
+ } );
8967
+
8968
+
8969
+
8970
+
8971
+ // Return jQuery for attributes-only inclusion
8972
+
8973
+
8974
+ jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
8975
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8976
+ "change select submit keydown keypress keyup error contextmenu" ).split( " " ),
8977
+ function( i, name ) {
8978
+
8979
+ // Handle event binding
8980
+ jQuery.fn[ name ] = function( data, fn ) {
8981
+ return arguments.length > 0 ?
8982
+ this.on( name, null, data, fn ) :
8983
+ this.trigger( name );
8984
+ };
8985
+ } );
8986
+
8987
+ jQuery.fn.extend( {
8988
+ hover: function( fnOver, fnOut ) {
8989
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
8990
+ }
8991
+ } );
8992
+
8993
+
8994
+ var location = window.location;
8995
+
8996
+ var nonce = jQuery.now();
8997
+
8998
+ var rquery = ( /\?/ );
8999
+
9000
+
9001
+
9002
+ var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
9003
+
9004
+ jQuery.parseJSON = function( data ) {
9005
+
9006
+ // Attempt to parse using the native JSON parser first
9007
+ if ( window.JSON && window.JSON.parse ) {
9008
+
9009
+ // Support: Android 2.3
9010
+ // Workaround failure to string-cast null input
9011
+ return window.JSON.parse( data + "" );
9012
+ }
9013
+
9014
+ var requireNonComma,
9015
+ depth = null,
9016
+ str = jQuery.trim( data + "" );
9017
+
9018
+ // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
9019
+ // after removing valid tokens
9020
+ return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
9021
+
9022
+ // Force termination if we see a misplaced comma
9023
+ if ( requireNonComma && comma ) {
9024
+ depth = 0;
9025
+ }
9026
+
9027
+ // Perform no more replacements after returning to outermost depth
9028
+ if ( depth === 0 ) {
9029
+ return token;
9030
+ }
9031
+
9032
+ // Commas must not follow "[", "{", or ","
9033
+ requireNonComma = open || comma;
9034
+
9035
+ // Determine new depth
9036
+ // array/object open ("[" or "{"): depth += true - false (increment)
9037
+ // array/object close ("]" or "}"): depth += false - true (decrement)
9038
+ // other cases ("," or primitive): depth += true - true (numeric cast)
9039
+ depth += !close - !open;
9040
+
9041
+ // Remove this token
9042
+ return "";
9043
+ } ) ) ?
9044
+ ( Function( "return " + str ) )() :
9045
+ jQuery.error( "Invalid JSON: " + data );
9046
+ };
9047
+
9048
+
9049
+ // Cross-browser xml parsing
9050
+ jQuery.parseXML = function( data ) {
9051
+ var xml, tmp;
9052
+ if ( !data || typeof data !== "string" ) {
9053
+ return null;
9054
+ }
9055
+ try {
9056
+ if ( window.DOMParser ) { // Standard
9057
+ tmp = new window.DOMParser();
9058
+ xml = tmp.parseFromString( data, "text/xml" );
9059
+ } else { // IE
9060
+ xml = new window.ActiveXObject( "Microsoft.XMLDOM" );
9061
+ xml.async = "false";
9062
+ xml.loadXML( data );
9063
+ }
9064
+ } catch ( e ) {
9065
+ xml = undefined;
9066
+ }
9067
+ if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
9068
+ jQuery.error( "Invalid XML: " + data );
9069
+ }
9070
+ return xml;
9071
+ };
9072
+
9073
+
9074
+ var
9075
+ rhash = /#.*$/,
9076
+ rts = /([?&])_=[^&]*/,
9077
+
9078
+ // IE leaves an \r character at EOL
9079
+ rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg,
9080
+
9081
+ // #7653, #8125, #8152: local protocol detection
9082
+ rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
9083
+ rnoContent = /^(?:GET|HEAD)$/,
9084
+ rprotocol = /^\/\//,
9085
+ rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
9086
+
9087
+ /* Prefilters
9088
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
9089
+ * 2) These are called:
9090
+ * - BEFORE asking for a transport
9091
+ * - AFTER param serialization (s.data is a string if s.processData is true)
9092
+ * 3) key is the dataType
9093
+ * 4) the catchall symbol "*" can be used
9094
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
9095
+ */
9096
+ prefilters = {},
9097
+
9098
+ /* Transports bindings
9099
+ * 1) key is the dataType
9100
+ * 2) the catchall symbol "*" can be used
9101
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
9102
+ */
9103
+ transports = {},
9104
+
9105
+ // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
9106
+ allTypes = "*/".concat( "*" ),
9107
+
9108
+ // Document location
9109
+ ajaxLocation = location.href,
9110
+
9111
+ // Segment location into parts
9112
+ ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
9113
+
9114
+ // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
9115
+ function addToPrefiltersOrTransports( structure ) {
9116
+
9117
+ // dataTypeExpression is optional and defaults to "*"
9118
+ return function( dataTypeExpression, func ) {
9119
+
9120
+ if ( typeof dataTypeExpression !== "string" ) {
9121
+ func = dataTypeExpression;
9122
+ dataTypeExpression = "*";
9123
+ }
9124
+
9125
+ var dataType,
9126
+ i = 0,
9127
+ dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
9128
+
9129
+ if ( jQuery.isFunction( func ) ) {
9130
+
9131
+ // For each dataType in the dataTypeExpression
9132
+ while ( ( dataType = dataTypes[ i++ ] ) ) {
9133
+
9134
+ // Prepend if requested
9135
+ if ( dataType.charAt( 0 ) === "+" ) {
9136
+ dataType = dataType.slice( 1 ) || "*";
9137
+ ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
9138
+
9139
+ // Otherwise append
9140
+ } else {
9141
+ ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
9142
+ }
9143
+ }
9144
+ }
9145
+ };
9146
+ }
9147
+
9148
+ // Base inspection function for prefilters and transports
9149
+ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
9150
+
9151
+ var inspected = {},
9152
+ seekingTransport = ( structure === transports );
9153
+
9154
+ function inspect( dataType ) {
9155
+ var selected;
9156
+ inspected[ dataType ] = true;
9157
+ jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
9158
+ var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
9159
+ if ( typeof dataTypeOrTransport === "string" &&
9160
+ !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
9161
+
9162
+ options.dataTypes.unshift( dataTypeOrTransport );
9163
+ inspect( dataTypeOrTransport );
9164
+ return false;
9165
+ } else if ( seekingTransport ) {
9166
+ return !( selected = dataTypeOrTransport );
9167
+ }
9168
+ } );
9169
+ return selected;
9170
+ }
9171
+
9172
+ return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
9173
+ }
9174
+
9175
+ // A special extend for ajax options
9176
+ // that takes "flat" options (not to be deep extended)
9177
+ // Fixes #9887
9178
+ function ajaxExtend( target, src ) {
9179
+ var deep, key,
9180
+ flatOptions = jQuery.ajaxSettings.flatOptions || {};
9181
+
9182
+ for ( key in src ) {
9183
+ if ( src[ key ] !== undefined ) {
9184
+ ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
9185
+ }
9186
+ }
9187
+ if ( deep ) {
9188
+ jQuery.extend( true, target, deep );
9189
+ }
9190
+
9191
+ return target;
9192
+ }
9193
+
9194
+ /* Handles responses to an ajax request:
9195
+ * - finds the right dataType (mediates between content-type and expected dataType)
9196
+ * - returns the corresponding response
9197
+ */
9198
+ function ajaxHandleResponses( s, jqXHR, responses ) {
9199
+ var firstDataType, ct, finalDataType, type,
9200
+ contents = s.contents,
9201
+ dataTypes = s.dataTypes;
9202
+
9203
+ // Remove auto dataType and get content-type in the process
9204
+ while ( dataTypes[ 0 ] === "*" ) {
9205
+ dataTypes.shift();
9206
+ if ( ct === undefined ) {
9207
+ ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
9208
+ }
9209
+ }
9210
+
9211
+ // Check if we're dealing with a known content-type
9212
+ if ( ct ) {
9213
+ for ( type in contents ) {
9214
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
9215
+ dataTypes.unshift( type );
9216
+ break;
9217
+ }
9218
+ }
9219
+ }
9220
+
9221
+ // Check to see if we have a response for the expected dataType
9222
+ if ( dataTypes[ 0 ] in responses ) {
9223
+ finalDataType = dataTypes[ 0 ];
9224
+ } else {
9225
+
9226
+ // Try convertible dataTypes
9227
+ for ( type in responses ) {
9228
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
9229
+ finalDataType = type;
9230
+ break;
9231
+ }
9232
+ if ( !firstDataType ) {
9233
+ firstDataType = type;
9234
+ }
9235
+ }
9236
+
9237
+ // Or just use first one
9238
+ finalDataType = finalDataType || firstDataType;
9239
+ }
9240
+
9241
+ // If we found a dataType
9242
+ // We add the dataType to the list if needed
9243
+ // and return the corresponding response
9244
+ if ( finalDataType ) {
9245
+ if ( finalDataType !== dataTypes[ 0 ] ) {
9246
+ dataTypes.unshift( finalDataType );
9247
+ }
9248
+ return responses[ finalDataType ];
9249
+ }
9250
+ }
9251
+
9252
+ /* Chain conversions given the request and the original response
9253
+ * Also sets the responseXXX fields on the jqXHR instance
9254
+ */
9255
+ function ajaxConvert( s, response, jqXHR, isSuccess ) {
9256
+ var conv2, current, conv, tmp, prev,
9257
+ converters = {},
9258
+
9259
+ // Work with a copy of dataTypes in case we need to modify it for conversion
9260
+ dataTypes = s.dataTypes.slice();
9261
+
9262
+ // Create converters map with lowercased keys
9263
+ if ( dataTypes[ 1 ] ) {
9264
+ for ( conv in s.converters ) {
9265
+ converters[ conv.toLowerCase() ] = s.converters[ conv ];
9266
+ }
9267
+ }
9268
+
9269
+ current = dataTypes.shift();
9270
+
9271
+ // Convert to each sequential dataType
9272
+ while ( current ) {
9273
+
9274
+ if ( s.responseFields[ current ] ) {
9275
+ jqXHR[ s.responseFields[ current ] ] = response;
9276
+ }
9277
+
9278
+ // Apply the dataFilter if provided
9279
+ if ( !prev && isSuccess && s.dataFilter ) {
9280
+ response = s.dataFilter( response, s.dataType );
9281
+ }
9282
+
9283
+ prev = current;
9284
+ current = dataTypes.shift();
9285
+
9286
+ if ( current ) {
9287
+
9288
+ // There's only work to do if current dataType is non-auto
9289
+ if ( current === "*" ) {
9290
+
9291
+ current = prev;
9292
+
9293
+ // Convert response if prev dataType is non-auto and differs from current
9294
+ } else if ( prev !== "*" && prev !== current ) {
9295
+
9296
+ // Seek a direct converter
9297
+ conv = converters[ prev + " " + current ] || converters[ "* " + current ];
9298
+
9299
+ // If none found, seek a pair
9300
+ if ( !conv ) {
9301
+ for ( conv2 in converters ) {
9302
+
9303
+ // If conv2 outputs current
9304
+ tmp = conv2.split( " " );
9305
+ if ( tmp[ 1 ] === current ) {
9306
+
9307
+ // If prev can be converted to accepted input
9308
+ conv = converters[ prev + " " + tmp[ 0 ] ] ||
9309
+ converters[ "* " + tmp[ 0 ] ];
9310
+ if ( conv ) {
9311
+
9312
+ // Condense equivalence converters
9313
+ if ( conv === true ) {
9314
+ conv = converters[ conv2 ];
9315
+
9316
+ // Otherwise, insert the intermediate dataType
9317
+ } else if ( converters[ conv2 ] !== true ) {
9318
+ current = tmp[ 0 ];
9319
+ dataTypes.unshift( tmp[ 1 ] );
9320
+ }
9321
+ break;
9322
+ }
9323
+ }
9324
+ }
9325
+ }
9326
+
9327
+ // Apply converter (if not an equivalence)
9328
+ if ( conv !== true ) {
9329
+
9330
+ // Unless errors are allowed to bubble, catch and return them
9331
+ if ( conv && s[ "throws" ] ) { // jscs:ignore requireDotNotation
9332
+ response = conv( response );
9333
+ } else {
9334
+ try {
9335
+ response = conv( response );
9336
+ } catch ( e ) {
9337
+ return {
9338
+ state: "parsererror",
9339
+ error: conv ? e : "No conversion from " + prev + " to " + current
9340
+ };
9341
+ }
9342
+ }
9343
+ }
9344
+ }
9345
+ }
9346
+ }
9347
+
9348
+ return { state: "success", data: response };
9349
+ }
9350
+
9351
+ jQuery.extend( {
9352
+
9353
+ // Counter for holding the number of active queries
9354
+ active: 0,
9355
+
9356
+ // Last-Modified header cache for next request
9357
+ lastModified: {},
9358
+ etag: {},
9359
+
9360
+ ajaxSettings: {
9361
+ url: ajaxLocation,
9362
+ type: "GET",
9363
+ isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
9364
+ global: true,
9365
+ processData: true,
9366
+ async: true,
9367
+ contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9368
+ /*
9369
+ timeout: 0,
9370
+ data: null,
9371
+ dataType: null,
9372
+ username: null,
9373
+ password: null,
9374
+ cache: null,
9375
+ throws: false,
9376
+ traditional: false,
9377
+ headers: {},
9378
+ */
9379
+
9380
+ accepts: {
9381
+ "*": allTypes,
9382
+ text: "text/plain",
9383
+ html: "text/html",
9384
+ xml: "application/xml, text/xml",
9385
+ json: "application/json, text/javascript"
9386
+ },
9387
+
9388
+ contents: {
9389
+ xml: /\bxml\b/,
9390
+ html: /\bhtml/,
9391
+ json: /\bjson\b/
9392
+ },
9393
+
9394
+ responseFields: {
9395
+ xml: "responseXML",
9396
+ text: "responseText",
9397
+ json: "responseJSON"
9398
+ },
9399
+
9400
+ // Data converters
9401
+ // Keys separate source (or catchall "*") and destination types with a single space
9402
+ converters: {
9403
+
9404
+ // Convert anything to text
9405
+ "* text": String,
9406
+
9407
+ // Text to html (true = no transformation)
9408
+ "text html": true,
9409
+
9410
+ // Evaluate text as a json expression
9411
+ "text json": jQuery.parseJSON,
9412
+
9413
+ // Parse text as xml
9414
+ "text xml": jQuery.parseXML
9415
+ },
9416
+
9417
+ // For options that shouldn't be deep extended:
9418
+ // you can add your own custom options here if
9419
+ // and when you create one that shouldn't be
9420
+ // deep extended (see ajaxExtend)
9421
+ flatOptions: {
9422
+ url: true,
9423
+ context: true
9424
+ }
9425
+ },
9426
+
9427
+ // Creates a full fledged settings object into target
9428
+ // with both ajaxSettings and settings fields.
9429
+ // If target is omitted, writes into ajaxSettings.
9430
+ ajaxSetup: function( target, settings ) {
9431
+ return settings ?
9432
+
9433
+ // Building a settings object
9434
+ ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
9435
+
9436
+ // Extending ajaxSettings
9437
+ ajaxExtend( jQuery.ajaxSettings, target );
9438
+ },
9439
+
9440
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
9441
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
9442
+
9443
+ // Main method
9444
+ ajax: function( url, options ) {
9445
+
9446
+ // If url is an object, simulate pre-1.5 signature
9447
+ if ( typeof url === "object" ) {
9448
+ options = url;
9449
+ url = undefined;
9450
+ }
9451
+
9452
+ // Force options to be an object
9453
+ options = options || {};
9454
+
9455
+ var
9456
+
9457
+ // Cross-domain detection vars
9458
+ parts,
9459
+
9460
+ // Loop variable
9461
+ i,
9462
+
9463
+ // URL without anti-cache param
9464
+ cacheURL,
9465
+
9466
+ // Response headers as string
9467
+ responseHeadersString,
9468
+
9469
+ // timeout handle
9470
+ timeoutTimer,
9471
+
9472
+ // To know if global events are to be dispatched
9473
+ fireGlobals,
9474
+
9475
+ transport,
9476
+
9477
+ // Response headers
9478
+ responseHeaders,
9479
+
9480
+ // Create the final options object
9481
+ s = jQuery.ajaxSetup( {}, options ),
9482
+
9483
+ // Callbacks context
9484
+ callbackContext = s.context || s,
9485
+
9486
+ // Context for global events is callbackContext if it is a DOM node or jQuery collection
9487
+ globalEventContext = s.context &&
9488
+ ( callbackContext.nodeType || callbackContext.jquery ) ?
9489
+ jQuery( callbackContext ) :
9490
+ jQuery.event,
9491
+
9492
+ // Deferreds
9493
+ deferred = jQuery.Deferred(),
9494
+ completeDeferred = jQuery.Callbacks( "once memory" ),
9495
+
9496
+ // Status-dependent callbacks
9497
+ statusCode = s.statusCode || {},
9498
+
9499
+ // Headers (they are sent all at once)
9500
+ requestHeaders = {},
9501
+ requestHeadersNames = {},
9502
+
9503
+ // The jqXHR state
9504
+ state = 0,
9505
+
9506
+ // Default abort message
9507
+ strAbort = "canceled",
9508
+
9509
+ // Fake xhr
9510
+ jqXHR = {
9511
+ readyState: 0,
9512
+
9513
+ // Builds headers hashtable if needed
9514
+ getResponseHeader: function( key ) {
9515
+ var match;
9516
+ if ( state === 2 ) {
9517
+ if ( !responseHeaders ) {
9518
+ responseHeaders = {};
9519
+ while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
9520
+ responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
9521
+ }
9522
+ }
9523
+ match = responseHeaders[ key.toLowerCase() ];
9524
+ }
9525
+ return match == null ? null : match;
9526
+ },
9527
+
9528
+ // Raw string
9529
+ getAllResponseHeaders: function() {
9530
+ return state === 2 ? responseHeadersString : null;
9531
+ },
9532
+
9533
+ // Caches the header
9534
+ setRequestHeader: function( name, value ) {
9535
+ var lname = name.toLowerCase();
9536
+ if ( !state ) {
9537
+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
9538
+ requestHeaders[ name ] = value;
9539
+ }
9540
+ return this;
9541
+ },
9542
+
9543
+ // Overrides response content-type header
9544
+ overrideMimeType: function( type ) {
9545
+ if ( !state ) {
9546
+ s.mimeType = type;
9547
+ }
9548
+ return this;
9549
+ },
9550
+
9551
+ // Status-dependent callbacks
9552
+ statusCode: function( map ) {
9553
+ var code;
9554
+ if ( map ) {
9555
+ if ( state < 2 ) {
9556
+ for ( code in map ) {
9557
+
9558
+ // Lazy-add the new callback in a way that preserves old ones
9559
+ statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9560
+ }
9561
+ } else {
9562
+
9563
+ // Execute the appropriate callbacks
9564
+ jqXHR.always( map[ jqXHR.status ] );
9565
+ }
9566
+ }
9567
+ return this;
9568
+ },
9569
+
9570
+ // Cancel the request
9571
+ abort: function( statusText ) {
9572
+ var finalText = statusText || strAbort;
9573
+ if ( transport ) {
9574
+ transport.abort( finalText );
9575
+ }
9576
+ done( 0, finalText );
9577
+ return this;
9578
+ }
9579
+ };
9580
+
9581
+ // Attach deferreds
9582
+ deferred.promise( jqXHR ).complete = completeDeferred.add;
9583
+ jqXHR.success = jqXHR.done;
9584
+ jqXHR.error = jqXHR.fail;
9585
+
9586
+ // Remove hash character (#7531: and string promotion)
9587
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
9588
+ // Handle falsy url in the settings object (#10093: consistency with old signature)
9589
+ // We also use the url parameter if available
9590
+ s.url = ( ( url || s.url || ajaxLocation ) + "" )
9591
+ .replace( rhash, "" )
9592
+ .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
9593
+
9594
+ // Alias method option to type as per ticket #12004
9595
+ s.type = options.method || options.type || s.method || s.type;
9596
+
9597
+ // Extract dataTypes list
9598
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
9599
+
9600
+ // A cross-domain request is in order when we have a protocol:host:port mismatch
9601
+ if ( s.crossDomain == null ) {
9602
+ parts = rurl.exec( s.url.toLowerCase() );
9603
+ s.crossDomain = !!( parts &&
9604
+ ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
9605
+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
9606
+ ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
9607
+ );
9608
+ }
9609
+
9610
+ // Convert data if not already a string
9611
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
9612
+ s.data = jQuery.param( s.data, s.traditional );
9613
+ }
9614
+
9615
+ // Apply prefilters
9616
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9617
+
9618
+ // If request was aborted inside a prefilter, stop there
9619
+ if ( state === 2 ) {
9620
+ return jqXHR;
9621
+ }
9622
+
9623
+ // We can fire global events as of now if asked to
9624
+ // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9625
+ fireGlobals = jQuery.event && s.global;
9626
+
9627
+ // Watch for a new set of requests
9628
+ if ( fireGlobals && jQuery.active++ === 0 ) {
9629
+ jQuery.event.trigger( "ajaxStart" );
9630
+ }
9631
+
9632
+ // Uppercase the type
9633
+ s.type = s.type.toUpperCase();
9634
+
9635
+ // Determine if request has content
9636
+ s.hasContent = !rnoContent.test( s.type );
9637
+
9638
+ // Save the URL in case we're toying with the If-Modified-Since
9639
+ // and/or If-None-Match header later on
9640
+ cacheURL = s.url;
9641
+
9642
+ // More options handling for requests with no content
9643
+ if ( !s.hasContent ) {
9644
+
9645
+ // If data is available, append data to url
9646
+ if ( s.data ) {
9647
+ cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
9648
+
9649
+ // #9682: remove data so that it's not used in an eventual retry
9650
+ delete s.data;
9651
+ }
9652
+
9653
+ // Add anti-cache in url if needed
9654
+ if ( s.cache === false ) {
9655
+ s.url = rts.test( cacheURL ) ?
9656
+
9657
+ // If there is already a '_' parameter, set its value
9658
+ cacheURL.replace( rts, "$1_=" + nonce++ ) :
9659
+
9660
+ // Otherwise add one to the end
9661
+ cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
9662
+ }
9663
+ }
9664
+
9665
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9666
+ if ( s.ifModified ) {
9667
+ if ( jQuery.lastModified[ cacheURL ] ) {
9668
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9669
+ }
9670
+ if ( jQuery.etag[ cacheURL ] ) {
9671
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9672
+ }
9673
+ }
9674
+
9675
+ // Set the correct header, if data is being sent
9676
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9677
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
9678
+ }
9679
+
9680
+ // Set the Accepts header for the server, depending on the dataType
9681
+ jqXHR.setRequestHeader(
9682
+ "Accept",
9683
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9684
+ s.accepts[ s.dataTypes[ 0 ] ] +
9685
+ ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9686
+ s.accepts[ "*" ]
9687
+ );
9688
+
9689
+ // Check for headers option
9690
+ for ( i in s.headers ) {
9691
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
9692
+ }
9693
+
9694
+ // Allow custom headers/mimetypes and early abort
9695
+ if ( s.beforeSend &&
9696
+ ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
9697
+
9698
+ // Abort if not done already and return
9699
+ return jqXHR.abort();
9700
+ }
9701
+
9702
+ // aborting is no longer a cancellation
9703
+ strAbort = "abort";
9704
+
9705
+ // Install callbacks on deferreds
9706
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
9707
+ jqXHR[ i ]( s[ i ] );
9708
+ }
9709
+
9710
+ // Get transport
9711
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9712
+
9713
+ // If no transport, we auto-abort
9714
+ if ( !transport ) {
9715
+ done( -1, "No Transport" );
9716
+ } else {
9717
+ jqXHR.readyState = 1;
9718
+
9719
+ // Send global event
9720
+ if ( fireGlobals ) {
9721
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9722
+ }
9723
+
9724
+ // If request was aborted inside ajaxSend, stop there
9725
+ if ( state === 2 ) {
9726
+ return jqXHR;
9727
+ }
9728
+
9729
+ // Timeout
9730
+ if ( s.async && s.timeout > 0 ) {
9731
+ timeoutTimer = window.setTimeout( function() {
9732
+ jqXHR.abort( "timeout" );
9733
+ }, s.timeout );
9734
+ }
9735
+
9736
+ try {
9737
+ state = 1;
9738
+ transport.send( requestHeaders, done );
9739
+ } catch ( e ) {
9740
+
9741
+ // Propagate exception as error if not done
9742
+ if ( state < 2 ) {
9743
+ done( -1, e );
9744
+
9745
+ // Simply rethrow otherwise
9746
+ } else {
9747
+ throw e;
9748
+ }
9749
+ }
9750
+ }
9751
+
9752
+ // Callback for when everything is done
9753
+ function done( status, nativeStatusText, responses, headers ) {
9754
+ var isSuccess, success, error, response, modified,
9755
+ statusText = nativeStatusText;
9756
+
9757
+ // Called once
9758
+ if ( state === 2 ) {
9759
+ return;
9760
+ }
9761
+
9762
+ // State is "done" now
9763
+ state = 2;
9764
+
9765
+ // Clear timeout if it exists
9766
+ if ( timeoutTimer ) {
9767
+ window.clearTimeout( timeoutTimer );
9768
+ }
9769
+
9770
+ // Dereference transport for early garbage collection
9771
+ // (no matter how long the jqXHR object will be used)
9772
+ transport = undefined;
9773
+
9774
+ // Cache response headers
9775
+ responseHeadersString = headers || "";
9776
+
9777
+ // Set readyState
9778
+ jqXHR.readyState = status > 0 ? 4 : 0;
9779
+
9780
+ // Determine if successful
9781
+ isSuccess = status >= 200 && status < 300 || status === 304;
9782
+
9783
+ // Get response data
9784
+ if ( responses ) {
9785
+ response = ajaxHandleResponses( s, jqXHR, responses );
9786
+ }
9787
+
9788
+ // Convert no matter what (that way responseXXX fields are always set)
9789
+ response = ajaxConvert( s, response, jqXHR, isSuccess );
9790
+
9791
+ // If successful, handle type chaining
9792
+ if ( isSuccess ) {
9793
+
9794
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9795
+ if ( s.ifModified ) {
9796
+ modified = jqXHR.getResponseHeader( "Last-Modified" );
9797
+ if ( modified ) {
9798
+ jQuery.lastModified[ cacheURL ] = modified;
9799
+ }
9800
+ modified = jqXHR.getResponseHeader( "etag" );
9801
+ if ( modified ) {
9802
+ jQuery.etag[ cacheURL ] = modified;
9803
+ }
9804
+ }
9805
+
9806
+ // if no content
9807
+ if ( status === 204 || s.type === "HEAD" ) {
9808
+ statusText = "nocontent";
9809
+
9810
+ // if not modified
9811
+ } else if ( status === 304 ) {
9812
+ statusText = "notmodified";
9813
+
9814
+ // If we have data, let's convert it
9815
+ } else {
9816
+ statusText = response.state;
9817
+ success = response.data;
9818
+ error = response.error;
9819
+ isSuccess = !error;
9820
+ }
9821
+ } else {
9822
+
9823
+ // We extract error from statusText
9824
+ // then normalize statusText and status for non-aborts
9825
+ error = statusText;
9826
+ if ( status || !statusText ) {
9827
+ statusText = "error";
9828
+ if ( status < 0 ) {
9829
+ status = 0;
9830
+ }
9831
+ }
9832
+ }
9833
+
9834
+ // Set data for the fake xhr object
9835
+ jqXHR.status = status;
9836
+ jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9837
+
9838
+ // Success/Error
9839
+ if ( isSuccess ) {
9840
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9841
+ } else {
9842
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9843
+ }
9844
+
9845
+ // Status-dependent callbacks
9846
+ jqXHR.statusCode( statusCode );
9847
+ statusCode = undefined;
9848
+
9849
+ if ( fireGlobals ) {
9850
+ globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9851
+ [ jqXHR, s, isSuccess ? success : error ] );
9852
+ }
9853
+
9854
+ // Complete
9855
+ completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9856
+
9857
+ if ( fireGlobals ) {
9858
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9859
+
9860
+ // Handle the global AJAX counter
9861
+ if ( !( --jQuery.active ) ) {
9862
+ jQuery.event.trigger( "ajaxStop" );
9863
+ }
9864
+ }
9865
+ }
9866
+
9867
+ return jqXHR;
9868
+ },
9869
+
9870
+ getJSON: function( url, data, callback ) {
9871
+ return jQuery.get( url, data, callback, "json" );
9872
+ },
9873
+
9874
+ getScript: function( url, callback ) {
9875
+ return jQuery.get( url, undefined, callback, "script" );
9876
+ }
9877
+ } );
9878
+
9879
+ jQuery.each( [ "get", "post" ], function( i, method ) {
9880
+ jQuery[ method ] = function( url, data, callback, type ) {
9881
+
9882
+ // shift arguments if data argument was omitted
9883
+ if ( jQuery.isFunction( data ) ) {
9884
+ type = type || callback;
9885
+ callback = data;
9886
+ data = undefined;
9887
+ }
9888
+
9889
+ // The url can be an options object (which then must have .url)
9890
+ return jQuery.ajax( jQuery.extend( {
9891
+ url: url,
9892
+ type: method,
9893
+ dataType: type,
9894
+ data: data,
9895
+ success: callback
9896
+ }, jQuery.isPlainObject( url ) && url ) );
9897
+ };
9898
+ } );
9899
+
9900
+
9901
+ jQuery._evalUrl = function( url ) {
9902
+ return jQuery.ajax( {
9903
+ url: url,
9904
+
9905
+ // Make this explicit, since user can override this through ajaxSetup (#11264)
9906
+ type: "GET",
9907
+ dataType: "script",
9908
+ cache: true,
9909
+ async: false,
9910
+ global: false,
9911
+ "throws": true
9912
+ } );
9913
+ };
9914
+
9915
+
9916
+ jQuery.fn.extend( {
9917
+ wrapAll: function( html ) {
9918
+ if ( jQuery.isFunction( html ) ) {
9919
+ return this.each( function( i ) {
9920
+ jQuery( this ).wrapAll( html.call( this, i ) );
9921
+ } );
9922
+ }
9923
+
9924
+ if ( this[ 0 ] ) {
9925
+
9926
+ // The elements to wrap the target around
9927
+ var wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9928
+
9929
+ if ( this[ 0 ].parentNode ) {
9930
+ wrap.insertBefore( this[ 0 ] );
9931
+ }
9932
+
9933
+ wrap.map( function() {
9934
+ var elem = this;
9935
+
9936
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
9937
+ elem = elem.firstChild;
9938
+ }
9939
+
9940
+ return elem;
9941
+ } ).append( this );
9942
+ }
9943
+
9944
+ return this;
9945
+ },
9946
+
9947
+ wrapInner: function( html ) {
9948
+ if ( jQuery.isFunction( html ) ) {
9949
+ return this.each( function( i ) {
9950
+ jQuery( this ).wrapInner( html.call( this, i ) );
9951
+ } );
9952
+ }
9953
+
9954
+ return this.each( function() {
9955
+ var self = jQuery( this ),
9956
+ contents = self.contents();
9957
+
9958
+ if ( contents.length ) {
9959
+ contents.wrapAll( html );
9960
+
9961
+ } else {
9962
+ self.append( html );
9963
+ }
9964
+ } );
9965
+ },
9966
+
9967
+ wrap: function( html ) {
9968
+ var isFunction = jQuery.isFunction( html );
9969
+
9970
+ return this.each( function( i ) {
9971
+ jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
9972
+ } );
9973
+ },
9974
+
9975
+ unwrap: function() {
9976
+ return this.parent().each( function() {
9977
+ if ( !jQuery.nodeName( this, "body" ) ) {
9978
+ jQuery( this ).replaceWith( this.childNodes );
9979
+ }
9980
+ } ).end();
9981
+ }
9982
+ } );
9983
+
9984
+
9985
+ function getDisplay( elem ) {
9986
+ return elem.style && elem.style.display || jQuery.css( elem, "display" );
9987
+ }
9988
+
9989
+ function filterHidden( elem ) {
9990
+
9991
+ // Disconnected elements are considered hidden
9992
+ if ( !jQuery.contains( elem.ownerDocument || document, elem ) ) {
9993
+ return true;
9994
+ }
9995
+ while ( elem && elem.nodeType === 1 ) {
9996
+ if ( getDisplay( elem ) === "none" || elem.type === "hidden" ) {
9997
+ return true;
9998
+ }
9999
+ elem = elem.parentNode;
10000
+ }
10001
+ return false;
10002
+ }
10003
+
10004
+ jQuery.expr.filters.hidden = function( elem ) {
10005
+
10006
+ // Support: Opera <= 12.12
10007
+ // Opera reports offsetWidths and offsetHeights less than zero on some elements
10008
+ return support.reliableHiddenOffsets() ?
10009
+ ( elem.offsetWidth <= 0 && elem.offsetHeight <= 0 &&
10010
+ !elem.getClientRects().length ) :
10011
+ filterHidden( elem );
10012
+ };
10013
+
10014
+ jQuery.expr.filters.visible = function( elem ) {
10015
+ return !jQuery.expr.filters.hidden( elem );
10016
+ };
10017
+
10018
+
10019
+
10020
+
10021
+ var r20 = /%20/g,
10022
+ rbracket = /\[\]$/,
10023
+ rCRLF = /\r?\n/g,
10024
+ rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
10025
+ rsubmittable = /^(?:input|select|textarea|keygen)/i;
10026
+
10027
+ function buildParams( prefix, obj, traditional, add ) {
10028
+ var name;
10029
+
10030
+ if ( jQuery.isArray( obj ) ) {
10031
+
10032
+ // Serialize array item.
10033
+ jQuery.each( obj, function( i, v ) {
10034
+ if ( traditional || rbracket.test( prefix ) ) {
10035
+
10036
+ // Treat each array item as a scalar.
10037
+ add( prefix, v );
10038
+
10039
+ } else {
10040
+
10041
+ // Item is non-scalar (array or object), encode its numeric index.
10042
+ buildParams(
10043
+ prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
10044
+ v,
10045
+ traditional,
10046
+ add
10047
+ );
10048
+ }
10049
+ } );
10050
+
10051
+ } else if ( !traditional && jQuery.type( obj ) === "object" ) {
10052
+
10053
+ // Serialize object item.
10054
+ for ( name in obj ) {
10055
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
10056
+ }
10057
+
10058
+ } else {
10059
+
10060
+ // Serialize scalar item.
10061
+ add( prefix, obj );
10062
+ }
10063
+ }
10064
+
10065
+ // Serialize an array of form elements or a set of
10066
+ // key/values into a query string
10067
+ jQuery.param = function( a, traditional ) {
10068
+ var prefix,
10069
+ s = [],
10070
+ add = function( key, value ) {
10071
+
10072
+ // If value is a function, invoke it and return its value
10073
+ value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
10074
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
10075
+ };
10076
+
10077
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
10078
+ if ( traditional === undefined ) {
10079
+ traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
10080
+ }
10081
+
10082
+ // If an array was passed in, assume that it is an array of form elements.
10083
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
10084
+
10085
+ // Serialize the form elements
10086
+ jQuery.each( a, function() {
10087
+ add( this.name, this.value );
10088
+ } );
10089
+
10090
+ } else {
10091
+
10092
+ // If traditional, encode the "old" way (the way 1.3.2 or older
10093
+ // did it), otherwise encode params recursively.
10094
+ for ( prefix in a ) {
10095
+ buildParams( prefix, a[ prefix ], traditional, add );
10096
+ }
10097
+ }
10098
+
10099
+ // Return the resulting serialization
10100
+ return s.join( "&" ).replace( r20, "+" );
10101
+ };
10102
+
10103
+ jQuery.fn.extend( {
10104
+ serialize: function() {
10105
+ return jQuery.param( this.serializeArray() );
10106
+ },
10107
+ serializeArray: function() {
10108
+ return this.map( function() {
10109
+
10110
+ // Can add propHook for "elements" to filter or add form elements
10111
+ var elements = jQuery.prop( this, "elements" );
10112
+ return elements ? jQuery.makeArray( elements ) : this;
10113
+ } )
10114
+ .filter( function() {
10115
+ var type = this.type;
10116
+
10117
+ // Use .is(":disabled") so that fieldset[disabled] works
10118
+ return this.name && !jQuery( this ).is( ":disabled" ) &&
10119
+ rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
10120
+ ( this.checked || !rcheckableType.test( type ) );
10121
+ } )
10122
+ .map( function( i, elem ) {
10123
+ var val = jQuery( this ).val();
10124
+
10125
+ return val == null ?
10126
+ null :
10127
+ jQuery.isArray( val ) ?
10128
+ jQuery.map( val, function( val ) {
10129
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10130
+ } ) :
10131
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10132
+ } ).get();
10133
+ }
10134
+ } );
10135
+
10136
+
10137
+ // Create the request object
10138
+ // (This is still attached to ajaxSettings for backward compatibility)
10139
+ jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
10140
+
10141
+ // Support: IE6-IE8
10142
+ function() {
10143
+
10144
+ // XHR cannot access local files, always use ActiveX for that case
10145
+ if ( this.isLocal ) {
10146
+ return createActiveXHR();
10147
+ }
10148
+
10149
+ // Support: IE 9-11
10150
+ // IE seems to error on cross-domain PATCH requests when ActiveX XHR
10151
+ // is used. In IE 9+ always use the native XHR.
10152
+ // Note: this condition won't catch Edge as it doesn't define
10153
+ // document.documentMode but it also doesn't support ActiveX so it won't
10154
+ // reach this code.
10155
+ if ( document.documentMode > 8 ) {
10156
+ return createStandardXHR();
10157
+ }
10158
+
10159
+ // Support: IE<9
10160
+ // oldIE XHR does not support non-RFC2616 methods (#13240)
10161
+ // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
10162
+ // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
10163
+ // Although this check for six methods instead of eight
10164
+ // since IE also does not support "trace" and "connect"
10165
+ return /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
10166
+ createStandardXHR() || createActiveXHR();
10167
+ } :
10168
+
10169
+ // For all other browsers, use the standard XMLHttpRequest object
10170
+ createStandardXHR;
10171
+
10172
+ var xhrId = 0,
10173
+ xhrCallbacks = {},
10174
+ xhrSupported = jQuery.ajaxSettings.xhr();
10175
+
10176
+ // Support: IE<10
10177
+ // Open requests must be manually aborted on unload (#5280)
10178
+ // See https://support.microsoft.com/kb/2856746 for more info
10179
+ if ( window.attachEvent ) {
10180
+ window.attachEvent( "onunload", function() {
10181
+ for ( var key in xhrCallbacks ) {
10182
+ xhrCallbacks[ key ]( undefined, true );
10183
+ }
10184
+ } );
10185
+ }
10186
+
10187
+ // Determine support properties
10188
+ support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
10189
+ xhrSupported = support.ajax = !!xhrSupported;
10190
+
10191
+ // Create transport if the browser can provide an xhr
10192
+ if ( xhrSupported ) {
10193
+
10194
+ jQuery.ajaxTransport( function( options ) {
10195
+
10196
+ // Cross domain only allowed if supported through XMLHttpRequest
10197
+ if ( !options.crossDomain || support.cors ) {
10198
+
10199
+ var callback;
10200
+
10201
+ return {
10202
+ send: function( headers, complete ) {
10203
+ var i,
10204
+ xhr = options.xhr(),
10205
+ id = ++xhrId;
10206
+
10207
+ // Open the socket
10208
+ xhr.open(
10209
+ options.type,
10210
+ options.url,
10211
+ options.async,
10212
+ options.username,
10213
+ options.password
10214
+ );
10215
+
10216
+ // Apply custom fields if provided
10217
+ if ( options.xhrFields ) {
10218
+ for ( i in options.xhrFields ) {
10219
+ xhr[ i ] = options.xhrFields[ i ];
10220
+ }
10221
+ }
10222
+
10223
+ // Override mime type if needed
10224
+ if ( options.mimeType && xhr.overrideMimeType ) {
10225
+ xhr.overrideMimeType( options.mimeType );
10226
+ }
10227
+
10228
+ // X-Requested-With header
10229
+ // For cross-domain requests, seeing as conditions for a preflight are
10230
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
10231
+ // (it can always be set on a per-request basis or even using ajaxSetup)
10232
+ // For same-domain requests, won't change header if already provided.
10233
+ if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
10234
+ headers[ "X-Requested-With" ] = "XMLHttpRequest";
10235
+ }
10236
+
10237
+ // Set headers
10238
+ for ( i in headers ) {
10239
+
10240
+ // Support: IE<9
10241
+ // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
10242
+ // request header to a null-value.
10243
+ //
10244
+ // To keep consistent with other XHR implementations, cast the value
10245
+ // to string and ignore `undefined`.
10246
+ if ( headers[ i ] !== undefined ) {
10247
+ xhr.setRequestHeader( i, headers[ i ] + "" );
10248
+ }
10249
+ }
10250
+
10251
+ // Do send the request
10252
+ // This may raise an exception which is actually
10253
+ // handled in jQuery.ajax (so no try/catch here)
10254
+ xhr.send( ( options.hasContent && options.data ) || null );
10255
+
10256
+ // Listener
10257
+ callback = function( _, isAbort ) {
10258
+ var status, statusText, responses;
10259
+
10260
+ // Was never called and is aborted or complete
10261
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
10262
+
10263
+ // Clean up
10264
+ delete xhrCallbacks[ id ];
10265
+ callback = undefined;
10266
+ xhr.onreadystatechange = jQuery.noop;
10267
+
10268
+ // Abort manually if needed
10269
+ if ( isAbort ) {
10270
+ if ( xhr.readyState !== 4 ) {
10271
+ xhr.abort();
10272
+ }
10273
+ } else {
10274
+ responses = {};
10275
+ status = xhr.status;
10276
+
10277
+ // Support: IE<10
10278
+ // Accessing binary-data responseText throws an exception
10279
+ // (#11426)
10280
+ if ( typeof xhr.responseText === "string" ) {
10281
+ responses.text = xhr.responseText;
10282
+ }
10283
+
10284
+ // Firefox throws an exception when accessing
10285
+ // statusText for faulty cross-domain requests
10286
+ try {
10287
+ statusText = xhr.statusText;
10288
+ } catch ( e ) {
10289
+
10290
+ // We normalize with Webkit giving an empty statusText
10291
+ statusText = "";
10292
+ }
10293
+
10294
+ // Filter status for non standard behaviors
10295
+
10296
+ // If the request is local and we have data: assume a success
10297
+ // (success with no data won't get notified, that's the best we
10298
+ // can do given current implementations)
10299
+ if ( !status && options.isLocal && !options.crossDomain ) {
10300
+ status = responses.text ? 200 : 404;
10301
+
10302
+ // IE - #1450: sometimes returns 1223 when it should be 204
10303
+ } else if ( status === 1223 ) {
10304
+ status = 204;
10305
+ }
10306
+ }
10307
+ }
10308
+
10309
+ // Call complete if needed
10310
+ if ( responses ) {
10311
+ complete( status, statusText, responses, xhr.getAllResponseHeaders() );
10312
+ }
10313
+ };
10314
+
10315
+ // Do send the request
10316
+ // `xhr.send` may raise an exception, but it will be
10317
+ // handled in jQuery.ajax (so no try/catch here)
10318
+ if ( !options.async ) {
10319
+
10320
+ // If we're in sync mode we fire the callback
10321
+ callback();
10322
+ } else if ( xhr.readyState === 4 ) {
10323
+
10324
+ // (IE6 & IE7) if it's in cache and has been
10325
+ // retrieved directly we need to fire the callback
10326
+ window.setTimeout( callback );
10327
+ } else {
10328
+
10329
+ // Register the callback, but delay it in case `xhr.send` throws
10330
+ // Add to the list of active xhr callbacks
10331
+ xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
10332
+ }
10333
+ },
10334
+
10335
+ abort: function() {
10336
+ if ( callback ) {
10337
+ callback( undefined, true );
10338
+ }
10339
+ }
10340
+ };
10341
+ }
10342
+ } );
10343
+ }
10344
+
10345
+ // Functions to create xhrs
10346
+ function createStandardXHR() {
10347
+ try {
10348
+ return new window.XMLHttpRequest();
10349
+ } catch ( e ) {}
10350
+ }
10351
+
10352
+ function createActiveXHR() {
10353
+ try {
10354
+ return new window.ActiveXObject( "Microsoft.XMLHTTP" );
10355
+ } catch ( e ) {}
10356
+ }
10357
+
10358
+
10359
+
10360
+
10361
+ // Install script dataType
10362
+ jQuery.ajaxSetup( {
10363
+ accepts: {
10364
+ script: "text/javascript, application/javascript, " +
10365
+ "application/ecmascript, application/x-ecmascript"
10366
+ },
10367
+ contents: {
10368
+ script: /\b(?:java|ecma)script\b/
10369
+ },
10370
+ converters: {
10371
+ "text script": function( text ) {
10372
+ jQuery.globalEval( text );
10373
+ return text;
10374
+ }
10375
+ }
10376
+ } );
10377
+
10378
+ // Handle cache's special case and global
10379
+ jQuery.ajaxPrefilter( "script", function( s ) {
10380
+ if ( s.cache === undefined ) {
10381
+ s.cache = false;
10382
+ }
10383
+ if ( s.crossDomain ) {
10384
+ s.type = "GET";
10385
+ s.global = false;
10386
+ }
10387
+ } );
10388
+
10389
+ // Bind script tag hack transport
10390
+ jQuery.ajaxTransport( "script", function( s ) {
10391
+
10392
+ // This transport only deals with cross domain requests
10393
+ if ( s.crossDomain ) {
10394
+
10395
+ var script,
10396
+ head = document.head || jQuery( "head" )[ 0 ] || document.documentElement;
10397
+
10398
+ return {
10399
+
10400
+ send: function( _, callback ) {
10401
+
10402
+ script = document.createElement( "script" );
10403
+
10404
+ script.async = true;
10405
+
10406
+ if ( s.scriptCharset ) {
10407
+ script.charset = s.scriptCharset;
10408
+ }
10409
+
10410
+ script.src = s.url;
10411
+
10412
+ // Attach handlers for all browsers
10413
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
10414
+
10415
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
10416
+
10417
+ // Handle memory leak in IE
10418
+ script.onload = script.onreadystatechange = null;
10419
+
10420
+ // Remove the script
10421
+ if ( script.parentNode ) {
10422
+ script.parentNode.removeChild( script );
10423
+ }
10424
+
10425
+ // Dereference the script
10426
+ script = null;
10427
+
10428
+ // Callback if not abort
10429
+ if ( !isAbort ) {
10430
+ callback( 200, "success" );
10431
+ }
10432
+ }
10433
+ };
10434
+
10435
+ // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
10436
+ // Use native DOM manipulation to avoid our domManip AJAX trickery
10437
+ head.insertBefore( script, head.firstChild );
10438
+ },
10439
+
10440
+ abort: function() {
10441
+ if ( script ) {
10442
+ script.onload( undefined, true );
10443
+ }
10444
+ }
10445
+ };
10446
+ }
10447
+ } );
10448
+
10449
+
10450
+
10451
+
10452
+ var oldCallbacks = [],
10453
+ rjsonp = /(=)\?(?=&|$)|\?\?/;
10454
+
10455
+ // Default jsonp settings
10456
+ jQuery.ajaxSetup( {
10457
+ jsonp: "callback",
10458
+ jsonpCallback: function() {
10459
+ var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
10460
+ this[ callback ] = true;
10461
+ return callback;
10462
+ }
10463
+ } );
10464
+
10465
+ // Detect, normalize options and install callbacks for jsonp requests
10466
+ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
10467
+
10468
+ var callbackName, overwritten, responseContainer,
10469
+ jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
10470
+ "url" :
10471
+ typeof s.data === "string" &&
10472
+ ( s.contentType || "" )
10473
+ .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
10474
+ rjsonp.test( s.data ) && "data"
10475
+ );
10476
+
10477
+ // Handle iff the expected data type is "jsonp" or we have a parameter to set
10478
+ if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
10479
+
10480
+ // Get callback name, remembering preexisting value associated with it
10481
+ callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
10482
+ s.jsonpCallback() :
10483
+ s.jsonpCallback;
10484
+
10485
+ // Insert callback into url or form data
10486
+ if ( jsonProp ) {
10487
+ s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
10488
+ } else if ( s.jsonp !== false ) {
10489
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
10490
+ }
10491
+
10492
+ // Use data converter to retrieve json after script execution
10493
+ s.converters[ "script json" ] = function() {
10494
+ if ( !responseContainer ) {
10495
+ jQuery.error( callbackName + " was not called" );
10496
+ }
10497
+ return responseContainer[ 0 ];
10498
+ };
10499
+
10500
+ // force json dataType
10501
+ s.dataTypes[ 0 ] = "json";
10502
+
10503
+ // Install callback
10504
+ overwritten = window[ callbackName ];
10505
+ window[ callbackName ] = function() {
10506
+ responseContainer = arguments;
10507
+ };
10508
+
10509
+ // Clean-up function (fires after converters)
10510
+ jqXHR.always( function() {
10511
+
10512
+ // If previous value didn't exist - remove it
10513
+ if ( overwritten === undefined ) {
10514
+ jQuery( window ).removeProp( callbackName );
10515
+
10516
+ // Otherwise restore preexisting value
10517
+ } else {
10518
+ window[ callbackName ] = overwritten;
10519
+ }
10520
+
10521
+ // Save back as free
10522
+ if ( s[ callbackName ] ) {
10523
+
10524
+ // make sure that re-using the options doesn't screw things around
10525
+ s.jsonpCallback = originalSettings.jsonpCallback;
10526
+
10527
+ // save the callback name for future use
10528
+ oldCallbacks.push( callbackName );
10529
+ }
10530
+
10531
+ // Call if it was a function and we have a response
10532
+ if ( responseContainer && jQuery.isFunction( overwritten ) ) {
10533
+ overwritten( responseContainer[ 0 ] );
10534
+ }
10535
+
10536
+ responseContainer = overwritten = undefined;
10537
+ } );
10538
+
10539
+ // Delegate to script
10540
+ return "script";
10541
+ }
10542
+ } );
10543
+
10544
+
10545
+
10546
+
10547
+ // data: string of html
10548
+ // context (optional): If specified, the fragment will be created in this context,
10549
+ // defaults to document
10550
+ // keepScripts (optional): If true, will include scripts passed in the html string
10551
+ jQuery.parseHTML = function( data, context, keepScripts ) {
10552
+ if ( !data || typeof data !== "string" ) {
10553
+ return null;
10554
+ }
10555
+ if ( typeof context === "boolean" ) {
10556
+ keepScripts = context;
10557
+ context = false;
10558
+ }
10559
+ context = context || document;
10560
+
10561
+ var parsed = rsingleTag.exec( data ),
10562
+ scripts = !keepScripts && [];
10563
+
10564
+ // Single tag
10565
+ if ( parsed ) {
10566
+ return [ context.createElement( parsed[ 1 ] ) ];
10567
+ }
10568
+
10569
+ parsed = buildFragment( [ data ], context, scripts );
10570
+
10571
+ if ( scripts && scripts.length ) {
10572
+ jQuery( scripts ).remove();
10573
+ }
10574
+
10575
+ return jQuery.merge( [], parsed.childNodes );
10576
+ };
10577
+
10578
+
10579
+ // Keep a copy of the old load method
10580
+ var _load = jQuery.fn.load;
10581
+
10582
+ /**
10583
+ * Load a url into a page
10584
+ */
10585
+ jQuery.fn.load = function( url, params, callback ) {
10586
+ if ( typeof url !== "string" && _load ) {
10587
+ return _load.apply( this, arguments );
10588
+ }
10589
+
10590
+ var selector, type, response,
10591
+ self = this,
10592
+ off = url.indexOf( " " );
10593
+
10594
+ if ( off > -1 ) {
10595
+ selector = jQuery.trim( url.slice( off, url.length ) );
10596
+ url = url.slice( 0, off );
10597
+ }
10598
+
10599
+ // If it's a function
10600
+ if ( jQuery.isFunction( params ) ) {
10601
+
10602
+ // We assume that it's the callback
10603
+ callback = params;
10604
+ params = undefined;
10605
+
10606
+ // Otherwise, build a param string
10607
+ } else if ( params && typeof params === "object" ) {
10608
+ type = "POST";
10609
+ }
10610
+
10611
+ // If we have elements to modify, make the request
10612
+ if ( self.length > 0 ) {
10613
+ jQuery.ajax( {
10614
+ url: url,
10615
+
10616
+ // If "type" variable is undefined, then "GET" method will be used.
10617
+ // Make value of this field explicit since
10618
+ // user can override it through ajaxSetup method
10619
+ type: type || "GET",
10620
+ dataType: "html",
10621
+ data: params
10622
+ } ).done( function( responseText ) {
10623
+
10624
+ // Save response for use in complete callback
10625
+ response = arguments;
10626
+
10627
+ self.html( selector ?
10628
+
10629
+ // If a selector was specified, locate the right elements in a dummy div
10630
+ // Exclude scripts to avoid IE 'Permission Denied' errors
10631
+ jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
10632
+
10633
+ // Otherwise use the full result
10634
+ responseText );
10635
+
10636
+ // If the request succeeds, this function gets "data", "status", "jqXHR"
10637
+ // but they are ignored because response was set above.
10638
+ // If it fails, this function gets "jqXHR", "status", "error"
10639
+ } ).always( callback && function( jqXHR, status ) {
10640
+ self.each( function() {
10641
+ callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
10642
+ } );
10643
+ } );
10644
+ }
10645
+
10646
+ return this;
10647
+ };
10648
+
10649
+
10650
+
10651
+
10652
+ // Attach a bunch of functions for handling common AJAX events
10653
+ jQuery.each( [
10654
+ "ajaxStart",
10655
+ "ajaxStop",
10656
+ "ajaxComplete",
10657
+ "ajaxError",
10658
+ "ajaxSuccess",
10659
+ "ajaxSend"
10660
+ ], function( i, type ) {
10661
+ jQuery.fn[ type ] = function( fn ) {
10662
+ return this.on( type, fn );
10663
+ };
10664
+ } );
10665
+
10666
+
10667
+
10668
+
10669
+ jQuery.expr.filters.animated = function( elem ) {
10670
+ return jQuery.grep( jQuery.timers, function( fn ) {
10671
+ return elem === fn.elem;
10672
+ } ).length;
10673
+ };
10674
+
10675
+
10676
+
10677
+
10678
+
10679
+ /**
10680
+ * Gets a window from an element
10681
+ */
10682
+ function getWindow( elem ) {
10683
+ return jQuery.isWindow( elem ) ?
10684
+ elem :
10685
+ elem.nodeType === 9 ?
10686
+ elem.defaultView || elem.parentWindow :
10687
+ false;
10688
+ }
10689
+
10690
+ jQuery.offset = {
10691
+ setOffset: function( elem, options, i ) {
10692
+ var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10693
+ position = jQuery.css( elem, "position" ),
10694
+ curElem = jQuery( elem ),
10695
+ props = {};
10696
+
10697
+ // set position first, in-case top/left are set even on static elem
10698
+ if ( position === "static" ) {
10699
+ elem.style.position = "relative";
10700
+ }
10701
+
10702
+ curOffset = curElem.offset();
10703
+ curCSSTop = jQuery.css( elem, "top" );
10704
+ curCSSLeft = jQuery.css( elem, "left" );
10705
+ calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10706
+ jQuery.inArray( "auto", [ curCSSTop, curCSSLeft ] ) > -1;
10707
+
10708
+ // need to be able to calculate position if either top or left
10709
+ // is auto and position is either absolute or fixed
10710
+ if ( calculatePosition ) {
10711
+ curPosition = curElem.position();
10712
+ curTop = curPosition.top;
10713
+ curLeft = curPosition.left;
10714
+ } else {
10715
+ curTop = parseFloat( curCSSTop ) || 0;
10716
+ curLeft = parseFloat( curCSSLeft ) || 0;
10717
+ }
10718
+
10719
+ if ( jQuery.isFunction( options ) ) {
10720
+
10721
+ // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10722
+ options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
10723
+ }
10724
+
10725
+ if ( options.top != null ) {
10726
+ props.top = ( options.top - curOffset.top ) + curTop;
10727
+ }
10728
+ if ( options.left != null ) {
10729
+ props.left = ( options.left - curOffset.left ) + curLeft;
10730
+ }
10731
+
10732
+ if ( "using" in options ) {
10733
+ options.using.call( elem, props );
10734
+ } else {
10735
+ curElem.css( props );
10736
+ }
10737
+ }
10738
+ };
10739
+
10740
+ jQuery.fn.extend( {
10741
+ offset: function( options ) {
10742
+ if ( arguments.length ) {
10743
+ return options === undefined ?
10744
+ this :
10745
+ this.each( function( i ) {
10746
+ jQuery.offset.setOffset( this, options, i );
10747
+ } );
10748
+ }
10749
+
10750
+ var docElem, win,
10751
+ box = { top: 0, left: 0 },
10752
+ elem = this[ 0 ],
10753
+ doc = elem && elem.ownerDocument;
10754
+
10755
+ if ( !doc ) {
10756
+ return;
10757
+ }
10758
+
10759
+ docElem = doc.documentElement;
10760
+
10761
+ // Make sure it's not a disconnected DOM node
10762
+ if ( !jQuery.contains( docElem, elem ) ) {
10763
+ return box;
10764
+ }
10765
+
10766
+ // If we don't have gBCR, just use 0,0 rather than error
10767
+ // BlackBerry 5, iOS 3 (original iPhone)
10768
+ if ( typeof elem.getBoundingClientRect !== "undefined" ) {
10769
+ box = elem.getBoundingClientRect();
10770
+ }
10771
+ win = getWindow( doc );
10772
+ return {
10773
+ top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
10774
+ left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
10775
+ };
10776
+ },
10777
+
10778
+ position: function() {
10779
+ if ( !this[ 0 ] ) {
10780
+ return;
10781
+ }
10782
+
10783
+ var offsetParent, offset,
10784
+ parentOffset = { top: 0, left: 0 },
10785
+ elem = this[ 0 ];
10786
+
10787
+ // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
10788
+ // because it is its only offset parent
10789
+ if ( jQuery.css( elem, "position" ) === "fixed" ) {
10790
+
10791
+ // we assume that getBoundingClientRect is available when computed position is fixed
10792
+ offset = elem.getBoundingClientRect();
10793
+ } else {
10794
+
10795
+ // Get *real* offsetParent
10796
+ offsetParent = this.offsetParent();
10797
+
10798
+ // Get correct offsets
10799
+ offset = this.offset();
10800
+ if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
10801
+ parentOffset = offsetParent.offset();
10802
+ }
10803
+
10804
+ // Add offsetParent borders
10805
+ parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
10806
+ parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
10807
+ }
10808
+
10809
+ // Subtract parent offsets and element margins
10810
+ // note: when an element has margin: auto the offsetLeft and marginLeft
10811
+ // are the same in Safari causing offset.left to incorrectly be 0
10812
+ return {
10813
+ top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10814
+ left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10815
+ };
10816
+ },
10817
+
10818
+ offsetParent: function() {
10819
+ return this.map( function() {
10820
+ var offsetParent = this.offsetParent;
10821
+
10822
+ while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) &&
10823
+ jQuery.css( offsetParent, "position" ) === "static" ) ) {
10824
+ offsetParent = offsetParent.offsetParent;
10825
+ }
10826
+ return offsetParent || documentElement;
10827
+ } );
10828
+ }
10829
+ } );
10830
+
10831
+ // Create scrollLeft and scrollTop methods
10832
+ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10833
+ var top = /Y/.test( prop );
10834
+
10835
+ jQuery.fn[ method ] = function( val ) {
10836
+ return access( this, function( elem, method, val ) {
10837
+ var win = getWindow( elem );
10838
+
10839
+ if ( val === undefined ) {
10840
+ return win ? ( prop in win ) ? win[ prop ] :
10841
+ win.document.documentElement[ method ] :
10842
+ elem[ method ];
10843
+ }
10844
+
10845
+ if ( win ) {
10846
+ win.scrollTo(
10847
+ !top ? val : jQuery( win ).scrollLeft(),
10848
+ top ? val : jQuery( win ).scrollTop()
10849
+ );
10850
+
10851
+ } else {
10852
+ elem[ method ] = val;
10853
+ }
10854
+ }, method, val, arguments.length, null );
10855
+ };
10856
+ } );
10857
+
10858
+ // Support: Safari<7-8+, Chrome<37-44+
10859
+ // Add the top/left cssHooks using jQuery.fn.position
10860
+ // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10861
+ // getComputedStyle returns percent when specified for top/left/bottom/right
10862
+ // rather than make the css module depend on the offset module, we just check for it here
10863
+ jQuery.each( [ "top", "left" ], function( i, prop ) {
10864
+ jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10865
+ function( elem, computed ) {
10866
+ if ( computed ) {
10867
+ computed = curCSS( elem, prop );
10868
+
10869
+ // if curCSS returns percentage, fallback to offset
10870
+ return rnumnonpx.test( computed ) ?
10871
+ jQuery( elem ).position()[ prop ] + "px" :
10872
+ computed;
10873
+ }
10874
+ }
10875
+ );
10876
+ } );
10877
+
10878
+
10879
+ // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10880
+ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10881
+ jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
10882
+ function( defaultExtra, funcName ) {
10883
+
10884
+ // margin is only for outerHeight, outerWidth
10885
+ jQuery.fn[ funcName ] = function( margin, value ) {
10886
+ var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10887
+ extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10888
+
10889
+ return access( this, function( elem, type, value ) {
10890
+ var doc;
10891
+
10892
+ if ( jQuery.isWindow( elem ) ) {
10893
+
10894
+ // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
10895
+ // isn't a whole lot we can do. See pull request at this URL for discussion:
10896
+ // https://github.com/jquery/jquery/pull/764
10897
+ return elem.document.documentElement[ "client" + name ];
10898
+ }
10899
+
10900
+ // Get document width or height
10901
+ if ( elem.nodeType === 9 ) {
10902
+ doc = elem.documentElement;
10903
+
10904
+ // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10905
+ // whichever is greatest
10906
+ // unfortunately, this causes bug #3838 in IE6/8 only,
10907
+ // but there is currently no good, small way to fix it.
10908
+ return Math.max(
10909
+ elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10910
+ elem.body[ "offset" + name ], doc[ "offset" + name ],
10911
+ doc[ "client" + name ]
10912
+ );
10913
+ }
10914
+
10915
+ return value === undefined ?
10916
+
10917
+ // Get width or height on the element, requesting but not forcing parseFloat
10918
+ jQuery.css( elem, type, extra ) :
10919
+
10920
+ // Set width or height on the element
10921
+ jQuery.style( elem, type, value, extra );
10922
+ }, type, chainable ? margin : undefined, chainable, null );
10923
+ };
10924
+ } );
10925
+ } );
10926
+
10927
+
10928
+ jQuery.fn.extend( {
10929
+
10930
+ bind: function( types, data, fn ) {
10931
+ return this.on( types, null, data, fn );
10932
+ },
10933
+ unbind: function( types, fn ) {
10934
+ return this.off( types, null, fn );
10935
+ },
10936
+
10937
+ delegate: function( selector, types, data, fn ) {
10938
+ return this.on( types, selector, data, fn );
10939
+ },
10940
+ undelegate: function( selector, types, fn ) {
10941
+
10942
+ // ( namespace ) or ( selector, types [, fn] )
10943
+ return arguments.length === 1 ?
10944
+ this.off( selector, "**" ) :
10945
+ this.off( types, selector || "**", fn );
10946
+ }
10947
+ } );
10948
+
10949
+ // The number of elements contained in the matched element set
10950
+ jQuery.fn.size = function() {
10951
+ return this.length;
10952
+ };
10953
+
10954
+ jQuery.fn.andSelf = jQuery.fn.addBack;
10955
+
10956
+
10957
+
10958
+
10959
+ // Register as a named AMD module, since jQuery can be concatenated with other
10960
+ // files that may use define, but not via a proper concatenation script that
10961
+ // understands anonymous AMD modules. A named AMD is safest and most robust
10962
+ // way to register. Lowercase jquery is used because AMD module names are
10963
+ // derived from file names, and jQuery is normally delivered in a lowercase
10964
+ // file name. Do this after creating the global so that if an AMD module wants
10965
+ // to call noConflict to hide this version of jQuery, it will work.
10966
+
10967
+ // Note that for maximum portability, libraries that are not jQuery should
10968
+ // declare themselves as anonymous modules, and avoid setting a global if an
10969
+ // AMD loader is present. jQuery is a special case. For more information, see
10970
+ // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10971
+
10972
+ if ( typeof define === "function" && define.amd ) {
10973
+ define( "jquery", [], function() {
10974
+ return jQuery;
10975
+ } );
10976
+ }
10977
+
10978
+
10979
+
10980
+ var
10981
+
10982
+ // Map over jQuery in case of overwrite
10983
+ _jQuery = window.jQuery,
10984
+
10985
+ // Map over the $ in case of overwrite
10986
+ _$ = window.$;
10987
+
10988
+ jQuery.noConflict = function( deep ) {
10989
+ if ( window.$ === jQuery ) {
10990
+ window.$ = _$;
10991
+ }
10992
+
10993
+ if ( deep && window.jQuery === jQuery ) {
10994
+ window.jQuery = _jQuery;
10995
+ }
10996
+
10997
+ return jQuery;
10998
+ };
10999
+
11000
+ // Expose jQuery and $ identifiers, even in
11001
+ // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
11002
+ // and CommonJS for browser emulators (#13566)
11003
+ if ( !noGlobal ) {
11004
+ window.jQuery = window.$ = jQuery;
11005
+ }
11006
+
11007
+ return jQuery;
11008
+ }));
admin/js/jquery-ui.js ADDED
@@ -0,0 +1,18706 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! jQuery UI - v1.12.1 - 2016-09-14
2
+ * http://jqueryui.com
3
+ * Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js
4
+ * Copyright jQuery Foundation and other contributors; Licensed MIT */
5
+
6
+ (function( factory ) {
7
+ if ( typeof define === "function" && define.amd ) {
8
+
9
+ // AMD. Register as an anonymous module.
10
+ define([ "jquery" ], factory );
11
+ } else {
12
+
13
+ // Browser globals
14
+ factory( jQuery );
15
+ }
16
+ }(function( $ ) {
17
+
18
+ $.ui = $.ui || {};
19
+
20
+ var version = $.ui.version = "1.12.1";
21
+
22
+
23
+ /*!
24
+ * jQuery UI Widget 1.12.1
25
+ * http://jqueryui.com
26
+ *
27
+ * Copyright jQuery Foundation and other contributors
28
+ * Released under the MIT license.
29
+ * http://jquery.org/license
30
+ */
31
+
32
+ //>>label: Widget
33
+ //>>group: Core
34
+ //>>description: Provides a factory for creating stateful widgets with a common API.
35
+ //>>docs: http://api.jqueryui.com/jQuery.widget/
36
+ //>>demos: http://jqueryui.com/widget/
37
+
38
+
39
+
40
+ var widgetUuid = 0;
41
+ var widgetSlice = Array.prototype.slice;
42
+
43
+ $.cleanData = ( function( orig ) {
44
+ return function( elems ) {
45
+ var events, elem, i;
46
+ for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
47
+ try {
48
+
49
+ // Only trigger remove when necessary to save time
50
+ events = $._data( elem, "events" );
51
+ if ( events && events.remove ) {
52
+ $( elem ).triggerHandler( "remove" );
53
+ }
54
+
55
+ // Http://bugs.jquery.com/ticket/8235
56
+ } catch ( e ) {}
57
+ }
58
+ orig( elems );
59
+ };
60
+ } )( $.cleanData );
61
+
62
+ $.widget = function( name, base, prototype ) {
63
+ var existingConstructor, constructor, basePrototype;
64
+
65
+ // ProxiedPrototype allows the provided prototype to remain unmodified
66
+ // so that it can be used as a mixin for multiple widgets (#8876)
67
+ var proxiedPrototype = {};
68
+
69
+ var namespace = name.split( "." )[ 0 ];
70
+ name = name.split( "." )[ 1 ];
71
+ var fullName = namespace + "-" + name;
72
+
73
+ if ( !prototype ) {
74
+ prototype = base;
75
+ base = $.Widget;
76
+ }
77
+
78
+ if ( $.isArray( prototype ) ) {
79
+ prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
80
+ }
81
+
82
+ // Create selector for plugin
83
+ $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
84
+ return !!$.data( elem, fullName );
85
+ };
86
+
87
+ $[ namespace ] = $[ namespace ] || {};
88
+ existingConstructor = $[ namespace ][ name ];
89
+ constructor = $[ namespace ][ name ] = function( options, element ) {
90
+
91
+ // Allow instantiation without "new" keyword
92
+ if ( !this._createWidget ) {
93
+ return new constructor( options, element );
94
+ }
95
+
96
+ // Allow instantiation without initializing for simple inheritance
97
+ // must use "new" keyword (the code above always passes args)
98
+ if ( arguments.length ) {
99
+ this._createWidget( options, element );
100
+ }
101
+ };
102
+
103
+ // Extend with the existing constructor to carry over any static properties
104
+ $.extend( constructor, existingConstructor, {
105
+ version: prototype.version,
106
+
107
+ // Copy the object used to create the prototype in case we need to
108
+ // redefine the widget later
109
+ _proto: $.extend( {}, prototype ),
110
+
111
+ // Track widgets that inherit from this widget in case this widget is
112
+ // redefined after a widget inherits from it
113
+ _childConstructors: []
114
+ } );
115
+
116
+ basePrototype = new base();
117
+
118
+ // We need to make the options hash a property directly on the new instance
119
+ // otherwise we'll modify the options hash on the prototype that we're
120
+ // inheriting from
121
+ basePrototype.options = $.widget.extend( {}, basePrototype.options );
122
+ $.each( prototype, function( prop, value ) {
123
+ if ( !$.isFunction( value ) ) {
124
+ proxiedPrototype[ prop ] = value;
125
+ return;
126
+ }
127
+ proxiedPrototype[ prop ] = ( function() {
128
+ function _super() {
129
+ return base.prototype[ prop ].apply( this, arguments );
130
+ }
131
+
132
+ function _superApply( args ) {
133
+ return base.prototype[ prop ].apply( this, args );
134
+ }
135
+
136
+ return function() {
137
+ var __super = this._super;
138
+ var __superApply = this._superApply;
139
+ var returnValue;
140
+
141
+ this._super = _super;
142
+ this._superApply = _superApply;
143
+
144
+ returnValue = value.apply( this, arguments );
145
+
146
+ this._super = __super;
147
+ this._superApply = __superApply;
148
+
149
+ return returnValue;
150
+ };
151
+ } )();
152
+ } );
153
+ constructor.prototype = $.widget.extend( basePrototype, {
154
+
155
+ // TODO: remove support for widgetEventPrefix
156
+ // always use the name + a colon as the prefix, e.g., draggable:start
157
+ // don't prefix for widgets that aren't DOM-based
158
+ widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
159
+ }, proxiedPrototype, {
160
+ constructor: constructor,
161
+ namespace: namespace,
162
+ widgetName: name,
163
+ widgetFullName: fullName
164
+ } );
165
+
166
+ // If this widget is being redefined then we need to find all widgets that
167
+ // are inheriting from it and redefine all of them so that they inherit from
168
+ // the new version of this widget. We're essentially trying to replace one
169
+ // level in the prototype chain.
170
+ if ( existingConstructor ) {
171
+ $.each( existingConstructor._childConstructors, function( i, child ) {
172
+ var childPrototype = child.prototype;
173
+
174
+ // Redefine the child widget using the same prototype that was
175
+ // originally used, but inherit from the new version of the base
176
+ $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
177
+ child._proto );
178
+ } );
179
+
180
+ // Remove the list of existing child constructors from the old constructor
181
+ // so the old child constructors can be garbage collected
182
+ delete existingConstructor._childConstructors;
183
+ } else {
184
+ base._childConstructors.push( constructor );
185
+ }
186
+
187
+ $.widget.bridge( name, constructor );
188
+
189
+ return constructor;
190
+ };
191
+
192
+ $.widget.extend = function( target ) {
193
+ var input = widgetSlice.call( arguments, 1 );
194
+ var inputIndex = 0;
195
+ var inputLength = input.length;
196
+ var key;
197
+ var value;
198
+
199
+ for ( ; inputIndex < inputLength; inputIndex++ ) {
200
+ for ( key in input[ inputIndex ] ) {
201
+ value = input[ inputIndex ][ key ];
202
+ if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
203
+
204
+ // Clone objects
205
+ if ( $.isPlainObject( value ) ) {
206
+ target[ key ] = $.isPlainObject( target[ key ] ) ?
207
+ $.widget.extend( {}, target[ key ], value ) :
208
+
209
+ // Don't extend strings, arrays, etc. with objects
210
+ $.widget.extend( {}, value );
211
+
212
+ // Copy everything else by reference
213
+ } else {
214
+ target[ key ] = value;
215
+ }
216
+ }
217
+ }
218
+ }
219
+ return target;
220
+ };
221
+
222
+ $.widget.bridge = function( name, object ) {
223
+ var fullName = object.prototype.widgetFullName || name;
224
+ $.fn[ name ] = function( options ) {
225
+ var isMethodCall = typeof options === "string";
226
+ var args = widgetSlice.call( arguments, 1 );
227
+ var returnValue = this;
228
+
229
+ if ( isMethodCall ) {
230
+
231
+ // If this is an empty collection, we need to have the instance method
232
+ // return undefined instead of the jQuery instance
233
+ if ( !this.length && options === "instance" ) {
234
+ returnValue = undefined;
235
+ } else {
236
+ this.each( function() {
237
+ var methodValue;
238
+ var instance = $.data( this, fullName );
239
+
240
+ if ( options === "instance" ) {
241
+ returnValue = instance;
242
+ return false;
243
+ }
244
+
245
+ if ( !instance ) {
246
+ return $.error( "cannot call methods on " + name +
247
+ " prior to initialization; " +
248
+ "attempted to call method '" + options + "'" );
249
+ }
250
+
251
+ if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
252
+ return $.error( "no such method '" + options + "' for " + name +
253
+ " widget instance" );
254
+ }
255
+
256
+ methodValue = instance[ options ].apply( instance, args );
257
+
258
+ if ( methodValue !== instance && methodValue !== undefined ) {
259
+ returnValue = methodValue && methodValue.jquery ?
260
+ returnValue.pushStack( methodValue.get() ) :
261
+ methodValue;
262
+ return false;
263
+ }
264
+ } );
265
+ }
266
+ } else {
267
+
268
+ // Allow multiple hashes to be passed on init
269
+ if ( args.length ) {
270
+ options = $.widget.extend.apply( null, [ options ].concat( args ) );
271
+ }
272
+
273
+ this.each( function() {
274
+ var instance = $.data( this, fullName );
275
+ if ( instance ) {
276
+ instance.option( options || {} );
277
+ if ( instance._init ) {
278
+ instance._init();
279
+ }
280
+ } else {
281
+ $.data( this, fullName, new object( options, this ) );
282
+ }
283
+ } );
284
+ }
285
+
286
+ return returnValue;
287
+ };
288
+ };
289
+
290
+ $.Widget = function( /* options, element */ ) {};
291
+ $.Widget._childConstructors = [];
292
+
293
+ $.Widget.prototype = {
294
+ widgetName: "widget",
295
+ widgetEventPrefix: "",
296
+ defaultElement: "<div>",
297
+
298
+ options: {
299
+ classes: {},
300
+ disabled: false,
301
+
302
+ // Callbacks
303
+ create: null
304
+ },
305
+
306
+ _createWidget: function( options, element ) {
307
+ element = $( element || this.defaultElement || this )[ 0 ];
308
+ this.element = $( element );
309
+ this.uuid = widgetUuid++;
310
+ this.eventNamespace = "." + this.widgetName + this.uuid;
311
+
312
+ this.bindings = $();
313
+ this.hoverable = $();
314
+ this.focusable = $();
315
+ this.classesElementLookup = {};
316
+
317
+ if ( element !== this ) {
318
+ $.data( element, this.widgetFullName, this );
319
+ this._on( true, this.element, {
320
+ remove: function( event ) {
321
+ if ( event.target === element ) {
322
+ this.destroy();
323
+ }
324
+ }
325
+ } );
326
+ this.document = $( element.style ?
327
+
328
+ // Element within the document
329
+ element.ownerDocument :
330
+
331
+ // Element is window or document
332
+ element.document || element );
333
+ this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
334
+ }
335
+
336
+ this.options = $.widget.extend( {},
337
+ this.options,
338
+ this._getCreateOptions(),
339
+ options );
340
+
341
+ this._create();
342
+
343
+ if ( this.options.disabled ) {
344
+ this._setOptionDisabled( this.options.disabled );
345
+ }
346
+
347
+ this._trigger( "create", null, this._getCreateEventData() );
348
+ this._init();
349
+ },
350
+
351
+ _getCreateOptions: function() {
352
+ return {};
353
+ },
354
+
355
+ _getCreateEventData: $.noop,
356
+
357
+ _create: $.noop,
358
+
359
+ _init: $.noop,
360
+
361
+ destroy: function() {
362
+ var that = this;
363
+
364
+ this._destroy();
365
+ $.each( this.classesElementLookup, function( key, value ) {
366
+ that._removeClass( value, key );
367
+ } );
368
+
369
+ // We can probably remove the unbind calls in 2.0
370
+ // all event bindings should go through this._on()
371
+ this.element
372
+ .off( this.eventNamespace )
373
+ .removeData( this.widgetFullName );
374
+ this.widget()
375
+ .off( this.eventNamespace )
376
+ .removeAttr( "aria-disabled" );
377
+
378
+ // Clean up events and states
379
+ this.bindings.off( this.eventNamespace );
380
+ },
381
+
382
+ _destroy: $.noop,
383
+
384
+ widget: function() {
385
+ return this.element;
386
+ },
387
+
388
+ option: function( key, value ) {
389
+ var options = key;
390
+ var parts;
391
+ var curOption;
392
+ var i;
393
+
394
+ if ( arguments.length === 0 ) {
395
+
396
+ // Don't return a reference to the internal hash
397
+ return $.widget.extend( {}, this.options );
398
+ }
399
+
400
+ if ( typeof key === "string" ) {
401
+
402
+ // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
403
+ options = {};
404
+ parts = key.split( "." );
405
+ key = parts.shift();
406
+ if ( parts.length ) {
407
+ curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
408
+ for ( i = 0; i < parts.length - 1; i++ ) {
409
+ curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
410
+ curOption = curOption[ parts[ i ] ];
411
+ }
412
+ key = parts.pop();
413
+ if ( arguments.length === 1 ) {
414
+ return curOption[ key ] === undefined ? null : curOption[ key ];
415
+ }
416
+ curOption[ key ] = value;
417
+ } else {
418
+ if ( arguments.length === 1 ) {
419
+ return this.options[ key ] === undefined ? null : this.options[ key ];
420
+ }
421
+ options[ key ] = value;
422
+ }
423
+ }
424
+
425
+ this._setOptions( options );
426
+
427
+ return this;
428
+ },
429
+
430
+ _setOptions: function( options ) {
431
+ var key;
432
+
433
+ for ( key in options ) {
434
+ this._setOption( key, options[ key ] );
435
+ }
436
+
437
+ return this;
438
+ },
439
+
440
+ _setOption: function( key, value ) {
441
+ if ( key === "classes" ) {
442
+ this._setOptionClasses( value );
443
+ }
444
+
445
+ this.options[ key ] = value;
446
+
447
+ if ( key === "disabled" ) {
448
+ this._setOptionDisabled( value );
449
+ }
450
+
451
+ return this;
452
+ },
453
+
454
+ _setOptionClasses: function( value ) {
455
+ var classKey, elements, currentElements;
456
+
457
+ for ( classKey in value ) {
458
+ currentElements = this.classesElementLookup[ classKey ];
459
+ if ( value[ classKey ] === this.options.classes[ classKey ] ||
460
+ !currentElements ||
461
+ !currentElements.length ) {
462
+ continue;
463
+ }
464
+
465
+ // We are doing this to create a new jQuery object because the _removeClass() call
466
+ // on the next line is going to destroy the reference to the current elements being
467
+ // tracked. We need to save a copy of this collection so that we can add the new classes
468
+ // below.
469
+ elements = $( currentElements.get() );
470
+ this._removeClass( currentElements, classKey );
471
+
472
+ // We don't use _addClass() here, because that uses this.options.classes
473
+ // for generating the string of classes. We want to use the value passed in from
474
+ // _setOption(), this is the new value of the classes option which was passed to
475
+ // _setOption(). We pass this value directly to _classes().
476
+ elements.addClass( this._classes( {
477
+ element: elements,
478
+ keys: classKey,
479
+ classes: value,
480
+ add: true
481
+ } ) );
482
+ }
483
+ },
484
+
485
+ _setOptionDisabled: function( value ) {
486
+ this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
487
+
488
+ // If the widget is becoming disabled, then nothing is interactive
489
+ if ( value ) {
490
+ this._removeClass( this.hoverable, null, "ui-state-hover" );
491
+ this._removeClass( this.focusable, null, "ui-state-focus" );
492
+ }
493
+ },
494
+
495
+ enable: function() {
496
+ return this._setOptions( { disabled: false } );
497
+ },
498
+
499
+ disable: function() {
500
+ return this._setOptions( { disabled: true } );
501
+ },
502
+
503
+ _classes: function( options ) {
504
+ var full = [];
505
+ var that = this;
506
+
507
+ options = $.extend( {
508
+ element: this.element,
509
+ classes: this.options.classes || {}
510
+ }, options );
511
+
512
+ function processClassString( classes, checkOption ) {
513
+ var current, i;
514
+ for ( i = 0; i < classes.length; i++ ) {
515
+ current = that.classesElementLookup[ classes[ i ] ] || $();
516
+ if ( options.add ) {
517
+ current = $( $.unique( current.get().concat( options.element.get() ) ) );
518
+ } else {
519
+ current = $( current.not( options.element ).get() );
520
+ }
521
+ that.classesElementLookup[ classes[ i ] ] = current;
522
+ full.push( classes[ i ] );
523
+ if ( checkOption && options.classes[ classes[ i ] ] ) {
524
+ full.push( options.classes[ classes[ i ] ] );
525
+ }
526
+ }
527
+ }
528
+
529
+ this._on( options.element, {
530
+ "remove": "_untrackClassesElement"
531
+ } );
532
+
533
+ if ( options.keys ) {
534
+ processClassString( options.keys.match( /\S+/g ) || [], true );
535
+ }
536
+ if ( options.extra ) {
537
+ processClassString( options.extra.match( /\S+/g ) || [] );
538
+ }
539
+
540
+ return full.join( " " );
541
+ },
542
+
543
+ _untrackClassesElement: function( event ) {
544
+ var that = this;
545
+ $.each( that.classesElementLookup, function( key, value ) {
546
+ if ( $.inArray( event.target, value ) !== -1 ) {
547
+ that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
548
+ }
549
+ } );
550
+ },
551
+
552
+ _removeClass: function( element, keys, extra ) {
553
+ return this._toggleClass( element, keys, extra, false );
554
+ },
555
+
556
+ _addClass: function( element, keys, extra ) {
557
+ return this._toggleClass( element, keys, extra, true );
558
+ },
559
+
560
+ _toggleClass: function( element, keys, extra, add ) {
561
+ add = ( typeof add === "boolean" ) ? add : extra;
562
+ var shift = ( typeof element === "string" || element === null ),
563
+ options = {
564
+ extra: shift ? keys : extra,
565
+ keys: shift ? element : keys,
566
+ element: shift ? this.element : element,
567
+ add: add
568
+ };
569
+ options.element.toggleClass( this._classes( options ), add );
570
+ return this;
571
+ },
572
+
573
+ _on: function( suppressDisabledCheck, element, handlers ) {
574
+ var delegateElement;
575
+ var instance = this;
576
+
577
+ // No suppressDisabledCheck flag, shuffle arguments
578
+ if ( typeof suppressDisabledCheck !== "boolean" ) {
579
+ handlers = element;
580
+ element = suppressDisabledCheck;
581
+ suppressDisabledCheck = false;
582
+ }
583
+
584
+ // No element argument, shuffle and use this.element
585
+ if ( !handlers ) {
586
+ handlers = element;
587
+ element = this.element;
588
+ delegateElement = this.widget();
589
+ } else {
590
+ element = delegateElement = $( element );
591
+ this.bindings = this.bindings.add( element );
592
+ }
593
+
594
+ $.each( handlers, function( event, handler ) {
595
+ function handlerProxy() {
596
+
597
+ // Allow widgets to customize the disabled handling
598
+ // - disabled as an array instead of boolean
599
+ // - disabled class as method for disabling individual parts
600
+ if ( !suppressDisabledCheck &&
601
+ ( instance.options.disabled === true ||
602
+ $( this ).hasClass( "ui-state-disabled" ) ) ) {
603
+ return;
604
+ }
605
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
606
+ .apply( instance, arguments );
607
+ }
608
+
609
+ // Copy the guid so direct unbinding works
610
+ if ( typeof handler !== "string" ) {
611
+ handlerProxy.guid = handler.guid =
612
+ handler.guid || handlerProxy.guid || $.guid++;
613
+ }
614
+
615
+ var match = event.match( /^([\w:-]*)\s*(.*)$/ );
616
+ var eventName = match[ 1 ] + instance.eventNamespace;
617
+ var selector = match[ 2 ];
618
+
619
+ if ( selector ) {
620
+ delegateElement.on( eventName, selector, handlerProxy );
621
+ } else {
622
+ element.on( eventName, handlerProxy );
623
+ }
624
+ } );
625
+ },
626
+
627
+ _off: function( element, eventName ) {
628
+ eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
629
+ this.eventNamespace;
630
+ element.off( eventName ).off( eventName );
631
+
632
+ // Clear the stack to avoid memory leaks (#10056)
633
+ this.bindings = $( this.bindings.not( element ).get() );
634
+ this.focusable = $( this.focusable.not( element ).get() );
635
+ this.hoverable = $( this.hoverable.not( element ).get() );
636
+ },
637
+
638
+ _delay: function( handler, delay ) {
639
+ function handlerProxy() {
640
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
641
+ .apply( instance, arguments );
642
+ }
643
+ var instance = this;
644
+ return setTimeout( handlerProxy, delay || 0 );
645
+ },
646
+
647
+ _hoverable: function( element ) {
648
+ this.hoverable = this.hoverable.add( element );
649
+ this._on( element, {
650
+ mouseenter: function( event ) {
651
+ this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
652
+ },
653
+ mouseleave: function( event ) {
654
+ this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
655
+ }
656
+ } );
657
+ },
658
+
659
+ _focusable: function( element ) {
660
+ this.focusable = this.focusable.add( element );
661
+ this._on( element, {
662
+ focusin: function( event ) {
663
+ this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
664
+ },
665
+ focusout: function( event ) {
666
+ this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
667
+ }
668
+ } );
669
+ },
670
+
671
+ _trigger: function( type, event, data ) {
672
+ var prop, orig;
673
+ var callback = this.options[ type ];
674
+
675
+ data = data || {};
676
+ event = $.Event( event );
677
+ event.type = ( type === this.widgetEventPrefix ?
678
+ type :
679
+ this.widgetEventPrefix + type ).toLowerCase();
680
+
681
+ // The original event may come from any element
682
+ // so we need to reset the target on the new event
683
+ event.target = this.element[ 0 ];
684
+
685
+ // Copy original event properties over to the new event
686
+ orig = event.originalEvent;
687
+ if ( orig ) {
688
+ for ( prop in orig ) {
689
+ if ( !( prop in event ) ) {
690
+ event[ prop ] = orig[ prop ];
691
+ }
692
+ }
693
+ }
694
+
695
+ this.element.trigger( event, data );
696
+ return !( $.isFunction( callback ) &&
697
+ callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
698
+ event.isDefaultPrevented() );
699
+ }
700
+ };
701
+
702
+ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
703
+ $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
704
+ if ( typeof options === "string" ) {
705
+ options = { effect: options };
706
+ }
707
+
708
+ var hasOptions;
709
+ var effectName = !options ?
710
+ method :
711
+ options === true || typeof options === "number" ?
712
+ defaultEffect :
713
+ options.effect || defaultEffect;
714
+
715
+ options = options || {};
716
+ if ( typeof options === "number" ) {
717
+ options = { duration: options };
718
+ }
719
+
720
+ hasOptions = !$.isEmptyObject( options );
721
+ options.complete = callback;
722
+
723
+ if ( options.delay ) {
724
+ element.delay( options.delay );
725
+ }
726
+
727
+ if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
728
+ element[ method ]( options );
729
+ } else if ( effectName !== method && element[ effectName ] ) {
730
+ element[ effectName ]( options.duration, options.easing, callback );
731
+ } else {
732
+ element.queue( function( next ) {
733
+ $( this )[ method ]();
734
+ if ( callback ) {
735
+ callback.call( element[ 0 ] );
736
+ }
737
+ next();
738
+ } );
739
+ }
740
+ };
741
+ } );
742
+
743
+ var widget = $.widget;
744
+
745
+
746
+ /*!
747
+ * jQuery UI Position 1.12.1
748
+ * http://jqueryui.com
749
+ *
750
+ * Copyright jQuery Foundation and other contributors
751
+ * Released under the MIT license.
752
+ * http://jquery.org/license
753
+ *
754
+ * http://api.jqueryui.com/position/
755
+ */
756
+
757
+ //>>label: Position
758
+ //>>group: Core
759
+ //>>description: Positions elements relative to other elements.
760
+ //>>docs: http://api.jqueryui.com/position/
761
+ //>>demos: http://jqueryui.com/position/
762
+
763
+
764
+ ( function() {
765
+ var cachedScrollbarWidth,
766
+ max = Math.max,
767
+ abs = Math.abs,
768
+ rhorizontal = /left|center|right/,
769
+ rvertical = /top|center|bottom/,
770
+ roffset = /[\+\-]\d+(\.[\d]+)?%?/,
771
+ rposition = /^\w+/,
772
+ rpercent = /%$/,
773
+ _position = $.fn.position;
774
+
775
+ function getOffsets( offsets, width, height ) {
776
+ return [
777
+ parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
778
+ parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
779
+ ];
780
+ }
781
+
782
+ function parseCss( element, property ) {
783
+ return parseInt( $.css( element, property ), 10 ) || 0;
784
+ }
785
+
786
+ function getDimensions( elem ) {
787
+ var raw = elem[ 0 ];
788
+ if ( raw.nodeType === 9 ) {
789
+ return {
790
+ width: elem.width(),
791
+ height: elem.height(),
792
+ offset: { top: 0, left: 0 }
793
+ };
794
+ }
795
+ if ( $.isWindow( raw ) ) {
796
+ return {
797
+ width: elem.width(),
798
+ height: elem.height(),
799
+ offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
800
+ };
801
+ }
802
+ if ( raw.preventDefault ) {
803
+ return {
804
+ width: 0,
805
+ height: 0,
806
+ offset: { top: raw.pageY, left: raw.pageX }
807
+ };
808
+ }
809
+ return {
810
+ width: elem.outerWidth(),
811
+ height: elem.outerHeight(),
812
+ offset: elem.offset()
813
+ };
814
+ }
815
+
816
+ $.position = {
817
+ scrollbarWidth: function() {
818
+ if ( cachedScrollbarWidth !== undefined ) {
819
+ return cachedScrollbarWidth;
820
+ }
821
+ var w1, w2,
822
+ div = $( "<div " +
823
+ "style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
824
+ "<div style='height:100px;width:auto;'></div></div>" ),
825
+ innerDiv = div.children()[ 0 ];
826
+
827
+ $( "body" ).append( div );
828
+ w1 = innerDiv.offsetWidth;
829
+ div.css( "overflow", "scroll" );
830
+
831
+ w2 = innerDiv.offsetWidth;
832
+
833
+ if ( w1 === w2 ) {
834
+ w2 = div[ 0 ].clientWidth;
835
+ }
836
+
837
+ div.remove();
838
+
839
+ return ( cachedScrollbarWidth = w1 - w2 );
840
+ },
841
+ getScrollInfo: function( within ) {
842
+ var overflowX = within.isWindow || within.isDocument ? "" :
843
+ within.element.css( "overflow-x" ),
844
+ overflowY = within.isWindow || within.isDocument ? "" :
845
+ within.element.css( "overflow-y" ),
846
+ hasOverflowX = overflowX === "scroll" ||
847
+ ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
848
+ hasOverflowY = overflowY === "scroll" ||
849
+ ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
850
+ return {
851
+ width: hasOverflowY ? $.position.scrollbarWidth() : 0,
852
+ height: hasOverflowX ? $.position.scrollbarWidth() : 0
853
+ };
854
+ },
855
+ getWithinInfo: function( element ) {
856
+ var withinElement = $( element || window ),
857
+ isWindow = $.isWindow( withinElement[ 0 ] ),
858
+ isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
859
+ hasOffset = !isWindow && !isDocument;
860
+ return {
861
+ element: withinElement,
862
+ isWindow: isWindow,
863
+ isDocument: isDocument,
864
+ offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
865
+ scrollLeft: withinElement.scrollLeft(),
866
+ scrollTop: withinElement.scrollTop(),
867
+ width: withinElement.outerWidth(),
868
+ height: withinElement.outerHeight()
869
+ };
870
+ }
871
+ };
872
+
873
+ $.fn.position = function( options ) {
874
+ if ( !options || !options.of ) {
875
+ return _position.apply( this, arguments );
876
+ }
877
+
878
+ // Make a copy, we don't want to modify arguments
879
+ options = $.extend( {}, options );
880
+
881
+ var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
882
+ target = $( options.of ),
883
+ within = $.position.getWithinInfo( options.within ),
884
+ scrollInfo = $.position.getScrollInfo( within ),
885
+ collision = ( options.collision || "flip" ).split( " " ),
886
+ offsets = {};
887
+
888
+ dimensions = getDimensions( target );
889
+ if ( target[ 0 ].preventDefault ) {
890
+
891
+ // Force left top to allow flipping
892
+ options.at = "left top";
893
+ }
894
+ targetWidth = dimensions.width;
895
+ targetHeight = dimensions.height;
896
+ targetOffset = dimensions.offset;
897
+
898
+ // Clone to reuse original targetOffset later
899
+ basePosition = $.extend( {}, targetOffset );
900
+
901
+ // Force my and at to have valid horizontal and vertical positions
902
+ // if a value is missing or invalid, it will be converted to center
903
+ $.each( [ "my", "at" ], function() {
904
+ var pos = ( options[ this ] || "" ).split( " " ),
905
+ horizontalOffset,
906
+ verticalOffset;
907
+
908
+ if ( pos.length === 1 ) {
909
+ pos = rhorizontal.test( pos[ 0 ] ) ?
910
+ pos.concat( [ "center" ] ) :
911
+ rvertical.test( pos[ 0 ] ) ?
912
+ [ "center" ].concat( pos ) :
913
+ [ "center", "center" ];
914
+ }
915
+ pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
916
+ pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
917
+
918
+ // Calculate offsets
919
+ horizontalOffset = roffset.exec( pos[ 0 ] );
920
+ verticalOffset = roffset.exec( pos[ 1 ] );
921
+ offsets[ this ] = [
922
+ horizontalOffset ? horizontalOffset[ 0 ] : 0,
923
+ verticalOffset ? verticalOffset[ 0 ] : 0
924
+ ];
925
+
926
+ // Reduce to just the positions without the offsets
927
+ options[ this ] = [
928
+ rposition.exec( pos[ 0 ] )[ 0 ],
929
+ rposition.exec( pos[ 1 ] )[ 0 ]
930
+ ];
931
+ } );
932
+
933
+ // Normalize collision option
934
+ if ( collision.length === 1 ) {
935
+ collision[ 1 ] = collision[ 0 ];
936
+ }
937
+
938
+ if ( options.at[ 0 ] === "right" ) {
939
+ basePosition.left += targetWidth;
940
+ } else if ( options.at[ 0 ] === "center" ) {
941
+ basePosition.left += targetWidth / 2;
942
+ }
943
+
944
+ if ( options.at[ 1 ] === "bottom" ) {
945
+ basePosition.top += targetHeight;
946
+ } else if ( options.at[ 1 ] === "center" ) {
947
+ basePosition.top += targetHeight / 2;
948
+ }
949
+
950
+ atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
951
+ basePosition.left += atOffset[ 0 ];
952
+ basePosition.top += atOffset[ 1 ];
953
+
954
+ return this.each( function() {
955
+ var collisionPosition, using,
956
+ elem = $( this ),
957
+ elemWidth = elem.outerWidth(),
958
+ elemHeight = elem.outerHeight(),
959
+ marginLeft = parseCss( this, "marginLeft" ),
960
+ marginTop = parseCss( this, "marginTop" ),
961
+ collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
962
+ scrollInfo.width,
963
+ collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
964
+ scrollInfo.height,
965
+ position = $.extend( {}, basePosition ),
966
+ myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
967
+
968
+ if ( options.my[ 0 ] === "right" ) {
969
+ position.left -= elemWidth;
970
+ } else if ( options.my[ 0 ] === "center" ) {
971
+ position.left -= elemWidth / 2;
972
+ }
973
+
974
+ if ( options.my[ 1 ] === "bottom" ) {
975
+ position.top -= elemHeight;
976
+ } else if ( options.my[ 1 ] === "center" ) {
977
+ position.top -= elemHeight / 2;
978
+ }
979
+
980
+ position.left += myOffset[ 0 ];
981
+ position.top += myOffset[ 1 ];
982
+
983
+ collisionPosition = {
984
+ marginLeft: marginLeft,
985
+ marginTop: marginTop
986
+ };
987
+
988
+ $.each( [ "left", "top" ], function( i, dir ) {
989
+ if ( $.ui.position[ collision[ i ] ] ) {
990
+ $.ui.position[ collision[ i ] ][ dir ]( position, {
991
+ targetWidth: targetWidth,
992
+ targetHeight: targetHeight,
993
+ elemWidth: elemWidth,
994
+ elemHeight: elemHeight,
995
+ collisionPosition: collisionPosition,
996
+ collisionWidth: collisionWidth,
997
+ collisionHeight: collisionHeight,
998
+ offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
999
+ my: options.my,
1000
+ at: options.at,
1001
+ within: within,
1002
+ elem: elem
1003
+ } );
1004
+ }
1005
+ } );
1006
+
1007
+ if ( options.using ) {
1008
+
1009
+ // Adds feedback as second argument to using callback, if present
1010
+ using = function( props ) {
1011
+ var left = targetOffset.left - position.left,
1012
+ right = left + targetWidth - elemWidth,
1013
+ top = targetOffset.top - position.top,
1014
+ bottom = top + targetHeight - elemHeight,
1015
+ feedback = {
1016
+ target: {
1017
+ element: target,
1018
+ left: targetOffset.left,
1019
+ top: targetOffset.top,
1020
+ width: targetWidth,
1021
+ height: targetHeight
1022
+ },
1023
+ element: {
1024
+ element: elem,
1025
+ left: position.left,
1026
+ top: position.top,
1027
+ width: elemWidth,
1028
+ height: elemHeight
1029
+ },
1030
+ horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1031
+ vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1032
+ };
1033
+ if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1034
+ feedback.horizontal = "center";
1035
+ }
1036
+ if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1037
+ feedback.vertical = "middle";
1038
+ }
1039
+ if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1040
+ feedback.important = "horizontal";
1041
+ } else {
1042
+ feedback.important = "vertical";
1043
+ }
1044
+ options.using.call( this, props, feedback );
1045
+ };
1046
+ }
1047
+
1048
+ elem.offset( $.extend( position, { using: using } ) );
1049
+ } );
1050
+ };
1051
+
1052
+ $.ui.position = {
1053
+ fit: {
1054
+ left: function( position, data ) {
1055
+ var within = data.within,
1056
+ withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1057
+ outerWidth = within.width,
1058
+ collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1059
+ overLeft = withinOffset - collisionPosLeft,
1060
+ overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1061
+ newOverRight;
1062
+
1063
+ // Element is wider than within
1064
+ if ( data.collisionWidth > outerWidth ) {
1065
+
1066
+ // Element is initially over the left side of within
1067
+ if ( overLeft > 0 && overRight <= 0 ) {
1068
+ newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1069
+ withinOffset;
1070
+ position.left += overLeft - newOverRight;
1071
+
1072
+ // Element is initially over right side of within
1073
+ } else if ( overRight > 0 && overLeft <= 0 ) {
1074
+ position.left = withinOffset;
1075
+
1076
+ // Element is initially over both left and right sides of within
1077
+ } else {
1078
+ if ( overLeft > overRight ) {
1079
+ position.left = withinOffset + outerWidth - data.collisionWidth;
1080
+ } else {
1081
+ position.left = withinOffset;
1082
+ }
1083
+ }
1084
+
1085
+ // Too far left -> align with left edge
1086
+ } else if ( overLeft > 0 ) {
1087
+ position.left += overLeft;
1088
+
1089
+ // Too far right -> align with right edge
1090
+ } else if ( overRight > 0 ) {
1091
+ position.left -= overRight;
1092
+
1093
+ // Adjust based on position and margin
1094
+ } else {
1095
+ position.left = max( position.left - collisionPosLeft, position.left );
1096
+ }
1097
+ },
1098
+ top: function( position, data ) {
1099
+ var within = data.within,
1100
+ withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1101
+ outerHeight = data.within.height,
1102
+ collisionPosTop = position.top - data.collisionPosition.marginTop,
1103
+ overTop = withinOffset - collisionPosTop,
1104
+ overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1105
+ newOverBottom;
1106
+
1107
+ // Element is taller than within
1108
+ if ( data.collisionHeight > outerHeight ) {
1109
+
1110
+ // Element is initially over the top of within
1111
+ if ( overTop > 0 && overBottom <= 0 ) {
1112
+ newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1113
+ withinOffset;
1114
+ position.top += overTop - newOverBottom;
1115
+
1116
+ // Element is initially over bottom of within
1117
+ } else if ( overBottom > 0 && overTop <= 0 ) {
1118
+ position.top = withinOffset;
1119
+
1120
+ // Element is initially over both top and bottom of within
1121
+ } else {
1122
+ if ( overTop > overBottom ) {
1123
+ position.top = withinOffset + outerHeight - data.collisionHeight;
1124
+ } else {
1125
+ position.top = withinOffset;
1126
+ }
1127
+ }
1128
+
1129
+ // Too far up -> align with top
1130
+ } else if ( overTop > 0 ) {
1131
+ position.top += overTop;
1132
+
1133
+ // Too far down -> align with bottom edge
1134
+ } else if ( overBottom > 0 ) {
1135
+ position.top -= overBottom;
1136
+
1137
+ // Adjust based on position and margin
1138
+ } else {
1139
+ position.top = max( position.top - collisionPosTop, position.top );
1140
+ }
1141
+ }
1142
+ },
1143
+ flip: {
1144
+ left: function( position, data ) {
1145
+ var within = data.within,
1146
+ withinOffset = within.offset.left + within.scrollLeft,
1147
+ outerWidth = within.width,
1148
+ offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1149
+ collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1150
+ overLeft = collisionPosLeft - offsetLeft,
1151
+ overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1152
+ myOffset = data.my[ 0 ] === "left" ?
1153
+ -data.elemWidth :
1154
+ data.my[ 0 ] === "right" ?
1155
+ data.elemWidth :
1156
+ 0,
1157
+ atOffset = data.at[ 0 ] === "left" ?
1158
+ data.targetWidth :
1159
+ data.at[ 0 ] === "right" ?
1160
+ -data.targetWidth :
1161
+ 0,
1162
+ offset = -2 * data.offset[ 0 ],
1163
+ newOverRight,
1164
+ newOverLeft;
1165
+
1166
+ if ( overLeft < 0 ) {
1167
+ newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1168
+ outerWidth - withinOffset;
1169
+ if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1170
+ position.left += myOffset + atOffset + offset;
1171
+ }
1172
+ } else if ( overRight > 0 ) {
1173
+ newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1174
+ atOffset + offset - offsetLeft;
1175
+ if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1176
+ position.left += myOffset + atOffset + offset;
1177
+ }
1178
+ }
1179
+ },
1180
+ top: function( position, data ) {
1181
+ var within = data.within,
1182
+ withinOffset = within.offset.top + within.scrollTop,
1183
+ outerHeight = within.height,
1184
+ offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1185
+ collisionPosTop = position.top - data.collisionPosition.marginTop,
1186
+ overTop = collisionPosTop - offsetTop,
1187
+ overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1188
+ top = data.my[ 1 ] === "top",
1189
+ myOffset = top ?
1190
+ -data.elemHeight :
1191
+ data.my[ 1 ] === "bottom" ?
1192
+ data.elemHeight :
1193
+ 0,
1194
+ atOffset = data.at[ 1 ] === "top" ?
1195
+ data.targetHeight :
1196
+ data.at[ 1 ] === "bottom" ?
1197
+ -data.targetHeight :
1198
+ 0,
1199
+ offset = -2 * data.offset[ 1 ],
1200
+ newOverTop,
1201
+ newOverBottom;
1202
+ if ( overTop < 0 ) {
1203
+ newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1204
+ outerHeight - withinOffset;
1205
+ if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1206
+ position.top += myOffset + atOffset + offset;
1207
+ }
1208
+ } else if ( overBottom > 0 ) {
1209
+ newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1210
+ offset - offsetTop;
1211
+ if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1212
+ position.top += myOffset + atOffset + offset;
1213
+ }
1214
+ }
1215
+ }
1216
+ },
1217
+ flipfit: {
1218
+ left: function() {
1219
+ $.ui.position.flip.left.apply( this, arguments );
1220
+ $.ui.position.fit.left.apply( this, arguments );
1221
+ },
1222
+ top: function() {
1223
+ $.ui.position.flip.top.apply( this, arguments );
1224
+ $.ui.position.fit.top.apply( this, arguments );
1225
+ }
1226
+ }
1227
+ };
1228
+
1229
+ } )();
1230
+
1231
+ var position = $.ui.position;
1232
+
1233
+
1234
+ /*!
1235
+ * jQuery UI :data 1.12.1
1236
+ * http://jqueryui.com
1237
+ *
1238
+ * Copyright jQuery Foundation and other contributors
1239
+ * Released under the MIT license.
1240
+ * http://jquery.org/license
1241
+ */
1242
+
1243
+ //>>label: :data Selector
1244
+ //>>group: Core
1245
+ //>>description: Selects elements which have data stored under the specified key.
1246
+ //>>docs: http://api.jqueryui.com/data-selector/
1247
+
1248
+
1249
+ var data = $.extend( $.expr[ ":" ], {
1250
+ data: $.expr.createPseudo ?
1251
+ $.expr.createPseudo( function( dataName ) {
1252
+ return function( elem ) {
1253
+ return !!$.data( elem, dataName );
1254
+ };
1255
+ } ) :
1256
+
1257
+ // Support: jQuery <1.8
1258
+ function( elem, i, match ) {
1259
+ return !!$.data( elem, match[ 3 ] );
1260
+ }
1261
+ } );
1262
+
1263
+ /*!
1264
+ * jQuery UI Disable Selection 1.12.1
1265
+ * http://jqueryui.com
1266
+ *
1267
+ * Copyright jQuery Foundation and other contributors
1268
+ * Released under the MIT license.
1269
+ * http://jquery.org/license
1270
+ */
1271
+
1272
+ //>>label: disableSelection
1273
+ //>>group: Core
1274
+ //>>description: Disable selection of text content within the set of matched elements.
1275
+ //>>docs: http://api.jqueryui.com/disableSelection/
1276
+
1277
+ // This file is deprecated
1278
+
1279
+
1280
+ var disableSelection = $.fn.extend( {
1281
+ disableSelection: ( function() {
1282
+ var eventType = "onselectstart" in document.createElement( "div" ) ?
1283
+ "selectstart" :
1284
+ "mousedown";
1285
+
1286
+ return function() {
1287
+ return this.on( eventType + ".ui-disableSelection", function( event ) {
1288
+ event.preventDefault();
1289
+ } );
1290
+ };
1291
+ } )(),
1292
+
1293
+ enableSelection: function() {
1294
+ return this.off( ".ui-disableSelection" );
1295
+ }
1296
+ } );
1297
+
1298
+
1299
+ /*!
1300
+ * jQuery UI Effects 1.12.1
1301
+ * http://jqueryui.com
1302
+ *
1303
+ * Copyright jQuery Foundation and other contributors
1304
+ * Released under the MIT license.
1305
+ * http://jquery.org/license
1306
+ */
1307
+
1308
+ //>>label: Effects Core
1309
+ //>>group: Effects
1310
+ // jscs:disable maximumLineLength
1311
+ //>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
1312
+ // jscs:enable maximumLineLength
1313
+ //>>docs: http://api.jqueryui.com/category/effects-core/
1314
+ //>>demos: http://jqueryui.com/effect/
1315
+
1316
+
1317
+
1318
+ var dataSpace = "ui-effects-",
1319
+ dataSpaceStyle = "ui-effects-style",
1320
+ dataSpaceAnimated = "ui-effects-animated",
1321
+
1322
+ // Create a local jQuery because jQuery Color relies on it and the
1323
+ // global may not exist with AMD and a custom build (#10199)
1324
+ jQuery = $;
1325
+
1326
+ $.effects = {
1327
+ effect: {}
1328
+ };
1329
+
1330
+ /*!
1331
+ * jQuery Color Animations v2.1.2
1332
+ * https://github.com/jquery/jquery-color
1333
+ *
1334
+ * Copyright 2014 jQuery Foundation and other contributors
1335
+ * Released under the MIT license.
1336
+ * http://jquery.org/license
1337
+ *
1338
+ * Date: Wed Jan 16 08:47:09 2013 -0600
1339
+ */
1340
+ ( function( jQuery, undefined ) {
1341
+
1342
+ var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
1343
+ "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
1344
+
1345
+ // Plusequals test for += 100 -= 100
1346
+ rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
1347
+
1348
+ // A set of RE's that can match strings and generate color tuples.
1349
+ stringParsers = [ {
1350
+ re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1351
+ parse: function( execResult ) {
1352
+ return [
1353
+ execResult[ 1 ],
1354
+ execResult[ 2 ],
1355
+ execResult[ 3 ],
1356
+ execResult[ 4 ]
1357
+ ];
1358
+ }
1359
+ }, {
1360
+ re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1361
+ parse: function( execResult ) {
1362
+ return [
1363
+ execResult[ 1 ] * 2.55,
1364
+ execResult[ 2 ] * 2.55,
1365
+ execResult[ 3 ] * 2.55,
1366
+ execResult[ 4 ]
1367
+ ];
1368
+ }
1369
+ }, {
1370
+
1371
+ // This regex ignores A-F because it's compared against an already lowercased string
1372
+ re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
1373
+ parse: function( execResult ) {
1374
+ return [
1375
+ parseInt( execResult[ 1 ], 16 ),
1376
+ parseInt( execResult[ 2 ], 16 ),
1377
+ parseInt( execResult[ 3 ], 16 )
1378
+ ];
1379
+ }
1380
+ }, {
1381
+
1382
+ // This regex ignores A-F because it's compared against an already lowercased string
1383
+ re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
1384
+ parse: function( execResult ) {
1385
+ return [
1386
+ parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
1387
+ parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
1388
+ parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
1389
+ ];
1390
+ }
1391
+ }, {
1392
+ re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1393
+ space: "hsla",
1394
+ parse: function( execResult ) {
1395
+ return [
1396
+ execResult[ 1 ],
1397
+ execResult[ 2 ] / 100,
1398
+ execResult[ 3 ] / 100,
1399
+ execResult[ 4 ]
1400
+ ];
1401
+ }
1402
+ } ],
1403
+
1404
+ // JQuery.Color( )
1405
+ color = jQuery.Color = function( color, green, blue, alpha ) {
1406
+ return new jQuery.Color.fn.parse( color, green, blue, alpha );
1407
+ },
1408
+ spaces = {
1409
+ rgba: {
1410
+ props: {
1411
+ red: {
1412
+ idx: 0,
1413
+ type: "byte"
1414
+ },
1415
+ green: {
1416
+ idx: 1,
1417
+ type: "byte"
1418
+ },
1419
+ blue: {
1420
+ idx: 2,
1421
+ type: "byte"
1422
+ }
1423
+ }
1424
+ },
1425
+
1426
+ hsla: {
1427
+ props: {
1428
+ hue: {
1429
+ idx: 0,
1430
+ type: "degrees"
1431
+ },
1432
+ saturation: {
1433
+ idx: 1,
1434
+ type: "percent"
1435
+ },
1436
+ lightness: {
1437
+ idx: 2,
1438
+ type: "percent"
1439
+ }
1440
+ }
1441
+ }
1442
+ },
1443
+ propTypes = {
1444
+ "byte": {
1445
+ floor: true,
1446
+ max: 255
1447
+ },
1448
+ "percent": {
1449
+ max: 1
1450
+ },
1451
+ "degrees": {
1452
+ mod: 360,
1453
+ floor: true
1454
+ }
1455
+ },
1456
+ support = color.support = {},
1457
+
1458
+ // Element for support tests
1459
+ supportElem = jQuery( "<p>" )[ 0 ],
1460
+
1461
+ // Colors = jQuery.Color.names
1462
+ colors,
1463
+
1464
+ // Local aliases of functions called often
1465
+ each = jQuery.each;
1466
+
1467
+ // Determine rgba support immediately
1468
+ supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
1469
+ support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
1470
+
1471
+ // Define cache name and alpha properties
1472
+ // for rgba and hsla spaces
1473
+ each( spaces, function( spaceName, space ) {
1474
+ space.cache = "_" + spaceName;
1475
+ space.props.alpha = {
1476
+ idx: 3,
1477
+ type: "percent",
1478
+ def: 1
1479
+ };
1480
+ } );
1481
+
1482
+ function clamp( value, prop, allowEmpty ) {
1483
+ var type = propTypes[ prop.type ] || {};
1484
+
1485
+ if ( value == null ) {
1486
+ return ( allowEmpty || !prop.def ) ? null : prop.def;
1487
+ }
1488
+
1489
+ // ~~ is an short way of doing floor for positive numbers
1490
+ value = type.floor ? ~~value : parseFloat( value );
1491
+
1492
+ // IE will pass in empty strings as value for alpha,
1493
+ // which will hit this case
1494
+ if ( isNaN( value ) ) {
1495
+ return prop.def;
1496
+ }
1497
+
1498
+ if ( type.mod ) {
1499
+
1500
+ // We add mod before modding to make sure that negatives values
1501
+ // get converted properly: -10 -> 350
1502
+ return ( value + type.mod ) % type.mod;
1503
+ }
1504
+
1505
+ // For now all property types without mod have min and max
1506
+ return 0 > value ? 0 : type.max < value ? type.max : value;
1507
+ }
1508
+
1509
+ function stringParse( string ) {
1510
+ var inst = color(),
1511
+ rgba = inst._rgba = [];
1512
+
1513
+ string = string.toLowerCase();
1514
+
1515
+ each( stringParsers, function( i, parser ) {
1516
+ var parsed,
1517
+ match = parser.re.exec( string ),
1518
+ values = match && parser.parse( match ),
1519
+ spaceName = parser.space || "rgba";
1520
+
1521
+ if ( values ) {
1522
+ parsed = inst[ spaceName ]( values );
1523
+
1524
+ // If this was an rgba parse the assignment might happen twice
1525
+ // oh well....
1526
+ inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
1527
+ rgba = inst._rgba = parsed._rgba;
1528
+
1529
+ // Exit each( stringParsers ) here because we matched
1530
+ return false;
1531
+ }
1532
+ } );
1533
+
1534
+ // Found a stringParser that handled it
1535
+ if ( rgba.length ) {
1536
+
1537
+ // If this came from a parsed string, force "transparent" when alpha is 0
1538
+ // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
1539
+ if ( rgba.join() === "0,0,0,0" ) {
1540
+ jQuery.extend( rgba, colors.transparent );
1541
+ }
1542
+ return inst;
1543
+ }
1544
+
1545
+ // Named colors
1546
+ return colors[ string ];
1547
+ }
1548
+
1549
+ color.fn = jQuery.extend( color.prototype, {
1550
+ parse: function( red, green, blue, alpha ) {
1551
+ if ( red === undefined ) {
1552
+ this._rgba = [ null, null, null, null ];
1553
+ return this;
1554
+ }
1555
+ if ( red.jquery || red.nodeType ) {
1556
+ red = jQuery( red ).css( green );
1557
+ green = undefined;
1558
+ }
1559
+
1560
+ var inst = this,
1561
+ type = jQuery.type( red ),
1562
+ rgba = this._rgba = [];
1563
+
1564
+ // More than 1 argument specified - assume ( red, green, blue, alpha )
1565
+ if ( green !== undefined ) {
1566
+ red = [ red, green, blue, alpha ];
1567
+ type = "array";
1568
+ }
1569
+
1570
+ if ( type === "string" ) {
1571
+ return this.parse( stringParse( red ) || colors._default );
1572
+ }
1573
+
1574
+ if ( type === "array" ) {
1575
+ each( spaces.rgba.props, function( key, prop ) {
1576
+ rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
1577
+ } );
1578
+ return this;
1579
+ }
1580
+
1581
+ if ( type === "object" ) {
1582
+ if ( red instanceof color ) {
1583
+ each( spaces, function( spaceName, space ) {
1584
+ if ( red[ space.cache ] ) {
1585
+ inst[ space.cache ] = red[ space.cache ].slice();
1586
+ }
1587
+ } );
1588
+ } else {
1589
+ each( spaces, function( spaceName, space ) {
1590
+ var cache = space.cache;
1591
+ each( space.props, function( key, prop ) {
1592
+
1593
+ // If the cache doesn't exist, and we know how to convert
1594
+ if ( !inst[ cache ] && space.to ) {
1595
+
1596
+ // If the value was null, we don't need to copy it
1597
+ // if the key was alpha, we don't need to copy it either
1598
+ if ( key === "alpha" || red[ key ] == null ) {
1599
+ return;
1600
+ }
1601
+ inst[ cache ] = space.to( inst._rgba );
1602
+ }
1603
+
1604
+ // This is the only case where we allow nulls for ALL properties.
1605
+ // call clamp with alwaysAllowEmpty
1606
+ inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
1607
+ } );
1608
+
1609
+ // Everything defined but alpha?
1610
+ if ( inst[ cache ] &&
1611
+ jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
1612
+
1613
+ // Use the default of 1
1614
+ inst[ cache ][ 3 ] = 1;
1615
+ if ( space.from ) {
1616
+ inst._rgba = space.from( inst[ cache ] );
1617
+ }
1618
+ }
1619
+ } );
1620
+ }
1621
+ return this;
1622
+ }
1623
+ },
1624
+ is: function( compare ) {
1625
+ var is = color( compare ),
1626
+ same = true,
1627
+ inst = this;
1628
+
1629
+ each( spaces, function( _, space ) {
1630
+ var localCache,
1631
+ isCache = is[ space.cache ];
1632
+ if ( isCache ) {
1633
+ localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
1634
+ each( space.props, function( _, prop ) {
1635
+ if ( isCache[ prop.idx ] != null ) {
1636
+ same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
1637
+ return same;
1638
+ }
1639
+ } );
1640
+ }
1641
+ return same;
1642
+ } );
1643
+ return same;
1644
+ },
1645
+ _space: function() {
1646
+ var used = [],
1647
+ inst = this;
1648
+ each( spaces, function( spaceName, space ) {
1649
+ if ( inst[ space.cache ] ) {
1650
+ used.push( spaceName );
1651
+ }
1652
+ } );
1653
+ return used.pop();
1654
+ },
1655
+ transition: function( other, distance ) {
1656
+ var end = color( other ),
1657
+ spaceName = end._space(),
1658
+ space = spaces[ spaceName ],
1659
+ startColor = this.alpha() === 0 ? color( "transparent" ) : this,
1660
+ start = startColor[ space.cache ] || space.to( startColor._rgba ),
1661
+ result = start.slice();
1662
+
1663
+ end = end[ space.cache ];
1664
+ each( space.props, function( key, prop ) {
1665
+ var index = prop.idx,
1666
+ startValue = start[ index ],
1667
+ endValue = end[ index ],
1668
+ type = propTypes[ prop.type ] || {};
1669
+
1670
+ // If null, don't override start value
1671
+ if ( endValue === null ) {
1672
+ return;
1673
+ }
1674
+
1675
+ // If null - use end
1676
+ if ( startValue === null ) {
1677
+ result[ index ] = endValue;
1678
+ } else {
1679
+ if ( type.mod ) {
1680
+ if ( endValue - startValue > type.mod / 2 ) {
1681
+ startValue += type.mod;
1682
+ } else if ( startValue - endValue > type.mod / 2 ) {
1683
+ startValue -= type.mod;
1684
+ }
1685
+ }
1686
+ result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
1687
+ }
1688
+ } );
1689
+ return this[ spaceName ]( result );
1690
+ },
1691
+ blend: function( opaque ) {
1692
+
1693
+ // If we are already opaque - return ourself
1694
+ if ( this._rgba[ 3 ] === 1 ) {
1695
+ return this;
1696
+ }
1697
+
1698
+ var rgb = this._rgba.slice(),
1699
+ a = rgb.pop(),
1700
+ blend = color( opaque )._rgba;
1701
+
1702
+ return color( jQuery.map( rgb, function( v, i ) {
1703
+ return ( 1 - a ) * blend[ i ] + a * v;
1704
+ } ) );
1705
+ },
1706
+ toRgbaString: function() {
1707
+ var prefix = "rgba(",
1708
+ rgba = jQuery.map( this._rgba, function( v, i ) {
1709
+ return v == null ? ( i > 2 ? 1 : 0 ) : v;
1710
+ } );
1711
+
1712
+ if ( rgba[ 3 ] === 1 ) {
1713
+ rgba.pop();
1714
+ prefix = "rgb(";
1715
+ }
1716
+
1717
+ return prefix + rgba.join() + ")";
1718
+ },
1719
+ toHslaString: function() {
1720
+ var prefix = "hsla(",
1721
+ hsla = jQuery.map( this.hsla(), function( v, i ) {
1722
+ if ( v == null ) {
1723
+ v = i > 2 ? 1 : 0;
1724
+ }
1725
+
1726
+ // Catch 1 and 2
1727
+ if ( i && i < 3 ) {
1728
+ v = Math.round( v * 100 ) + "%";
1729
+ }
1730
+ return v;
1731
+ } );
1732
+
1733
+ if ( hsla[ 3 ] === 1 ) {
1734
+ hsla.pop();
1735
+ prefix = "hsl(";
1736
+ }
1737
+ return prefix + hsla.join() + ")";
1738
+ },
1739
+ toHexString: function( includeAlpha ) {
1740
+ var rgba = this._rgba.slice(),
1741
+ alpha = rgba.pop();
1742
+
1743
+ if ( includeAlpha ) {
1744
+ rgba.push( ~~( alpha * 255 ) );
1745
+ }
1746
+
1747
+ return "#" + jQuery.map( rgba, function( v ) {
1748
+
1749
+ // Default to 0 when nulls exist
1750
+ v = ( v || 0 ).toString( 16 );
1751
+ return v.length === 1 ? "0" + v : v;
1752
+ } ).join( "" );
1753
+ },
1754
+ toString: function() {
1755
+ return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
1756
+ }
1757
+ } );
1758
+ color.fn.parse.prototype = color.fn;
1759
+
1760
+ // Hsla conversions adapted from:
1761
+ // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
1762
+
1763
+ function hue2rgb( p, q, h ) {
1764
+ h = ( h + 1 ) % 1;
1765
+ if ( h * 6 < 1 ) {
1766
+ return p + ( q - p ) * h * 6;
1767
+ }
1768
+ if ( h * 2 < 1 ) {
1769
+ return q;
1770
+ }
1771
+ if ( h * 3 < 2 ) {
1772
+ return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
1773
+ }
1774
+ return p;
1775
+ }
1776
+
1777
+ spaces.hsla.to = function( rgba ) {
1778
+ if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
1779
+ return [ null, null, null, rgba[ 3 ] ];
1780
+ }
1781
+ var r = rgba[ 0 ] / 255,
1782
+ g = rgba[ 1 ] / 255,
1783
+ b = rgba[ 2 ] / 255,
1784
+ a = rgba[ 3 ],
1785
+ max = Math.max( r, g, b ),
1786
+ min = Math.min( r, g, b ),
1787
+ diff = max - min,
1788
+ add = max + min,
1789
+ l = add * 0.5,
1790
+ h, s;
1791
+
1792
+ if ( min === max ) {
1793
+ h = 0;
1794
+ } else if ( r === max ) {
1795
+ h = ( 60 * ( g - b ) / diff ) + 360;
1796
+ } else if ( g === max ) {
1797
+ h = ( 60 * ( b - r ) / diff ) + 120;
1798
+ } else {
1799
+ h = ( 60 * ( r - g ) / diff ) + 240;
1800
+ }
1801
+
1802
+ // Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
1803
+ // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
1804
+ if ( diff === 0 ) {
1805
+ s = 0;
1806
+ } else if ( l <= 0.5 ) {
1807
+ s = diff / add;
1808
+ } else {
1809
+ s = diff / ( 2 - add );
1810
+ }
1811
+ return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
1812
+ };
1813
+
1814
+ spaces.hsla.from = function( hsla ) {
1815
+ if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
1816
+ return [ null, null, null, hsla[ 3 ] ];
1817
+ }
1818
+ var h = hsla[ 0 ] / 360,
1819
+ s = hsla[ 1 ],
1820
+ l = hsla[ 2 ],
1821
+ a = hsla[ 3 ],
1822
+ q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
1823
+ p = 2 * l - q;
1824
+
1825
+ return [
1826
+ Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
1827
+ Math.round( hue2rgb( p, q, h ) * 255 ),
1828
+ Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
1829
+ a
1830
+ ];
1831
+ };
1832
+
1833
+ each( spaces, function( spaceName, space ) {
1834
+ var props = space.props,
1835
+ cache = space.cache,
1836
+ to = space.to,
1837
+ from = space.from;
1838
+
1839
+ // Makes rgba() and hsla()
1840
+ color.fn[ spaceName ] = function( value ) {
1841
+
1842
+ // Generate a cache for this space if it doesn't exist
1843
+ if ( to && !this[ cache ] ) {
1844
+ this[ cache ] = to( this._rgba );
1845
+ }
1846
+ if ( value === undefined ) {
1847
+ return this[ cache ].slice();
1848
+ }
1849
+
1850
+ var ret,
1851
+ type = jQuery.type( value ),
1852
+ arr = ( type === "array" || type === "object" ) ? value : arguments,
1853
+ local = this[ cache ].slice();
1854
+
1855
+ each( props, function( key, prop ) {
1856
+ var val = arr[ type === "object" ? key : prop.idx ];
1857
+ if ( val == null ) {
1858
+ val = local[ prop.idx ];
1859
+ }
1860
+ local[ prop.idx ] = clamp( val, prop );
1861
+ } );
1862
+
1863
+ if ( from ) {
1864
+ ret = color( from( local ) );
1865
+ ret[ cache ] = local;
1866
+ return ret;
1867
+ } else {
1868
+ return color( local );
1869
+ }
1870
+ };
1871
+
1872
+ // Makes red() green() blue() alpha() hue() saturation() lightness()
1873
+ each( props, function( key, prop ) {
1874
+
1875
+ // Alpha is included in more than one space
1876
+ if ( color.fn[ key ] ) {
1877
+ return;
1878
+ }
1879
+ color.fn[ key ] = function( value ) {
1880
+ var vtype = jQuery.type( value ),
1881
+ fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
1882
+ local = this[ fn ](),
1883
+ cur = local[ prop.idx ],
1884
+ match;
1885
+
1886
+ if ( vtype === "undefined" ) {
1887
+ return cur;
1888
+ }
1889
+
1890
+ if ( vtype === "function" ) {
1891
+ value = value.call( this, cur );
1892
+ vtype = jQuery.type( value );
1893
+ }
1894
+ if ( value == null && prop.empty ) {
1895
+ return this;
1896
+ }
1897
+ if ( vtype === "string" ) {
1898
+ match = rplusequals.exec( value );
1899
+ if ( match ) {
1900
+ value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
1901
+ }
1902
+ }
1903
+ local[ prop.idx ] = value;
1904
+ return this[ fn ]( local );
1905
+ };
1906
+ } );
1907
+ } );
1908
+
1909
+ // Add cssHook and .fx.step function for each named hook.
1910
+ // accept a space separated string of properties
1911
+ color.hook = function( hook ) {
1912
+ var hooks = hook.split( " " );
1913
+ each( hooks, function( i, hook ) {
1914
+ jQuery.cssHooks[ hook ] = {
1915
+ set: function( elem, value ) {
1916
+ var parsed, curElem,
1917
+ backgroundColor = "";
1918
+
1919
+ if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
1920
+ ( parsed = stringParse( value ) ) ) ) {
1921
+ value = color( parsed || value );
1922
+ if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
1923
+ curElem = hook === "backgroundColor" ? elem.parentNode : elem;
1924
+ while (
1925
+ ( backgroundColor === "" || backgroundColor === "transparent" ) &&
1926
+ curElem && curElem.style
1927
+ ) {
1928
+ try {
1929
+ backgroundColor = jQuery.css( curElem, "backgroundColor" );
1930
+ curElem = curElem.parentNode;
1931
+ } catch ( e ) {
1932
+ }
1933
+ }
1934
+
1935
+ value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
1936
+ backgroundColor :
1937
+ "_default" );
1938
+ }
1939
+
1940
+ value = value.toRgbaString();
1941
+ }
1942
+ try {
1943
+ elem.style[ hook ] = value;
1944
+ } catch ( e ) {
1945
+
1946
+ // Wrapped to prevent IE from throwing errors on "invalid" values like
1947
+ // 'auto' or 'inherit'
1948
+ }
1949
+ }
1950
+ };
1951
+ jQuery.fx.step[ hook ] = function( fx ) {
1952
+ if ( !fx.colorInit ) {
1953
+ fx.start = color( fx.elem, hook );
1954
+ fx.end = color( fx.end );
1955
+ fx.colorInit = true;
1956
+ }
1957
+ jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
1958
+ };
1959
+ } );
1960
+
1961
+ };
1962
+
1963
+ color.hook( stepHooks );
1964
+
1965
+ jQuery.cssHooks.borderColor = {
1966
+ expand: function( value ) {
1967
+ var expanded = {};
1968
+
1969
+ each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
1970
+ expanded[ "border" + part + "Color" ] = value;
1971
+ } );
1972
+ return expanded;
1973
+ }
1974
+ };
1975
+
1976
+ // Basic color names only.
1977
+ // Usage of any of the other color names requires adding yourself or including
1978
+ // jquery.color.svg-names.js.
1979
+ colors = jQuery.Color.names = {
1980
+
1981
+ // 4.1. Basic color keywords
1982
+ aqua: "#00ffff",
1983
+ black: "#000000",
1984
+ blue: "#0000ff",
1985
+ fuchsia: "#ff00ff",
1986
+ gray: "#808080",
1987
+ green: "#008000",
1988
+ lime: "#00ff00",
1989
+ maroon: "#800000",
1990
+ navy: "#000080",
1991
+ olive: "#808000",
1992
+ purple: "#800080",
1993
+ red: "#ff0000",
1994
+ silver: "#c0c0c0",
1995
+ teal: "#008080",
1996
+ white: "#ffffff",
1997
+ yellow: "#ffff00",
1998
+
1999
+ // 4.2.3. "transparent" color keyword
2000
+ transparent: [ null, null, null, 0 ],
2001
+
2002
+ _default: "#ffffff"
2003
+ };
2004
+
2005
+ } )( jQuery );
2006
+
2007
+ /******************************************************************************/
2008
+ /****************************** CLASS ANIMATIONS ******************************/
2009
+ /******************************************************************************/
2010
+ ( function() {
2011
+
2012
+ var classAnimationActions = [ "add", "remove", "toggle" ],
2013
+ shorthandStyles = {
2014
+ border: 1,
2015
+ borderBottom: 1,
2016
+ borderColor: 1,
2017
+ borderLeft: 1,
2018
+ borderRight: 1,
2019
+ borderTop: 1,
2020
+ borderWidth: 1,
2021
+ margin: 1,
2022
+ padding: 1
2023
+ };
2024
+
2025
+ $.each(
2026
+ [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
2027
+ function( _, prop ) {
2028
+ $.fx.step[ prop ] = function( fx ) {
2029
+ if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
2030
+ jQuery.style( fx.elem, prop, fx.end );
2031
+ fx.setAttr = true;
2032
+ }
2033
+ };
2034
+ }
2035
+ );
2036
+
2037
+ function getElementStyles( elem ) {
2038
+ var key, len,
2039
+ style = elem.ownerDocument.defaultView ?
2040
+ elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
2041
+ elem.currentStyle,
2042
+ styles = {};
2043
+
2044
+ if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
2045
+ len = style.length;
2046
+ while ( len-- ) {
2047
+ key = style[ len ];
2048
+ if ( typeof style[ key ] === "string" ) {
2049
+ styles[ $.camelCase( key ) ] = style[ key ];
2050
+ }
2051
+ }
2052
+
2053
+ // Support: Opera, IE <9
2054
+ } else {
2055
+ for ( key in style ) {
2056
+ if ( typeof style[ key ] === "string" ) {
2057
+ styles[ key ] = style[ key ];
2058
+ }
2059
+ }
2060
+ }
2061
+
2062
+ return styles;
2063
+ }
2064
+
2065
+ function styleDifference( oldStyle, newStyle ) {
2066
+ var diff = {},
2067
+ name, value;
2068
+
2069
+ for ( name in newStyle ) {
2070
+ value = newStyle[ name ];
2071
+ if ( oldStyle[ name ] !== value ) {
2072
+ if ( !shorthandStyles[ name ] ) {
2073
+ if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
2074
+ diff[ name ] = value;
2075
+ }
2076
+ }
2077
+ }
2078
+ }
2079
+
2080
+ return diff;
2081
+ }
2082
+
2083
+ // Support: jQuery <1.8
2084
+ if ( !$.fn.addBack ) {
2085
+ $.fn.addBack = function( selector ) {
2086
+ return this.add( selector == null ?
2087
+ this.prevObject : this.prevObject.filter( selector )
2088
+ );
2089
+ };
2090
+ }
2091
+
2092
+ $.effects.animateClass = function( value, duration, easing, callback ) {
2093
+ var o = $.speed( duration, easing, callback );
2094
+
2095
+ return this.queue( function() {
2096
+ var animated = $( this ),
2097
+ baseClass = animated.attr( "class" ) || "",
2098
+ applyClassChange,
2099
+ allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
2100
+
2101
+ // Map the animated objects to store the original styles.
2102
+ allAnimations = allAnimations.map( function() {
2103
+ var el = $( this );
2104
+ return {
2105
+ el: el,
2106
+ start: getElementStyles( this )
2107
+ };
2108
+ } );
2109
+
2110
+ // Apply class change
2111
+ applyClassChange = function() {
2112
+ $.each( classAnimationActions, function( i, action ) {
2113
+ if ( value[ action ] ) {
2114
+ animated[ action + "Class" ]( value[ action ] );
2115
+ }
2116
+ } );
2117
+ };
2118
+ applyClassChange();
2119
+
2120
+ // Map all animated objects again - calculate new styles and diff
2121
+ allAnimations = allAnimations.map( function() {
2122
+ this.end = getElementStyles( this.el[ 0 ] );
2123
+ this.diff = styleDifference( this.start, this.end );
2124
+ return this;
2125
+ } );
2126
+
2127
+ // Apply original class
2128
+ animated.attr( "class", baseClass );
2129
+
2130
+ // Map all animated objects again - this time collecting a promise
2131
+ allAnimations = allAnimations.map( function() {
2132
+ var styleInfo = this,
2133
+ dfd = $.Deferred(),
2134
+ opts = $.extend( {}, o, {
2135
+ queue: false,
2136
+ complete: function() {
2137
+ dfd.resolve( styleInfo );
2138
+ }
2139
+ } );
2140
+
2141
+ this.el.animate( this.diff, opts );
2142
+ return dfd.promise();
2143
+ } );
2144
+
2145
+ // Once all animations have completed:
2146
+ $.when.apply( $, allAnimations.get() ).done( function() {
2147
+
2148
+ // Set the final class
2149
+ applyClassChange();
2150
+
2151
+ // For each animated element,
2152
+ // clear all css properties that were animated
2153
+ $.each( arguments, function() {
2154
+ var el = this.el;
2155
+ $.each( this.diff, function( key ) {
2156
+ el.css( key, "" );
2157
+ } );
2158
+ } );
2159
+
2160
+ // This is guarnteed to be there if you use jQuery.speed()
2161
+ // it also handles dequeuing the next anim...
2162
+ o.complete.call( animated[ 0 ] );
2163
+ } );
2164
+ } );
2165
+ };
2166
+
2167
+ $.fn.extend( {
2168
+ addClass: ( function( orig ) {
2169
+ return function( classNames, speed, easing, callback ) {
2170
+ return speed ?
2171
+ $.effects.animateClass.call( this,
2172
+ { add: classNames }, speed, easing, callback ) :
2173
+ orig.apply( this, arguments );
2174
+ };
2175
+ } )( $.fn.addClass ),
2176
+
2177
+ removeClass: ( function( orig ) {
2178
+ return function( classNames, speed, easing, callback ) {
2179
+ return arguments.length > 1 ?
2180
+ $.effects.animateClass.call( this,
2181
+ { remove: classNames }, speed, easing, callback ) :
2182
+ orig.apply( this, arguments );
2183
+ };
2184
+ } )( $.fn.removeClass ),
2185
+
2186
+ toggleClass: ( function( orig ) {
2187
+ return function( classNames, force, speed, easing, callback ) {
2188
+ if ( typeof force === "boolean" || force === undefined ) {
2189
+ if ( !speed ) {
2190
+
2191
+ // Without speed parameter
2192
+ return orig.apply( this, arguments );
2193
+ } else {
2194
+ return $.effects.animateClass.call( this,
2195
+ ( force ? { add: classNames } : { remove: classNames } ),
2196
+ speed, easing, callback );
2197
+ }
2198
+ } else {
2199
+
2200
+ // Without force parameter
2201
+ return $.effects.animateClass.call( this,
2202
+ { toggle: classNames }, force, speed, easing );
2203
+ }
2204
+ };
2205
+ } )( $.fn.toggleClass ),
2206
+
2207
+ switchClass: function( remove, add, speed, easing, callback ) {
2208
+ return $.effects.animateClass.call( this, {
2209
+ add: add,
2210
+ remove: remove
2211
+ }, speed, easing, callback );
2212
+ }
2213
+ } );
2214
+
2215
+ } )();
2216
+
2217
+ /******************************************************************************/
2218
+ /*********************************** EFFECTS **********************************/
2219
+ /******************************************************************************/
2220
+
2221
+ ( function() {
2222
+
2223
+ if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
2224
+ $.expr.filters.animated = ( function( orig ) {
2225
+ return function( elem ) {
2226
+ return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
2227
+ };
2228
+ } )( $.expr.filters.animated );
2229
+ }
2230
+
2231
+ if ( $.uiBackCompat !== false ) {
2232
+ $.extend( $.effects, {
2233
+
2234
+ // Saves a set of properties in a data storage
2235
+ save: function( element, set ) {
2236
+ var i = 0, length = set.length;
2237
+ for ( ; i < length; i++ ) {
2238
+ if ( set[ i ] !== null ) {
2239
+ element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
2240
+ }
2241
+ }
2242
+ },
2243
+
2244
+ // Restores a set of previously saved properties from a data storage
2245
+ restore: function( element, set ) {
2246
+ var val, i = 0, length = set.length;
2247
+ for ( ; i < length; i++ ) {
2248
+ if ( set[ i ] !== null ) {
2249
+ val = element.data( dataSpace + set[ i ] );
2250
+ element.css( set[ i ], val );
2251
+ }
2252
+ }
2253
+ },
2254
+
2255
+ setMode: function( el, mode ) {
2256
+ if ( mode === "toggle" ) {
2257
+ mode = el.is( ":hidden" ) ? "show" : "hide";
2258
+ }
2259
+ return mode;
2260
+ },
2261
+
2262
+ // Wraps the element around a wrapper that copies position properties
2263
+ createWrapper: function( element ) {
2264
+
2265
+ // If the element is already wrapped, return it
2266
+ if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2267
+ return element.parent();
2268
+ }
2269
+
2270
+ // Wrap the element
2271
+ var props = {
2272
+ width: element.outerWidth( true ),
2273
+ height: element.outerHeight( true ),
2274
+ "float": element.css( "float" )
2275
+ },
2276
+ wrapper = $( "<div></div>" )
2277
+ .addClass( "ui-effects-wrapper" )
2278
+ .css( {
2279
+ fontSize: "100%",
2280
+ background: "transparent",
2281
+ border: "none",
2282
+ margin: 0,
2283
+ padding: 0
2284
+ } ),
2285
+
2286
+ // Store the size in case width/height are defined in % - Fixes #5245
2287
+ size = {
2288
+ width: element.width(),
2289
+ height: element.height()
2290
+ },
2291
+ active = document.activeElement;
2292
+
2293
+ // Support: Firefox
2294
+ // Firefox incorrectly exposes anonymous content
2295
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
2296
+ try {
2297
+ active.id;
2298
+ } catch ( e ) {
2299
+ active = document.body;
2300
+ }
2301
+
2302
+ element.wrap( wrapper );
2303
+
2304
+ // Fixes #7595 - Elements lose focus when wrapped.
2305
+ if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2306
+ $( active ).trigger( "focus" );
2307
+ }
2308
+
2309
+ // Hotfix for jQuery 1.4 since some change in wrap() seems to actually
2310
+ // lose the reference to the wrapped element
2311
+ wrapper = element.parent();
2312
+
2313
+ // Transfer positioning properties to the wrapper
2314
+ if ( element.css( "position" ) === "static" ) {
2315
+ wrapper.css( { position: "relative" } );
2316
+ element.css( { position: "relative" } );
2317
+ } else {
2318
+ $.extend( props, {
2319
+ position: element.css( "position" ),
2320
+ zIndex: element.css( "z-index" )
2321
+ } );
2322
+ $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
2323
+ props[ pos ] = element.css( pos );
2324
+ if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
2325
+ props[ pos ] = "auto";
2326
+ }
2327
+ } );
2328
+ element.css( {
2329
+ position: "relative",
2330
+ top: 0,
2331
+ left: 0,
2332
+ right: "auto",
2333
+ bottom: "auto"
2334
+ } );
2335
+ }
2336
+ element.css( size );
2337
+
2338
+ return wrapper.css( props ).show();
2339
+ },
2340
+
2341
+ removeWrapper: function( element ) {
2342
+ var active = document.activeElement;
2343
+
2344
+ if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2345
+ element.parent().replaceWith( element );
2346
+
2347
+ // Fixes #7595 - Elements lose focus when wrapped.
2348
+ if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2349
+ $( active ).trigger( "focus" );
2350
+ }
2351
+ }
2352
+
2353
+ return element;
2354
+ }
2355
+ } );
2356
+ }
2357
+
2358
+ $.extend( $.effects, {
2359
+ version: "1.12.1",
2360
+
2361
+ define: function( name, mode, effect ) {
2362
+ if ( !effect ) {
2363
+ effect = mode;
2364
+ mode = "effect";
2365
+ }
2366
+
2367
+ $.effects.effect[ name ] = effect;
2368
+ $.effects.effect[ name ].mode = mode;
2369
+
2370
+ return effect;
2371
+ },
2372
+
2373
+ scaledDimensions: function( element, percent, direction ) {
2374
+ if ( percent === 0 ) {
2375
+ return {
2376
+ height: 0,
2377
+ width: 0,
2378
+ outerHeight: 0,
2379
+ outerWidth: 0
2380
+ };
2381
+ }
2382
+
2383
+ var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
2384
+ y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
2385
+
2386
+ return {
2387
+ height: element.height() * y,
2388
+ width: element.width() * x,
2389
+ outerHeight: element.outerHeight() * y,
2390
+ outerWidth: element.outerWidth() * x
2391
+ };
2392
+
2393
+ },
2394
+
2395
+ clipToBox: function( animation ) {
2396
+ return {
2397
+ width: animation.clip.right - animation.clip.left,
2398
+ height: animation.clip.bottom - animation.clip.top,
2399
+ left: animation.clip.left,
2400
+ top: animation.clip.top
2401
+ };
2402
+ },
2403
+
2404
+ // Injects recently queued functions to be first in line (after "inprogress")
2405
+ unshift: function( element, queueLength, count ) {
2406
+ var queue = element.queue();
2407
+
2408
+ if ( queueLength > 1 ) {
2409
+ queue.splice.apply( queue,
2410
+ [ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
2411
+ }
2412
+ element.dequeue();
2413
+ },
2414
+
2415
+ saveStyle: function( element ) {
2416
+ element.data( dataSpaceStyle, element[ 0 ].style.cssText );
2417
+ },
2418
+
2419
+ restoreStyle: function( element ) {
2420
+ element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
2421
+ element.removeData( dataSpaceStyle );
2422
+ },
2423
+
2424
+ mode: function( element, mode ) {
2425
+ var hidden = element.is( ":hidden" );
2426
+
2427
+ if ( mode === "toggle" ) {
2428
+ mode = hidden ? "show" : "hide";
2429
+ }
2430
+ if ( hidden ? mode === "hide" : mode === "show" ) {
2431
+ mode = "none";
2432
+ }
2433
+ return mode;
2434
+ },
2435
+
2436
+ // Translates a [top,left] array into a baseline value
2437
+ getBaseline: function( origin, original ) {
2438
+ var y, x;
2439
+
2440
+ switch ( origin[ 0 ] ) {
2441
+ case "top":
2442
+ y = 0;
2443
+ break;
2444
+ case "middle":
2445
+ y = 0.5;
2446
+ break;
2447
+ case "bottom":
2448
+ y = 1;
2449
+ break;
2450
+ default:
2451
+ y = origin[ 0 ] / original.height;
2452
+ }
2453
+
2454
+ switch ( origin[ 1 ] ) {
2455
+ case "left":
2456
+ x = 0;
2457
+ break;
2458
+ case "center":
2459
+ x = 0.5;
2460
+ break;
2461
+ case "right":
2462
+ x = 1;
2463
+ break;
2464
+ default:
2465
+ x = origin[ 1 ] / original.width;
2466
+ }
2467
+
2468
+ return {
2469
+ x: x,
2470
+ y: y
2471
+ };
2472
+ },
2473
+
2474
+ // Creates a placeholder element so that the original element can be made absolute
2475
+ createPlaceholder: function( element ) {
2476
+ var placeholder,
2477
+ cssPosition = element.css( "position" ),
2478
+ position = element.position();
2479
+
2480
+ // Lock in margins first to account for form elements, which
2481
+ // will change margin if you explicitly set height
2482
+ // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
2483
+ // Support: Safari
2484
+ element.css( {
2485
+ marginTop: element.css( "marginTop" ),
2486
+ marginBottom: element.css( "marginBottom" ),
2487
+ marginLeft: element.css( "marginLeft" ),
2488
+ marginRight: element.css( "marginRight" )
2489
+ } )
2490
+ .outerWidth( element.outerWidth() )
2491
+ .outerHeight( element.outerHeight() );
2492
+
2493
+ if ( /^(static|relative)/.test( cssPosition ) ) {
2494
+ cssPosition = "absolute";
2495
+
2496
+ placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
2497
+
2498
+ // Convert inline to inline block to account for inline elements
2499
+ // that turn to inline block based on content (like img)
2500
+ display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
2501
+ "inline-block" :
2502
+ "block",
2503
+ visibility: "hidden",
2504
+
2505
+ // Margins need to be set to account for margin collapse
2506
+ marginTop: element.css( "marginTop" ),
2507
+ marginBottom: element.css( "marginBottom" ),
2508
+ marginLeft: element.css( "marginLeft" ),
2509
+ marginRight: element.css( "marginRight" ),
2510
+ "float": element.css( "float" )
2511
+ } )
2512
+ .outerWidth( element.outerWidth() )
2513
+ .outerHeight( element.outerHeight() )
2514
+ .addClass( "ui-effects-placeholder" );
2515
+
2516
+ element.data( dataSpace + "placeholder", placeholder );
2517
+ }
2518
+
2519
+ element.css( {
2520
+ position: cssPosition,
2521
+ left: position.left,
2522
+ top: position.top
2523
+ } );
2524
+
2525
+ return placeholder;
2526
+ },
2527
+
2528
+ removePlaceholder: function( element ) {
2529
+ var dataKey = dataSpace + "placeholder",
2530
+ placeholder = element.data( dataKey );
2531
+
2532
+ if ( placeholder ) {
2533
+ placeholder.remove();
2534
+ element.removeData( dataKey );
2535
+ }
2536
+ },
2537
+
2538
+ // Removes a placeholder if it exists and restores
2539
+ // properties that were modified during placeholder creation
2540
+ cleanUp: function( element ) {
2541
+ $.effects.restoreStyle( element );
2542
+ $.effects.removePlaceholder( element );
2543
+ },
2544
+
2545
+ setTransition: function( element, list, factor, value ) {
2546
+ value = value || {};
2547
+ $.each( list, function( i, x ) {
2548
+ var unit = element.cssUnit( x );
2549
+ if ( unit[ 0 ] > 0 ) {
2550
+ value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
2551
+ }
2552
+ } );
2553
+ return value;
2554
+ }
2555
+ } );
2556
+
2557
+ // Return an effect options object for the given parameters:
2558
+ function _normalizeArguments( effect, options, speed, callback ) {
2559
+
2560
+ // Allow passing all options as the first parameter
2561
+ if ( $.isPlainObject( effect ) ) {
2562
+ options = effect;
2563
+ effect = effect.effect;
2564
+ }
2565
+
2566
+ // Convert to an object
2567
+ effect = { effect: effect };
2568
+
2569
+ // Catch (effect, null, ...)
2570
+ if ( options == null ) {
2571
+ options = {};
2572
+ }
2573
+
2574
+ // Catch (effect, callback)
2575
+ if ( $.isFunction( options ) ) {
2576
+ callback = options;
2577
+ speed = null;
2578
+ options = {};
2579
+ }
2580
+
2581
+ // Catch (effect, speed, ?)
2582
+ if ( typeof options === "number" || $.fx.speeds[ options ] ) {
2583
+ callback = speed;
2584
+ speed = options;
2585
+ options = {};
2586
+ }
2587
+
2588
+ // Catch (effect, options, callback)
2589
+ if ( $.isFunction( speed ) ) {
2590
+ callback = speed;
2591
+ speed = null;
2592
+ }
2593
+
2594
+ // Add options to effect
2595
+ if ( options ) {
2596
+ $.extend( effect, options );
2597
+ }
2598
+
2599
+ speed = speed || options.duration;
2600
+ effect.duration = $.fx.off ? 0 :
2601
+ typeof speed === "number" ? speed :
2602
+ speed in $.fx.speeds ? $.fx.speeds[ speed ] :
2603
+ $.fx.speeds._default;
2604
+
2605
+ effect.complete = callback || options.complete;
2606
+
2607
+ return effect;
2608
+ }
2609
+
2610
+ function standardAnimationOption( option ) {
2611
+
2612
+ // Valid standard speeds (nothing, number, named speed)
2613
+ if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
2614
+ return true;
2615
+ }
2616
+
2617
+ // Invalid strings - treat as "normal" speed
2618
+ if ( typeof option === "string" && !$.effects.effect[ option ] ) {
2619
+ return true;
2620
+ }
2621
+
2622
+ // Complete callback
2623
+ if ( $.isFunction( option ) ) {
2624
+ return true;
2625
+ }
2626
+
2627
+ // Options hash (but not naming an effect)
2628
+ if ( typeof option === "object" && !option.effect ) {
2629
+ return true;
2630
+ }
2631
+
2632
+ // Didn't match any standard API
2633
+ return false;
2634
+ }
2635
+
2636
+ $.fn.extend( {
2637
+ effect: function( /* effect, options, speed, callback */ ) {
2638
+ var args = _normalizeArguments.apply( this, arguments ),
2639
+ effectMethod = $.effects.effect[ args.effect ],
2640
+ defaultMode = effectMethod.mode,
2641
+ queue = args.queue,
2642
+ queueName = queue || "fx",
2643
+ complete = args.complete,
2644
+ mode = args.mode,
2645
+ modes = [],
2646
+ prefilter = function( next ) {
2647
+ var el = $( this ),
2648
+ normalizedMode = $.effects.mode( el, mode ) || defaultMode;
2649
+
2650
+ // Sentinel for duck-punching the :animated psuedo-selector
2651
+ el.data( dataSpaceAnimated, true );
2652
+
2653
+ // Save effect mode for later use,
2654
+ // we can't just call $.effects.mode again later,
2655
+ // as the .show() below destroys the initial state
2656
+ modes.push( normalizedMode );
2657
+
2658
+ // See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
2659
+ if ( defaultMode && ( normalizedMode === "show" ||
2660
+ ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
2661
+ el.show();
2662
+ }
2663
+
2664
+ if ( !defaultMode || normalizedMode !== "none" ) {
2665
+ $.effects.saveStyle( el );
2666
+ }
2667
+
2668
+ if ( $.isFunction( next ) ) {
2669
+ next();
2670
+ }
2671
+ };
2672
+
2673
+ if ( $.fx.off || !effectMethod ) {
2674
+
2675
+ // Delegate to the original method (e.g., .show()) if possible
2676
+ if ( mode ) {
2677
+ return this[ mode ]( args.duration, complete );
2678
+ } else {
2679
+ return this.each( function() {
2680
+ if ( complete ) {
2681
+ complete.call( this );
2682
+ }
2683
+ } );
2684
+ }
2685
+ }
2686
+
2687
+ function run( next ) {
2688
+ var elem = $( this );
2689
+
2690
+ function cleanup() {
2691
+ elem.removeData( dataSpaceAnimated );
2692
+
2693
+ $.effects.cleanUp( elem );
2694
+
2695
+ if ( args.mode === "hide" ) {
2696
+ elem.hide();
2697
+ }
2698
+
2699
+ done();
2700
+ }
2701
+
2702
+ function done() {
2703
+ if ( $.isFunction( complete ) ) {
2704
+ complete.call( elem[ 0 ] );
2705
+ }
2706
+
2707
+ if ( $.isFunction( next ) ) {
2708
+ next();
2709
+ }
2710
+ }
2711
+
2712
+ // Override mode option on a per element basis,
2713
+ // as toggle can be either show or hide depending on element state
2714
+ args.mode = modes.shift();
2715
+
2716
+ if ( $.uiBackCompat !== false && !defaultMode ) {
2717
+ if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
2718
+
2719
+ // Call the core method to track "olddisplay" properly
2720
+ elem[ mode ]();
2721
+ done();
2722
+ } else {
2723
+ effectMethod.call( elem[ 0 ], args, done );
2724
+ }
2725
+ } else {
2726
+ if ( args.mode === "none" ) {
2727
+
2728
+ // Call the core method to track "olddisplay" properly
2729
+ elem[ mode ]();
2730
+ done();
2731
+ } else {
2732
+ effectMethod.call( elem[ 0 ], args, cleanup );
2733
+ }
2734
+ }
2735
+ }
2736
+
2737
+ // Run prefilter on all elements first to ensure that
2738
+ // any showing or hiding happens before placeholder creation,
2739
+ // which ensures that any layout changes are correctly captured.
2740
+ return queue === false ?
2741
+ this.each( prefilter ).each( run ) :
2742
+ this.queue( queueName, prefilter ).queue( queueName, run );
2743
+ },
2744
+
2745
+ show: ( function( orig ) {
2746
+ return function( option ) {
2747
+ if ( standardAnimationOption( option ) ) {
2748
+ return orig.apply( this, arguments );
2749
+ } else {
2750
+ var args = _normalizeArguments.apply( this, arguments );
2751
+ args.mode = "show";
2752
+ return this.effect.call( this, args );
2753
+ }
2754
+ };
2755
+ } )( $.fn.show ),
2756
+
2757
+ hide: ( function( orig ) {
2758
+ return function( option ) {
2759
+ if ( standardAnimationOption( option ) ) {
2760
+ return orig.apply( this, arguments );
2761
+ } else {
2762
+ var args = _normalizeArguments.apply( this, arguments );
2763
+ args.mode = "hide";
2764
+ return this.effect.call( this, args );
2765
+ }
2766
+ };
2767
+ } )( $.fn.hide ),
2768
+
2769
+ toggle: ( function( orig ) {
2770
+ return function( option ) {
2771
+ if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
2772
+ return orig.apply( this, arguments );
2773
+ } else {
2774
+ var args = _normalizeArguments.apply( this, arguments );
2775
+ args.mode = "toggle";
2776
+ return this.effect.call( this, args );
2777
+ }
2778
+ };
2779
+ } )( $.fn.toggle ),
2780
+
2781
+ cssUnit: function( key ) {
2782
+ var style = this.css( key ),
2783
+ val = [];
2784
+
2785
+ $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
2786
+ if ( style.indexOf( unit ) > 0 ) {
2787
+ val = [ parseFloat( style ), unit ];
2788
+ }
2789
+ } );
2790
+ return val;
2791
+ },
2792
+
2793
+ cssClip: function( clipObj ) {
2794
+ if ( clipObj ) {
2795
+ return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
2796
+ clipObj.bottom + "px " + clipObj.left + "px)" );
2797
+ }
2798
+ return parseClip( this.css( "clip" ), this );
2799
+ },
2800
+
2801
+ transfer: function( options, done ) {
2802
+ var element = $( this ),
2803
+ target = $( options.to ),
2804
+ targetFixed = target.css( "position" ) === "fixed",
2805
+ body = $( "body" ),
2806
+ fixTop = targetFixed ? body.scrollTop() : 0,
2807
+ fixLeft = targetFixed ? body.scrollLeft() : 0,
2808
+ endPosition = target.offset(),
2809
+ animation = {
2810
+ top: endPosition.top - fixTop,
2811
+ left: endPosition.left - fixLeft,
2812
+ height: target.innerHeight(),
2813
+ width: target.innerWidth()
2814
+ },
2815
+ startPosition = element.offset(),
2816
+ transfer = $( "<div class='ui-effects-transfer'></div>" )
2817
+ .appendTo( "body" )
2818
+ .addClass( options.className )
2819
+ .css( {
2820
+ top: startPosition.top - fixTop,
2821
+ left: startPosition.left - fixLeft,
2822
+ height: element.innerHeight(),
2823
+ width: element.innerWidth(),
2824
+ position: targetFixed ? "fixed" : "absolute"
2825
+ } )
2826
+ .animate( animation, options.duration, options.easing, function() {
2827
+ transfer.remove();
2828
+ if ( $.isFunction( done ) ) {
2829
+ done();
2830
+ }
2831
+ } );
2832
+ }
2833
+ } );
2834
+
2835
+ function parseClip( str, element ) {
2836
+ var outerWidth = element.outerWidth(),
2837
+ outerHeight = element.outerHeight(),
2838
+ clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
2839
+ values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
2840
+
2841
+ return {
2842
+ top: parseFloat( values[ 1 ] ) || 0,
2843
+ right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
2844
+ bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
2845
+ left: parseFloat( values[ 4 ] ) || 0
2846
+ };
2847
+ }
2848
+
2849
+ $.fx.step.clip = function( fx ) {
2850
+ if ( !fx.clipInit ) {
2851
+ fx.start = $( fx.elem ).cssClip();
2852
+ if ( typeof fx.end === "string" ) {
2853
+ fx.end = parseClip( fx.end, fx.elem );
2854
+ }
2855
+ fx.clipInit = true;
2856
+ }
2857
+
2858
+ $( fx.elem ).cssClip( {
2859
+ top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
2860
+ right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
2861
+ bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
2862
+ left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
2863
+ } );
2864
+ };
2865
+
2866
+ } )();
2867
+
2868
+ /******************************************************************************/
2869
+ /*********************************** EASING ***********************************/
2870
+ /******************************************************************************/
2871
+
2872
+ ( function() {
2873
+
2874
+ // Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
2875
+
2876
+ var baseEasings = {};
2877
+
2878
+ $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
2879
+ baseEasings[ name ] = function( p ) {
2880
+ return Math.pow( p, i + 2 );
2881
+ };
2882
+ } );
2883
+
2884
+ $.extend( baseEasings, {
2885
+ Sine: function( p ) {
2886
+ return 1 - Math.cos( p * Math.PI / 2 );
2887
+ },
2888
+ Circ: function( p ) {
2889
+ return 1 - Math.sqrt( 1 - p * p );
2890
+ },
2891
+ Elastic: function( p ) {
2892
+ return p === 0 || p === 1 ? p :
2893
+ -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
2894
+ },
2895
+ Back: function( p ) {
2896
+ return p * p * ( 3 * p - 2 );
2897
+ },
2898
+ Bounce: function( p ) {
2899
+ var pow2,
2900
+ bounce = 4;
2901
+
2902
+ while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
2903
+ return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
2904
+ }
2905
+ } );
2906
+
2907
+ $.each( baseEasings, function( name, easeIn ) {
2908
+ $.easing[ "easeIn" + name ] = easeIn;
2909
+ $.easing[ "easeOut" + name ] = function( p ) {
2910
+ return 1 - easeIn( 1 - p );
2911
+ };
2912
+ $.easing[ "easeInOut" + name ] = function( p ) {
2913
+ return p < 0.5 ?
2914
+ easeIn( p * 2 ) / 2 :
2915
+ 1 - easeIn( p * -2 + 2 ) / 2;
2916
+ };
2917
+ } );
2918
+
2919
+ } )();
2920
+
2921
+ var effect = $.effects;
2922
+
2923
+
2924
+ /*!
2925
+ * jQuery UI Effects Blind 1.12.1
2926
+ * http://jqueryui.com
2927
+ *
2928
+ * Copyright jQuery Foundation and other contributors
2929
+ * Released under the MIT license.
2930
+ * http://jquery.org/license
2931
+ */
2932
+
2933
+ //>>label: Blind Effect
2934
+ //>>group: Effects
2935
+ //>>description: Blinds the element.
2936
+ //>>docs: http://api.jqueryui.com/blind-effect/
2937
+ //>>demos: http://jqueryui.com/effect/
2938
+
2939
+
2940
+
2941
+ var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
2942
+ var map = {
2943
+ up: [ "bottom", "top" ],
2944
+ vertical: [ "bottom", "top" ],
2945
+ down: [ "top", "bottom" ],
2946
+ left: [ "right", "left" ],
2947
+ horizontal: [ "right", "left" ],
2948
+ right: [ "left", "right" ]
2949
+ },
2950
+ element = $( this ),
2951
+ direction = options.direction || "up",
2952
+ start = element.cssClip(),
2953
+ animate = { clip: $.extend( {}, start ) },
2954
+ placeholder = $.effects.createPlaceholder( element );
2955
+
2956
+ animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
2957
+
2958
+ if ( options.mode === "show" ) {
2959
+ element.cssClip( animate.clip );
2960
+ if ( placeholder ) {
2961
+ placeholder.css( $.effects.clipToBox( animate ) );
2962
+ }
2963
+
2964
+ animate.clip = start;
2965
+ }
2966
+
2967
+ if ( placeholder ) {
2968
+ placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
2969
+ }
2970
+
2971
+ element.animate( animate, {
2972
+ queue: false,
2973
+ duration: options.duration,
2974
+ easing: options.easing,
2975
+ complete: done
2976
+ } );
2977
+ } );
2978
+
2979
+
2980
+ /*!
2981
+ * jQuery UI Effects Bounce 1.12.1
2982
+ * http://jqueryui.com
2983
+ *
2984
+ * Copyright jQuery Foundation and other contributors
2985
+ * Released under the MIT license.
2986
+ * http://jquery.org/license
2987
+ */
2988
+
2989
+ //>>label: Bounce Effect
2990
+ //>>group: Effects
2991
+ //>>description: Bounces an element horizontally or vertically n times.
2992
+ //>>docs: http://api.jqueryui.com/bounce-effect/
2993
+ //>>demos: http://jqueryui.com/effect/
2994
+
2995
+
2996
+
2997
+ var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
2998
+ var upAnim, downAnim, refValue,
2999
+ element = $( this ),
3000
+
3001
+ // Defaults:
3002
+ mode = options.mode,
3003
+ hide = mode === "hide",
3004
+ show = mode === "show",
3005
+ direction = options.direction || "up",
3006
+ distance = options.distance,
3007
+ times = options.times || 5,
3008
+
3009
+ // Number of internal animations
3010
+ anims = times * 2 + ( show || hide ? 1 : 0 ),
3011
+ speed = options.duration / anims,
3012
+ easing = options.easing,
3013
+
3014
+ // Utility:
3015
+ ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3016
+ motion = ( direction === "up" || direction === "left" ),
3017
+ i = 0,
3018
+
3019
+ queuelen = element.queue().length;
3020
+
3021
+ $.effects.createPlaceholder( element );
3022
+
3023
+ refValue = element.css( ref );
3024
+
3025
+ // Default distance for the BIGGEST bounce is the outer Distance / 3
3026
+ if ( !distance ) {
3027
+ distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
3028
+ }
3029
+
3030
+ if ( show ) {
3031
+ downAnim = { opacity: 1 };
3032
+ downAnim[ ref ] = refValue;
3033
+
3034
+ // If we are showing, force opacity 0 and set the initial position
3035
+ // then do the "first" animation
3036
+ element
3037
+ .css( "opacity", 0 )
3038
+ .css( ref, motion ? -distance * 2 : distance * 2 )
3039
+ .animate( downAnim, speed, easing );
3040
+ }
3041
+
3042
+ // Start at the smallest distance if we are hiding
3043
+ if ( hide ) {
3044
+ distance = distance / Math.pow( 2, times - 1 );
3045
+ }
3046
+
3047
+ downAnim = {};
3048
+ downAnim[ ref ] = refValue;
3049
+
3050
+ // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
3051
+ for ( ; i < times; i++ ) {
3052
+ upAnim = {};
3053
+ upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3054
+
3055
+ element
3056
+ .animate( upAnim, speed, easing )
3057
+ .animate( downAnim, speed, easing );
3058
+
3059
+ distance = hide ? distance * 2 : distance / 2;
3060
+ }
3061
+
3062
+ // Last Bounce when Hiding
3063
+ if ( hide ) {
3064
+ upAnim = { opacity: 0 };
3065
+ upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3066
+
3067
+ element.animate( upAnim, speed, easing );
3068
+ }
3069
+
3070
+ element.queue( done );
3071
+
3072
+ $.effects.unshift( element, queuelen, anims + 1 );
3073
+ } );
3074
+
3075
+
3076
+ /*!
3077
+ * jQuery UI Effects Clip 1.12.1
3078
+ * http://jqueryui.com
3079
+ *
3080
+ * Copyright jQuery Foundation and other contributors
3081
+ * Released under the MIT license.
3082
+ * http://jquery.org/license
3083
+ */
3084
+
3085
+ //>>label: Clip Effect
3086
+ //>>group: Effects
3087
+ //>>description: Clips the element on and off like an old TV.
3088
+ //>>docs: http://api.jqueryui.com/clip-effect/
3089
+ //>>demos: http://jqueryui.com/effect/
3090
+
3091
+
3092
+
3093
+ var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
3094
+ var start,
3095
+ animate = {},
3096
+ element = $( this ),
3097
+ direction = options.direction || "vertical",
3098
+ both = direction === "both",
3099
+ horizontal = both || direction === "horizontal",
3100
+ vertical = both || direction === "vertical";
3101
+
3102
+ start = element.cssClip();
3103
+ animate.clip = {
3104
+ top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
3105
+ right: horizontal ? ( start.right - start.left ) / 2 : start.right,
3106
+ bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
3107
+ left: horizontal ? ( start.right - start.left ) / 2 : start.left
3108
+ };
3109
+
3110
+ $.effects.createPlaceholder( element );
3111
+
3112
+ if ( options.mode === "show" ) {
3113
+ element.cssClip( animate.clip );
3114
+ animate.clip = start;
3115
+ }
3116
+
3117
+ element.animate( animate, {
3118
+ queue: false,
3119
+ duration: options.duration,
3120
+ easing: options.easing,
3121
+ complete: done
3122
+ } );
3123
+
3124
+ } );
3125
+
3126
+
3127
+ /*!
3128
+ * jQuery UI Effects Drop 1.12.1
3129
+ * http://jqueryui.com
3130
+ *
3131
+ * Copyright jQuery Foundation and other contributors
3132
+ * Released under the MIT license.
3133
+ * http://jquery.org/license
3134
+ */
3135
+
3136
+ //>>label: Drop Effect
3137
+ //>>group: Effects
3138
+ //>>description: Moves an element in one direction and hides it at the same time.
3139
+ //>>docs: http://api.jqueryui.com/drop-effect/
3140
+ //>>demos: http://jqueryui.com/effect/
3141
+
3142
+
3143
+
3144
+ var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
3145
+
3146
+ var distance,
3147
+ element = $( this ),
3148
+ mode = options.mode,
3149
+ show = mode === "show",
3150
+ direction = options.direction || "left",
3151
+ ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3152
+ motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
3153
+ oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
3154
+ animation = {
3155
+ opacity: 0
3156
+ };
3157
+
3158
+ $.effects.createPlaceholder( element );
3159
+
3160
+ distance = options.distance ||
3161
+ element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
3162
+
3163
+ animation[ ref ] = motion + distance;
3164
+
3165
+ if ( show ) {
3166
+ element.css( animation );
3167
+
3168
+ animation[ ref ] = oppositeMotion + distance;
3169
+ animation.opacity = 1;
3170
+ }
3171
+
3172
+ // Animate
3173
+ element.animate( animation, {
3174
+ queue: false,
3175
+ duration: options.duration,
3176
+ easing: options.easing,
3177
+ complete: done
3178
+ } );
3179
+ } );
3180
+
3181
+
3182
+ /*!
3183
+ * jQuery UI Effects Explode 1.12.1
3184
+ * http://jqueryui.com
3185
+ *
3186
+ * Copyright jQuery Foundation and other contributors
3187
+ * Released under the MIT license.
3188
+ * http://jquery.org/license
3189
+ */
3190
+
3191
+ //>>label: Explode Effect
3192
+ //>>group: Effects
3193
+ // jscs:disable maximumLineLength
3194
+ //>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
3195
+ // jscs:enable maximumLineLength
3196
+ //>>docs: http://api.jqueryui.com/explode-effect/
3197
+ //>>demos: http://jqueryui.com/effect/
3198
+
3199
+
3200
+
3201
+ var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
3202
+
3203
+ var i, j, left, top, mx, my,
3204
+ rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
3205
+ cells = rows,
3206
+ element = $( this ),
3207
+ mode = options.mode,
3208
+ show = mode === "show",
3209
+
3210
+ // Show and then visibility:hidden the element before calculating offset
3211
+ offset = element.show().css( "visibility", "hidden" ).offset(),
3212
+
3213
+ // Width and height of a piece
3214
+ width = Math.ceil( element.outerWidth() / cells ),
3215
+ height = Math.ceil( element.outerHeight() / rows ),
3216
+ pieces = [];
3217
+
3218
+ // Children animate complete:
3219
+ function childComplete() {
3220
+ pieces.push( this );
3221
+ if ( pieces.length === rows * cells ) {
3222
+ animComplete();
3223
+ }
3224
+ }
3225
+
3226
+ // Clone the element for each row and cell.
3227
+ for ( i = 0; i < rows; i++ ) { // ===>
3228
+ top = offset.top + i * height;
3229
+ my = i - ( rows - 1 ) / 2;
3230
+
3231
+ for ( j = 0; j < cells; j++ ) { // |||
3232
+ left = offset.left + j * width;
3233
+ mx = j - ( cells - 1 ) / 2;
3234
+
3235
+ // Create a clone of the now hidden main element that will be absolute positioned
3236
+ // within a wrapper div off the -left and -top equal to size of our pieces
3237
+ element
3238
+ .clone()
3239
+ .appendTo( "body" )
3240
+ .wrap( "<div></div>" )
3241
+ .css( {
3242
+ position: "absolute",
3243
+ visibility: "visible",
3244
+ left: -j * width,
3245
+ top: -i * height
3246
+ } )
3247
+
3248
+ // Select the wrapper - make it overflow: hidden and absolute positioned based on
3249
+ // where the original was located +left and +top equal to the size of pieces
3250
+ .parent()
3251
+ .addClass( "ui-effects-explode" )
3252
+ .css( {
3253
+ position: "absolute",
3254
+ overflow: "hidden",
3255
+ width: width,
3256
+ height: height,
3257
+ left: left + ( show ? mx * width : 0 ),
3258
+ top: top + ( show ? my * height : 0 ),
3259
+ opacity: show ? 0 : 1
3260
+ } )
3261
+ .animate( {
3262
+ left: left + ( show ? 0 : mx * width ),
3263
+ top: top + ( show ? 0 : my * height ),
3264
+ opacity: show ? 1 : 0
3265
+ }, options.duration || 500, options.easing, childComplete );
3266
+ }
3267
+ }
3268
+
3269
+ function animComplete() {
3270
+ element.css( {
3271
+ visibility: "visible"
3272
+ } );
3273
+ $( pieces ).remove();
3274
+ done();
3275
+ }
3276
+ } );
3277
+
3278
+
3279
+ /*!
3280
+ * jQuery UI Effects Fade 1.12.1
3281
+ * http://jqueryui.com
3282
+ *
3283
+ * Copyright jQuery Foundation and other contributors
3284
+ * Released under the MIT license.
3285
+ * http://jquery.org/license
3286
+ */
3287
+
3288
+ //>>label: Fade Effect
3289
+ //>>group: Effects
3290
+ //>>description: Fades the element.
3291
+ //>>docs: http://api.jqueryui.com/fade-effect/
3292
+ //>>demos: http://jqueryui.com/effect/
3293
+
3294
+
3295
+
3296
+ var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
3297
+ var show = options.mode === "show";
3298
+
3299
+ $( this )
3300
+ .css( "opacity", show ? 0 : 1 )
3301
+ .animate( {
3302
+ opacity: show ? 1 : 0
3303
+ }, {
3304
+ queue: false,
3305
+ duration: options.duration,
3306
+ easing: options.easing,
3307
+ complete: done
3308
+ } );
3309
+ } );
3310
+
3311
+
3312
+ /*!
3313
+ * jQuery UI Effects Fold 1.12.1
3314
+ * http://jqueryui.com
3315
+ *
3316
+ * Copyright jQuery Foundation and other contributors
3317
+ * Released under the MIT license.
3318
+ * http://jquery.org/license
3319
+ */
3320
+
3321
+ //>>label: Fold Effect
3322
+ //>>group: Effects
3323
+ //>>description: Folds an element first horizontally and then vertically.
3324
+ //>>docs: http://api.jqueryui.com/fold-effect/
3325
+ //>>demos: http://jqueryui.com/effect/
3326
+
3327
+
3328
+
3329
+ var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
3330
+
3331
+ // Create element
3332
+ var element = $( this ),
3333
+ mode = options.mode,
3334
+ show = mode === "show",
3335
+ hide = mode === "hide",
3336
+ size = options.size || 15,
3337
+ percent = /([0-9]+)%/.exec( size ),
3338
+ horizFirst = !!options.horizFirst,
3339
+ ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
3340
+ duration = options.duration / 2,
3341
+
3342
+ placeholder = $.effects.createPlaceholder( element ),
3343
+
3344
+ start = element.cssClip(),
3345
+ animation1 = { clip: $.extend( {}, start ) },
3346
+ animation2 = { clip: $.extend( {}, start ) },
3347
+
3348
+ distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
3349
+
3350
+ queuelen = element.queue().length;
3351
+
3352
+ if ( percent ) {
3353
+ size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
3354
+ }
3355
+ animation1.clip[ ref[ 0 ] ] = size;
3356
+ animation2.clip[ ref[ 0 ] ] = size;
3357
+ animation2.clip[ ref[ 1 ] ] = 0;
3358
+
3359
+ if ( show ) {
3360
+ element.cssClip( animation2.clip );
3361
+ if ( placeholder ) {
3362
+ placeholder.css( $.effects.clipToBox( animation2 ) );
3363
+ }
3364
+
3365
+ animation2.clip = start;
3366
+ }
3367
+
3368
+ // Animate
3369
+ element
3370
+ .queue( function( next ) {
3371
+ if ( placeholder ) {
3372
+ placeholder
3373
+ .animate( $.effects.clipToBox( animation1 ), duration, options.easing )
3374
+ .animate( $.effects.clipToBox( animation2 ), duration, options.easing );
3375
+ }
3376
+
3377
+ next();
3378
+ } )
3379
+ .animate( animation1, duration, options.easing )
3380
+ .animate( animation2, duration, options.easing )
3381
+ .queue( done );
3382
+
3383
+ $.effects.unshift( element, queuelen, 4 );
3384
+ } );
3385
+
3386
+
3387
+ /*!
3388
+ * jQuery UI Effects Highlight 1.12.1
3389
+ * http://jqueryui.com
3390
+ *
3391
+ * Copyright jQuery Foundation and other contributors
3392
+ * Released under the MIT license.
3393
+ * http://jquery.org/license
3394
+ */
3395
+
3396
+ //>>label: Highlight Effect
3397
+ //>>group: Effects
3398
+ //>>description: Highlights the background of an element in a defined color for a custom duration.
3399
+ //>>docs: http://api.jqueryui.com/highlight-effect/
3400
+ //>>demos: http://jqueryui.com/effect/
3401
+
3402
+
3403
+
3404
+ var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
3405
+ var element = $( this ),
3406
+ animation = {
3407
+ backgroundColor: element.css( "backgroundColor" )
3408
+ };
3409
+
3410
+ if ( options.mode === "hide" ) {
3411
+ animation.opacity = 0;
3412
+ }
3413
+
3414
+ $.effects.saveStyle( element );
3415
+
3416
+ element
3417
+ .css( {
3418
+ backgroundImage: "none",
3419
+ backgroundColor: options.color || "#ffff99"
3420
+ } )
3421
+ .animate( animation, {
3422
+ queue: false,
3423
+ duration: options.duration,
3424
+ easing: options.easing,
3425
+ complete: done
3426
+ } );
3427
+ } );
3428
+
3429
+
3430
+ /*!
3431
+ * jQuery UI Effects Size 1.12.1
3432
+ * http://jqueryui.com
3433
+ *
3434
+ * Copyright jQuery Foundation and other contributors
3435
+ * Released under the MIT license.
3436
+ * http://jquery.org/license
3437
+ */
3438
+
3439
+ //>>label: Size Effect
3440
+ //>>group: Effects
3441
+ //>>description: Resize an element to a specified width and height.
3442
+ //>>docs: http://api.jqueryui.com/size-effect/
3443
+ //>>demos: http://jqueryui.com/effect/
3444
+
3445
+
3446
+
3447
+ var effectsEffectSize = $.effects.define( "size", function( options, done ) {
3448
+
3449
+ // Create element
3450
+ var baseline, factor, temp,
3451
+ element = $( this ),
3452
+
3453
+ // Copy for children
3454
+ cProps = [ "fontSize" ],
3455
+ vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
3456
+ hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
3457
+
3458
+ // Set options
3459
+ mode = options.mode,
3460
+ restore = mode !== "effect",
3461
+ scale = options.scale || "both",
3462
+ origin = options.origin || [ "middle", "center" ],
3463
+ position = element.css( "position" ),
3464
+ pos = element.position(),
3465
+ original = $.effects.scaledDimensions( element ),
3466
+ from = options.from || original,
3467
+ to = options.to || $.effects.scaledDimensions( element, 0 );
3468
+
3469
+ $.effects.createPlaceholder( element );
3470
+
3471
+ if ( mode === "show" ) {
3472
+ temp = from;
3473
+ from = to;
3474
+ to = temp;
3475
+ }
3476
+
3477
+ // Set scaling factor
3478
+ factor = {
3479
+ from: {
3480
+ y: from.height / original.height,
3481
+ x: from.width / original.width
3482
+ },
3483
+ to: {
3484
+ y: to.height / original.height,
3485
+ x: to.width / original.width
3486
+ }
3487
+ };
3488
+
3489
+ // Scale the css box
3490
+ if ( scale === "box" || scale === "both" ) {
3491
+
3492
+ // Vertical props scaling
3493
+ if ( factor.from.y !== factor.to.y ) {
3494
+ from = $.effects.setTransition( element, vProps, factor.from.y, from );
3495
+ to = $.effects.setTransition( element, vProps, factor.to.y, to );
3496
+ }
3497
+
3498
+ // Horizontal props scaling
3499
+ if ( factor.from.x !== factor.to.x ) {
3500
+ from = $.effects.setTransition( element, hProps, factor.from.x, from );
3501
+ to = $.effects.setTransition( element, hProps, factor.to.x, to );
3502
+ }
3503
+ }
3504
+
3505
+ // Scale the content
3506
+ if ( scale === "content" || scale === "both" ) {
3507
+
3508
+ // Vertical props scaling
3509
+ if ( factor.from.y !== factor.to.y ) {
3510
+ from = $.effects.setTransition( element, cProps, factor.from.y, from );
3511
+ to = $.effects.setTransition( element, cProps, factor.to.y, to );
3512
+ }
3513
+ }
3514
+
3515
+ // Adjust the position properties based on the provided origin points
3516
+ if ( origin ) {
3517
+ baseline = $.effects.getBaseline( origin, original );
3518
+ from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
3519
+ from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
3520
+ to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
3521
+ to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
3522
+ }
3523
+ element.css( from );
3524
+
3525
+ // Animate the children if desired
3526
+ if ( scale === "content" || scale === "both" ) {
3527
+
3528
+ vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
3529
+ hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
3530
+
3531
+ // Only animate children with width attributes specified
3532
+ // TODO: is this right? should we include anything with css width specified as well
3533
+ element.find( "*[width]" ).each( function() {
3534
+ var child = $( this ),
3535
+ childOriginal = $.effects.scaledDimensions( child ),
3536
+ childFrom = {
3537
+ height: childOriginal.height * factor.from.y,
3538
+ width: childOriginal.width * factor.from.x,
3539
+ outerHeight: childOriginal.outerHeight * factor.from.y,
3540
+ outerWidth: childOriginal.outerWidth * factor.from.x
3541
+ },
3542
+ childTo = {
3543
+ height: childOriginal.height * factor.to.y,
3544
+ width: childOriginal.width * factor.to.x,
3545
+ outerHeight: childOriginal.height * factor.to.y,
3546
+ outerWidth: childOriginal.width * factor.to.x
3547
+ };
3548
+
3549
+ // Vertical props scaling
3550
+ if ( factor.from.y !== factor.to.y ) {
3551
+ childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
3552
+ childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
3553
+ }
3554
+
3555
+ // Horizontal props scaling
3556
+ if ( factor.from.x !== factor.to.x ) {
3557
+ childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
3558
+ childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
3559
+ }
3560
+
3561
+ if ( restore ) {
3562
+ $.effects.saveStyle( child );
3563
+ }
3564
+
3565
+ // Animate children
3566
+ child.css( childFrom );
3567
+ child.animate( childTo, options.duration, options.easing, function() {
3568
+
3569
+ // Restore children
3570
+ if ( restore ) {
3571
+ $.effects.restoreStyle( child );
3572
+ }
3573
+ } );
3574
+ } );
3575
+ }
3576
+
3577
+ // Animate
3578
+ element.animate( to, {
3579
+ queue: false,
3580
+ duration: options.duration,
3581
+ easing: options.easing,
3582
+ complete: function() {
3583
+
3584
+ var offset = element.offset();
3585
+
3586
+ if ( to.opacity === 0 ) {
3587
+ element.css( "opacity", from.opacity );
3588
+ }
3589
+
3590
+ if ( !restore ) {
3591
+ element
3592
+ .css( "position", position === "static" ? "relative" : position )
3593
+ .offset( offset );
3594
+
3595
+ // Need to save style here so that automatic style restoration
3596
+ // doesn't restore to the original styles from before the animation.
3597
+ $.effects.saveStyle( element );
3598
+ }
3599
+
3600
+ done();
3601
+ }
3602
+ } );
3603
+
3604
+ } );
3605
+
3606
+
3607
+ /*!
3608
+ * jQuery UI Effects Scale 1.12.1
3609
+ * http://jqueryui.com
3610
+ *
3611
+ * Copyright jQuery Foundation and other contributors
3612
+ * Released under the MIT license.
3613
+ * http://jquery.org/license
3614
+ */
3615
+
3616
+ //>>label: Scale Effect
3617
+ //>>group: Effects
3618
+ //>>description: Grows or shrinks an element and its content.
3619
+ //>>docs: http://api.jqueryui.com/scale-effect/
3620
+ //>>demos: http://jqueryui.com/effect/
3621
+
3622
+
3623
+
3624
+ var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
3625
+
3626
+ // Create element
3627
+ var el = $( this ),
3628
+ mode = options.mode,
3629
+ percent = parseInt( options.percent, 10 ) ||
3630
+ ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
3631
+
3632
+ newOptions = $.extend( true, {
3633
+ from: $.effects.scaledDimensions( el ),
3634
+ to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
3635
+ origin: options.origin || [ "middle", "center" ]
3636
+ }, options );
3637
+
3638
+ // Fade option to support puff
3639
+ if ( options.fade ) {
3640
+ newOptions.from.opacity = 1;
3641
+ newOptions.to.opacity = 0;
3642
+ }
3643
+
3644
+ $.effects.effect.size.call( this, newOptions, done );
3645
+ } );
3646
+
3647
+
3648
+ /*!
3649
+ * jQuery UI Effects Puff 1.12.1
3650
+ * http://jqueryui.com
3651
+ *
3652
+ * Copyright jQuery Foundation and other contributors
3653
+ * Released under the MIT license.
3654
+ * http://jquery.org/license
3655
+ */
3656
+
3657
+ //>>label: Puff Effect
3658
+ //>>group: Effects
3659
+ //>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
3660
+ //>>docs: http://api.jqueryui.com/puff-effect/
3661
+ //>>demos: http://jqueryui.com/effect/
3662
+
3663
+
3664
+
3665
+ var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
3666
+ var newOptions = $.extend( true, {}, options, {
3667
+ fade: true,
3668
+ percent: parseInt( options.percent, 10 ) || 150
3669
+ } );
3670
+
3671
+ $.effects.effect.scale.call( this, newOptions, done );
3672
+ } );
3673
+
3674
+
3675
+ /*!
3676
+ * jQuery UI Effects Pulsate 1.12.1
3677
+ * http://jqueryui.com
3678
+ *
3679
+ * Copyright jQuery Foundation and other contributors
3680
+ * Released under the MIT license.
3681
+ * http://jquery.org/license
3682
+ */
3683
+
3684
+ //>>label: Pulsate Effect
3685
+ //>>group: Effects
3686
+ //>>description: Pulsates an element n times by changing the opacity to zero and back.
3687
+ //>>docs: http://api.jqueryui.com/pulsate-effect/
3688
+ //>>demos: http://jqueryui.com/effect/
3689
+
3690
+
3691
+
3692
+ var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
3693
+ var element = $( this ),
3694
+ mode = options.mode,
3695
+ show = mode === "show",
3696
+ hide = mode === "hide",
3697
+ showhide = show || hide,
3698
+
3699
+ // Showing or hiding leaves off the "last" animation
3700
+ anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
3701
+ duration = options.duration / anims,
3702
+ animateTo = 0,
3703
+ i = 1,
3704
+ queuelen = element.queue().length;
3705
+
3706
+ if ( show || !element.is( ":visible" ) ) {
3707
+ element.css( "opacity", 0 ).show();
3708
+ animateTo = 1;
3709
+ }
3710
+
3711
+ // Anims - 1 opacity "toggles"
3712
+ for ( ; i < anims; i++ ) {
3713
+ element.animate( { opacity: animateTo }, duration, options.easing );
3714
+ animateTo = 1 - animateTo;
3715
+ }
3716
+
3717
+ element.animate( { opacity: animateTo }, duration, options.easing );
3718
+
3719
+ element.queue( done );
3720
+
3721
+ $.effects.unshift( element, queuelen, anims + 1 );
3722
+ } );
3723
+
3724
+
3725
+ /*!
3726
+ * jQuery UI Effects Shake 1.12.1
3727
+ * http://jqueryui.com
3728
+ *
3729
+ * Copyright jQuery Foundation and other contributors
3730
+ * Released under the MIT license.
3731
+ * http://jquery.org/license
3732
+ */
3733
+
3734
+ //>>label: Shake Effect
3735
+ //>>group: Effects
3736
+ //>>description: Shakes an element horizontally or vertically n times.
3737
+ //>>docs: http://api.jqueryui.com/shake-effect/
3738
+ //>>demos: http://jqueryui.com/effect/
3739
+
3740
+
3741
+
3742
+ var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
3743
+
3744
+ var i = 1,
3745
+ element = $( this ),
3746
+ direction = options.direction || "left",
3747
+ distance = options.distance || 20,
3748
+ times = options.times || 3,
3749
+ anims = times * 2 + 1,
3750
+ speed = Math.round( options.duration / anims ),
3751
+ ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3752
+ positiveMotion = ( direction === "up" || direction === "left" ),
3753
+ animation = {},
3754
+ animation1 = {},
3755
+ animation2 = {},
3756
+
3757
+ queuelen = element.queue().length;
3758
+
3759
+ $.effects.createPlaceholder( element );
3760
+
3761
+ // Animation
3762
+ animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
3763
+ animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
3764
+ animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
3765
+
3766
+ // Animate
3767
+ element.animate( animation, speed, options.easing );
3768
+
3769
+ // Shakes
3770
+ for ( ; i < times; i++ ) {
3771
+ element
3772
+ .animate( animation1, speed, options.easing )
3773
+ .animate( animation2, speed, options.easing );
3774
+ }
3775
+
3776
+ element
3777
+ .animate( animation1, speed, options.easing )
3778
+ .animate( animation, speed / 2, options.easing )
3779
+ .queue( done );
3780
+
3781
+ $.effects.unshift( element, queuelen, anims + 1 );
3782
+ } );
3783
+
3784
+
3785
+ /*!
3786
+ * jQuery UI Effects Slide 1.12.1
3787
+ * http://jqueryui.com
3788
+ *
3789
+ * Copyright jQuery Foundation and other contributors
3790
+ * Released under the MIT license.
3791
+ * http://jquery.org/license
3792
+ */
3793
+
3794
+ //>>label: Slide Effect
3795
+ //>>group: Effects
3796
+ //>>description: Slides an element in and out of the viewport.
3797
+ //>>docs: http://api.jqueryui.com/slide-effect/
3798
+ //>>demos: http://jqueryui.com/effect/
3799
+
3800
+
3801
+
3802
+ var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
3803
+ var startClip, startRef,
3804
+ element = $( this ),
3805
+ map = {
3806
+ up: [ "bottom", "top" ],
3807
+ down: [ "top", "bottom" ],
3808
+ left: [ "right", "left" ],
3809
+ right: [ "left", "right" ]
3810
+ },
3811
+ mode = options.mode,
3812
+ direction = options.direction || "left",
3813
+ ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3814
+ positiveMotion = ( direction === "up" || direction === "left" ),
3815
+ distance = options.distance ||
3816
+ element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
3817
+ animation = {};
3818
+
3819
+ $.effects.createPlaceholder( element );
3820
+
3821
+ startClip = element.cssClip();
3822
+ startRef = element.position()[ ref ];
3823
+
3824
+ // Define hide animation
3825
+ animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
3826
+ animation.clip = element.cssClip();
3827
+ animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
3828
+
3829
+ // Reverse the animation if we're showing
3830
+ if ( mode === "show" ) {
3831
+ element.cssClip( animation.clip );
3832
+ element.css( ref, animation[ ref ] );
3833
+ animation.clip = startClip;
3834
+ animation[ ref ] = startRef;
3835
+ }
3836
+
3837
+ // Actually animate
3838
+ element.animate( animation, {
3839
+ queue: false,
3840
+ duration: options.duration,
3841
+ easing: options.easing,
3842
+ complete: done
3843
+ } );
3844
+ } );
3845
+
3846
+
3847
+ /*!
3848
+ * jQuery UI Effects Transfer 1.12.1
3849
+ * http://jqueryui.com
3850
+ *
3851
+ * Copyright jQuery Foundation and other contributors
3852
+ * Released under the MIT license.
3853
+ * http://jquery.org/license
3854
+ */
3855
+
3856
+ //>>label: Transfer Effect
3857
+ //>>group: Effects
3858
+ //>>description: Displays a transfer effect from one element to another.
3859
+ //>>docs: http://api.jqueryui.com/transfer-effect/
3860
+ //>>demos: http://jqueryui.com/effect/
3861
+
3862
+
3863
+
3864
+ var effect;
3865
+ if ( $.uiBackCompat !== false ) {
3866
+ effect = $.effects.define( "transfer", function( options, done ) {
3867
+ $( this ).transfer( options, done );
3868
+ } );
3869
+ }
3870
+ var effectsEffectTransfer = effect;
3871
+
3872
+
3873
+ /*!
3874
+ * jQuery UI Focusable 1.12.1
3875
+ * http://jqueryui.com
3876
+ *
3877
+ * Copyright jQuery Foundation and other contributors
3878
+ * Released under the MIT license.
3879
+ * http://jquery.org/license
3880
+ */
3881
+
3882
+ //>>label: :focusable Selector
3883
+ //>>group: Core
3884
+ //>>description: Selects elements which can be focused.
3885
+ //>>docs: http://api.jqueryui.com/focusable-selector/
3886
+
3887
+
3888
+
3889
+ // Selectors
3890
+ $.ui.focusable = function( element, hasTabindex ) {
3891
+ var map, mapName, img, focusableIfVisible, fieldset,
3892
+ nodeName = element.nodeName.toLowerCase();
3893
+
3894
+ if ( "area" === nodeName ) {
3895
+ map = element.parentNode;
3896
+ mapName = map.name;
3897
+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3898
+ return false;
3899
+ }
3900
+ img = $( "img[usemap='#" + mapName + "']" );
3901
+ return img.length > 0 && img.is( ":visible" );
3902
+ }
3903
+
3904
+ if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
3905
+ focusableIfVisible = !element.disabled;
3906
+
3907
+ if ( focusableIfVisible ) {
3908
+
3909
+ // Form controls within a disabled fieldset are disabled.
3910
+ // However, controls within the fieldset's legend do not get disabled.
3911
+ // Since controls generally aren't placed inside legends, we skip
3912
+ // this portion of the check.
3913
+ fieldset = $( element ).closest( "fieldset" )[ 0 ];
3914
+ if ( fieldset ) {
3915
+ focusableIfVisible = !fieldset.disabled;
3916
+ }
3917
+ }
3918
+ } else if ( "a" === nodeName ) {
3919
+ focusableIfVisible = element.href || hasTabindex;
3920
+ } else {
3921
+ focusableIfVisible = hasTabindex;
3922
+ }
3923
+
3924
+ return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
3925
+ };
3926
+
3927
+ // Support: IE 8 only
3928
+ // IE 8 doesn't resolve inherit to visible/hidden for computed values
3929
+ function visible( element ) {
3930
+ var visibility = element.css( "visibility" );
3931
+ while ( visibility === "inherit" ) {
3932
+ element = element.parent();
3933
+ visibility = element.css( "visibility" );
3934
+ }
3935
+ return visibility !== "hidden";
3936
+ }
3937
+
3938
+ $.extend( $.expr[ ":" ], {
3939
+ focusable: function( element ) {
3940
+ return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
3941
+ }
3942
+ } );
3943
+
3944
+ var focusable = $.ui.focusable;
3945
+
3946
+
3947
+
3948
+
3949
+ // Support: IE8 Only
3950
+ // IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
3951
+ // with a string, so we need to find the proper form.
3952
+ var form = $.fn.form = function() {
3953
+ return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
3954
+ };
3955
+
3956
+
3957
+ /*!
3958
+ * jQuery UI Form Reset Mixin 1.12.1
3959
+ * http://jqueryui.com
3960
+ *
3961
+ * Copyright jQuery Foundation and other contributors
3962
+ * Released under the MIT license.
3963
+ * http://jquery.org/license
3964
+ */
3965
+
3966
+ //>>label: Form Reset Mixin
3967
+ //>>group: Core
3968
+ //>>description: Refresh input widgets when their form is reset
3969
+ //>>docs: http://api.jqueryui.com/form-reset-mixin/
3970
+
3971
+
3972
+
3973
+ var formResetMixin = $.ui.formResetMixin = {
3974
+ _formResetHandler: function() {
3975
+ var form = $( this );
3976
+
3977
+ // Wait for the form reset to actually happen before refreshing
3978
+ setTimeout( function() {
3979
+ var instances = form.data( "ui-form-reset-instances" );
3980
+ $.each( instances, function() {
3981
+ this.refresh();
3982
+ } );
3983
+ } );
3984
+ },
3985
+
3986
+ _bindFormResetHandler: function() {
3987
+ this.form = this.element.form();
3988
+ if ( !this.form.length ) {
3989
+ return;
3990
+ }
3991
+
3992
+ var instances = this.form.data( "ui-form-reset-instances" ) || [];
3993
+ if ( !instances.length ) {
3994
+
3995
+ // We don't use _on() here because we use a single event handler per form
3996
+ this.form.on( "reset.ui-form-reset", this._formResetHandler );
3997
+ }
3998
+ instances.push( this );
3999
+ this.form.data( "ui-form-reset-instances", instances );
4000
+ },
4001
+
4002
+ _unbindFormResetHandler: function() {
4003
+ if ( !this.form.length ) {
4004
+ return;
4005
+ }
4006
+
4007
+ var instances = this.form.data( "ui-form-reset-instances" );
4008
+ instances.splice( $.inArray( this, instances ), 1 );
4009
+ if ( instances.length ) {
4010
+ this.form.data( "ui-form-reset-instances", instances );
4011
+ } else {
4012
+ this.form
4013
+ .removeData( "ui-form-reset-instances" )
4014
+ .off( "reset.ui-form-reset" );
4015
+ }
4016
+ }
4017
+ };
4018
+
4019
+
4020
+ /*!
4021
+ * jQuery UI Support for jQuery core 1.7.x 1.12.1
4022
+ * http://jqueryui.com
4023
+ *
4024
+ * Copyright jQuery Foundation and other contributors
4025
+ * Released under the MIT license.
4026
+ * http://jquery.org/license
4027
+ *
4028
+ */
4029
+
4030
+ //>>label: jQuery 1.7 Support
4031
+ //>>group: Core
4032
+ //>>description: Support version 1.7.x of jQuery core
4033
+
4034
+
4035
+
4036
+ // Support: jQuery 1.7 only
4037
+ // Not a great way to check versions, but since we only support 1.7+ and only
4038
+ // need to detect <1.8, this is a simple check that should suffice. Checking
4039
+ // for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
4040
+ // and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
4041
+ // 1.7 anymore). See #11197 for why we're not using feature detection.
4042
+ if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
4043
+
4044
+ // Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
4045
+ // Unlike jQuery Core 1.8+, these only support numeric values to set the
4046
+ // dimensions in pixels
4047
+ $.each( [ "Width", "Height" ], function( i, name ) {
4048
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
4049
+ type = name.toLowerCase(),
4050
+ orig = {
4051
+ innerWidth: $.fn.innerWidth,
4052
+ innerHeight: $.fn.innerHeight,
4053
+ outerWidth: $.fn.outerWidth,
4054
+ outerHeight: $.fn.outerHeight
4055
+ };
4056
+
4057
+ function reduce( elem, size, border, margin ) {
4058
+ $.each( side, function() {
4059
+ size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
4060
+ if ( border ) {
4061
+ size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
4062
+ }
4063
+ if ( margin ) {
4064
+ size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
4065
+ }
4066
+ } );
4067
+ return size;
4068
+ }
4069
+
4070
+ $.fn[ "inner" + name ] = function( size ) {
4071
+ if ( size === undefined ) {
4072
+ return orig[ "inner" + name ].call( this );
4073
+ }
4074
+
4075
+ return this.each( function() {
4076
+ $( this ).css( type, reduce( this, size ) + "px" );
4077
+ } );
4078
+ };
4079
+
4080
+ $.fn[ "outer" + name ] = function( size, margin ) {
4081
+ if ( typeof size !== "number" ) {
4082
+ return orig[ "outer" + name ].call( this, size );
4083
+ }
4084
+
4085
+ return this.each( function() {
4086
+ $( this ).css( type, reduce( this, size, true, margin ) + "px" );
4087
+ } );
4088
+ };
4089
+ } );
4090
+
4091
+ $.fn.addBack = function( selector ) {
4092
+ return this.add( selector == null ?
4093
+ this.prevObject : this.prevObject.filter( selector )
4094
+ );
4095
+ };
4096
+ }
4097
+
4098
+ ;
4099
+ /*!
4100
+ * jQuery UI Keycode 1.12.1
4101
+ * http://jqueryui.com
4102
+ *
4103
+ * Copyright jQuery Foundation and other contributors
4104
+ * Released under the MIT license.
4105
+ * http://jquery.org/license
4106
+ */
4107
+
4108
+ //>>label: Keycode
4109
+ //>>group: Core
4110
+ //>>description: Provide keycodes as keynames
4111
+ //>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
4112
+
4113
+
4114
+ var keycode = $.ui.keyCode = {
4115
+ BACKSPACE: 8,
4116
+ COMMA: 188,
4117
+ DELETE: 46,
4118
+ DOWN: 40,
4119
+ END: 35,
4120
+ ENTER: 13,
4121
+ ESCAPE: 27,
4122
+ HOME: 36,
4123
+ LEFT: 37,
4124
+ PAGE_DOWN: 34,
4125
+ PAGE_UP: 33,
4126
+ PERIOD: 190,
4127
+ RIGHT: 39,
4128
+ SPACE: 32,
4129
+ TAB: 9,
4130
+ UP: 38
4131
+ };
4132
+
4133
+
4134
+
4135
+
4136
+ // Internal use only
4137
+ var escapeSelector = $.ui.escapeSelector = ( function() {
4138
+ var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
4139
+ return function( selector ) {
4140
+ return selector.replace( selectorEscape, "\\$1" );
4141
+ };
4142
+ } )();
4143
+
4144
+
4145
+ /*!
4146
+ * jQuery UI Labels 1.12.1
4147
+ * http://jqueryui.com
4148
+ *
4149
+ * Copyright jQuery Foundation and other contributors
4150
+ * Released under the MIT license.
4151
+ * http://jquery.org/license
4152
+ */
4153
+
4154
+ //>>label: labels
4155
+ //>>group: Core
4156
+ //>>description: Find all the labels associated with a given input
4157
+ //>>docs: http://api.jqueryui.com/labels/
4158
+
4159
+
4160
+
4161
+ var labels = $.fn.labels = function() {
4162
+ var ancestor, selector, id, labels, ancestors;
4163
+
4164
+ // Check control.labels first
4165
+ if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
4166
+ return this.pushStack( this[ 0 ].labels );
4167
+ }
4168
+
4169
+ // Support: IE <= 11, FF <= 37, Android <= 2.3 only
4170
+ // Above browsers do not support control.labels. Everything below is to support them
4171
+ // as well as document fragments. control.labels does not work on document fragments
4172
+ labels = this.eq( 0 ).parents( "label" );
4173
+
4174
+ // Look for the label based on the id
4175
+ id = this.attr( "id" );
4176
+ if ( id ) {
4177
+
4178
+ // We don't search against the document in case the element
4179
+ // is disconnected from the DOM
4180
+ ancestor = this.eq( 0 ).parents().last();
4181
+
4182
+ // Get a full set of top level ancestors
4183
+ ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
4184
+
4185
+ // Create a selector for the label based on the id
4186
+ selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
4187
+
4188
+ labels = labels.add( ancestors.find( selector ).addBack( selector ) );
4189
+
4190
+ }
4191
+
4192
+ // Return whatever we have found for labels
4193
+ return this.pushStack( labels );
4194
+ };
4195
+
4196
+
4197
+ /*!
4198
+ * jQuery UI Scroll Parent 1.12.1
4199
+ * http://jqueryui.com
4200
+ *
4201
+ * Copyright jQuery Foundation and other contributors
4202
+ * Released under the MIT license.
4203
+ * http://jquery.org/license
4204
+ */
4205
+
4206
+ //>>label: scrollParent
4207
+ //>>group: Core
4208
+ //>>description: Get the closest ancestor element that is scrollable.
4209
+ //>>docs: http://api.jqueryui.com/scrollParent/
4210
+
4211
+
4212
+
4213
+ var scrollParent = $.fn.scrollParent = function( includeHidden ) {
4214
+ var position = this.css( "position" ),
4215
+ excludeStaticParent = position === "absolute",
4216
+ overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
4217
+ scrollParent = this.parents().filter( function() {
4218
+ var parent = $( this );
4219
+ if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
4220
+ return false;
4221
+ }
4222
+ return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
4223
+ parent.css( "overflow-x" ) );
4224
+ } ).eq( 0 );
4225
+
4226
+ return position === "fixed" || !scrollParent.length ?
4227
+ $( this[ 0 ].ownerDocument || document ) :
4228
+ scrollParent;
4229
+ };
4230
+
4231
+
4232
+ /*!
4233
+ * jQuery UI Tabbable 1.12.1
4234
+ * http://jqueryui.com
4235
+ *
4236
+ * Copyright jQuery Foundation and other contributors
4237
+ * Released under the MIT license.
4238
+ * http://jquery.org/license
4239
+ */
4240
+
4241
+ //>>label: :tabbable Selector
4242
+ //>>group: Core
4243
+ //>>description: Selects elements which can be tabbed to.
4244
+ //>>docs: http://api.jqueryui.com/tabbable-selector/
4245
+
4246
+
4247
+
4248
+ var tabbable = $.extend( $.expr[ ":" ], {
4249
+ tabbable: function( element ) {
4250
+ var tabIndex = $.attr( element, "tabindex" ),
4251
+ hasTabindex = tabIndex != null;
4252
+ return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
4253
+ }
4254
+ } );
4255
+
4256
+
4257
+ /*!
4258
+ * jQuery UI Unique ID 1.12.1
4259
+ * http://jqueryui.com
4260
+ *
4261
+ * Copyright jQuery Foundation and other contributors
4262
+ * Released under the MIT license.
4263
+ * http://jquery.org/license
4264
+ */
4265
+
4266
+ //>>label: uniqueId
4267
+ //>>group: Core
4268
+ //>>description: Functions to generate and remove uniqueId's
4269
+ //>>docs: http://api.jqueryui.com/uniqueId/
4270
+
4271
+
4272
+
4273
+ var uniqueId = $.fn.extend( {
4274
+ uniqueId: ( function() {
4275
+ var uuid = 0;
4276
+
4277
+ return function() {
4278
+ return this.each( function() {
4279
+ if ( !this.id ) {
4280
+ this.id = "ui-id-" + ( ++uuid );
4281
+ }
4282
+ } );
4283
+ };
4284
+ } )(),
4285
+
4286
+ removeUniqueId: function() {
4287
+ return this.each( function() {
4288
+ if ( /^ui-id-\d+$/.test( this.id ) ) {
4289
+ $( this ).removeAttr( "id" );
4290
+ }
4291
+ } );
4292
+ }
4293
+ } );
4294
+
4295
+
4296
+ /*!
4297
+ * jQuery UI Accordion 1.12.1
4298
+ * http://jqueryui.com
4299
+ *
4300
+ * Copyright jQuery Foundation and other contributors
4301
+ * Released under the MIT license.
4302
+ * http://jquery.org/license
4303
+ */
4304
+
4305
+ //>>label: Accordion
4306
+ //>>group: Widgets
4307
+ // jscs:disable maximumLineLength
4308
+ //>>description: Displays collapsible content panels for presenting information in a limited amount of space.
4309
+ // jscs:enable maximumLineLength
4310
+ //>>docs: http://api.jqueryui.com/accordion/
4311
+ //>>demos: http://jqueryui.com/accordion/
4312
+ //>>css.structure: ../../themes/base/core.css
4313
+ //>>css.structure: ../../themes/base/accordion.css
4314
+ //>>css.theme: ../../themes/base/theme.css
4315
+
4316
+
4317
+
4318
+ var widgetsAccordion = $.widget( "ui.accordion", {
4319
+ version: "1.12.1",
4320
+ options: {
4321
+ active: 0,
4322
+ animate: {},
4323
+ classes: {
4324
+ "ui-accordion-header": "ui-corner-top",
4325
+ "ui-accordion-header-collapsed": "ui-corner-all",
4326
+ "ui-accordion-content": "ui-corner-bottom"
4327
+ },
4328
+ collapsible: false,
4329
+ event: "click",
4330
+ header: "> li > :first-child, > :not(li):even",
4331
+ heightStyle: "auto",
4332
+ icons: {
4333
+ activeHeader: "ui-icon-triangle-1-s",
4334
+ header: "ui-icon-triangle-1-e"
4335
+ },
4336
+
4337
+ // Callbacks
4338
+ activate: null,
4339
+ beforeActivate: null
4340
+ },
4341
+
4342
+ hideProps: {
4343
+ borderTopWidth: "hide",
4344
+ borderBottomWidth: "hide",
4345
+ paddingTop: "hide",
4346
+ paddingBottom: "hide",
4347
+ height: "hide"
4348
+ },
4349
+
4350
+ showProps: {
4351
+ borderTopWidth: "show",
4352
+ borderBottomWidth: "show",
4353
+ paddingTop: "show",
4354
+ paddingBottom: "show",
4355
+ height: "show"
4356
+ },
4357
+
4358
+ _create: function() {
4359
+ var options = this.options;
4360
+
4361
+ this.prevShow = this.prevHide = $();
4362
+ this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
4363
+ this.element.attr( "role", "tablist" );
4364
+
4365
+ // Don't allow collapsible: false and active: false / null
4366
+ if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
4367
+ options.active = 0;
4368
+ }
4369
+
4370
+ this._processPanels();
4371
+
4372
+ // handle negative values
4373
+ if ( options.active < 0 ) {
4374
+ options.active += this.headers.length;
4375
+ }
4376
+ this._refresh();
4377
+ },
4378
+
4379
+ _getCreateEventData: function() {
4380
+ return {
4381
+ header: this.active,
4382
+ panel: !this.active.length ? $() : this.active.next()
4383
+ };
4384
+ },
4385
+
4386
+ _createIcons: function() {
4387
+ var icon, children,
4388
+ icons = this.options.icons;
4389
+
4390
+ if ( icons ) {
4391
+ icon = $( "<span>" );
4392
+ this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
4393
+ icon.prependTo( this.headers );
4394
+ children = this.active.children( ".ui-accordion-header-icon" );
4395
+ this._removeClass( children, icons.header )
4396
+ ._addClass( children, null, icons.activeHeader )
4397
+ ._addClass( this.headers, "ui-accordion-icons" );
4398
+ }
4399
+ },
4400
+
4401
+ _destroyIcons: function() {
4402
+ this._removeClass( this.headers, "ui-accordion-icons" );
4403
+ this.headers.children( ".ui-accordion-header-icon" ).remove();
4404
+ },
4405
+
4406
+ _destroy: function() {
4407
+ var contents;
4408
+
4409
+ // Clean up main element
4410
+ this.element.removeAttr( "role" );
4411
+
4412
+ // Clean up headers
4413
+ this.headers
4414
+ .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
4415
+ .removeUniqueId();
4416
+
4417
+ this._destroyIcons();
4418
+
4419
+ // Clean up content panels
4420
+ contents = this.headers.next()
4421
+ .css( "display", "" )
4422
+ .removeAttr( "role aria-hidden aria-labelledby" )
4423
+ .removeUniqueId();
4424
+
4425
+ if ( this.options.heightStyle !== "content" ) {
4426
+ contents.css( "height", "" );
4427
+ }
4428
+ },
4429
+
4430
+ _setOption: function( key, value ) {
4431
+ if ( key === "active" ) {
4432
+
4433
+ // _activate() will handle invalid values and update this.options
4434
+ this._activate( value );
4435
+ return;
4436
+ }
4437
+
4438
+ if ( key === "event" ) {
4439
+ if ( this.options.event ) {
4440
+ this._off( this.headers, this.options.event );
4441
+ }
4442
+ this._setupEvents( value );
4443
+ }
4444
+
4445
+ this._super( key, value );
4446
+
4447
+ // Setting collapsible: false while collapsed; open first panel
4448
+ if ( key === "collapsible" && !value && this.options.active === false ) {
4449
+ this._activate( 0 );
4450
+ }
4451
+
4452
+ if ( key === "icons" ) {
4453
+ this._destroyIcons();
4454
+ if ( value ) {
4455
+ this._createIcons();
4456
+ }
4457
+ }
4458
+ },
4459
+
4460
+ _setOptionDisabled: function( value ) {
4461
+ this._super( value );
4462
+
4463
+ this.element.attr( "aria-disabled", value );
4464
+
4465
+ // Support: IE8 Only
4466
+ // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
4467
+ // so we need to add the disabled class to the headers and panels
4468
+ this._toggleClass( null, "ui-state-disabled", !!value );
4469
+ this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
4470
+ !!value );
4471
+ },
4472
+
4473
+ _keydown: function( event ) {
4474
+ if ( event.altKey || event.ctrlKey ) {
4475
+ return;
4476
+ }
4477
+
4478
+ var keyCode = $.ui.keyCode,
4479
+ length = this.headers.length,
4480
+ currentIndex = this.headers.index( event.target ),
4481
+ toFocus = false;
4482
+
4483
+ switch ( event.keyCode ) {
4484
+ case keyCode.RIGHT:
4485
+ case keyCode.DOWN:
4486
+ toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4487
+ break;
4488
+ case keyCode.LEFT:
4489
+ case keyCode.UP:
4490
+ toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4491
+ break;
4492
+ case keyCode.SPACE:
4493
+ case keyCode.ENTER:
4494
+ this._eventHandler( event );
4495
+ break;
4496
+ case keyCode.HOME:
4497
+ toFocus = this.headers[ 0 ];
4498
+ break;
4499
+ case keyCode.END:
4500
+ toFocus = this.headers[ length - 1 ];
4501
+ break;
4502
+ }
4503
+
4504
+ if ( toFocus ) {
4505
+ $( event.target ).attr( "tabIndex", -1 );
4506
+ $( toFocus ).attr( "tabIndex", 0 );
4507
+ $( toFocus ).trigger( "focus" );
4508
+ event.preventDefault();
4509
+ }
4510
+ },
4511
+
4512
+ _panelKeyDown: function( event ) {
4513
+ if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4514
+ $( event.currentTarget ).prev().trigger( "focus" );
4515
+ }
4516
+ },
4517
+
4518
+ refresh: function() {
4519
+ var options = this.options;
4520
+ this._processPanels();
4521
+
4522
+ // Was collapsed or no panel
4523
+ if ( ( options.active === false && options.collapsible === true ) ||
4524
+ !this.headers.length ) {
4525
+ options.active = false;
4526
+ this.active = $();
4527
+
4528
+ // active false only when collapsible is true
4529
+ } else if ( options.active === false ) {
4530
+ this._activate( 0 );
4531
+
4532
+ // was active, but active panel is gone
4533
+ } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4534
+
4535
+ // all remaining panel are disabled
4536
+ if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
4537
+ options.active = false;
4538
+ this.active = $();
4539
+
4540
+ // activate previous panel
4541
+ } else {
4542
+ this._activate( Math.max( 0, options.active - 1 ) );
4543
+ }
4544
+
4545
+ // was active, active panel still exists
4546
+ } else {
4547
+
4548
+ // make sure active index is correct
4549
+ options.active = this.headers.index( this.active );
4550
+ }
4551
+
4552
+ this._destroyIcons();
4553
+
4554
+ this._refresh();
4555
+ },
4556
+
4557
+ _processPanels: function() {
4558
+ var prevHeaders = this.headers,
4559
+ prevPanels = this.panels;
4560
+
4561
+ this.headers = this.element.find( this.options.header );
4562
+ this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
4563
+ "ui-state-default" );
4564
+
4565
+ this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
4566
+ this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
4567
+
4568
+ // Avoid memory leaks (#10056)
4569
+ if ( prevPanels ) {
4570
+ this._off( prevHeaders.not( this.headers ) );
4571
+ this._off( prevPanels.not( this.panels ) );
4572
+ }
4573
+ },
4574
+
4575
+ _refresh: function() {
4576
+ var maxHeight,
4577
+ options = this.options,
4578
+ heightStyle = options.heightStyle,
4579
+ parent = this.element.parent();
4580
+
4581
+ this.active = this._findActive( options.active );
4582
+ this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
4583
+ ._removeClass( this.active, "ui-accordion-header-collapsed" );
4584
+ this._addClass( this.active.next(), "ui-accordion-content-active" );
4585
+ this.active.next().show();
4586
+
4587
+ this.headers
4588
+ .attr( "role", "tab" )
4589
+ .each( function() {
4590
+ var header = $( this ),
4591
+ headerId = header.uniqueId().attr( "id" ),
4592
+ panel = header.next(),
4593
+ panelId = panel.uniqueId().attr( "id" );
4594
+ header.attr( "aria-controls", panelId );
4595
+ panel.attr( "aria-labelledby", headerId );
4596
+ } )
4597
+ .next()
4598
+ .attr( "role", "tabpanel" );
4599
+
4600
+ this.headers
4601
+ .not( this.active )
4602
+ .attr( {
4603
+ "aria-selected": "false",
4604
+ "aria-expanded": "false",
4605
+ tabIndex: -1
4606
+ } )
4607
+ .next()
4608
+ .attr( {
4609
+ "aria-hidden": "true"
4610
+ } )
4611
+ .hide();
4612
+
4613
+ // Make sure at least one header is in the tab order
4614
+ if ( !this.active.length ) {
4615
+ this.headers.eq( 0 ).attr( "tabIndex", 0 );
4616
+ } else {
4617
+ this.active.attr( {
4618
+ "aria-selected": "true",
4619
+ "aria-expanded": "true",
4620
+ tabIndex: 0
4621
+ } )
4622
+ .next()
4623
+ .attr( {
4624
+ "aria-hidden": "false"
4625
+ } );
4626
+ }
4627
+
4628
+ this._createIcons();
4629
+
4630
+ this._setupEvents( options.event );
4631
+
4632
+ if ( heightStyle === "fill" ) {
4633
+ maxHeight = parent.height();
4634
+ this.element.siblings( ":visible" ).each( function() {
4635
+ var elem = $( this ),
4636
+ position = elem.css( "position" );
4637
+
4638
+ if ( position === "absolute" || position === "fixed" ) {
4639
+ return;
4640
+ }
4641
+ maxHeight -= elem.outerHeight( true );
4642
+ } );
4643
+
4644
+ this.headers.each( function() {
4645
+ maxHeight -= $( this ).outerHeight( true );
4646
+ } );
4647
+
4648
+ this.headers.next()
4649
+ .each( function() {
4650
+ $( this ).height( Math.max( 0, maxHeight -
4651
+ $( this ).innerHeight() + $( this ).height() ) );
4652
+ } )
4653
+ .css( "overflow", "auto" );
4654
+ } else if ( heightStyle === "auto" ) {
4655
+ maxHeight = 0;
4656
+ this.headers.next()
4657
+ .each( function() {
4658
+ var isVisible = $( this ).is( ":visible" );
4659
+ if ( !isVisible ) {
4660
+ $( this ).show();
4661
+ }
4662
+ maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4663
+ if ( !isVisible ) {
4664
+ $( this ).hide();
4665
+ }
4666
+ } )
4667
+ .height( maxHeight );
4668
+ }
4669
+ },
4670
+
4671
+ _activate: function( index ) {
4672
+ var active = this._findActive( index )[ 0 ];
4673
+
4674
+ // Trying to activate the already active panel
4675
+ if ( active === this.active[ 0 ] ) {
4676
+ return;
4677
+ }
4678
+
4679
+ // Trying to collapse, simulate a click on the currently active header
4680
+ active = active || this.active[ 0 ];
4681
+
4682
+ this._eventHandler( {
4683
+ target: active,
4684
+ currentTarget: active,
4685
+ preventDefault: $.noop
4686
+ } );
4687
+ },
4688
+
4689
+ _findActive: function( selector ) {
4690
+ return typeof selector === "number" ? this.headers.eq( selector ) : $();
4691
+ },
4692
+
4693
+ _setupEvents: function( event ) {
4694
+ var events = {
4695
+ keydown: "_keydown"
4696
+ };
4697
+ if ( event ) {
4698
+ $.each( event.split( " " ), function( index, eventName ) {
4699
+ events[ eventName ] = "_eventHandler";
4700
+ } );
4701
+ }
4702
+
4703
+ this._off( this.headers.add( this.headers.next() ) );
4704
+ this._on( this.headers, events );
4705
+ this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
4706
+ this._hoverable( this.headers );
4707
+ this._focusable( this.headers );
4708
+ },
4709
+
4710
+ _eventHandler: function( event ) {
4711
+ var activeChildren, clickedChildren,
4712
+ options = this.options,
4713
+ active = this.active,
4714
+ clicked = $( event.currentTarget ),
4715
+ clickedIsActive = clicked[ 0 ] === active[ 0 ],
4716
+ collapsing = clickedIsActive && options.collapsible,
4717
+ toShow = collapsing ? $() : clicked.next(),
4718
+ toHide = active.next(),
4719
+ eventData = {
4720
+ oldHeader: active,
4721
+ oldPanel: toHide,
4722
+ newHeader: collapsing ? $() : clicked,
4723
+ newPanel: toShow
4724
+ };
4725
+
4726
+ event.preventDefault();
4727
+
4728
+ if (
4729
+
4730
+ // click on active header, but not collapsible
4731
+ ( clickedIsActive && !options.collapsible ) ||
4732
+
4733
+ // allow canceling activation
4734
+ ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4735
+ return;
4736
+ }
4737
+
4738
+ options.active = collapsing ? false : this.headers.index( clicked );
4739
+
4740
+ // When the call to ._toggle() comes after the class changes
4741
+ // it causes a very odd bug in IE 8 (see #6720)
4742
+ this.active = clickedIsActive ? $() : clicked;
4743
+ this._toggle( eventData );
4744
+
4745
+ // Switch classes
4746
+ // corner classes on the previously active header stay after the animation
4747
+ this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
4748
+ if ( options.icons ) {
4749
+ activeChildren = active.children( ".ui-accordion-header-icon" );
4750
+ this._removeClass( activeChildren, null, options.icons.activeHeader )
4751
+ ._addClass( activeChildren, null, options.icons.header );
4752
+ }
4753
+
4754
+ if ( !clickedIsActive ) {
4755
+ this._removeClass( clicked, "ui-accordion-header-collapsed" )
4756
+ ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
4757
+ if ( options.icons ) {
4758
+ clickedChildren = clicked.children( ".ui-accordion-header-icon" );
4759
+ this._removeClass( clickedChildren, null, options.icons.header )
4760
+ ._addClass( clickedChildren, null, options.icons.activeHeader );
4761
+ }
4762
+
4763
+ this._addClass( clicked.next(), "ui-accordion-content-active" );
4764
+ }
4765
+ },
4766
+
4767
+ _toggle: function( data ) {
4768
+ var toShow = data.newPanel,
4769
+ toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4770
+
4771
+ // Handle activating a panel during the animation for another activation
4772
+ this.prevShow.add( this.prevHide ).stop( true, true );
4773
+ this.prevShow = toShow;
4774
+ this.prevHide = toHide;
4775
+
4776
+ if ( this.options.animate ) {
4777
+ this._animate( toShow, toHide, data );
4778
+ } else {
4779
+ toHide.hide();
4780
+ toShow.show();
4781
+ this._toggleComplete( data );
4782
+ }
4783
+
4784
+ toHide.attr( {
4785
+ "aria-hidden": "true"
4786
+ } );
4787
+ toHide.prev().attr( {
4788
+ "aria-selected": "false",
4789
+ "aria-expanded": "false"
4790
+ } );
4791
+
4792
+ // if we're switching panels, remove the old header from the tab order
4793
+ // if we're opening from collapsed state, remove the previous header from the tab order
4794
+ // if we're collapsing, then keep the collapsing header in the tab order
4795
+ if ( toShow.length && toHide.length ) {
4796
+ toHide.prev().attr( {
4797
+ "tabIndex": -1,
4798
+ "aria-expanded": "false"
4799
+ } );
4800
+ } else if ( toShow.length ) {
4801
+ this.headers.filter( function() {
4802
+ return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4803
+ } )
4804
+ .attr( "tabIndex", -1 );
4805
+ }
4806
+
4807
+ toShow
4808
+ .attr( "aria-hidden", "false" )
4809
+ .prev()
4810
+ .attr( {
4811
+ "aria-selected": "true",
4812
+ "aria-expanded": "true",
4813
+ tabIndex: 0
4814
+ } );
4815
+ },
4816
+
4817
+ _animate: function( toShow, toHide, data ) {
4818
+ var total, easing, duration,
4819
+ that = this,
4820
+ adjust = 0,
4821
+ boxSizing = toShow.css( "box-sizing" ),
4822
+ down = toShow.length &&
4823
+ ( !toHide.length || ( toShow.index() < toHide.index() ) ),
4824
+ animate = this.options.animate || {},
4825
+ options = down && animate.down || animate,
4826
+ complete = function() {
4827
+ that._toggleComplete( data );
4828
+ };
4829
+
4830
+ if ( typeof options === "number" ) {
4831
+ duration = options;
4832
+ }
4833
+ if ( typeof options === "string" ) {
4834
+ easing = options;
4835
+ }
4836
+
4837
+ // fall back from options to animation in case of partial down settings
4838
+ easing = easing || options.easing || animate.easing;
4839
+ duration = duration || options.duration || animate.duration;
4840
+
4841
+ if ( !toHide.length ) {
4842
+ return toShow.animate( this.showProps, duration, easing, complete );
4843
+ }
4844
+ if ( !toShow.length ) {
4845
+ return toHide.animate( this.hideProps, duration, easing, complete );
4846
+ }
4847
+
4848
+ total = toShow.show().outerHeight();
4849
+ toHide.animate( this.hideProps, {
4850
+ duration: duration,
4851
+ easing: easing,
4852
+ step: function( now, fx ) {
4853
+ fx.now = Math.round( now );
4854
+ }
4855
+ } );
4856
+ toShow
4857
+ .hide()
4858
+ .animate( this.showProps, {
4859
+ duration: duration,
4860
+ easing: easing,
4861
+ complete: complete,
4862
+ step: function( now, fx ) {
4863
+ fx.now = Math.round( now );
4864
+ if ( fx.prop !== "height" ) {
4865
+ if ( boxSizing === "content-box" ) {
4866
+ adjust += fx.now;
4867
+ }
4868
+ } else if ( that.options.heightStyle !== "content" ) {
4869
+ fx.now = Math.round( total - toHide.outerHeight() - adjust );
4870
+ adjust = 0;
4871
+ }
4872
+ }
4873
+ } );
4874
+ },
4875
+
4876
+ _toggleComplete: function( data ) {
4877
+ var toHide = data.oldPanel,
4878
+ prev = toHide.prev();
4879
+
4880
+ this._removeClass( toHide, "ui-accordion-content-active" );
4881
+ this._removeClass( prev, "ui-accordion-header-active" )
4882
+ ._addClass( prev, "ui-accordion-header-collapsed" );
4883
+
4884
+ // Work around for rendering bug in IE (#5421)
4885
+ if ( toHide.length ) {
4886
+ toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4887
+ }
4888
+ this._trigger( "activate", null, data );
4889
+ }
4890
+ } );
4891
+
4892
+
4893
+
4894
+ var safeActiveElement = $.ui.safeActiveElement = function( document ) {
4895
+ var activeElement;
4896
+
4897
+ // Support: IE 9 only
4898
+ // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
4899
+ try {
4900
+ activeElement = document.activeElement;
4901
+ } catch ( error ) {
4902
+ activeElement = document.body;
4903
+ }
4904
+
4905
+ // Support: IE 9 - 11 only
4906
+ // IE may return null instead of an element
4907
+ // Interestingly, this only seems to occur when NOT in an iframe
4908
+ if ( !activeElement ) {
4909
+ activeElement = document.body;
4910
+ }
4911
+
4912
+ // Support: IE 11 only
4913
+ // IE11 returns a seemingly empty object in some cases when accessing
4914
+ // document.activeElement from an <iframe>
4915
+ if ( !activeElement.nodeName ) {
4916
+ activeElement = document.body;
4917
+ }
4918
+
4919
+ return activeElement;
4920
+ };
4921
+
4922
+
4923
+ /*!
4924
+ * jQuery UI Menu 1.12.1
4925
+ * http://jqueryui.com
4926
+ *
4927
+ * Copyright jQuery Foundation and other contributors
4928
+ * Released under the MIT license.
4929
+ * http://jquery.org/license
4930
+ */
4931
+
4932
+ //>>label: Menu
4933
+ //>>group: Widgets
4934
+ //>>description: Creates nestable menus.
4935
+ //>>docs: http://api.jqueryui.com/menu/
4936
+ //>>demos: http://jqueryui.com/menu/
4937
+ //>>css.structure: ../../themes/base/core.css
4938
+ //>>css.structure: ../../themes/base/menu.css
4939
+ //>>css.theme: ../../themes/base/theme.css
4940
+
4941
+
4942
+
4943
+ var widgetsMenu = $.widget( "ui.menu", {
4944
+ version: "1.12.1",
4945
+ defaultElement: "<ul>",
4946
+ delay: 300,
4947
+ options: {
4948
+ icons: {
4949
+ submenu: "ui-icon-caret-1-e"
4950
+ },
4951
+ items: "> *",
4952
+ menus: "ul",
4953
+ position: {
4954
+ my: "left top",
4955
+ at: "right top"
4956
+ },
4957
+ role: "menu",
4958
+
4959
+ // Callbacks
4960
+ blur: null,
4961
+ focus: null,
4962
+ select: null
4963
+ },
4964
+
4965
+ _create: function() {
4966
+ this.activeMenu = this.element;
4967
+
4968
+ // Flag used to prevent firing of the click handler
4969
+ // as the event bubbles up through nested menus
4970
+ this.mouseHandled = false;
4971
+ this.element
4972
+ .uniqueId()
4973
+ .attr( {
4974
+ role: this.options.role,
4975
+ tabIndex: 0
4976
+ } );
4977
+
4978
+ this._addClass( "ui-menu", "ui-widget ui-widget-content" );
4979
+ this._on( {
4980
+
4981
+ // Prevent focus from sticking to links inside menu after clicking
4982
+ // them (focus should always stay on UL during navigation).
4983
+ "mousedown .ui-menu-item": function( event ) {
4984
+ event.preventDefault();
4985
+ },
4986
+ "click .ui-menu-item": function( event ) {
4987
+ var target = $( event.target );
4988
+ var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
4989
+ if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
4990
+ this.select( event );
4991
+
4992
+ // Only set the mouseHandled flag if the event will bubble, see #9469.
4993
+ if ( !event.isPropagationStopped() ) {
4994
+ this.mouseHandled = true;
4995
+ }
4996
+
4997
+ // Open submenu on click
4998
+ if ( target.has( ".ui-menu" ).length ) {
4999
+ this.expand( event );
5000
+ } else if ( !this.element.is( ":focus" ) &&
5001
+ active.closest( ".ui-menu" ).length ) {
5002
+
5003
+ // Redirect focus to the menu
5004
+ this.element.trigger( "focus", [ true ] );
5005
+
5006
+ // If the active item is on the top level, let it stay active.
5007
+ // Otherwise, blur the active item since it is no longer visible.
5008
+ if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
5009
+ clearTimeout( this.timer );
5010
+ }
5011
+ }
5012
+ }
5013
+ },
5014
+ "mouseenter .ui-menu-item": function( event ) {
5015
+
5016
+ // Ignore mouse events while typeahead is active, see #10458.
5017
+ // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
5018
+ // is over an item in the menu
5019
+ if ( this.previousFilter ) {
5020
+ return;
5021
+ }
5022
+
5023
+ var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
5024
+ target = $( event.currentTarget );
5025
+
5026
+ // Ignore bubbled events on parent items, see #11641
5027
+ if ( actualTarget[ 0 ] !== target[ 0 ] ) {
5028
+ return;
5029
+ }
5030
+
5031
+ // Remove ui-state-active class from siblings of the newly focused menu item
5032
+ // to avoid a jump caused by adjacent elements both having a class with a border
5033
+ this._removeClass( target.siblings().children( ".ui-state-active" ),
5034
+ null, "ui-state-active" );
5035
+ this.focus( event, target );
5036
+ },
5037
+ mouseleave: "collapseAll",
5038
+ "mouseleave .ui-menu": "collapseAll",
5039
+ focus: function( event, keepActiveItem ) {
5040
+
5041
+ // If there's already an active item, keep it active
5042
+ // If not, activate the first item
5043
+ var item = this.active || this.element.find( this.options.items ).eq( 0 );
5044
+
5045
+ if ( !keepActiveItem ) {
5046
+ this.focus( event, item );
5047
+ }
5048
+ },
5049
+ blur: function( event ) {
5050
+ this._delay( function() {
5051
+ var notContained = !$.contains(
5052
+ this.element[ 0 ],
5053
+ $.ui.safeActiveElement( this.document[ 0 ] )
5054
+ );
5055
+ if ( notContained ) {
5056
+ this.collapseAll( event );
5057
+ }
5058
+ } );
5059
+ },
5060
+ keydown: "_keydown"
5061
+ } );
5062
+
5063
+ this.refresh();
5064
+
5065
+ // Clicks outside of a menu collapse any open menus
5066
+ this._on( this.document, {
5067
+ click: function( event ) {
5068
+ if ( this._closeOnDocumentClick( event ) ) {
5069
+ this.collapseAll( event );
5070
+ }
5071
+
5072
+ // Reset the mouseHandled flag
5073
+ this.mouseHandled = false;
5074
+ }
5075
+ } );
5076
+ },
5077
+
5078
+ _destroy: function() {
5079
+ var items = this.element.find( ".ui-menu-item" )
5080
+ .removeAttr( "role aria-disabled" ),
5081
+ submenus = items.children( ".ui-menu-item-wrapper" )
5082
+ .removeUniqueId()
5083
+ .removeAttr( "tabIndex role aria-haspopup" );
5084
+
5085
+ // Destroy (sub)menus
5086
+ this.element
5087
+ .removeAttr( "aria-activedescendant" )
5088
+ .find( ".ui-menu" ).addBack()
5089
+ .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
5090
+ "tabIndex" )
5091
+ .removeUniqueId()
5092
+ .show();
5093
+
5094
+ submenus.children().each( function() {
5095
+ var elem = $( this );
5096
+ if ( elem.data( "ui-menu-submenu-caret" ) ) {
5097
+ elem.remove();
5098
+ }
5099
+ } );
5100
+ },
5101
+
5102
+ _keydown: function( event ) {
5103
+ var match, prev, character, skip,
5104
+ preventDefault = true;
5105
+
5106
+ switch ( event.keyCode ) {
5107
+ case $.ui.keyCode.PAGE_UP:
5108
+ this.previousPage( event );
5109
+ break;
5110
+ case $.ui.keyCode.PAGE_DOWN:
5111
+ this.nextPage( event );
5112
+ break;
5113
+ case $.ui.keyCode.HOME:
5114
+ this._move( "first", "first", event );
5115
+ break;
5116
+ case $.ui.keyCode.END:
5117
+ this._move( "last", "last", event );
5118
+ break;
5119
+ case $.ui.keyCode.UP:
5120
+ this.previous( event );
5121
+ break;
5122
+ case $.ui.keyCode.DOWN:
5123
+ this.next( event );
5124
+ break;
5125
+ case $.ui.keyCode.LEFT:
5126
+ this.collapse( event );
5127
+ break;
5128
+ case $.ui.keyCode.RIGHT:
5129
+ if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5130
+ this.expand( event );
5131
+ }
5132
+ break;
5133
+ case $.ui.keyCode.ENTER:
5134
+ case $.ui.keyCode.SPACE:
5135
+ this._activate( event );
5136
+ break;
5137
+ case $.ui.keyCode.ESCAPE:
5138
+ this.collapse( event );
5139
+ break;
5140
+ default:
5141
+ preventDefault = false;
5142
+ prev = this.previousFilter || "";
5143
+ skip = false;
5144
+
5145
+ // Support number pad values
5146
+ character = event.keyCode >= 96 && event.keyCode <= 105 ?
5147
+ ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
5148
+
5149
+ clearTimeout( this.filterTimer );
5150
+
5151
+ if ( character === prev ) {
5152
+ skip = true;
5153
+ } else {
5154
+ character = prev + character;
5155
+ }
5156
+
5157
+ match = this._filterMenuItems( character );
5158
+ match = skip && match.index( this.active.next() ) !== -1 ?
5159
+ this.active.nextAll( ".ui-menu-item" ) :
5160
+ match;
5161
+
5162
+ // If no matches on the current filter, reset to the last character pressed
5163
+ // to move down the menu to the first item that starts with that character
5164
+ if ( !match.length ) {
5165
+ character = String.fromCharCode( event.keyCode );
5166
+ match = this._filterMenuItems( character );
5167
+ }
5168
+
5169
+ if ( match.length ) {
5170
+ this.focus( event, match );
5171
+ this.previousFilter = character;
5172
+ this.filterTimer = this._delay( function() {
5173
+ delete this.previousFilter;
5174
+ }, 1000 );
5175
+ } else {
5176
+ delete this.previousFilter;
5177
+ }
5178
+ }
5179
+
5180
+ if ( preventDefault ) {
5181
+ event.preventDefault();
5182
+ }
5183
+ },
5184
+
5185
+ _activate: function( event ) {
5186
+ if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5187
+ if ( this.active.children( "[aria-haspopup='true']" ).length ) {
5188
+ this.expand( event );
5189
+ } else {
5190
+ this.select( event );
5191
+ }
5192
+ }
5193
+ },
5194
+
5195
+ refresh: function() {
5196
+ var menus, items, newSubmenus, newItems, newWrappers,
5197
+ that = this,
5198
+ icon = this.options.icons.submenu,
5199
+ submenus = this.element.find( this.options.menus );
5200
+
5201
+ this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
5202
+
5203
+ // Initialize nested menus
5204
+ newSubmenus = submenus.filter( ":not(.ui-menu)" )
5205
+ .hide()
5206
+ .attr( {
5207
+ role: this.options.role,
5208
+ "aria-hidden": "true",
5209
+ "aria-expanded": "false"
5210
+ } )
5211
+ .each( function() {
5212
+ var menu = $( this ),
5213
+ item = menu.prev(),
5214
+ submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
5215
+
5216
+ that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
5217
+ item
5218
+ .attr( "aria-haspopup", "true" )
5219
+ .prepend( submenuCaret );
5220
+ menu.attr( "aria-labelledby", item.attr( "id" ) );
5221
+ } );
5222
+
5223
+ this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
5224
+
5225
+ menus = submenus.add( this.element );
5226
+ items = menus.find( this.options.items );
5227
+
5228
+ // Initialize menu-items containing spaces and/or dashes only as dividers
5229
+ items.not( ".ui-menu-item" ).each( function() {
5230
+ var item = $( this );
5231
+ if ( that._isDivider( item ) ) {
5232
+ that._addClass( item, "ui-menu-divider", "ui-widget-content" );
5233
+ }
5234
+ } );
5235
+
5236
+ // Don't refresh list items that are already adapted
5237
+ newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
5238
+ newWrappers = newItems.children()
5239
+ .not( ".ui-menu" )
5240
+ .uniqueId()
5241
+ .attr( {
5242
+ tabIndex: -1,
5243
+ role: this._itemRole()
5244
+ } );
5245
+ this._addClass( newItems, "ui-menu-item" )
5246
+ ._addClass( newWrappers, "ui-menu-item-wrapper" );
5247
+
5248
+ // Add aria-disabled attribute to any disabled menu item
5249
+ items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5250
+
5251
+ // If the active item has been removed, blur the menu
5252
+ if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5253
+ this.blur();
5254
+ }
5255
+ },
5256
+
5257
+ _itemRole: function() {
5258
+ return {
5259
+ menu: "menuitem",
5260
+ listbox: "option"
5261
+ }[ this.options.role ];
5262
+ },
5263
+
5264
+ _setOption: function( key, value ) {
5265
+ if ( key === "icons" ) {
5266
+ var icons = this.element.find( ".ui-menu-icon" );
5267
+ this._removeClass( icons, null, this.options.icons.submenu )
5268
+ ._addClass( icons, null, value.submenu );
5269
+ }
5270
+ this._super( key, value );
5271
+ },
5272
+
5273
+ _setOptionDisabled: function( value ) {
5274
+ this._super( value );
5275
+
5276
+ this.element.attr( "aria-disabled", String( value ) );
5277
+ this._toggleClass( null, "ui-state-disabled", !!value );
5278
+ },
5279
+
5280
+ focus: function( event, item ) {
5281
+ var nested, focused, activeParent;
5282
+ this.blur( event, event && event.type === "focus" );
5283
+
5284
+ this._scrollIntoView( item );
5285
+
5286
+ this.active = item.first();
5287
+
5288
+ focused = this.active.children( ".ui-menu-item-wrapper" );
5289
+ this._addClass( focused, null, "ui-state-active" );
5290
+
5291
+ // Only update aria-activedescendant if there's a role
5292
+ // otherwise we assume focus is managed elsewhere
5293
+ if ( this.options.role ) {
5294
+ this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5295
+ }
5296
+
5297
+ // Highlight active parent menu item, if any
5298
+ activeParent = this.active
5299
+ .parent()
5300
+ .closest( ".ui-menu-item" )
5301
+ .children( ".ui-menu-item-wrapper" );
5302
+ this._addClass( activeParent, null, "ui-state-active" );
5303
+
5304
+ if ( event && event.type === "keydown" ) {
5305
+ this._close();
5306
+ } else {
5307
+ this.timer = this._delay( function() {
5308
+ this._close();
5309
+ }, this.delay );
5310
+ }
5311
+
5312
+ nested = item.children( ".ui-menu" );
5313
+ if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5314
+ this._startOpening( nested );
5315
+ }
5316
+ this.activeMenu = item.parent();
5317
+
5318
+ this._trigger( "focus", event, { item: item } );
5319
+ },
5320
+
5321
+ _scrollIntoView: function( item ) {
5322
+ var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5323
+ if ( this._hasScroll() ) {
5324
+ borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
5325
+ paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
5326
+ offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5327
+ scroll = this.activeMenu.scrollTop();
5328
+ elementHeight = this.activeMenu.height();
5329
+ itemHeight = item.outerHeight();
5330
+
5331
+ if ( offset < 0 ) {
5332
+ this.activeMenu.scrollTop( scroll + offset );
5333
+ } else if ( offset + itemHeight > elementHeight ) {
5334
+ this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5335
+ }
5336
+ }
5337
+ },
5338
+
5339
+ blur: function( event, fromFocus ) {
5340
+ if ( !fromFocus ) {
5341
+ clearTimeout( this.timer );
5342
+ }
5343
+
5344
+ if ( !this.active ) {
5345
+ return;
5346
+ }
5347
+
5348
+ this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
5349
+ null, "ui-state-active" );
5350
+
5351
+ this._trigger( "blur", event, { item: this.active } );
5352
+ this.active = null;
5353
+ },
5354
+
5355
+ _startOpening: function( submenu ) {
5356
+ clearTimeout( this.timer );
5357
+
5358
+ // Don't open if already open fixes a Firefox bug that caused a .5 pixel
5359
+ // shift in the submenu position when mousing over the caret icon
5360
+ if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5361
+ return;
5362
+ }
5363
+
5364
+ this.timer = this._delay( function() {
5365
+ this._close();
5366
+ this._open( submenu );
5367
+ }, this.delay );
5368
+ },
5369
+
5370
+ _open: function( submenu ) {
5371
+ var position = $.extend( {
5372
+ of: this.active
5373
+ }, this.options.position );
5374
+
5375
+ clearTimeout( this.timer );
5376
+ this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5377
+ .hide()
5378
+ .attr( "aria-hidden", "true" );
5379
+
5380
+ submenu
5381
+ .show()
5382
+ .removeAttr( "aria-hidden" )
5383
+ .attr( "aria-expanded", "true" )
5384
+ .position( position );
5385
+ },
5386
+
5387
+ collapseAll: function( event, all ) {
5388
+ clearTimeout( this.timer );
5389
+ this.timer = this._delay( function() {
5390
+
5391
+ // If we were passed an event, look for the submenu that contains the event
5392
+ var currentMenu = all ? this.element :
5393
+ $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5394
+
5395
+ // If we found no valid submenu ancestor, use the main menu to close all
5396
+ // sub menus anyway
5397
+ if ( !currentMenu.length ) {
5398
+ currentMenu = this.element;
5399
+ }
5400
+
5401
+ this._close( currentMenu );
5402
+
5403
+ this.blur( event );
5404
+
5405
+ // Work around active item staying active after menu is blurred
5406
+ this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
5407
+
5408
+ this.activeMenu = currentMenu;
5409
+ }, this.delay );
5410
+ },
5411
+
5412
+ // With no arguments, closes the currently active menu - if nothing is active
5413
+ // it closes all menus. If passed an argument, it will search for menus BELOW
5414
+ _close: function( startMenu ) {
5415
+ if ( !startMenu ) {
5416
+ startMenu = this.active ? this.active.parent() : this.element;
5417
+ }
5418
+
5419
+ startMenu.find( ".ui-menu" )
5420
+ .hide()
5421
+ .attr( "aria-hidden", "true" )
5422
+ .attr( "aria-expanded", "false" );
5423
+ },
5424
+
5425
+ _closeOnDocumentClick: function( event ) {
5426
+ return !$( event.target ).closest( ".ui-menu" ).length;
5427
+ },
5428
+
5429
+ _isDivider: function( item ) {
5430
+
5431
+ // Match hyphen, em dash, en dash
5432
+ return !/[^\-\u2014\u2013\s]/.test( item.text() );
5433
+ },
5434
+
5435
+ collapse: function( event ) {
5436
+ var newItem = this.active &&
5437
+ this.active.parent().closest( ".ui-menu-item", this.element );
5438
+ if ( newItem && newItem.length ) {
5439
+ this._close();
5440
+ this.focus( event, newItem );
5441
+ }
5442
+ },
5443
+
5444
+ expand: function( event ) {
5445
+ var newItem = this.active &&
5446
+ this.active
5447
+ .children( ".ui-menu " )
5448
+ .find( this.options.items )
5449
+ .first();
5450
+
5451
+ if ( newItem && newItem.length ) {
5452
+ this._open( newItem.parent() );
5453
+
5454
+ // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5455
+ this._delay( function() {
5456
+ this.focus( event, newItem );
5457
+ } );
5458
+ }
5459
+ },
5460
+
5461
+ next: function( event ) {
5462
+ this._move( "next", "first", event );
5463
+ },
5464
+
5465
+ previous: function( event ) {
5466
+ this._move( "prev", "last", event );
5467
+ },
5468
+
5469
+ isFirstItem: function() {
5470
+ return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5471
+ },
5472
+
5473
+ isLastItem: function() {
5474
+ return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5475
+ },
5476
+
5477
+ _move: function( direction, filter, event ) {
5478
+ var next;
5479
+ if ( this.active ) {
5480
+ if ( direction === "first" || direction === "last" ) {
5481
+ next = this.active
5482
+ [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5483
+ .eq( -1 );
5484
+ } else {
5485
+ next = this.active
5486
+ [ direction + "All" ]( ".ui-menu-item" )
5487
+ .eq( 0 );
5488
+ }
5489
+ }
5490
+ if ( !next || !next.length || !this.active ) {
5491
+ next = this.activeMenu.find( this.options.items )[ filter ]();
5492
+ }
5493
+
5494
+ this.focus( event, next );
5495
+ },
5496
+
5497
+ nextPage: function( event ) {
5498
+ var item, base, height;
5499
+
5500
+ if ( !this.active ) {
5501
+ this.next( event );
5502
+ return;
5503
+ }
5504
+ if ( this.isLastItem() ) {
5505
+ return;
5506
+ }
5507
+ if ( this._hasScroll() ) {
5508
+ base = this.active.offset().top;
5509
+ height = this.element.height();
5510
+ this.active.nextAll( ".ui-menu-item" ).each( function() {
5511
+ item = $( this );
5512
+ return item.offset().top - base - height < 0;
5513
+ } );
5514
+
5515
+ this.focus( event, item );
5516
+ } else {
5517
+ this.focus( event, this.activeMenu.find( this.options.items )
5518
+ [ !this.active ? "first" : "last" ]() );
5519
+ }
5520
+ },
5521
+
5522
+ previousPage: function( event ) {
5523
+ var item, base, height;
5524
+ if ( !this.active ) {
5525
+ this.next( event );
5526
+ return;
5527
+ }
5528
+ if ( this.isFirstItem() ) {
5529
+ return;
5530
+ }
5531
+ if ( this._hasScroll() ) {
5532
+ base = this.active.offset().top;
5533
+ height = this.element.height();
5534
+ this.active.prevAll( ".ui-menu-item" ).each( function() {
5535
+ item = $( this );
5536
+ return item.offset().top - base + height > 0;
5537
+ } );
5538
+
5539
+ this.focus( event, item );
5540
+ } else {
5541
+ this.focus( event, this.activeMenu.find( this.options.items ).first() );
5542
+ }
5543
+ },
5544
+
5545
+ _hasScroll: function() {
5546
+ return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5547
+ },
5548
+
5549
+ select: function( event ) {
5550
+
5551
+ // TODO: It should never be possible to not have an active item at this
5552
+ // point, but the tests don't trigger mouseenter before click.
5553
+ this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5554
+ var ui = { item: this.active };
5555
+ if ( !this.active.has( ".ui-menu" ).length ) {
5556
+ this.collapseAll( event, true );
5557
+ }
5558
+ this._trigger( "select", event, ui );
5559
+ },
5560
+
5561
+ _filterMenuItems: function( character ) {
5562
+ var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5563
+ regex = new RegExp( "^" + escapedCharacter, "i" );
5564
+
5565
+ return this.activeMenu
5566
+ .find( this.options.items )
5567
+
5568
+ // Only match on items, not dividers or other content (#10571)
5569
+ .filter( ".ui-menu-item" )
5570
+ .filter( function() {
5571
+ return regex.test(
5572
+ $.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
5573
+ } );
5574
+ }
5575
+ } );
5576
+
5577
+
5578
+ /*!
5579
+ * jQuery UI Autocomplete 1.12.1
5580
+ * http://jqueryui.com
5581
+ *
5582
+ * Copyright jQuery Foundation and other contributors
5583
+ * Released under the MIT license.
5584
+ * http://jquery.org/license
5585
+ */
5586
+
5587
+ //>>label: Autocomplete
5588
+ //>>group: Widgets
5589
+ //>>description: Lists suggested words as the user is typing.
5590
+ //>>docs: http://api.jqueryui.com/autocomplete/
5591
+ //>>demos: http://jqueryui.com/autocomplete/
5592
+ //>>css.structure: ../../themes/base/core.css
5593
+ //>>css.structure: ../../themes/base/autocomplete.css
5594
+ //>>css.theme: ../../themes/base/theme.css
5595
+
5596
+
5597
+
5598
+ $.widget( "ui.autocomplete", {
5599
+ version: "1.12.1",
5600
+ defaultElement: "<input>",
5601
+ options: {
5602
+ appendTo: null,
5603
+ autoFocus: false,
5604
+ delay: 300,
5605
+ minLength: 1,
5606
+ position: {
5607
+ my: "left top",
5608
+ at: "left bottom",
5609
+ collision: "none"
5610
+ },
5611
+ source: null,
5612
+
5613
+ // Callbacks
5614
+ change: null,
5615
+ close: null,
5616
+ focus: null,
5617
+ open: null,
5618
+ response: null,
5619
+ search: null,
5620
+ select: null
5621
+ },
5622
+
5623
+ requestIndex: 0,
5624
+ pending: 0,
5625
+
5626
+ _create: function() {
5627
+
5628
+ // Some browsers only repeat keydown events, not keypress events,
5629
+ // so we use the suppressKeyPress flag to determine if we've already
5630
+ // handled the keydown event. #7269
5631
+ // Unfortunately the code for & in keypress is the same as the up arrow,
5632
+ // so we use the suppressKeyPressRepeat flag to avoid handling keypress
5633
+ // events when we know the keydown event was used to modify the
5634
+ // search term. #7799
5635
+ var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5636
+ nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5637
+ isTextarea = nodeName === "textarea",
5638
+ isInput = nodeName === "input";
5639
+
5640
+ // Textareas are always multi-line
5641
+ // Inputs are always single-line, even if inside a contentEditable element
5642
+ // IE also treats inputs as contentEditable
5643
+ // All other element types are determined by whether or not they're contentEditable
5644
+ this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
5645
+
5646
+ this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5647
+ this.isNewMenu = true;
5648
+
5649
+ this._addClass( "ui-autocomplete-input" );
5650
+ this.element.attr( "autocomplete", "off" );
5651
+
5652
+ this._on( this.element, {
5653
+ keydown: function( event ) {
5654
+ if ( this.element.prop( "readOnly" ) ) {
5655
+ suppressKeyPress = true;
5656
+ suppressInput = true;
5657
+ suppressKeyPressRepeat = true;
5658
+ return;
5659
+ }
5660
+
5661
+ suppressKeyPress = false;
5662
+ suppressInput = false;
5663
+ suppressKeyPressRepeat = false;
5664
+ var keyCode = $.ui.keyCode;
5665
+ switch ( event.keyCode ) {
5666
+ case keyCode.PAGE_UP:
5667
+ suppressKeyPress = true;
5668
+ this._move( "previousPage", event );
5669
+ break;
5670
+ case keyCode.PAGE_DOWN:
5671
+ suppressKeyPress = true;
5672
+ this._move( "nextPage", event );
5673
+ break;
5674
+ case keyCode.UP:
5675
+ suppressKeyPress = true;
5676
+ this._keyEvent( "previous", event );
5677
+ break;
5678
+ case keyCode.DOWN:
5679
+ suppressKeyPress = true;
5680
+ this._keyEvent( "next", event );
5681
+ break;
5682
+ case keyCode.ENTER:
5683
+
5684
+ // when menu is open and has focus
5685
+ if ( this.menu.active ) {
5686
+
5687
+ // #6055 - Opera still allows the keypress to occur
5688
+ // which causes forms to submit
5689
+ suppressKeyPress = true;
5690
+ event.preventDefault();
5691
+ this.menu.select( event );
5692
+ }
5693
+ break;
5694
+ case keyCode.TAB:
5695
+ if ( this.menu.active ) {
5696
+ this.menu.select( event );
5697
+ }
5698
+ break;
5699
+ case keyCode.ESCAPE:
5700
+ if ( this.menu.element.is( ":visible" ) ) {
5701
+ if ( !this.isMultiLine ) {
5702
+ this._value( this.term );
5703
+ }
5704
+ this.close( event );
5705
+
5706
+ // Different browsers have different default behavior for escape
5707
+ // Single press can mean undo or clear
5708
+ // Double press in IE means clear the whole form
5709
+ event.preventDefault();
5710
+ }
5711
+ break;
5712
+ default:
5713
+ suppressKeyPressRepeat = true;
5714
+
5715
+ // search timeout should be triggered before the input value is changed
5716
+ this._searchTimeout( event );
5717
+ break;
5718
+ }
5719
+ },
5720
+ keypress: function( event ) {
5721
+ if ( suppressKeyPress ) {
5722
+ suppressKeyPress = false;
5723
+ if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5724
+ event.preventDefault();
5725
+ }
5726
+ return;
5727
+ }
5728
+ if ( suppressKeyPressRepeat ) {
5729
+ return;
5730
+ }
5731
+
5732
+ // Replicate some key handlers to allow them to repeat in Firefox and Opera
5733
+ var keyCode = $.ui.keyCode;
5734
+ switch ( event.keyCode ) {
5735
+ case keyCode.PAGE_UP:
5736
+ this._move( "previousPage", event );
5737
+ break;
5738
+ case keyCode.PAGE_DOWN:
5739
+ this._move( "nextPage", event );
5740
+ break;
5741
+ case keyCode.UP:
5742
+ this._keyEvent( "previous", event );
5743
+ break;
5744
+ case keyCode.DOWN:
5745
+ this._keyEvent( "next", event );
5746
+ break;
5747
+ }
5748
+ },
5749
+ input: function( event ) {
5750
+ if ( suppressInput ) {
5751
+ suppressInput = false;
5752
+ event.preventDefault();
5753
+ return;
5754
+ }
5755
+ this._searchTimeout( event );
5756
+ },
5757
+ focus: function() {
5758
+ this.selectedItem = null;
5759
+ this.previous = this._value();
5760
+ },
5761
+ blur: function( event ) {
5762
+ if ( this.cancelBlur ) {
5763
+ delete this.cancelBlur;
5764
+ return;
5765
+ }
5766
+
5767
+ clearTimeout( this.searching );
5768
+ this.close( event );
5769
+ this._change( event );
5770
+ }
5771
+ } );
5772
+
5773
+ this._initSource();
5774
+ this.menu = $( "<ul>" )
5775
+ .appendTo( this._appendTo() )
5776
+ .menu( {
5777
+
5778
+ // disable ARIA support, the live region takes care of that
5779
+ role: null
5780
+ } )
5781
+ .hide()
5782
+ .menu( "instance" );
5783
+
5784
+ this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
5785
+ this._on( this.menu.element, {
5786
+ mousedown: function( event ) {
5787
+
5788
+ // prevent moving focus out of the text field
5789
+ event.preventDefault();
5790
+
5791
+ // IE doesn't prevent moving focus even with event.preventDefault()
5792
+ // so we set a flag to know when we should ignore the blur event
5793
+ this.cancelBlur = true;
5794
+ this._delay( function() {
5795
+ delete this.cancelBlur;
5796
+
5797
+ // Support: IE 8 only
5798
+ // Right clicking a menu item or selecting text from the menu items will
5799
+ // result in focus moving out of the input. However, we've already received
5800
+ // and ignored the blur event because of the cancelBlur flag set above. So
5801
+ // we restore focus to ensure that the menu closes properly based on the user's
5802
+ // next actions.
5803
+ if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5804
+ this.element.trigger( "focus" );
5805
+ }
5806
+ } );
5807
+ },
5808
+ menufocus: function( event, ui ) {
5809
+ var label, item;
5810
+
5811
+ // support: Firefox
5812
+ // Prevent accidental activation of menu items in Firefox (#7024 #9118)
5813
+ if ( this.isNewMenu ) {
5814
+ this.isNewMenu = false;
5815
+ if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5816
+ this.menu.blur();
5817
+
5818
+ this.document.one( "mousemove", function() {
5819
+ $( event.target ).trigger( event.originalEvent );
5820
+ } );
5821
+
5822
+ return;
5823
+ }
5824
+ }
5825
+
5826
+ item = ui.item.data( "ui-autocomplete-item" );
5827
+ if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5828
+
5829
+ // use value to match what will end up in the input, if it was a key event
5830
+ if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5831
+ this._value( item.value );
5832
+ }
5833
+ }
5834
+
5835
+ // Announce the value in the liveRegion
5836
+ label = ui.item.attr( "aria-label" ) || item.value;
5837
+ if ( label && $.trim( label ).length ) {
5838
+ this.liveRegion.children().hide();
5839
+ $( "<div>" ).text( label ).appendTo( this.liveRegion );
5840
+ }
5841
+ },
5842
+ menuselect: function( event, ui ) {
5843
+ var item = ui.item.data( "ui-autocomplete-item" ),
5844
+ previous = this.previous;
5845
+
5846
+ // Only trigger when focus was lost (click on menu)
5847
+ if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5848
+ this.element.trigger( "focus" );
5849
+ this.previous = previous;
5850
+
5851
+ // #6109 - IE triggers two focus events and the second
5852
+ // is asynchronous, so we need to reset the previous
5853
+ // term synchronously and asynchronously :-(
5854
+ this._delay( function() {
5855
+ this.previous = previous;
5856
+ this.selectedItem = item;
5857
+ } );
5858
+ }
5859
+
5860
+ if ( false !== this._trigger( "select", event, { item: item } ) ) {
5861
+ this._value( item.value );
5862
+ }
5863
+
5864
+ // reset the term after the select event
5865
+ // this allows custom select handling to work properly
5866
+ this.term = this._value();
5867
+
5868
+ this.close( event );
5869
+ this.selectedItem = item;
5870
+ }
5871
+ } );
5872
+
5873
+ this.liveRegion = $( "<div>", {
5874
+ role: "status",
5875
+ "aria-live": "assertive",
5876
+ "aria-relevant": "additions"
5877
+ } )
5878
+ .appendTo( this.document[ 0 ].body );
5879
+
5880
+ this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
5881
+
5882
+ // Turning off autocomplete prevents the browser from remembering the
5883
+ // value when navigating through history, so we re-enable autocomplete
5884
+ // if the page is unloaded before the widget is destroyed. #7790
5885
+ this._on( this.window, {
5886
+ beforeunload: function() {
5887
+ this.element.removeAttr( "autocomplete" );
5888
+ }
5889
+ } );
5890
+ },
5891
+
5892
+ _destroy: function() {
5893
+ clearTimeout( this.searching );
5894
+ this.element.removeAttr( "autocomplete" );
5895
+ this.menu.element.remove();
5896
+ this.liveRegion.remove();
5897
+ },
5898
+
5899
+ _setOption: function( key, value ) {
5900
+ this._super( key, value );
5901
+ if ( key === "source" ) {
5902
+ this._initSource();
5903
+ }
5904
+ if ( key === "appendTo" ) {
5905
+ this.menu.element.appendTo( this._appendTo() );
5906
+ }
5907
+ if ( key === "disabled" && value && this.xhr ) {
5908
+ this.xhr.abort();
5909
+ }
5910
+ },
5911
+
5912
+ _isEventTargetInWidget: function( event ) {
5913
+ var menuElement = this.menu.element[ 0 ];
5914
+
5915
+ return event.target === this.element[ 0 ] ||
5916
+ event.target === menuElement ||
5917
+ $.contains( menuElement, event.target );
5918
+ },
5919
+
5920
+ _closeOnClickOutside: function( event ) {
5921
+ if ( !this._isEventTargetInWidget( event ) ) {
5922
+ this.close();
5923
+ }
5924
+ },
5925
+
5926
+ _appendTo: function() {
5927
+ var element = this.options.appendTo;
5928
+
5929
+ if ( element ) {
5930
+ element = element.jquery || element.nodeType ?
5931
+ $( element ) :
5932
+ this.document.find( element ).eq( 0 );
5933
+ }
5934
+
5935
+ if ( !element || !element[ 0 ] ) {
5936
+ element = this.element.closest( ".ui-front, dialog" );
5937
+ }
5938
+
5939
+ if ( !element.length ) {
5940
+ element = this.document[ 0 ].body;
5941
+ }
5942
+
5943
+ return element;
5944
+ },
5945
+
5946
+ _initSource: function() {
5947
+ var array, url,
5948
+ that = this;
5949
+ if ( $.isArray( this.options.source ) ) {
5950
+ array = this.options.source;
5951
+ this.source = function( request, response ) {
5952
+ response( $.ui.autocomplete.filter( array, request.term ) );
5953
+ };
5954
+ } else if ( typeof this.options.source === "string" ) {
5955
+ url = this.options.source;
5956
+ this.source = function( request, response ) {
5957
+ if ( that.xhr ) {
5958
+ that.xhr.abort();
5959
+ }
5960
+ that.xhr = $.ajax( {
5961
+ url: url,
5962
+ data: request,
5963
+ dataType: "json",
5964
+ success: function( data ) {
5965
+ response( data );
5966
+ },
5967
+ error: function() {
5968
+ response( [] );
5969
+ }
5970
+ } );
5971
+ };
5972
+ } else {
5973
+ this.source = this.options.source;
5974
+ }
5975
+ },
5976
+
5977
+ _searchTimeout: function( event ) {
5978
+ clearTimeout( this.searching );
5979
+ this.searching = this._delay( function() {
5980
+
5981
+ // Search if the value has changed, or if the user retypes the same value (see #7434)
5982
+ var equalValues = this.term === this._value(),
5983
+ menuVisible = this.menu.element.is( ":visible" ),
5984
+ modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
5985
+
5986
+ if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
5987
+ this.selectedItem = null;
5988
+ this.search( null, event );
5989
+ }
5990
+ }, this.options.delay );
5991
+ },
5992
+
5993
+ search: function( value, event ) {
5994
+ value = value != null ? value : this._value();
5995
+
5996
+ // Always save the actual value, not the one passed as an argument
5997
+ this.term = this._value();
5998
+
5999
+ if ( value.length < this.options.minLength ) {
6000
+ return this.close( event );
6001
+ }
6002
+
6003
+ if ( this._trigger( "search", event ) === false ) {
6004
+ return;
6005
+ }
6006
+
6007
+ return this._search( value );
6008
+ },
6009
+
6010
+ _search: function( value ) {
6011
+ this.pending++;
6012
+ this._addClass( "ui-autocomplete-loading" );
6013
+ this.cancelSearch = false;
6014
+
6015
+ this.source( { term: value }, this._response() );
6016
+ },
6017
+
6018
+ _response: function() {
6019
+ var index = ++this.requestIndex;
6020
+
6021
+ return $.proxy( function( content ) {
6022
+ if ( index === this.requestIndex ) {
6023
+ this.__response( content );
6024
+ }
6025
+
6026
+ this.pending--;
6027
+ if ( !this.pending ) {
6028
+ this._removeClass( "ui-autocomplete-loading" );
6029
+ }
6030
+ }, this );
6031
+ },
6032
+
6033
+ __response: function( content ) {
6034
+ if ( content ) {
6035
+ content = this._normalize( content );
6036
+ }
6037
+ this._trigger( "response", null, { content: content } );
6038
+ if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6039
+ this._suggest( content );
6040
+ this._trigger( "open" );
6041
+ } else {
6042
+
6043
+ // use ._close() instead of .close() so we don't cancel future searches
6044
+ this._close();
6045
+ }
6046
+ },
6047
+
6048
+ close: function( event ) {
6049
+ this.cancelSearch = true;
6050
+ this._close( event );
6051
+ },
6052
+
6053
+ _close: function( event ) {
6054
+
6055
+ // Remove the handler that closes the menu on outside clicks
6056
+ this._off( this.document, "mousedown" );
6057
+
6058
+ if ( this.menu.element.is( ":visible" ) ) {
6059
+ this.menu.element.hide();
6060
+ this.menu.blur();
6061
+ this.isNewMenu = true;
6062
+ this._trigger( "close", event );
6063
+ }
6064
+ },
6065
+
6066
+ _change: function( event ) {
6067
+ if ( this.previous !== this._value() ) {
6068
+ this._trigger( "change", event, { item: this.selectedItem } );
6069
+ }
6070
+ },
6071
+
6072
+ _normalize: function( items ) {
6073
+
6074
+ // assume all items have the right format when the first item is complete
6075
+ if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
6076
+ return items;
6077
+ }
6078
+ return $.map( items, function( item ) {
6079
+ if ( typeof item === "string" ) {
6080
+ return {
6081
+ label: item,
6082
+ value: item
6083
+ };
6084
+ }
6085
+ return $.extend( {}, item, {
6086
+ label: item.label || item.value,
6087
+ value: item.value || item.label
6088
+ } );
6089
+ } );
6090
+ },
6091
+
6092
+ _suggest: function( items ) {
6093
+ var ul = this.menu.element.empty();
6094
+ this._renderMenu( ul, items );
6095
+ this.isNewMenu = true;
6096
+ this.menu.refresh();
6097
+
6098
+ // Size and position menu
6099
+ ul.show();
6100
+ this._resizeMenu();
6101
+ ul.position( $.extend( {
6102
+ of: this.element
6103
+ }, this.options.position ) );
6104
+
6105
+ if ( this.options.autoFocus ) {
6106
+ this.menu.next();
6107
+ }
6108
+
6109
+ // Listen for interactions outside of the widget (#6642)
6110
+ this._on( this.document, {
6111
+ mousedown: "_closeOnClickOutside"
6112
+ } );
6113
+ },
6114
+
6115
+ _resizeMenu: function() {
6116
+ var ul = this.menu.element;
6117
+ ul.outerWidth( Math.max(
6118
+
6119
+ // Firefox wraps long text (possibly a rounding bug)
6120
+ // so we add 1px to avoid the wrapping (#7513)
6121
+ ul.width( "" ).outerWidth() + 1,
6122
+ this.element.outerWidth()
6123
+ ) );
6124
+ },
6125
+
6126
+ _renderMenu: function( ul, items ) {
6127
+ var that = this;
6128
+ $.each( items, function( index, item ) {
6129
+ that._renderItemData( ul, item );
6130
+ } );
6131
+ },
6132
+
6133
+ _renderItemData: function( ul, item ) {
6134
+ return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6135
+ },
6136
+
6137
+ _renderItem: function( ul, item ) {
6138
+ return $( "<li>" )
6139
+ .append( $( "<div>" ).text( item.label ) )
6140
+ .appendTo( ul );
6141
+ },
6142
+
6143
+ _move: function( direction, event ) {
6144
+ if ( !this.menu.element.is( ":visible" ) ) {
6145
+ this.search( null, event );
6146
+ return;
6147
+ }
6148
+ if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6149
+ this.menu.isLastItem() && /^next/.test( direction ) ) {
6150
+
6151
+ if ( !this.isMultiLine ) {
6152
+ this._value( this.term );
6153
+ }
6154
+
6155
+ this.menu.blur();
6156
+ return;
6157
+ }
6158
+ this.menu[ direction ]( event );
6159
+ },
6160
+
6161
+ widget: function() {
6162
+ return this.menu.element;
6163
+ },
6164
+
6165
+ _value: function() {
6166
+ return this.valueMethod.apply( this.element, arguments );
6167
+ },
6168
+
6169
+ _keyEvent: function( keyEvent, event ) {
6170
+ if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6171
+ this._move( keyEvent, event );
6172
+
6173
+ // Prevents moving cursor to beginning/end of the text field in some browsers
6174
+ event.preventDefault();
6175
+ }
6176
+ },
6177
+
6178
+ // Support: Chrome <=50
6179
+ // We should be able to just use this.element.prop( "isContentEditable" )
6180
+ // but hidden elements always report false in Chrome.
6181
+ // https://code.google.com/p/chromium/issues/detail?id=313082
6182
+ _isContentEditable: function( element ) {
6183
+ if ( !element.length ) {
6184
+ return false;
6185
+ }
6186
+
6187
+ var editable = element.prop( "contentEditable" );
6188
+
6189
+ if ( editable === "inherit" ) {
6190
+ return this._isContentEditable( element.parent() );
6191
+ }
6192
+
6193
+ return editable === "true";
6194
+ }
6195
+ } );
6196
+
6197
+ $.extend( $.ui.autocomplete, {
6198
+ escapeRegex: function( value ) {
6199
+ return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6200
+ },
6201
+ filter: function( array, term ) {
6202
+ var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6203
+ return $.grep( array, function( value ) {
6204
+ return matcher.test( value.label || value.value || value );
6205
+ } );
6206
+ }
6207
+ } );
6208
+
6209
+ // Live region extension, adding a `messages` option
6210
+ // NOTE: This is an experimental API. We are still investigating
6211
+ // a full solution for string manipulation and internationalization.
6212
+ $.widget( "ui.autocomplete", $.ui.autocomplete, {
6213
+ options: {
6214
+ messages: {
6215
+ noResults: "No search results.",
6216
+ results: function( amount ) {
6217
+ return amount + ( amount > 1 ? " results are" : " result is" ) +
6218
+ " available, use up and down arrow keys to navigate.";
6219
+ }
6220
+ }
6221
+ },
6222
+
6223
+ __response: function( content ) {
6224
+ var message;
6225
+ this._superApply( arguments );
6226
+ if ( this.options.disabled || this.cancelSearch ) {
6227
+ return;
6228
+ }
6229
+ if ( content && content.length ) {
6230
+ message = this.options.messages.results( content.length );
6231
+ } else {
6232
+ message = this.options.messages.noResults;
6233
+ }
6234
+ this.liveRegion.children().hide();
6235
+ $( "<div>" ).text( message ).appendTo( this.liveRegion );
6236
+ }
6237
+ } );
6238
+
6239
+ var widgetsAutocomplete = $.ui.autocomplete;
6240
+
6241
+
6242
+ /*!
6243
+ * jQuery UI Controlgroup 1.12.1
6244
+ * http://jqueryui.com
6245
+ *
6246
+ * Copyright jQuery Foundation and other contributors
6247
+ * Released under the MIT license.
6248
+ * http://jquery.org/license
6249
+ */
6250
+
6251
+ //>>label: Controlgroup
6252
+ //>>group: Widgets
6253
+ //>>description: Visually groups form control widgets
6254
+ //>>docs: http://api.jqueryui.com/controlgroup/
6255
+ //>>demos: http://jqueryui.com/controlgroup/
6256
+ //>>css.structure: ../../themes/base/core.css
6257
+ //>>css.structure: ../../themes/base/controlgroup.css
6258
+ //>>css.theme: ../../themes/base/theme.css
6259
+
6260
+
6261
+ var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6262
+
6263
+ var widgetsControlgroup = $.widget( "ui.controlgroup", {
6264
+ version: "1.12.1",
6265
+ defaultElement: "<div>",
6266
+ options: {
6267
+ direction: "horizontal",
6268
+ disabled: null,
6269
+ onlyVisible: true,
6270
+ items: {
6271
+ "button": "input[type=button], input[type=submit], input[type=reset], button, a",
6272
+ "controlgroupLabel": ".ui-controlgroup-label",
6273
+ "checkboxradio": "input[type='checkbox'], input[type='radio']",
6274
+ "selectmenu": "select",
6275
+ "spinner": ".ui-spinner-input"
6276
+ }
6277
+ },
6278
+
6279
+ _create: function() {
6280
+ this._enhance();
6281
+ },
6282
+
6283
+ // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
6284
+ _enhance: function() {
6285
+ this.element.attr( "role", "toolbar" );
6286
+ this.refresh();
6287
+ },
6288
+
6289
+ _destroy: function() {
6290
+ this._callChildMethod( "destroy" );
6291
+ this.childWidgets.removeData( "ui-controlgroup-data" );
6292
+ this.element.removeAttr( "role" );
6293
+ if ( this.options.items.controlgroupLabel ) {
6294
+ this.element
6295
+ .find( this.options.items.controlgroupLabel )
6296
+ .find( ".ui-controlgroup-label-contents" )
6297
+ .contents().unwrap();
6298
+ }
6299
+ },
6300
+
6301
+ _initWidgets: function() {
6302
+ var that = this,
6303
+ childWidgets = [];
6304
+
6305
+ // First we iterate over each of the items options
6306
+ $.each( this.options.items, function( widget, selector ) {
6307
+ var labels;
6308
+ var options = {};
6309
+
6310
+ // Make sure the widget has a selector set
6311
+ if ( !selector ) {
6312
+ return;
6313
+ }
6314
+
6315
+ if ( widget === "controlgroupLabel" ) {
6316
+ labels = that.element.find( selector );
6317
+ labels.each( function() {
6318
+ var element = $( this );
6319
+
6320
+ if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
6321
+ return;
6322
+ }
6323
+ element.contents()
6324
+ .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
6325
+ } );
6326
+ that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
6327
+ childWidgets = childWidgets.concat( labels.get() );
6328
+ return;
6329
+ }
6330
+
6331
+ // Make sure the widget actually exists
6332
+ if ( !$.fn[ widget ] ) {
6333
+ return;
6334
+ }
6335
+
6336
+ // We assume everything is in the middle to start because we can't determine
6337
+ // first / last elements until all enhancments are done.
6338
+ if ( that[ "_" + widget + "Options" ] ) {
6339
+ options = that[ "_" + widget + "Options" ]( "middle" );
6340
+ } else {
6341
+ options = { classes: {} };
6342
+ }
6343
+
6344
+ // Find instances of this widget inside controlgroup and init them
6345
+ that.element
6346
+ .find( selector )
6347
+ .each( function() {
6348
+ var element = $( this );
6349
+ var instance = element[ widget ]( "instance" );
6350
+
6351
+ // We need to clone the default options for this type of widget to avoid
6352
+ // polluting the variable options which has a wider scope than a single widget.
6353
+ var instanceOptions = $.widget.extend( {}, options );
6354
+
6355
+ // If the button is the child of a spinner ignore it
6356
+ // TODO: Find a more generic solution
6357
+ if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
6358
+ return;
6359
+ }
6360
+
6361
+ // Create the widget if it doesn't exist
6362
+ if ( !instance ) {
6363
+ instance = element[ widget ]()[ widget ]( "instance" );
6364
+ }
6365
+ if ( instance ) {
6366
+ instanceOptions.classes =
6367
+ that._resolveClassesValues( instanceOptions.classes, instance );
6368
+ }
6369
+ element[ widget ]( instanceOptions );
6370
+
6371
+ // Store an instance of the controlgroup to be able to reference
6372
+ // from the outermost element for changing options and refresh
6373
+ var widgetElement = element[ widget ]( "widget" );
6374
+ $.data( widgetElement[ 0 ], "ui-controlgroup-data",
6375
+ instance ? instance : element[ widget ]( "instance" ) );
6376
+
6377
+ childWidgets.push( widgetElement[ 0 ] );
6378
+ } );
6379
+ } );
6380
+
6381
+ this.childWidgets = $( $.unique( childWidgets ) );
6382
+ this._addClass( this.childWidgets, "ui-controlgroup-item" );
6383
+ },
6384
+
6385
+ _callChildMethod: function( method ) {
6386
+ this.childWidgets.each( function() {
6387
+ var element = $( this ),
6388
+ data = element.data( "ui-controlgroup-data" );
6389
+ if ( data && data[ method ] ) {
6390
+ data[ method ]();
6391
+ }
6392
+ } );
6393
+ },
6394
+
6395
+ _updateCornerClass: function( element, position ) {
6396
+ var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
6397
+ var add = this._buildSimpleOptions( position, "label" ).classes.label;
6398
+
6399
+ this._removeClass( element, null, remove );
6400
+ this._addClass( element, null, add );
6401
+ },
6402
+
6403
+ _buildSimpleOptions: function( position, key ) {
6404
+ var direction = this.options.direction === "vertical";
6405
+ var result = {
6406
+ classes: {}
6407
+ };
6408
+ result.classes[ key ] = {
6409
+ "middle": "",
6410
+ "first": "ui-corner-" + ( direction ? "top" : "left" ),
6411
+ "last": "ui-corner-" + ( direction ? "bottom" : "right" ),
6412
+ "only": "ui-corner-all"
6413
+ }[ position ];
6414
+
6415
+ return result;
6416
+ },
6417
+
6418
+ _spinnerOptions: function( position ) {
6419
+ var options = this._buildSimpleOptions( position, "ui-spinner" );
6420
+
6421
+ options.classes[ "ui-spinner-up" ] = "";
6422
+ options.classes[ "ui-spinner-down" ] = "";
6423
+
6424
+ return options;
6425
+ },
6426
+
6427
+ _buttonOptions: function( position ) {
6428
+ return this._buildSimpleOptions( position, "ui-button" );
6429
+ },
6430
+
6431
+ _checkboxradioOptions: function( position ) {
6432
+ return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
6433
+ },
6434
+
6435
+ _selectmenuOptions: function( position ) {
6436
+ var direction = this.options.direction === "vertical";
6437
+ return {
6438
+ width: direction ? "auto" : false,
6439
+ classes: {
6440
+ middle: {
6441
+ "ui-selectmenu-button-open": "",
6442
+ "ui-selectmenu-button-closed": ""
6443
+ },
6444
+ first: {
6445
+ "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
6446
+ "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
6447
+ },
6448
+ last: {
6449
+ "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
6450
+ "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
6451
+ },
6452
+ only: {
6453
+ "ui-selectmenu-button-open": "ui-corner-top",
6454
+ "ui-selectmenu-button-closed": "ui-corner-all"
6455
+ }
6456
+
6457
+ }[ position ]
6458
+ };
6459
+ },
6460
+
6461
+ _resolveClassesValues: function( classes, instance ) {
6462
+ var result = {};
6463
+ $.each( classes, function( key ) {
6464
+ var current = instance.options.classes[ key ] || "";
6465
+ current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
6466
+ result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
6467
+ } );
6468
+ return result;
6469
+ },
6470
+
6471
+ _setOption: function( key, value ) {
6472
+ if ( key === "direction" ) {
6473
+ this._removeClass( "ui-controlgroup-" + this.options.direction );
6474
+ }
6475
+
6476
+ this._super( key, value );
6477
+ if ( key === "disabled" ) {
6478
+ this._callChildMethod( value ? "disable" : "enable" );
6479
+ return;
6480
+ }
6481
+
6482
+ this.refresh();
6483
+ },
6484
+
6485
+ refresh: function() {
6486
+ var children,
6487
+ that = this;
6488
+
6489
+ this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
6490
+
6491
+ if ( this.options.direction === "horizontal" ) {
6492
+ this._addClass( null, "ui-helper-clearfix" );
6493
+ }
6494
+ this._initWidgets();
6495
+
6496
+ children = this.childWidgets;
6497
+
6498
+ // We filter here because we need to track all childWidgets not just the visible ones
6499
+ if ( this.options.onlyVisible ) {
6500
+ children = children.filter( ":visible" );
6501
+ }
6502
+
6503
+ if ( children.length ) {
6504
+
6505
+ // We do this last because we need to make sure all enhancment is done
6506
+ // before determining first and last
6507
+ $.each( [ "first", "last" ], function( index, value ) {
6508
+ var instance = children[ value ]().data( "ui-controlgroup-data" );
6509
+
6510
+ if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
6511
+ var options = that[ "_" + instance.widgetName + "Options" ](
6512
+ children.length === 1 ? "only" : value
6513
+ );
6514
+ options.classes = that._resolveClassesValues( options.classes, instance );
6515
+ instance.element[ instance.widgetName ]( options );
6516
+ } else {
6517
+ that._updateCornerClass( children[ value ](), value );
6518
+ }
6519
+ } );
6520
+
6521
+ // Finally call the refresh method on each of the child widgets.
6522
+ this._callChildMethod( "refresh" );
6523
+ }
6524
+ }
6525
+ } );
6526
+
6527
+ /*!
6528
+ * jQuery UI Checkboxradio 1.12.1
6529
+ * http://jqueryui.com
6530
+ *
6531
+ * Copyright jQuery Foundation and other contributors
6532
+ * Released under the MIT license.
6533
+ * http://jquery.org/license
6534
+ */
6535
+
6536
+ //>>label: Checkboxradio
6537
+ //>>group: Widgets
6538
+ //>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
6539
+ //>>docs: http://api.jqueryui.com/checkboxradio/
6540
+ //>>demos: http://jqueryui.com/checkboxradio/
6541
+ //>>css.structure: ../../themes/base/core.css
6542
+ //>>css.structure: ../../themes/base/button.css
6543
+ //>>css.structure: ../../themes/base/checkboxradio.css
6544
+ //>>css.theme: ../../themes/base/theme.css
6545
+
6546
+
6547
+
6548
+ $.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
6549
+ version: "1.12.1",
6550
+ options: {
6551
+ disabled: null,
6552
+ label: null,
6553
+ icon: true,
6554
+ classes: {
6555
+ "ui-checkboxradio-label": "ui-corner-all",
6556
+ "ui-checkboxradio-icon": "ui-corner-all"
6557
+ }
6558
+ },
6559
+
6560
+ _getCreateOptions: function() {
6561
+ var disabled, labels;
6562
+ var that = this;
6563
+ var options = this._super() || {};
6564
+
6565
+ // We read the type here, because it makes more sense to throw a element type error first,
6566
+ // rather then the error for lack of a label. Often if its the wrong type, it
6567
+ // won't have a label (e.g. calling on a div, btn, etc)
6568
+ this._readType();
6569
+
6570
+ labels = this.element.labels();
6571
+
6572
+ // If there are multiple labels, use the last one
6573
+ this.label = $( labels[ labels.length - 1 ] );
6574
+ if ( !this.label.length ) {
6575
+ $.error( "No label found for checkboxradio widget" );
6576
+ }
6577
+
6578
+ this.originalLabel = "";
6579
+
6580
+ // We need to get the label text but this may also need to make sure it does not contain the
6581
+ // input itself.
6582
+ this.label.contents().not( this.element[ 0 ] ).each( function() {
6583
+
6584
+ // The label contents could be text, html, or a mix. We concat each element to get a
6585
+ // string representation of the label, without the input as part of it.
6586
+ that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
6587
+ } );
6588
+
6589
+ // Set the label option if we found label text
6590
+ if ( this.originalLabel ) {
6591
+ options.label = this.originalLabel;
6592
+ }
6593
+
6594
+ disabled = this.element[ 0 ].disabled;
6595
+ if ( disabled != null ) {
6596
+ options.disabled = disabled;
6597
+ }
6598
+ return options;
6599
+ },
6600
+
6601
+ _create: function() {
6602
+ var checked = this.element[ 0 ].checked;
6603
+
6604
+ this._bindFormResetHandler();
6605
+
6606
+ if ( this.options.disabled == null ) {
6607
+ this.options.disabled = this.element[ 0 ].disabled;
6608
+ }
6609
+
6610
+ this._setOption( "disabled", this.options.disabled );
6611
+ this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
6612
+ this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
6613
+
6614
+ if ( this.type === "radio" ) {
6615
+ this._addClass( this.label, "ui-checkboxradio-radio-label" );
6616
+ }
6617
+
6618
+ if ( this.options.label && this.options.label !== this.originalLabel ) {
6619
+ this._updateLabel();
6620
+ } else if ( this.originalLabel ) {
6621
+ this.options.label = this.originalLabel;
6622
+ }
6623
+
6624
+ this._enhance();
6625
+
6626
+ if ( checked ) {
6627
+ this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
6628
+ if ( this.icon ) {
6629
+ this._addClass( this.icon, null, "ui-state-hover" );
6630
+ }
6631
+ }
6632
+
6633
+ this._on( {
6634
+ change: "_toggleClasses",
6635
+ focus: function() {
6636
+ this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
6637
+ },
6638
+ blur: function() {
6639
+ this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
6640
+ }
6641
+ } );
6642
+ },
6643
+
6644
+ _readType: function() {
6645
+ var nodeName = this.element[ 0 ].nodeName.toLowerCase();
6646
+ this.type = this.element[ 0 ].type;
6647
+ if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
6648
+ $.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
6649
+ " and element.type=" + this.type );
6650
+ }
6651
+ },
6652
+
6653
+ // Support jQuery Mobile enhanced option
6654
+ _enhance: function() {
6655
+ this._updateIcon( this.element[ 0 ].checked );
6656
+ },
6657
+
6658
+ widget: function() {
6659
+ return this.label;
6660
+ },
6661
+
6662
+ _getRadioGroup: function() {
6663
+ var group;
6664
+ var name = this.element[ 0 ].name;
6665
+ var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
6666
+
6667
+ if ( !name ) {
6668
+ return $( [] );
6669
+ }
6670
+
6671
+ if ( this.form.length ) {
6672
+ group = $( this.form[ 0 ].elements ).filter( nameSelector );
6673
+ } else {
6674
+
6675
+ // Not inside a form, check all inputs that also are not inside a form
6676
+ group = $( nameSelector ).filter( function() {
6677
+ return $( this ).form().length === 0;
6678
+ } );
6679
+ }
6680
+
6681
+ return group.not( this.element );
6682
+ },
6683
+
6684
+ _toggleClasses: function() {
6685
+ var checked = this.element[ 0 ].checked;
6686
+ this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6687
+
6688
+ if ( this.options.icon && this.type === "checkbox" ) {
6689
+ this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
6690
+ ._toggleClass( this.icon, null, "ui-icon-blank", !checked );
6691
+ }
6692
+
6693
+ if ( this.type === "radio" ) {
6694
+ this._getRadioGroup()
6695
+ .each( function() {
6696
+ var instance = $( this ).checkboxradio( "instance" );
6697
+
6698
+ if ( instance ) {
6699
+ instance._removeClass( instance.label,
6700
+ "ui-checkboxradio-checked", "ui-state-active" );
6701
+ }
6702
+ } );
6703
+ }
6704
+ },
6705
+
6706
+ _destroy: function() {
6707
+ this._unbindFormResetHandler();
6708
+
6709
+ if ( this.icon ) {
6710
+ this.icon.remove();
6711
+ this.iconSpace.remove();
6712
+ }
6713
+ },
6714
+
6715
+ _setOption: function( key, value ) {
6716
+
6717
+ // We don't allow the value to be set to nothing
6718
+ if ( key === "label" && !value ) {
6719
+ return;
6720
+ }
6721
+
6722
+ this._super( key, value );
6723
+
6724
+ if ( key === "disabled" ) {
6725
+ this._toggleClass( this.label, null, "ui-state-disabled", value );
6726
+ this.element[ 0 ].disabled = value;
6727
+
6728
+ // Don't refresh when setting disabled
6729
+ return;
6730
+ }
6731
+ this.refresh();
6732
+ },
6733
+
6734
+ _updateIcon: function( checked ) {
6735
+ var toAdd = "ui-icon ui-icon-background ";
6736
+
6737
+ if ( this.options.icon ) {
6738
+ if ( !this.icon ) {
6739
+ this.icon = $( "<span>" );
6740
+ this.iconSpace = $( "<span> </span>" );
6741
+ this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
6742
+ }
6743
+
6744
+ if ( this.type === "checkbox" ) {
6745
+ toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
6746
+ this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
6747
+ } else {
6748
+ toAdd += "ui-icon-blank";
6749
+ }
6750
+ this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
6751
+ if ( !checked ) {
6752
+ this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
6753
+ }
6754
+ this.icon.prependTo( this.label ).after( this.iconSpace );
6755
+ } else if ( this.icon !== undefined ) {
6756
+ this.icon.remove();
6757
+ this.iconSpace.remove();
6758
+ delete this.icon;
6759
+ }
6760
+ },
6761
+
6762
+ _updateLabel: function() {
6763
+
6764
+ // Remove the contents of the label ( minus the icon, icon space, and input )
6765
+ var contents = this.label.contents().not( this.element[ 0 ] );
6766
+ if ( this.icon ) {
6767
+ contents = contents.not( this.icon[ 0 ] );
6768
+ }
6769
+ if ( this.iconSpace ) {
6770
+ contents = contents.not( this.iconSpace[ 0 ] );
6771
+ }
6772
+ contents.remove();
6773
+
6774
+ this.label.append( this.options.label );
6775
+ },
6776
+
6777
+ refresh: function() {
6778
+ var checked = this.element[ 0 ].checked,
6779
+ isDisabled = this.element[ 0 ].disabled;
6780
+
6781
+ this._updateIcon( checked );
6782
+ this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6783
+ if ( this.options.label !== null ) {
6784
+ this._updateLabel();
6785
+ }
6786
+
6787
+ if ( isDisabled !== this.options.disabled ) {
6788
+ this._setOptions( { "disabled": isDisabled } );
6789
+ }
6790
+ }
6791
+
6792
+ } ] );
6793
+
6794
+ var widgetsCheckboxradio = $.ui.checkboxradio;
6795
+
6796
+
6797
+ /*!
6798
+ * jQuery UI Button 1.12.1
6799
+ * http://jqueryui.com
6800
+ *
6801
+ * Copyright jQuery Foundation and other contributors
6802
+ * Released under the MIT license.
6803
+ * http://jquery.org/license
6804
+ */
6805
+
6806
+ //>>label: Button
6807
+ //>>group: Widgets
6808
+ //>>description: Enhances a form with themeable buttons.
6809
+ //>>docs: http://api.jqueryui.com/button/
6810
+ //>>demos: http://jqueryui.com/button/
6811
+ //>>css.structure: ../../themes/base/core.css
6812
+ //>>css.structure: ../../themes/base/button.css
6813
+ //>>css.theme: ../../themes/base/theme.css
6814
+
6815
+
6816
+
6817
+ $.widget( "ui.button", {
6818
+ version: "1.12.1",
6819
+ defaultElement: "<button>",
6820
+ options: {
6821
+ classes: {
6822
+ "ui-button": "ui-corner-all"
6823
+ },
6824
+ disabled: null,
6825
+ icon: null,
6826
+ iconPosition: "beginning",
6827
+ label: null,
6828
+ showLabel: true
6829
+ },
6830
+
6831
+ _getCreateOptions: function() {
6832
+ var disabled,
6833
+
6834
+ // This is to support cases like in jQuery Mobile where the base widget does have
6835
+ // an implementation of _getCreateOptions
6836
+ options = this._super() || {};
6837
+
6838
+ this.isInput = this.element.is( "input" );
6839
+
6840
+ disabled = this.element[ 0 ].disabled;
6841
+ if ( disabled != null ) {
6842
+ options.disabled = disabled;
6843
+ }
6844
+
6845
+ this.originalLabel = this.isInput ? this.element.val() : this.element.html();
6846
+ if ( this.originalLabel ) {
6847
+ options.label = this.originalLabel;
6848
+ }
6849
+
6850
+ return options;
6851
+ },
6852
+
6853
+ _create: function() {
6854
+ if ( !this.option.showLabel & !this.options.icon ) {
6855
+ this.options.showLabel = true;
6856
+ }
6857
+
6858
+ // We have to check the option again here even though we did in _getCreateOptions,
6859
+ // because null may have been passed on init which would override what was set in
6860
+ // _getCreateOptions
6861
+ if ( this.options.disabled == null ) {
6862
+ this.options.disabled = this.element[ 0 ].disabled || false;
6863
+ }
6864
+
6865
+ this.hasTitle = !!this.element.attr( "title" );
6866
+
6867
+ // Check to see if the label needs to be set or if its already correct
6868
+ if ( this.options.label && this.options.label !== this.originalLabel ) {
6869
+ if ( this.isInput ) {
6870
+ this.element.val( this.options.label );
6871
+ } else {
6872
+ this.element.html( this.options.label );
6873
+ }
6874
+ }
6875
+ this._addClass( "ui-button", "ui-widget" );
6876
+ this._setOption( "disabled", this.options.disabled );
6877
+ this._enhance();
6878
+
6879
+ if ( this.element.is( "a" ) ) {
6880
+ this._on( {
6881
+ "keyup": function( event ) {
6882
+ if ( event.keyCode === $.ui.keyCode.SPACE ) {
6883
+ event.preventDefault();
6884
+
6885
+ // Support: PhantomJS <= 1.9, IE 8 Only
6886
+ // If a native click is available use it so we actually cause navigation
6887
+ // otherwise just trigger a click event
6888
+ if ( this.element[ 0 ].click ) {
6889
+ this.element[ 0 ].click();
6890
+ } else {
6891
+ this.element.trigger( "click" );
6892
+ }
6893
+ }
6894
+ }
6895
+ } );
6896
+ }
6897
+ },
6898
+
6899
+ _enhance: function() {
6900
+ if ( !this.element.is( "button" ) ) {
6901
+ this.element.attr( "role", "button" );
6902
+ }
6903
+
6904
+ if ( this.options.icon ) {
6905
+ this._updateIcon( "icon", this.options.icon );
6906
+ this._updateTooltip();
6907
+ }
6908
+ },
6909
+
6910
+ _updateTooltip: function() {
6911
+ this.title = this.element.attr( "title" );
6912
+
6913
+ if ( !this.options.showLabel && !this.title ) {
6914
+ this.element.attr( "title", this.options.label );
6915
+ }
6916
+ },
6917
+
6918
+ _updateIcon: function( option, value ) {
6919
+ var icon = option !== "iconPosition",
6920
+ position = icon ? this.options.iconPosition : value,
6921
+ displayBlock = position === "top" || position === "bottom";
6922
+
6923
+ // Create icon
6924
+ if ( !this.icon ) {
6925
+ this.icon = $( "<span>" );
6926
+
6927
+ this._addClass( this.icon, "ui-button-icon", "ui-icon" );
6928
+
6929
+ if ( !this.options.showLabel ) {
6930
+ this._addClass( "ui-button-icon-only" );
6931
+ }
6932
+ } else if ( icon ) {
6933
+
6934
+ // If we are updating the icon remove the old icon class
6935
+ this._removeClass( this.icon, null, this.options.icon );
6936
+ }
6937
+
6938
+ // If we are updating the icon add the new icon class
6939
+ if ( icon ) {
6940
+ this._addClass( this.icon, null, value );
6941
+ }
6942
+
6943
+ this._attachIcon( position );
6944
+
6945
+ // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
6946
+ // the iconSpace if there is one.
6947
+ if ( displayBlock ) {
6948
+ this._addClass( this.icon, null, "ui-widget-icon-block" );
6949
+ if ( this.iconSpace ) {
6950
+ this.iconSpace.remove();
6951
+ }
6952
+ } else {
6953
+
6954
+ // Position is beginning or end so remove the ui-widget-icon-block class and add the
6955
+ // space if it does not exist
6956
+ if ( !this.iconSpace ) {
6957
+ this.iconSpace = $( "<span> </span>" );
6958
+ this._addClass( this.iconSpace, "ui-button-icon-space" );
6959
+ }
6960
+ this._removeClass( this.icon, null, "ui-wiget-icon-block" );
6961
+ this._attachIconSpace( position );
6962
+ }
6963
+ },
6964
+
6965
+ _destroy: function() {
6966
+ this.element.removeAttr( "role" );
6967
+
6968
+ if ( this.icon ) {
6969
+ this.icon.remove();
6970
+ }
6971
+ if ( this.iconSpace ) {
6972
+ this.iconSpace.remove();
6973
+ }
6974
+ if ( !this.hasTitle ) {
6975
+ this.element.removeAttr( "title" );
6976
+ }
6977
+ },
6978
+
6979
+ _attachIconSpace: function( iconPosition ) {
6980
+ this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
6981
+ },
6982
+
6983
+ _attachIcon: function( iconPosition ) {
6984
+ this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
6985
+ },
6986
+
6987
+ _setOptions: function( options ) {
6988
+ var newShowLabel = options.showLabel === undefined ?
6989
+ this.options.showLabel :
6990
+ options.showLabel,
6991
+ newIcon = options.icon === undefined ? this.options.icon : options.icon;
6992
+
6993
+ if ( !newShowLabel && !newIcon ) {
6994
+ options.showLabel = true;
6995
+ }
6996
+ this._super( options );
6997
+ },
6998
+
6999
+ _setOption: function( key, value ) {
7000
+ if ( key === "icon" ) {
7001
+ if ( value ) {
7002
+ this._updateIcon( key, value );
7003
+ } else if ( this.icon ) {
7004
+ this.icon.remove();
7005
+ if ( this.iconSpace ) {
7006
+ this.iconSpace.remove();
7007
+ }
7008
+ }
7009
+ }
7010
+
7011
+ if ( key === "iconPosition" ) {
7012
+ this._updateIcon( key, value );
7013
+ }
7014
+
7015
+ // Make sure we can't end up with a button that has neither text nor icon
7016
+ if ( key === "showLabel" ) {
7017
+ this._toggleClass( "ui-button-icon-only", null, !value );
7018
+ this._updateTooltip();
7019
+ }
7020
+
7021
+ if ( key === "label" ) {
7022
+ if ( this.isInput ) {
7023
+ this.element.val( value );
7024
+ } else {
7025
+
7026
+ // If there is an icon, append it, else nothing then append the value
7027
+ // this avoids removal of the icon when setting label text
7028
+ this.element.html( value );
7029
+ if ( this.icon ) {
7030
+ this._attachIcon( this.options.iconPosition );
7031
+ this._attachIconSpace( this.options.iconPosition );
7032
+ }
7033
+ }
7034
+ }
7035
+
7036
+ this._super( key, value );
7037
+
7038
+ if ( key === "disabled" ) {
7039
+ this._toggleClass( null, "ui-state-disabled", value );
7040
+ this.element[ 0 ].disabled = value;
7041
+ if ( value ) {
7042
+ this.element.blur();
7043
+ }
7044
+ }
7045
+ },
7046
+
7047
+ refresh: function() {
7048
+
7049
+ // Make sure to only check disabled if its an element that supports this otherwise
7050
+ // check for the disabled class to determine state
7051
+ var isDisabled = this.element.is( "input, button" ) ?
7052
+ this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
7053
+
7054
+ if ( isDisabled !== this.options.disabled ) {
7055
+ this._setOptions( { disabled: isDisabled } );
7056
+ }
7057
+
7058
+ this._updateTooltip();
7059
+ }
7060
+ } );
7061
+
7062
+ // DEPRECATED
7063
+ if ( $.uiBackCompat !== false ) {
7064
+
7065
+ // Text and Icons options
7066
+ $.widget( "ui.button", $.ui.button, {
7067
+ options: {
7068
+ text: true,
7069
+ icons: {
7070
+ primary: null,
7071
+ secondary: null
7072
+ }
7073
+ },
7074
+
7075
+ _create: function() {
7076
+ if ( this.options.showLabel && !this.options.text ) {
7077
+ this.options.showLabel = this.options.text;
7078
+ }
7079
+ if ( !this.options.showLabel && this.options.text ) {
7080
+ this.options.text = this.options.showLabel;
7081
+ }
7082
+ if ( !this.options.icon && ( this.options.icons.primary ||
7083
+ this.options.icons.secondary ) ) {
7084
+ if ( this.options.icons.primary ) {
7085
+ this.options.icon = this.options.icons.primary;
7086
+ } else {
7087
+ this.options.icon = this.options.icons.secondary;
7088
+ this.options.iconPosition = "end";
7089
+ }
7090
+ } else if ( this.options.icon ) {
7091
+ this.options.icons.primary = this.options.icon;
7092
+ }
7093
+ this._super();
7094
+ },
7095
+
7096
+ _setOption: function( key, value ) {
7097
+ if ( key === "text" ) {
7098
+ this._super( "showLabel", value );
7099
+ return;
7100
+ }
7101
+ if ( key === "showLabel" ) {
7102
+ this.options.text = value;
7103
+ }
7104
+ if ( key === "icon" ) {
7105
+ this.options.icons.primary = value;
7106
+ }
7107
+ if ( key === "icons" ) {
7108
+ if ( value.primary ) {
7109
+ this._super( "icon", value.primary );
7110
+ this._super( "iconPosition", "beginning" );
7111
+ } else if ( value.secondary ) {
7112
+ this._super( "icon", value.secondary );
7113
+ this._super( "iconPosition", "end" );
7114
+ }
7115
+ }
7116
+ this._superApply( arguments );
7117
+ }
7118
+ } );
7119
+
7120
+ $.fn.button = ( function( orig ) {
7121
+ return function() {
7122
+ if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
7123
+ ( this.length && this[ 0 ].tagName === "INPUT" && (
7124
+ this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
7125
+ ) ) ) {
7126
+ return orig.apply( this, arguments );
7127
+ }
7128
+ if ( !$.ui.checkboxradio ) {
7129
+ $.error( "Checkboxradio widget missing" );
7130
+ }
7131
+ if ( arguments.length === 0 ) {
7132
+ return this.checkboxradio( {
7133
+ "icon": false
7134
+ } );
7135
+ }
7136
+ return this.checkboxradio.apply( this, arguments );
7137
+ };
7138
+ } )( $.fn.button );
7139
+
7140
+ $.fn.buttonset = function() {
7141
+ if ( !$.ui.controlgroup ) {
7142
+ $.error( "Controlgroup widget missing" );
7143
+ }
7144
+ if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
7145
+ return this.controlgroup.apply( this,
7146
+ [ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
7147
+ }
7148
+ if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
7149
+ return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
7150
+ }
7151
+ if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
7152
+ arguments[ 0 ].items = {
7153
+ button: arguments[ 0 ].items
7154
+ };
7155
+ }
7156
+ return this.controlgroup.apply( this, arguments );
7157
+ };
7158
+ }
7159
+
7160
+ var widgetsButton = $.ui.button;
7161
+
7162
+
7163
+ // jscs:disable maximumLineLength
7164
+ /* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
7165
+ /*!
7166
+ * jQuery UI Datepicker 1.12.1
7167
+ * http://jqueryui.com
7168
+ *
7169
+ * Copyright jQuery Foundation and other contributors
7170
+ * Released under the MIT license.
7171
+ * http://jquery.org/license
7172
+ */
7173
+
7174
+ //>>label: Datepicker
7175
+ //>>group: Widgets
7176
+ //>>description: Displays a calendar from an input or inline for selecting dates.
7177
+ //>>docs: http://api.jqueryui.com/datepicker/
7178
+ //>>demos: http://jqueryui.com/datepicker/
7179
+ //>>css.structure: ../../themes/base/core.css
7180
+ //>>css.structure: ../../themes/base/datepicker.css
7181
+ //>>css.theme: ../../themes/base/theme.css
7182
+
7183
+
7184
+
7185
+ $.extend( $.ui, { datepicker: { version: "1.12.1" } } );
7186
+
7187
+ var datepicker_instActive;
7188
+
7189
+ function datepicker_getZindex( elem ) {
7190
+ var position, value;
7191
+ while ( elem.length && elem[ 0 ] !== document ) {
7192
+
7193
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
7194
+ // This makes behavior of this function consistent across browsers
7195
+ // WebKit always returns auto if the element is positioned
7196
+ position = elem.css( "position" );
7197
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7198
+
7199
+ // IE returns 0 when zIndex is not specified
7200
+ // other browsers return a string
7201
+ // we ignore the case of nested elements with an explicit value of 0
7202
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7203
+ value = parseInt( elem.css( "zIndex" ), 10 );
7204
+ if ( !isNaN( value ) && value !== 0 ) {
7205
+ return value;
7206
+ }
7207
+ }
7208
+ elem = elem.parent();
7209
+ }
7210
+
7211
+ return 0;
7212
+ }
7213
+ /* Date picker manager.
7214
+ Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7215
+ Settings for (groups of) date pickers are maintained in an instance object,
7216
+ allowing multiple different settings on the same page. */
7217
+
7218
+ function Datepicker() {
7219
+ this._curInst = null; // The current instance in use
7220
+ this._keyEvent = false; // If the last event was a key event
7221
+ this._disabledInputs = []; // List of date picker inputs that have been disabled
7222
+ this._datepickerShowing = false; // True if the popup picker is showing , false if not
7223
+ this._inDialog = false; // True if showing within a "dialog", false if not
7224
+ this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7225
+ this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7226
+ this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7227
+ this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7228
+ this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7229
+ this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7230
+ this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7231
+ this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7232
+ this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7233
+ this.regional = []; // Available regional settings, indexed by language code
7234
+ this.regional[ "" ] = { // Default regional settings
7235
+ closeText: "Done", // Display text for close link
7236
+ prevText: "Prev", // Display text for previous month link
7237
+ nextText: "Next", // Display text for next month link
7238
+ currentText: "Today", // Display text for current month link
7239
+ monthNames: [ "January","February","March","April","May","June",
7240
+ "July","August","September","October","November","December" ], // Names of months for drop-down and formatting
7241
+ monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
7242
+ dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
7243
+ dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
7244
+ dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
7245
+ weekHeader: "Wk", // Column header for week of the year
7246
+ dateFormat: "mm/dd/yy", // See format options on parseDate
7247
+ firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7248
+ isRTL: false, // True if right-to-left language, false if left-to-right
7249
+ showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7250
+ yearSuffix: "" // Additional text to append to the year in the month headers
7251
+ };
7252
+ this._defaults = { // Global defaults for all the date picker instances
7253
+ showOn: "focus", // "focus" for popup on focus,
7254
+ // "button" for trigger button, or "both" for either
7255
+ showAnim: "fadeIn", // Name of jQuery animation for popup
7256
+ showOptions: {}, // Options for enhanced animations
7257
+ defaultDate: null, // Used when field is blank: actual date,
7258
+ // +/-number for offset from today, null for today
7259
+ appendText: "", // Display text following the input box, e.g. showing the format
7260
+ buttonText: "...", // Text for trigger button
7261
+ buttonImage: "", // URL for trigger button image
7262
+ buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7263
+ hideIfNoPrevNext: false, // True to hide next/previous month links
7264
+ // if not applicable, false to just disable them
7265
+ navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7266
+ gotoCurrent: false, // True if today link goes back to current selection instead
7267
+ changeMonth: false, // True if month can be selected directly, false if only prev/next
7268
+ changeYear: false, // True if year can be selected directly, false if only prev/next
7269
+ yearRange: "c-10:c+10", // Range of years to display in drop-down,
7270
+ // either relative to today's year (-nn:+nn), relative to currently displayed year
7271
+ // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7272
+ showOtherMonths: false, // True to show dates in other months, false to leave blank
7273
+ selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7274
+ showWeek: false, // True to show week of the year, false to not show it
7275
+ calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7276
+ // takes a Date and returns the number of the week for it
7277
+ shortYearCutoff: "+10", // Short year values < this are in the current century,
7278
+ // > this are in the previous century,
7279
+ // string value starting with "+" for current year + value
7280
+ minDate: null, // The earliest selectable date, or null for no limit
7281
+ maxDate: null, // The latest selectable date, or null for no limit
7282
+ duration: "fast", // Duration of display/closure
7283
+ beforeShowDay: null, // Function that takes a date and returns an array with
7284
+ // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7285
+ // [2] = cell title (optional), e.g. $.datepicker.noWeekends
7286
+ beforeShow: null, // Function that takes an input field and
7287
+ // returns a set of custom settings for the date picker
7288
+ onSelect: null, // Define a callback function when a date is selected
7289
+ onChangeMonthYear: null, // Define a callback function when the month or year is changed
7290
+ onClose: null, // Define a callback function when the datepicker is closed
7291
+ numberOfMonths: 1, // Number of months to show at a time
7292
+ showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7293
+ stepMonths: 1, // Number of months to step back/forward
7294
+ stepBigMonths: 12, // Number of months to step back/forward for the big links
7295
+ altField: "", // Selector for an alternate field to store selected dates into
7296
+ altFormat: "", // The date format to use for the alternate field
7297
+ constrainInput: true, // The input is constrained by the current date format
7298
+ showButtonPanel: false, // True to show button panel, false to not show it
7299
+ autoSize: false, // True to size the input for the date format, false to leave as is
7300
+ disabled: false // The initial disabled state
7301
+ };
7302
+ $.extend( this._defaults, this.regional[ "" ] );
7303
+ this.regional.en = $.extend( true, {}, this.regional[ "" ] );
7304
+ this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7305
+ this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
7306
+ }
7307
+
7308
+ $.extend( Datepicker.prototype, {
7309
+ /* Class name added to elements to indicate already configured with a date picker. */
7310
+ markerClassName: "hasDatepicker",
7311
+
7312
+ //Keep track of the maximum number of rows displayed (see #7043)
7313
+ maxRows: 4,
7314
+
7315
+ // TODO rename to "widget" when switching to widget factory
7316
+ _widgetDatepicker: function() {
7317
+ return this.dpDiv;
7318
+ },
7319
+
7320
+ /* Override the default settings for all instances of the date picker.
7321
+ * @param settings object - the new settings to use as defaults (anonymous object)
7322
+ * @return the manager object
7323
+ */
7324
+ setDefaults: function( settings ) {
7325
+ datepicker_extendRemove( this._defaults, settings || {} );
7326
+ return this;
7327
+ },
7328
+
7329
+ /* Attach the date picker to a jQuery selection.
7330
+ * @param target element - the target input field or division or span
7331
+ * @param settings object - the new settings to use for this date picker instance (anonymous)
7332
+ */
7333
+ _attachDatepicker: function( target, settings ) {
7334
+ var nodeName, inline, inst;
7335
+ nodeName = target.nodeName.toLowerCase();
7336
+ inline = ( nodeName === "div" || nodeName === "span" );
7337
+ if ( !target.id ) {
7338
+ this.uuid += 1;
7339
+ target.id = "dp" + this.uuid;
7340
+ }
7341
+ inst = this._newInst( $( target ), inline );
7342
+ inst.settings = $.extend( {}, settings || {} );
7343
+ if ( nodeName === "input" ) {
7344
+ this._connectDatepicker( target, inst );
7345
+ } else if ( inline ) {
7346
+ this._inlineDatepicker( target, inst );
7347
+ }
7348
+ },
7349
+
7350
+ /* Create a new instance object. */
7351
+ _newInst: function( target, inline ) {
7352
+ var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
7353
+ return { id: id, input: target, // associated target
7354
+ selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7355
+ drawMonth: 0, drawYear: 0, // month being drawn
7356
+ inline: inline, // is datepicker inline or not
7357
+ dpDiv: ( !inline ? this.dpDiv : // presentation div
7358
+ datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
7359
+ },
7360
+
7361
+ /* Attach the date picker to an input field. */
7362
+ _connectDatepicker: function( target, inst ) {
7363
+ var input = $( target );
7364
+ inst.append = $( [] );
7365
+ inst.trigger = $( [] );
7366
+ if ( input.hasClass( this.markerClassName ) ) {
7367
+ return;
7368
+ }
7369
+ this._attachments( input, inst );
7370
+ input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
7371
+ on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
7372
+ this._autoSize( inst );
7373
+ $.data( target, "datepicker", inst );
7374
+
7375
+ //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7376
+ if ( inst.settings.disabled ) {
7377
+ this._disableDatepicker( target );
7378
+ }
7379
+ },
7380
+
7381
+ /* Make attachments based on settings. */
7382
+ _attachments: function( input, inst ) {
7383
+ var showOn, buttonText, buttonImage,
7384
+ appendText = this._get( inst, "appendText" ),
7385
+ isRTL = this._get( inst, "isRTL" );
7386
+
7387
+ if ( inst.append ) {
7388
+ inst.append.remove();
7389
+ }
7390
+ if ( appendText ) {
7391
+ inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
7392
+ input[ isRTL ? "before" : "after" ]( inst.append );
7393
+ }
7394
+
7395
+ input.off( "focus", this._showDatepicker );
7396
+
7397
+ if ( inst.trigger ) {
7398
+ inst.trigger.remove();
7399
+ }
7400
+
7401
+ showOn = this._get( inst, "showOn" );
7402
+ if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
7403
+ input.on( "focus", this._showDatepicker );
7404
+ }
7405
+ if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
7406
+ buttonText = this._get( inst, "buttonText" );
7407
+ buttonImage = this._get( inst, "buttonImage" );
7408
+ inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
7409
+ $( "<img/>" ).addClass( this._triggerClass ).
7410
+ attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
7411
+ $( "<button type='button'></button>" ).addClass( this._triggerClass ).
7412
+ html( !buttonImage ? buttonText : $( "<img/>" ).attr(
7413
+ { src:buttonImage, alt:buttonText, title:buttonText } ) ) );
7414
+ input[ isRTL ? "before" : "after" ]( inst.trigger );
7415
+ inst.trigger.on( "click", function() {
7416
+ if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
7417
+ $.datepicker._hideDatepicker();
7418
+ } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
7419
+ $.datepicker._hideDatepicker();
7420
+ $.datepicker._showDatepicker( input[ 0 ] );
7421
+ } else {
7422
+ $.datepicker._showDatepicker( input[ 0 ] );
7423
+ }
7424
+ return false;
7425
+ } );
7426
+ }
7427
+ },
7428
+
7429
+ /* Apply the maximum length for the date format. */
7430
+ _autoSize: function( inst ) {
7431
+ if ( this._get( inst, "autoSize" ) && !inst.inline ) {
7432
+ var findMax, max, maxI, i,
7433
+ date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
7434
+ dateFormat = this._get( inst, "dateFormat" );
7435
+
7436
+ if ( dateFormat.match( /[DM]/ ) ) {
7437
+ findMax = function( names ) {
7438
+ max = 0;
7439
+ maxI = 0;
7440
+ for ( i = 0; i < names.length; i++ ) {
7441
+ if ( names[ i ].length > max ) {
7442
+ max = names[ i ].length;
7443
+ maxI = i;
7444
+ }
7445
+ }
7446
+ return maxI;
7447
+ };
7448
+ date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
7449
+ "monthNames" : "monthNamesShort" ) ) ) );
7450
+ date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
7451
+ "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
7452
+ }
7453
+ inst.input.attr( "size", this._formatDate( inst, date ).length );
7454
+ }
7455
+ },
7456
+
7457
+ /* Attach an inline date picker to a div. */
7458
+ _inlineDatepicker: function( target, inst ) {
7459
+ var divSpan = $( target );
7460
+ if ( divSpan.hasClass( this.markerClassName ) ) {
7461
+ return;
7462
+ }
7463
+ divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
7464
+ $.data( target, "datepicker", inst );
7465
+ this._setDate( inst, this._getDefaultDate( inst ), true );
7466
+ this._updateDatepicker( inst );
7467
+ this._updateAlternate( inst );
7468
+
7469
+ //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7470
+ if ( inst.settings.disabled ) {
7471
+ this._disableDatepicker( target );
7472
+ }
7473
+
7474
+ // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7475
+ // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7476
+ inst.dpDiv.css( "display", "block" );
7477
+ },
7478
+
7479
+ /* Pop-up the date picker in a "dialog" box.
7480
+ * @param input element - ignored
7481
+ * @param date string or Date - the initial date to display
7482
+ * @param onSelect function - the function to call when a date is selected
7483
+ * @param settings object - update the dialog date picker instance's settings (anonymous object)
7484
+ * @param pos int[2] - coordinates for the dialog's position within the screen or
7485
+ * event - with x/y coordinates or
7486
+ * leave empty for default (screen centre)
7487
+ * @return the manager object
7488
+ */
7489
+ _dialogDatepicker: function( input, date, onSelect, settings, pos ) {
7490
+ var id, browserWidth, browserHeight, scrollX, scrollY,
7491
+ inst = this._dialogInst; // internal instance
7492
+
7493
+ if ( !inst ) {
7494
+ this.uuid += 1;
7495
+ id = "dp" + this.uuid;
7496
+ this._dialogInput = $( "<input type='text' id='" + id +
7497
+ "' style='position: absolute; top: -100px; width: 0px;'/>" );
7498
+ this._dialogInput.on( "keydown", this._doKeyDown );
7499
+ $( "body" ).append( this._dialogInput );
7500
+ inst = this._dialogInst = this._newInst( this._dialogInput, false );
7501
+ inst.settings = {};
7502
+ $.data( this._dialogInput[ 0 ], "datepicker", inst );
7503
+ }
7504
+ datepicker_extendRemove( inst.settings, settings || {} );
7505
+ date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
7506
+ this._dialogInput.val( date );
7507
+
7508
+ this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
7509
+ if ( !this._pos ) {
7510
+ browserWidth = document.documentElement.clientWidth;
7511
+ browserHeight = document.documentElement.clientHeight;
7512
+ scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7513
+ scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7514
+ this._pos = // should use actual width/height below
7515
+ [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
7516
+ }
7517
+
7518
+ // Move input on screen for focus, but hidden behind dialog
7519
+ this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
7520
+ inst.settings.onSelect = onSelect;
7521
+ this._inDialog = true;
7522
+ this.dpDiv.addClass( this._dialogClass );
7523
+ this._showDatepicker( this._dialogInput[ 0 ] );
7524
+ if ( $.blockUI ) {
7525
+ $.blockUI( this.dpDiv );
7526
+ }
7527
+ $.data( this._dialogInput[ 0 ], "datepicker", inst );
7528
+ return this;
7529
+ },
7530
+
7531
+ /* Detach a datepicker from its control.
7532
+ * @param target element - the target input field or division or span
7533
+ */
7534
+ _destroyDatepicker: function( target ) {
7535
+ var nodeName,
7536
+ $target = $( target ),
7537
+ inst = $.data( target, "datepicker" );
7538
+
7539
+ if ( !$target.hasClass( this.markerClassName ) ) {
7540
+ return;
7541
+ }
7542
+
7543
+ nodeName = target.nodeName.toLowerCase();
7544
+ $.removeData( target, "datepicker" );
7545
+ if ( nodeName === "input" ) {
7546
+ inst.append.remove();
7547
+ inst.trigger.remove();
7548
+ $target.removeClass( this.markerClassName ).
7549
+ off( "focus", this._showDatepicker ).
7550
+ off( "keydown", this._doKeyDown ).
7551
+ off( "keypress", this._doKeyPress ).
7552
+ off( "keyup", this._doKeyUp );
7553
+ } else if ( nodeName === "div" || nodeName === "span" ) {
7554
+ $target.removeClass( this.markerClassName ).empty();
7555
+ }
7556
+
7557
+ if ( datepicker_instActive === inst ) {
7558
+ datepicker_instActive = null;
7559
+ }
7560
+ },
7561
+
7562
+ /* Enable the date picker to a jQuery selection.
7563
+ * @param target element - the target input field or division or span
7564
+ */
7565
+ _enableDatepicker: function( target ) {
7566
+ var nodeName, inline,
7567
+ $target = $( target ),
7568
+ inst = $.data( target, "datepicker" );
7569
+
7570
+ if ( !$target.hasClass( this.markerClassName ) ) {
7571
+ return;
7572
+ }
7573
+
7574
+ nodeName = target.nodeName.toLowerCase();
7575
+ if ( nodeName === "input" ) {
7576
+ target.disabled = false;
7577
+ inst.trigger.filter( "button" ).
7578
+ each( function() { this.disabled = false; } ).end().
7579
+ filter( "img" ).css( { opacity: "1.0", cursor: "" } );
7580
+ } else if ( nodeName === "div" || nodeName === "span" ) {
7581
+ inline = $target.children( "." + this._inlineClass );
7582
+ inline.children().removeClass( "ui-state-disabled" );
7583
+ inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7584
+ prop( "disabled", false );
7585
+ }
7586
+ this._disabledInputs = $.map( this._disabledInputs,
7587
+ function( value ) { return ( value === target ? null : value ); } ); // delete entry
7588
+ },
7589
+
7590
+ /* Disable the date picker to a jQuery selection.
7591
+ * @param target element - the target input field or division or span
7592
+ */
7593
+ _disableDatepicker: function( target ) {
7594
+ var nodeName, inline,
7595
+ $target = $( target ),
7596
+ inst = $.data( target, "datepicker" );
7597
+
7598
+ if ( !$target.hasClass( this.markerClassName ) ) {
7599
+ return;
7600
+ }
7601
+
7602
+ nodeName = target.nodeName.toLowerCase();
7603
+ if ( nodeName === "input" ) {
7604
+ target.disabled = true;
7605
+ inst.trigger.filter( "button" ).
7606
+ each( function() { this.disabled = true; } ).end().
7607
+ filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
7608
+ } else if ( nodeName === "div" || nodeName === "span" ) {
7609
+ inline = $target.children( "." + this._inlineClass );
7610
+ inline.children().addClass( "ui-state-disabled" );
7611
+ inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7612
+ prop( "disabled", true );
7613
+ }
7614
+ this._disabledInputs = $.map( this._disabledInputs,
7615
+ function( value ) { return ( value === target ? null : value ); } ); // delete entry
7616
+ this._disabledInputs[ this._disabledInputs.length ] = target;
7617
+ },
7618
+
7619
+ /* Is the first field in a jQuery collection disabled as a datepicker?
7620
+ * @param target element - the target input field or division or span
7621
+ * @return boolean - true if disabled, false if enabled
7622
+ */
7623
+ _isDisabledDatepicker: function( target ) {
7624
+ if ( !target ) {
7625
+ return false;
7626
+ }
7627
+ for ( var i = 0; i < this._disabledInputs.length; i++ ) {
7628
+ if ( this._disabledInputs[ i ] === target ) {
7629
+ return true;
7630
+ }
7631
+ }
7632
+ return false;
7633
+ },
7634
+
7635
+ /* Retrieve the instance data for the target control.
7636
+ * @param target element - the target input field or division or span
7637
+ * @return object - the associated instance data
7638
+ * @throws error if a jQuery problem getting data
7639
+ */
7640
+ _getInst: function( target ) {
7641
+ try {
7642
+ return $.data( target, "datepicker" );
7643
+ }
7644
+ catch ( err ) {
7645
+ throw "Missing instance data for this datepicker";
7646
+ }
7647
+ },
7648
+
7649
+ /* Update or retrieve the settings for a date picker attached to an input field or division.
7650
+ * @param target element - the target input field or division or span
7651
+ * @param name object - the new settings to update or
7652
+ * string - the name of the setting to change or retrieve,
7653
+ * when retrieving also "all" for all instance settings or
7654
+ * "defaults" for all global defaults
7655
+ * @param value any - the new value for the setting
7656
+ * (omit if above is an object or to retrieve a value)
7657
+ */
7658
+ _optionDatepicker: function( target, name, value ) {
7659
+ var settings, date, minDate, maxDate,
7660
+ inst = this._getInst( target );
7661
+
7662
+ if ( arguments.length === 2 && typeof name === "string" ) {
7663
+ return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
7664
+ ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
7665
+ this._get( inst, name ) ) : null ) );
7666
+ }
7667
+
7668
+ settings = name || {};
7669
+ if ( typeof name === "string" ) {
7670
+ settings = {};
7671
+ settings[ name ] = value;
7672
+ }
7673
+
7674
+ if ( inst ) {
7675
+ if ( this._curInst === inst ) {
7676
+ this._hideDatepicker();
7677
+ }
7678
+
7679
+ date = this._getDateDatepicker( target, true );
7680
+ minDate = this._getMinMaxDate( inst, "min" );
7681
+ maxDate = this._getMinMaxDate( inst, "max" );
7682
+ datepicker_extendRemove( inst.settings, settings );
7683
+
7684
+ // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7685
+ if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
7686
+ inst.settings.minDate = this._formatDate( inst, minDate );
7687
+ }
7688
+ if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
7689
+ inst.settings.maxDate = this._formatDate( inst, maxDate );
7690
+ }
7691
+ if ( "disabled" in settings ) {
7692
+ if ( settings.disabled ) {
7693
+ this._disableDatepicker( target );
7694
+ } else {
7695
+ this._enableDatepicker( target );
7696
+ }
7697
+ }
7698
+ this._attachments( $( target ), inst );
7699
+ this._autoSize( inst );
7700
+ this._setDate( inst, date );
7701
+ this._updateAlternate( inst );
7702
+ this._updateDatepicker( inst );
7703
+ }
7704
+ },
7705
+
7706
+ // Change method deprecated
7707
+ _changeDatepicker: function( target, name, value ) {
7708
+ this._optionDatepicker( target, name, value );
7709
+ },
7710
+
7711
+ /* Redraw the date picker attached to an input field or division.
7712
+ * @param target element - the target input field or division or span
7713
+ */
7714
+ _refreshDatepicker: function( target ) {
7715
+ var inst = this._getInst( target );
7716
+ if ( inst ) {
7717
+ this._updateDatepicker( inst );
7718
+ }
7719
+ },
7720
+
7721
+ /* Set the dates for a jQuery selection.
7722
+ * @param target element - the target input field or division or span
7723
+ * @param date Date - the new date
7724
+ */
7725
+ _setDateDatepicker: function( target, date ) {
7726
+ var inst = this._getInst( target );
7727
+ if ( inst ) {
7728
+ this._setDate( inst, date );
7729
+ this._updateDatepicker( inst );
7730
+ this._updateAlternate( inst );
7731
+ }
7732
+ },
7733
+
7734
+ /* Get the date(s) for the first entry in a jQuery selection.
7735
+ * @param target element - the target input field or division or span
7736
+ * @param noDefault boolean - true if no default date is to be used
7737
+ * @return Date - the current date
7738
+ */
7739
+ _getDateDatepicker: function( target, noDefault ) {
7740
+ var inst = this._getInst( target );
7741
+ if ( inst && !inst.inline ) {
7742
+ this._setDateFromField( inst, noDefault );
7743
+ }
7744
+ return ( inst ? this._getDate( inst ) : null );
7745
+ },
7746
+
7747
+ /* Handle keystrokes. */
7748
+ _doKeyDown: function( event ) {
7749
+ var onSelect, dateStr, sel,
7750
+ inst = $.datepicker._getInst( event.target ),
7751
+ handled = true,
7752
+ isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
7753
+
7754
+ inst._keyEvent = true;
7755
+ if ( $.datepicker._datepickerShowing ) {
7756
+ switch ( event.keyCode ) {
7757
+ case 9: $.datepicker._hideDatepicker();
7758
+ handled = false;
7759
+ break; // hide on tab out
7760
+ case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
7761
+ $.datepicker._currentClass + ")", inst.dpDiv );
7762
+ if ( sel[ 0 ] ) {
7763
+ $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
7764
+ }
7765
+
7766
+ onSelect = $.datepicker._get( inst, "onSelect" );
7767
+ if ( onSelect ) {
7768
+ dateStr = $.datepicker._formatDate( inst );
7769
+
7770
+ // Trigger custom callback
7771
+ onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
7772
+ } else {
7773
+ $.datepicker._hideDatepicker();
7774
+ }
7775
+
7776
+ return false; // don't submit the form
7777
+ case 27: $.datepicker._hideDatepicker();
7778
+ break; // hide on escape
7779
+ case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7780
+ -$.datepicker._get( inst, "stepBigMonths" ) :
7781
+ -$.datepicker._get( inst, "stepMonths" ) ), "M" );
7782
+ break; // previous month/year on page up/+ ctrl
7783
+ case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7784
+ +$.datepicker._get( inst, "stepBigMonths" ) :
7785
+ +$.datepicker._get( inst, "stepMonths" ) ), "M" );
7786
+ break; // next month/year on page down/+ ctrl
7787
+ case 35: if ( event.ctrlKey || event.metaKey ) {
7788
+ $.datepicker._clearDate( event.target );
7789
+ }
7790
+ handled = event.ctrlKey || event.metaKey;
7791
+ break; // clear on ctrl or command +end
7792
+ case 36: if ( event.ctrlKey || event.metaKey ) {
7793
+ $.datepicker._gotoToday( event.target );
7794
+ }
7795
+ handled = event.ctrlKey || event.metaKey;
7796
+ break; // current on ctrl or command +home
7797
+ case 37: if ( event.ctrlKey || event.metaKey ) {
7798
+ $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
7799
+ }
7800
+ handled = event.ctrlKey || event.metaKey;
7801
+
7802
+ // -1 day on ctrl or command +left
7803
+ if ( event.originalEvent.altKey ) {
7804
+ $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7805
+ -$.datepicker._get( inst, "stepBigMonths" ) :
7806
+ -$.datepicker._get( inst, "stepMonths" ) ), "M" );
7807
+ }
7808
+
7809
+ // next month/year on alt +left on Mac
7810
+ break;
7811
+ case 38: if ( event.ctrlKey || event.metaKey ) {
7812
+ $.datepicker._adjustDate( event.target, -7, "D" );
7813
+ }
7814
+ handled = event.ctrlKey || event.metaKey;
7815
+ break; // -1 week on ctrl or command +up
7816
+ case 39: if ( event.ctrlKey || event.metaKey ) {
7817
+ $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
7818
+ }
7819
+ handled = event.ctrlKey || event.metaKey;
7820
+
7821
+ // +1 day on ctrl or command +right
7822
+ if ( event.originalEvent.altKey ) {
7823
+ $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7824
+ +$.datepicker._get( inst, "stepBigMonths" ) :
7825
+ +$.datepicker._get( inst, "stepMonths" ) ), "M" );
7826
+ }
7827
+
7828
+ // next month/year on alt +right
7829
+ break;
7830
+ case 40: if ( event.ctrlKey || event.metaKey ) {
7831
+ $.datepicker._adjustDate( event.target, +7, "D" );
7832
+ }
7833
+ handled = event.ctrlKey || event.metaKey;
7834
+ break; // +1 week on ctrl or command +down
7835
+ default: handled = false;
7836
+ }
7837
+ } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
7838
+ $.datepicker._showDatepicker( this );
7839
+ } else {
7840
+ handled = false;
7841
+ }
7842
+
7843
+ if ( handled ) {
7844
+ event.preventDefault();
7845
+ event.stopPropagation();
7846
+ }
7847
+ },
7848
+
7849
+ /* Filter entered characters - based on date format. */
7850
+ _doKeyPress: function( event ) {
7851
+ var chars, chr,
7852
+ inst = $.datepicker._getInst( event.target );
7853
+
7854
+ if ( $.datepicker._get( inst, "constrainInput" ) ) {
7855
+ chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
7856
+ chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
7857
+ return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
7858
+ }
7859
+ },
7860
+
7861
+ /* Synchronise manual entry and field/alternate field. */
7862
+ _doKeyUp: function( event ) {
7863
+ var date,
7864
+ inst = $.datepicker._getInst( event.target );
7865
+
7866
+ if ( inst.input.val() !== inst.lastVal ) {
7867
+ try {
7868
+ date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
7869
+ ( inst.input ? inst.input.val() : null ),
7870
+ $.datepicker._getFormatConfig( inst ) );
7871
+
7872
+ if ( date ) { // only if valid
7873
+ $.datepicker._setDateFromField( inst );
7874
+ $.datepicker._updateAlternate( inst );
7875
+ $.datepicker._updateDatepicker( inst );
7876
+ }
7877
+ }
7878
+ catch ( err ) {
7879
+ }
7880
+ }
7881
+ return true;
7882
+ },
7883
+
7884
+ /* Pop-up the date picker for a given input field.
7885
+ * If false returned from beforeShow event handler do not show.
7886
+ * @param input element - the input field attached to the date picker or
7887
+ * event - if triggered by focus
7888
+ */
7889
+ _showDatepicker: function( input ) {
7890
+ input = input.target || input;
7891
+ if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
7892
+ input = $( "input", input.parentNode )[ 0 ];
7893
+ }
7894
+
7895
+ if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
7896
+ return;
7897
+ }
7898
+
7899
+ var inst, beforeShow, beforeShowSettings, isFixed,
7900
+ offset, showAnim, duration;
7901
+
7902
+ inst = $.datepicker._getInst( input );
7903
+ if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
7904
+ $.datepicker._curInst.dpDiv.stop( true, true );
7905
+ if ( inst && $.datepicker._datepickerShowing ) {
7906
+ $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
7907
+ }
7908
+ }
7909
+
7910
+ beforeShow = $.datepicker._get( inst, "beforeShow" );
7911
+ beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
7912
+ if ( beforeShowSettings === false ) {
7913
+ return;
7914
+ }
7915
+ datepicker_extendRemove( inst.settings, beforeShowSettings );
7916
+
7917
+ inst.lastVal = null;
7918
+ $.datepicker._lastInput = input;
7919
+ $.datepicker._setDateFromField( inst );
7920
+
7921
+ if ( $.datepicker._inDialog ) { // hide cursor
7922
+ input.value = "";
7923
+ }
7924
+ if ( !$.datepicker._pos ) { // position below input
7925
+ $.datepicker._pos = $.datepicker._findPos( input );
7926
+ $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
7927
+ }
7928
+
7929
+ isFixed = false;
7930
+ $( input ).parents().each( function() {
7931
+ isFixed |= $( this ).css( "position" ) === "fixed";
7932
+ return !isFixed;
7933
+ } );
7934
+
7935
+ offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
7936
+ $.datepicker._pos = null;
7937
+
7938
+ //to avoid flashes on Firefox
7939
+ inst.dpDiv.empty();
7940
+
7941
+ // determine sizing offscreen
7942
+ inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
7943
+ $.datepicker._updateDatepicker( inst );
7944
+
7945
+ // fix width for dynamic number of date pickers
7946
+ // and adjust position before showing
7947
+ offset = $.datepicker._checkOffset( inst, offset, isFixed );
7948
+ inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
7949
+ "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
7950
+ left: offset.left + "px", top: offset.top + "px" } );
7951
+
7952
+ if ( !inst.inline ) {
7953
+ showAnim = $.datepicker._get( inst, "showAnim" );
7954
+ duration = $.datepicker._get( inst, "duration" );
7955
+ inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
7956
+ $.datepicker._datepickerShowing = true;
7957
+
7958
+ if ( $.effects && $.effects.effect[ showAnim ] ) {
7959
+ inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
7960
+ } else {
7961
+ inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
7962
+ }
7963
+
7964
+ if ( $.datepicker._shouldFocusInput( inst ) ) {
7965
+ inst.input.trigger( "focus" );
7966
+ }
7967
+
7968
+ $.datepicker._curInst = inst;
7969
+ }
7970
+ },
7971
+
7972
+ /* Generate the date picker content. */
7973
+ _updateDatepicker: function( inst ) {
7974
+ this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7975
+ datepicker_instActive = inst; // for delegate hover events
7976
+ inst.dpDiv.empty().append( this._generateHTML( inst ) );
7977
+ this._attachHandlers( inst );
7978
+
7979
+ var origyearshtml,
7980
+ numMonths = this._getNumberOfMonths( inst ),
7981
+ cols = numMonths[ 1 ],
7982
+ width = 17,
7983
+ activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
7984
+
7985
+ if ( activeCell.length > 0 ) {
7986
+ datepicker_handleMouseover.apply( activeCell.get( 0 ) );
7987
+ }
7988
+
7989
+ inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
7990
+ if ( cols > 1 ) {
7991
+ inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
7992
+ }
7993
+ inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
7994
+ "Class" ]( "ui-datepicker-multi" );
7995
+ inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
7996
+ "Class" ]( "ui-datepicker-rtl" );
7997
+
7998
+ if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7999
+ inst.input.trigger( "focus" );
8000
+ }
8001
+
8002
+ // Deffered render of the years select (to avoid flashes on Firefox)
8003
+ if ( inst.yearshtml ) {
8004
+ origyearshtml = inst.yearshtml;
8005
+ setTimeout( function() {
8006
+
8007
+ //assure that inst.yearshtml didn't change.
8008
+ if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
8009
+ inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
8010
+ }
8011
+ origyearshtml = inst.yearshtml = null;
8012
+ }, 0 );
8013
+ }
8014
+ },
8015
+
8016
+ // #6694 - don't focus the input if it's already focused
8017
+ // this breaks the change event in IE
8018
+ // Support: IE and jQuery <1.9
8019
+ _shouldFocusInput: function( inst ) {
8020
+ return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8021
+ },
8022
+
8023
+ /* Check positioning to remain on screen. */
8024
+ _checkOffset: function( inst, offset, isFixed ) {
8025
+ var dpWidth = inst.dpDiv.outerWidth(),
8026
+ dpHeight = inst.dpDiv.outerHeight(),
8027
+ inputWidth = inst.input ? inst.input.outerWidth() : 0,
8028
+ inputHeight = inst.input ? inst.input.outerHeight() : 0,
8029
+ viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
8030
+ viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
8031
+
8032
+ offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
8033
+ offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
8034
+ offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
8035
+
8036
+ // Now check if datepicker is showing outside window viewport - move to a better place if so.
8037
+ offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
8038
+ Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
8039
+ offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
8040
+ Math.abs( dpHeight + inputHeight ) : 0 );
8041
+
8042
+ return offset;
8043
+ },
8044
+
8045
+ /* Find an object's position on the screen. */
8046
+ _findPos: function( obj ) {
8047
+ var position,
8048
+ inst = this._getInst( obj ),
8049
+ isRTL = this._get( inst, "isRTL" );
8050
+
8051
+ while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
8052
+ obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
8053
+ }
8054
+
8055
+ position = $( obj ).offset();
8056
+ return [ position.left, position.top ];
8057
+ },
8058
+
8059
+ /* Hide the date picker from view.
8060
+ * @param input element - the input field attached to the date picker
8061
+ */
8062
+ _hideDatepicker: function( input ) {
8063
+ var showAnim, duration, postProcess, onClose,
8064
+ inst = this._curInst;
8065
+
8066
+ if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
8067
+ return;
8068
+ }
8069
+
8070
+ if ( this._datepickerShowing ) {
8071
+ showAnim = this._get( inst, "showAnim" );
8072
+ duration = this._get( inst, "duration" );
8073
+ postProcess = function() {
8074
+ $.datepicker._tidyDialog( inst );
8075
+ };
8076
+
8077
+ // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8078
+ if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8079
+ inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
8080
+ } else {
8081
+ inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
8082
+ ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
8083
+ }
8084
+
8085
+ if ( !showAnim ) {
8086
+ postProcess();
8087
+ }
8088
+ this._datepickerShowing = false;
8089
+
8090
+ onClose = this._get( inst, "onClose" );
8091
+ if ( onClose ) {
8092
+ onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
8093
+ }
8094
+
8095
+ this._lastInput = null;
8096
+ if ( this._inDialog ) {
8097
+ this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
8098
+ if ( $.blockUI ) {
8099
+ $.unblockUI();
8100
+ $( "body" ).append( this.dpDiv );
8101
+ }
8102
+ }
8103
+ this._inDialog = false;
8104
+ }
8105
+ },
8106
+
8107
+ /* Tidy up after a dialog display. */
8108
+ _tidyDialog: function( inst ) {
8109
+ inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
8110
+ },
8111
+
8112
+ /* Close date picker if clicked elsewhere. */
8113
+ _checkExternalClick: function( event ) {
8114
+ if ( !$.datepicker._curInst ) {
8115
+ return;
8116
+ }
8117
+
8118
+ var $target = $( event.target ),
8119
+ inst = $.datepicker._getInst( $target[ 0 ] );
8120
+
8121
+ if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
8122
+ $target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
8123
+ !$target.hasClass( $.datepicker.markerClassName ) &&
8124
+ !$target.closest( "." + $.datepicker._triggerClass ).length &&
8125
+ $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
8126
+ ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
8127
+ $.datepicker._hideDatepicker();
8128
+ }
8129
+ },
8130
+
8131
+ /* Adjust one of the date sub-fields. */
8132
+ _adjustDate: function( id, offset, period ) {
8133
+ var target = $( id ),
8134
+ inst = this._getInst( target[ 0 ] );
8135
+
8136
+ if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
8137
+ return;
8138
+ }
8139
+ this._adjustInstDate( inst, offset +
8140
+ ( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
8141
+ period );
8142
+ this._updateDatepicker( inst );
8143
+ },
8144
+
8145
+ /* Action for current link. */
8146
+ _gotoToday: function( id ) {
8147
+ var date,
8148
+ target = $( id ),
8149
+ inst = this._getInst( target[ 0 ] );
8150
+
8151
+ if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
8152
+ inst.selectedDay = inst.currentDay;
8153
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8154
+ inst.drawYear = inst.selectedYear = inst.currentYear;
8155
+ } else {
8156
+ date = new Date();
8157
+ inst.selectedDay = date.getDate();
8158
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
8159
+ inst.drawYear = inst.selectedYear = date.getFullYear();
8160
+ }
8161
+ this._notifyChange( inst );
8162
+ this._adjustDate( target );
8163
+ },
8164
+
8165
+ /* Action for selecting a new month/year. */
8166
+ _selectMonthYear: function( id, select, period ) {
8167
+ var target = $( id ),
8168
+ inst = this._getInst( target[ 0 ] );
8169
+
8170
+ inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
8171
+ inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
8172
+ parseInt( select.options[ select.selectedIndex ].value, 10 );
8173
+
8174
+ this._notifyChange( inst );
8175
+ this._adjustDate( target );
8176
+ },
8177
+
8178
+ /* Action for selecting a day. */
8179
+ _selectDay: function( id, month, year, td ) {
8180
+ var inst,
8181
+ target = $( id );
8182
+
8183
+ if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
8184
+ return;
8185
+ }
8186
+
8187
+ inst = this._getInst( target[ 0 ] );
8188
+ inst.selectedDay = inst.currentDay = $( "a", td ).html();
8189
+ inst.selectedMonth = inst.currentMonth = month;
8190
+ inst.selectedYear = inst.currentYear = year;
8191
+ this._selectDate( id, this._formatDate( inst,
8192
+ inst.currentDay, inst.currentMonth, inst.currentYear ) );
8193
+ },
8194
+
8195
+ /* Erase the input field and hide the date picker. */
8196
+ _clearDate: function( id ) {
8197
+ var target = $( id );
8198
+ this._selectDate( target, "" );
8199
+ },
8200
+
8201
+ /* Update the input field with the selected date. */
8202
+ _selectDate: function( id, dateStr ) {
8203
+ var onSelect,
8204
+ target = $( id ),
8205
+ inst = this._getInst( target[ 0 ] );
8206
+
8207
+ dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
8208
+ if ( inst.input ) {
8209
+ inst.input.val( dateStr );
8210
+ }
8211
+ this._updateAlternate( inst );
8212
+
8213
+ onSelect = this._get( inst, "onSelect" );
8214
+ if ( onSelect ) {
8215
+ onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback
8216
+ } else if ( inst.input ) {
8217
+ inst.input.trigger( "change" ); // fire the change event
8218
+ }
8219
+
8220
+ if ( inst.inline ) {
8221
+ this._updateDatepicker( inst );
8222
+ } else {
8223
+ this._hideDatepicker();
8224
+ this._lastInput = inst.input[ 0 ];
8225
+ if ( typeof( inst.input[ 0 ] ) !== "object" ) {
8226
+ inst.input.trigger( "focus" ); // restore focus
8227
+ }
8228
+ this._lastInput = null;
8229
+ }
8230
+ },
8231
+
8232
+ /* Update any alternate field to synchronise with the main field. */
8233
+ _updateAlternate: function( inst ) {
8234
+ var altFormat, date, dateStr,
8235
+ altField = this._get( inst, "altField" );
8236
+
8237
+ if ( altField ) { // update alternate field too
8238
+ altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
8239
+ date = this._getDate( inst );
8240
+ dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
8241
+ $( altField ).val( dateStr );
8242
+ }
8243
+ },
8244
+
8245
+ /* Set as beforeShowDay function to prevent selection of weekends.
8246
+ * @param date Date - the date to customise
8247
+ * @return [boolean, string] - is this date selectable?, what is its CSS class?
8248
+ */
8249
+ noWeekends: function( date ) {
8250
+ var day = date.getDay();
8251
+ return [ ( day > 0 && day < 6 ), "" ];
8252
+ },
8253
+
8254
+ /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8255
+ * @param date Date - the date to get the week for
8256
+ * @return number - the number of the week within the year that contains this date
8257
+ */
8258
+ iso8601Week: function( date ) {
8259
+ var time,
8260
+ checkDate = new Date( date.getTime() );
8261
+
8262
+ // Find Thursday of this week starting on Monday
8263
+ checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
8264
+
8265
+ time = checkDate.getTime();
8266
+ checkDate.setMonth( 0 ); // Compare with Jan 1
8267
+ checkDate.setDate( 1 );
8268
+ return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
8269
+ },
8270
+
8271
+ /* Parse a string value into a date object.
8272
+ * See formatDate below for the possible formats.
8273
+ *
8274
+ * @param format string - the expected format of the date
8275
+ * @param value string - the date in the above format
8276
+ * @param settings Object - attributes include:
8277
+ * shortYearCutoff number - the cutoff year for determining the century (optional)
8278
+ * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8279
+ * dayNames string[7] - names of the days from Sunday (optional)
8280
+ * monthNamesShort string[12] - abbreviated names of the months (optional)
8281
+ * monthNames string[12] - names of the months (optional)
8282
+ * @return Date - the extracted date value or null if value is blank
8283
+ */
8284
+ parseDate: function( format, value, settings ) {
8285
+ if ( format == null || value == null ) {
8286
+ throw "Invalid arguments";
8287
+ }
8288
+
8289
+ value = ( typeof value === "object" ? value.toString() : value + "" );
8290
+ if ( value === "" ) {
8291
+ return null;
8292
+ }
8293
+
8294
+ var iFormat, dim, extra,
8295
+ iValue = 0,
8296
+ shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
8297
+ shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8298
+ new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
8299
+ dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8300
+ dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8301
+ monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8302
+ monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8303
+ year = -1,
8304
+ month = -1,
8305
+ day = -1,
8306
+ doy = -1,
8307
+ literal = false,
8308
+ date,
8309
+
8310
+ // Check whether a format character is doubled
8311
+ lookAhead = function( match ) {
8312
+ var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8313
+ if ( matches ) {
8314
+ iFormat++;
8315
+ }
8316
+ return matches;
8317
+ },
8318
+
8319
+ // Extract a number from the string value
8320
+ getNumber = function( match ) {
8321
+ var isDoubled = lookAhead( match ),
8322
+ size = ( match === "@" ? 14 : ( match === "!" ? 20 :
8323
+ ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
8324
+ minSize = ( match === "y" ? size : 1 ),
8325
+ digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
8326
+ num = value.substring( iValue ).match( digits );
8327
+ if ( !num ) {
8328
+ throw "Missing number at position " + iValue;
8329
+ }
8330
+ iValue += num[ 0 ].length;
8331
+ return parseInt( num[ 0 ], 10 );
8332
+ },
8333
+
8334
+ // Extract a name from the string value and convert to an index
8335
+ getName = function( match, shortNames, longNames ) {
8336
+ var index = -1,
8337
+ names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
8338
+ return [ [ k, v ] ];
8339
+ } ).sort( function( a, b ) {
8340
+ return -( a[ 1 ].length - b[ 1 ].length );
8341
+ } );
8342
+
8343
+ $.each( names, function( i, pair ) {
8344
+ var name = pair[ 1 ];
8345
+ if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
8346
+ index = pair[ 0 ];
8347
+ iValue += name.length;
8348
+ return false;
8349
+ }
8350
+ } );
8351
+ if ( index !== -1 ) {
8352
+ return index + 1;
8353
+ } else {
8354
+ throw "Unknown name at position " + iValue;
8355
+ }
8356
+ },
8357
+
8358
+ // Confirm that a literal character matches the string value
8359
+ checkLiteral = function() {
8360
+ if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
8361
+ throw "Unexpected literal at position " + iValue;
8362
+ }
8363
+ iValue++;
8364
+ };
8365
+
8366
+ for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8367
+ if ( literal ) {
8368
+ if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8369
+ literal = false;
8370
+ } else {
8371
+ checkLiteral();
8372
+ }
8373
+ } else {
8374
+ switch ( format.charAt( iFormat ) ) {
8375
+ case "d":
8376
+ day = getNumber( "d" );
8377
+ break;
8378
+ case "D":
8379
+ getName( "D", dayNamesShort, dayNames );
8380
+ break;
8381
+ case "o":
8382
+ doy = getNumber( "o" );
8383
+ break;
8384
+ case "m":
8385
+ month = getNumber( "m" );
8386
+ break;
8387
+ case "M":
8388
+ month = getName( "M", monthNamesShort, monthNames );
8389
+ break;
8390
+ case "y":
8391
+ year = getNumber( "y" );
8392
+ break;
8393
+ case "@":
8394
+ date = new Date( getNumber( "@" ) );
8395
+ year = date.getFullYear();
8396
+ month = date.getMonth() + 1;
8397
+ day = date.getDate();
8398
+ break;
8399
+ case "!":
8400
+ date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
8401
+ year = date.getFullYear();
8402
+ month = date.getMonth() + 1;
8403
+ day = date.getDate();
8404
+ break;
8405
+ case "'":
8406
+ if ( lookAhead( "'" ) ) {
8407
+ checkLiteral();
8408
+ } else {
8409
+ literal = true;
8410
+ }
8411
+ break;
8412
+ default:
8413
+ checkLiteral();
8414
+ }
8415
+ }
8416
+ }
8417
+
8418
+ if ( iValue < value.length ) {
8419
+ extra = value.substr( iValue );
8420
+ if ( !/^\s+/.test( extra ) ) {
8421
+ throw "Extra/unparsed characters found in date: " + extra;
8422
+ }
8423
+ }
8424
+
8425
+ if ( year === -1 ) {
8426
+ year = new Date().getFullYear();
8427
+ } else if ( year < 100 ) {
8428
+ year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8429
+ ( year <= shortYearCutoff ? 0 : -100 );
8430
+ }
8431
+
8432
+ if ( doy > -1 ) {
8433
+ month = 1;
8434
+ day = doy;
8435
+ do {
8436
+ dim = this._getDaysInMonth( year, month - 1 );
8437
+ if ( day <= dim ) {
8438
+ break;
8439
+ }
8440
+ month++;
8441
+ day -= dim;
8442
+ } while ( true );
8443
+ }
8444
+
8445
+ date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
8446
+ if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
8447
+ throw "Invalid date"; // E.g. 31/02/00
8448
+ }
8449
+ return date;
8450
+ },
8451
+
8452
+ /* Standard date formats. */
8453
+ ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8454
+ COOKIE: "D, dd M yy",
8455
+ ISO_8601: "yy-mm-dd",
8456
+ RFC_822: "D, d M y",
8457
+ RFC_850: "DD, dd-M-y",
8458
+ RFC_1036: "D, d M y",
8459
+ RFC_1123: "D, d M yy",
8460
+ RFC_2822: "D, d M yy",
8461
+ RSS: "D, d M y", // RFC 822
8462
+ TICKS: "!",
8463
+ TIMESTAMP: "@",
8464
+ W3C: "yy-mm-dd", // ISO 8601
8465
+
8466
+ _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
8467
+ Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
8468
+
8469
+ /* Format a date object into a string value.
8470
+ * The format can be combinations of the following:
8471
+ * d - day of month (no leading zero)
8472
+ * dd - day of month (two digit)
8473
+ * o - day of year (no leading zeros)
8474
+ * oo - day of year (three digit)
8475
+ * D - day name short
8476
+ * DD - day name long
8477
+ * m - month of year (no leading zero)
8478
+ * mm - month of year (two digit)
8479
+ * M - month name short
8480
+ * MM - month name long
8481
+ * y - year (two digit)
8482
+ * yy - year (four digit)
8483
+ * @ - Unix timestamp (ms since 01/01/1970)
8484
+ * ! - Windows ticks (100ns since 01/01/0001)
8485
+ * "..." - literal text
8486
+ * '' - single quote
8487
+ *
8488
+ * @param format string - the desired format of the date
8489
+ * @param date Date - the date value to format
8490
+ * @param settings Object - attributes include:
8491
+ * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8492
+ * dayNames string[7] - names of the days from Sunday (optional)
8493
+ * monthNamesShort string[12] - abbreviated names of the months (optional)
8494
+ * monthNames string[12] - names of the months (optional)
8495
+ * @return string - the date in the above format
8496
+ */
8497
+ formatDate: function( format, date, settings ) {
8498
+ if ( !date ) {
8499
+ return "";
8500
+ }
8501
+
8502
+ var iFormat,
8503
+ dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8504
+ dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8505
+ monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8506
+ monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8507
+
8508
+ // Check whether a format character is doubled
8509
+ lookAhead = function( match ) {
8510
+ var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8511
+ if ( matches ) {
8512
+ iFormat++;
8513
+ }
8514
+ return matches;
8515
+ },
8516
+
8517
+ // Format a number, with leading zero if necessary
8518
+ formatNumber = function( match, value, len ) {
8519
+ var num = "" + value;
8520
+ if ( lookAhead( match ) ) {
8521
+ while ( num.length < len ) {
8522
+ num = "0" + num;
8523
+ }
8524
+ }
8525
+ return num;
8526
+ },
8527
+
8528
+ // Format a name, short or long as requested
8529
+ formatName = function( match, value, shortNames, longNames ) {
8530
+ return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
8531
+ },
8532
+ output = "",
8533
+ literal = false;
8534
+
8535
+ if ( date ) {
8536
+ for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8537
+ if ( literal ) {
8538
+ if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8539
+ literal = false;
8540
+ } else {
8541
+ output += format.charAt( iFormat );
8542
+ }
8543
+ } else {
8544
+ switch ( format.charAt( iFormat ) ) {
8545
+ case "d":
8546
+ output += formatNumber( "d", date.getDate(), 2 );
8547
+ break;
8548
+ case "D":
8549
+ output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
8550
+ break;
8551
+ case "o":
8552
+ output += formatNumber( "o",
8553
+ Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
8554
+ break;
8555
+ case "m":
8556
+ output += formatNumber( "m", date.getMonth() + 1, 2 );
8557
+ break;
8558
+ case "M":
8559
+ output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
8560
+ break;
8561
+ case "y":
8562
+ output += ( lookAhead( "y" ) ? date.getFullYear() :
8563
+ ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
8564
+ break;
8565
+ case "@":
8566
+ output += date.getTime();
8567
+ break;
8568
+ case "!":
8569
+ output += date.getTime() * 10000 + this._ticksTo1970;
8570
+ break;
8571
+ case "'":
8572
+ if ( lookAhead( "'" ) ) {
8573
+ output += "'";
8574
+ } else {
8575
+ literal = true;
8576
+ }
8577
+ break;
8578
+ default:
8579
+ output += format.charAt( iFormat );
8580
+ }
8581
+ }
8582
+ }
8583
+ }
8584
+ return output;
8585
+ },
8586
+
8587
+ /* Extract all possible characters from the date format. */
8588
+ _possibleChars: function( format ) {
8589
+ var iFormat,
8590
+ chars = "",
8591
+ literal = false,
8592
+
8593
+ // Check whether a format character is doubled
8594
+ lookAhead = function( match ) {
8595
+ var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8596
+ if ( matches ) {
8597
+ iFormat++;
8598
+ }
8599
+ return matches;
8600
+ };
8601
+
8602
+ for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8603
+ if ( literal ) {
8604
+ if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8605
+ literal = false;
8606
+ } else {
8607
+ chars += format.charAt( iFormat );
8608
+ }
8609
+ } else {
8610
+ switch ( format.charAt( iFormat ) ) {
8611
+ case "d": case "m": case "y": case "@":
8612
+ chars += "0123456789";
8613
+ break;
8614
+ case "D": case "M":
8615
+ return null; // Accept anything
8616
+ case "'":
8617
+ if ( lookAhead( "'" ) ) {
8618
+ chars += "'";
8619
+ } else {
8620
+ literal = true;
8621
+ }
8622
+ break;
8623
+ default:
8624
+ chars += format.charAt( iFormat );
8625
+ }
8626
+ }
8627
+ }
8628
+ return chars;
8629
+ },
8630
+
8631
+ /* Get a setting value, defaulting if necessary. */
8632
+ _get: function( inst, name ) {
8633
+ return inst.settings[ name ] !== undefined ?
8634
+ inst.settings[ name ] : this._defaults[ name ];
8635
+ },
8636
+
8637
+ /* Parse existing date and initialise date picker. */
8638
+ _setDateFromField: function( inst, noDefault ) {
8639
+ if ( inst.input.val() === inst.lastVal ) {
8640
+ return;
8641
+ }
8642
+
8643
+ var dateFormat = this._get( inst, "dateFormat" ),
8644
+ dates = inst.lastVal = inst.input ? inst.input.val() : null,
8645
+ defaultDate = this._getDefaultDate( inst ),
8646
+ date = defaultDate,
8647
+ settings = this._getFormatConfig( inst );
8648
+
8649
+ try {
8650
+ date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
8651
+ } catch ( event ) {
8652
+ dates = ( noDefault ? "" : dates );
8653
+ }
8654
+ inst.selectedDay = date.getDate();
8655
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
8656
+ inst.drawYear = inst.selectedYear = date.getFullYear();
8657
+ inst.currentDay = ( dates ? date.getDate() : 0 );
8658
+ inst.currentMonth = ( dates ? date.getMonth() : 0 );
8659
+ inst.currentYear = ( dates ? date.getFullYear() : 0 );
8660
+ this._adjustInstDate( inst );
8661
+ },
8662
+
8663
+ /* Retrieve the default date shown on opening. */
8664
+ _getDefaultDate: function( inst ) {
8665
+ return this._restrictMinMax( inst,
8666
+ this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
8667
+ },
8668
+
8669
+ /* A date may be specified as an exact value or a relative one. */
8670
+ _determineDate: function( inst, date, defaultDate ) {
8671
+ var offsetNumeric = function( offset ) {
8672
+ var date = new Date();
8673
+ date.setDate( date.getDate() + offset );
8674
+ return date;
8675
+ },
8676
+ offsetString = function( offset ) {
8677
+ try {
8678
+ return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8679
+ offset, $.datepicker._getFormatConfig( inst ) );
8680
+ }
8681
+ catch ( e ) {
8682
+
8683
+ // Ignore
8684
+ }
8685
+
8686
+ var date = ( offset.toLowerCase().match( /^c/ ) ?
8687
+ $.datepicker._getDate( inst ) : null ) || new Date(),
8688
+ year = date.getFullYear(),
8689
+ month = date.getMonth(),
8690
+ day = date.getDate(),
8691
+ pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8692
+ matches = pattern.exec( offset );
8693
+
8694
+ while ( matches ) {
8695
+ switch ( matches[ 2 ] || "d" ) {
8696
+ case "d" : case "D" :
8697
+ day += parseInt( matches[ 1 ], 10 ); break;
8698
+ case "w" : case "W" :
8699
+ day += parseInt( matches[ 1 ], 10 ) * 7; break;
8700
+ case "m" : case "M" :
8701
+ month += parseInt( matches[ 1 ], 10 );
8702
+ day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8703
+ break;
8704
+ case "y": case "Y" :
8705
+ year += parseInt( matches[ 1 ], 10 );
8706
+ day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8707
+ break;
8708
+ }
8709
+ matches = pattern.exec( offset );
8710
+ }
8711
+ return new Date( year, month, day );
8712
+ },
8713
+ newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
8714
+ ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
8715
+
8716
+ newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
8717
+ if ( newDate ) {
8718
+ newDate.setHours( 0 );
8719
+ newDate.setMinutes( 0 );
8720
+ newDate.setSeconds( 0 );
8721
+ newDate.setMilliseconds( 0 );
8722
+ }
8723
+ return this._daylightSavingAdjust( newDate );
8724
+ },
8725
+
8726
+ /* Handle switch to/from daylight saving.
8727
+ * Hours may be non-zero on daylight saving cut-over:
8728
+ * > 12 when midnight changeover, but then cannot generate
8729
+ * midnight datetime, so jump to 1AM, otherwise reset.
8730
+ * @param date (Date) the date to check
8731
+ * @return (Date) the corrected date
8732
+ */
8733
+ _daylightSavingAdjust: function( date ) {
8734
+ if ( !date ) {
8735
+ return null;
8736
+ }
8737
+ date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
8738
+ return date;
8739
+ },
8740
+
8741
+ /* Set the date(s) directly. */
8742
+ _setDate: function( inst, date, noChange ) {
8743
+ var clear = !date,
8744
+ origMonth = inst.selectedMonth,
8745
+ origYear = inst.selectedYear,
8746
+ newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
8747
+
8748
+ inst.selectedDay = inst.currentDay = newDate.getDate();
8749
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8750
+ inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8751
+ if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
8752
+ this._notifyChange( inst );
8753
+ }
8754
+ this._adjustInstDate( inst );
8755
+ if ( inst.input ) {
8756
+ inst.input.val( clear ? "" : this._formatDate( inst ) );
8757
+ }
8758
+ },
8759
+
8760
+ /* Retrieve the date(s) directly. */
8761
+ _getDate: function( inst ) {
8762
+ var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
8763
+ this._daylightSavingAdjust( new Date(
8764
+ inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
8765
+ return startDate;
8766
+ },
8767
+
8768
+ /* Attach the onxxx handlers. These are declared statically so
8769
+ * they work with static code transformers like Caja.
8770
+ */
8771
+ _attachHandlers: function( inst ) {
8772
+ var stepMonths = this._get( inst, "stepMonths" ),
8773
+ id = "#" + inst.id.replace( /\\\\/g, "\\" );
8774
+ inst.dpDiv.find( "[data-handler]" ).map( function() {
8775
+ var handler = {
8776
+ prev: function() {
8777
+ $.datepicker._adjustDate( id, -stepMonths, "M" );
8778
+ },
8779
+ next: function() {
8780
+ $.datepicker._adjustDate( id, +stepMonths, "M" );
8781
+ },
8782
+ hide: function() {
8783
+ $.datepicker._hideDatepicker();
8784
+ },
8785
+ today: function() {
8786
+ $.datepicker._gotoToday( id );
8787
+ },
8788
+ selectDay: function() {
8789
+ $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
8790
+ return false;
8791
+ },
8792
+ selectMonth: function() {
8793
+ $.datepicker._selectMonthYear( id, this, "M" );
8794
+ return false;
8795
+ },
8796
+ selectYear: function() {
8797
+ $.datepicker._selectMonthYear( id, this, "Y" );
8798
+ return false;
8799
+ }
8800
+ };
8801
+ $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
8802
+ } );
8803
+ },
8804
+
8805
+ /* Generate the HTML for the current state of the date picker. */
8806
+ _generateHTML: function( inst ) {
8807
+ var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8808
+ controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8809
+ monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8810
+ selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8811
+ cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8812
+ printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8813
+ tempDate = new Date(),
8814
+ today = this._daylightSavingAdjust(
8815
+ new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
8816
+ isRTL = this._get( inst, "isRTL" ),
8817
+ showButtonPanel = this._get( inst, "showButtonPanel" ),
8818
+ hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
8819
+ navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
8820
+ numMonths = this._getNumberOfMonths( inst ),
8821
+ showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
8822
+ stepMonths = this._get( inst, "stepMonths" ),
8823
+ isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
8824
+ currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
8825
+ new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
8826
+ minDate = this._getMinMaxDate( inst, "min" ),
8827
+ maxDate = this._getMinMaxDate( inst, "max" ),
8828
+ drawMonth = inst.drawMonth - showCurrentAtPos,
8829
+ drawYear = inst.drawYear;
8830
+
8831
+ if ( drawMonth < 0 ) {
8832
+ drawMonth += 12;
8833
+ drawYear--;
8834
+ }
8835
+ if ( maxDate ) {
8836
+ maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
8837
+ maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
8838
+ maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
8839
+ while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
8840
+ drawMonth--;
8841
+ if ( drawMonth < 0 ) {
8842
+ drawMonth = 11;
8843
+ drawYear--;
8844
+ }
8845
+ }
8846
+ }
8847
+ inst.drawMonth = drawMonth;
8848
+ inst.drawYear = drawYear;
8849
+
8850
+ prevText = this._get( inst, "prevText" );
8851
+ prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
8852
+ this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
8853
+ this._getFormatConfig( inst ) ) );
8854
+
8855
+ prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
8856
+ "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8857
+ " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
8858
+ ( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" ) );
8859
+
8860
+ nextText = this._get( inst, "nextText" );
8861
+ nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
8862
+ this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
8863
+ this._getFormatConfig( inst ) ) );
8864
+
8865
+ next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
8866
+ "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8867
+ " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
8868
+ ( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" ) );
8869
+
8870
+ currentText = this._get( inst, "currentText" );
8871
+ gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
8872
+ currentText = ( !navigationAsDateFormat ? currentText :
8873
+ this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
8874
+
8875
+ controls = ( !inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
8876
+ this._get( inst, "closeText" ) + "</button>" : "" );
8877
+
8878
+ buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
8879
+ ( this._isInRange( inst, gotoDate ) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
8880
+ ">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
8881
+
8882
+ firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
8883
+ firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
8884
+
8885
+ showWeek = this._get( inst, "showWeek" );
8886
+ dayNames = this._get( inst, "dayNames" );
8887
+ dayNamesMin = this._get( inst, "dayNamesMin" );
8888
+ monthNames = this._get( inst, "monthNames" );
8889
+ monthNamesShort = this._get( inst, "monthNamesShort" );
8890
+ beforeShowDay = this._get( inst, "beforeShowDay" );
8891
+ showOtherMonths = this._get( inst, "showOtherMonths" );
8892
+ selectOtherMonths = this._get( inst, "selectOtherMonths" );
8893
+ defaultDate = this._getDefaultDate( inst );
8894
+ html = "";
8895
+
8896
+ for ( row = 0; row < numMonths[ 0 ]; row++ ) {
8897
+ group = "";
8898
+ this.maxRows = 4;
8899
+ for ( col = 0; col < numMonths[ 1 ]; col++ ) {
8900
+ selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
8901
+ cornerClass = " ui-corner-all";
8902
+ calender = "";
8903
+ if ( isMultiMonth ) {
8904
+ calender += "<div class='ui-datepicker-group";
8905
+ if ( numMonths[ 1 ] > 1 ) {
8906
+ switch ( col ) {
8907
+ case 0: calender += " ui-datepicker-group-first";
8908
+ cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
8909
+ case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
8910
+ cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
8911
+ default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8912
+ }
8913
+ }
8914
+ calender += "'>";
8915
+ }
8916
+ calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8917
+ ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
8918
+ ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
8919
+ this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
8920
+ row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
8921
+ "</div><table class='ui-datepicker-calendar'><thead>" +
8922
+ "<tr>";
8923
+ thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
8924
+ for ( dow = 0; dow < 7; dow++ ) { // days of the week
8925
+ day = ( dow + firstDay ) % 7;
8926
+ thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
8927
+ "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
8928
+ }
8929
+ calender += thead + "</tr></thead><tbody>";
8930
+ daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
8931
+ if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
8932
+ inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
8933
+ }
8934
+ leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
8935
+ curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
8936
+ numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
8937
+ this.maxRows = numRows;
8938
+ printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
8939
+ for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
8940
+ calender += "<tr>";
8941
+ tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8942
+ this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
8943
+ for ( dow = 0; dow < 7; dow++ ) { // create date picker days
8944
+ daySettings = ( beforeShowDay ?
8945
+ beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
8946
+ otherMonth = ( printDate.getMonth() !== drawMonth );
8947
+ unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
8948
+ ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
8949
+ tbody += "<td class='" +
8950
+ ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
8951
+ ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
8952
+ ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
8953
+ ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
8954
+
8955
+ // or defaultDate is current printedDate and defaultDate is selectedDate
8956
+ " " + this._dayOverClass : "" ) + // highlight selected day
8957
+ ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days
8958
+ ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
8959
+ ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
8960
+ ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
8961
+ ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
8962
+ ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
8963
+ ( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8964
+ ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8965
+ ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
8966
+ ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
8967
+ ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
8968
+ "' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
8969
+ printDate.setDate( printDate.getDate() + 1 );
8970
+ printDate = this._daylightSavingAdjust( printDate );
8971
+ }
8972
+ calender += tbody + "</tr>";
8973
+ }
8974
+ drawMonth++;
8975
+ if ( drawMonth > 11 ) {
8976
+ drawMonth = 0;
8977
+ drawYear++;
8978
+ }
8979
+ calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
8980
+ ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
8981
+ group += calender;
8982
+ }
8983
+ html += group;
8984
+ }
8985
+ html += buttonPanel;
8986
+ inst._keyEvent = false;
8987
+ return html;
8988
+ },
8989
+
8990
+ /* Generate the month and year header. */
8991
+ _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
8992
+ secondary, monthNames, monthNamesShort ) {
8993
+
8994
+ var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8995
+ changeMonth = this._get( inst, "changeMonth" ),
8996
+ changeYear = this._get( inst, "changeYear" ),
8997
+ showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
8998
+ html = "<div class='ui-datepicker-title'>",
8999
+ monthHtml = "";
9000
+
9001
+ // Month selection
9002
+ if ( secondary || !changeMonth ) {
9003
+ monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
9004
+ } else {
9005
+ inMinYear = ( minDate && minDate.getFullYear() === drawYear );
9006
+ inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
9007
+ monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9008
+ for ( month = 0; month < 12; month++ ) {
9009
+ if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
9010
+ monthHtml += "<option value='" + month + "'" +
9011
+ ( month === drawMonth ? " selected='selected'" : "" ) +
9012
+ ">" + monthNamesShort[ month ] + "</option>";
9013
+ }
9014
+ }
9015
+ monthHtml += "</select>";
9016
+ }
9017
+
9018
+ if ( !showMonthAfterYear ) {
9019
+ html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
9020
+ }
9021
+
9022
+ // Year selection
9023
+ if ( !inst.yearshtml ) {
9024
+ inst.yearshtml = "";
9025
+ if ( secondary || !changeYear ) {
9026
+ html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9027
+ } else {
9028
+
9029
+ // determine range of years to display
9030
+ years = this._get( inst, "yearRange" ).split( ":" );
9031
+ thisYear = new Date().getFullYear();
9032
+ determineYear = function( value ) {
9033
+ var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
9034
+ ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
9035
+ parseInt( value, 10 ) ) );
9036
+ return ( isNaN( year ) ? thisYear : year );
9037
+ };
9038
+ year = determineYear( years[ 0 ] );
9039
+ endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
9040
+ year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
9041
+ endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
9042
+ inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9043
+ for ( ; year <= endYear; year++ ) {
9044
+ inst.yearshtml += "<option value='" + year + "'" +
9045
+ ( year === drawYear ? " selected='selected'" : "" ) +
9046
+ ">" + year + "</option>";
9047
+ }
9048
+ inst.yearshtml += "</select>";
9049
+
9050
+ html += inst.yearshtml;
9051
+ inst.yearshtml = null;
9052
+ }
9053
+ }
9054
+
9055
+ html += this._get( inst, "yearSuffix" );
9056
+ if ( showMonthAfterYear ) {
9057
+ html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
9058
+ }
9059
+ html += "</div>"; // Close datepicker_header
9060
+ return html;
9061
+ },
9062
+
9063
+ /* Adjust one of the date sub-fields. */
9064
+ _adjustInstDate: function( inst, offset, period ) {
9065
+ var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
9066
+ month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
9067
+ day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
9068
+ date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
9069
+
9070
+ inst.selectedDay = date.getDate();
9071
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
9072
+ inst.drawYear = inst.selectedYear = date.getFullYear();
9073
+ if ( period === "M" || period === "Y" ) {
9074
+ this._notifyChange( inst );
9075
+ }
9076
+ },
9077
+
9078
+ /* Ensure a date is within any min/max bounds. */
9079
+ _restrictMinMax: function( inst, date ) {
9080
+ var minDate = this._getMinMaxDate( inst, "min" ),
9081
+ maxDate = this._getMinMaxDate( inst, "max" ),
9082
+ newDate = ( minDate && date < minDate ? minDate : date );
9083
+ return ( maxDate && newDate > maxDate ? maxDate : newDate );
9084
+ },
9085
+
9086
+ /* Notify change of month/year. */
9087
+ _notifyChange: function( inst ) {
9088
+ var onChange = this._get( inst, "onChangeMonthYear" );
9089
+ if ( onChange ) {
9090
+ onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
9091
+ [ inst.selectedYear, inst.selectedMonth + 1, inst ] );
9092
+ }
9093
+ },
9094
+
9095
+ /* Determine the number of months to show. */
9096
+ _getNumberOfMonths: function( inst ) {
9097
+ var numMonths = this._get( inst, "numberOfMonths" );
9098
+ return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
9099
+ },
9100
+
9101
+ /* Determine the current maximum date - ensure no time components are set. */
9102
+ _getMinMaxDate: function( inst, minMax ) {
9103
+ return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
9104
+ },
9105
+
9106
+ /* Find the number of days in a given month. */
9107
+ _getDaysInMonth: function( year, month ) {
9108
+ return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
9109
+ },
9110
+
9111
+ /* Find the day of the week of the first of a month. */
9112
+ _getFirstDayOfMonth: function( year, month ) {
9113
+ return new Date( year, month, 1 ).getDay();
9114
+ },
9115
+
9116
+ /* Determines if we should allow a "next/prev" month display change. */
9117
+ _canAdjustMonth: function( inst, offset, curYear, curMonth ) {
9118
+ var numMonths = this._getNumberOfMonths( inst ),
9119
+ date = this._daylightSavingAdjust( new Date( curYear,
9120
+ curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
9121
+
9122
+ if ( offset < 0 ) {
9123
+ date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
9124
+ }
9125
+ return this._isInRange( inst, date );
9126
+ },
9127
+
9128
+ /* Is the given date in the accepted range? */
9129
+ _isInRange: function( inst, date ) {
9130
+ var yearSplit, currentYear,
9131
+ minDate = this._getMinMaxDate( inst, "min" ),
9132
+ maxDate = this._getMinMaxDate( inst, "max" ),
9133
+ minYear = null,
9134
+ maxYear = null,
9135
+ years = this._get( inst, "yearRange" );
9136
+ if ( years ) {
9137
+ yearSplit = years.split( ":" );
9138
+ currentYear = new Date().getFullYear();
9139
+ minYear = parseInt( yearSplit[ 0 ], 10 );
9140
+ maxYear = parseInt( yearSplit[ 1 ], 10 );
9141
+ if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
9142
+ minYear += currentYear;
9143
+ }
9144
+ if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
9145
+ maxYear += currentYear;
9146
+ }
9147
+ }
9148
+
9149
+ return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
9150
+ ( !maxDate || date.getTime() <= maxDate.getTime() ) &&
9151
+ ( !minYear || date.getFullYear() >= minYear ) &&
9152
+ ( !maxYear || date.getFullYear() <= maxYear ) );
9153
+ },
9154
+
9155
+ /* Provide the configuration settings for formatting/parsing. */
9156
+ _getFormatConfig: function( inst ) {
9157
+ var shortYearCutoff = this._get( inst, "shortYearCutoff" );
9158
+ shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
9159
+ new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
9160
+ return { shortYearCutoff: shortYearCutoff,
9161
+ dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
9162
+ monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
9163
+ },
9164
+
9165
+ /* Format the given date for display. */
9166
+ _formatDate: function( inst, day, month, year ) {
9167
+ if ( !day ) {
9168
+ inst.currentDay = inst.selectedDay;
9169
+ inst.currentMonth = inst.selectedMonth;
9170
+ inst.currentYear = inst.selectedYear;
9171
+ }
9172
+ var date = ( day ? ( typeof day === "object" ? day :
9173
+ this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
9174
+ this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
9175
+ return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
9176
+ }
9177
+ } );
9178
+
9179
+ /*
9180
+ * Bind hover events for datepicker elements.
9181
+ * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9182
+ * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9183
+ */
9184
+ function datepicker_bindHover( dpDiv ) {
9185
+ var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9186
+ return dpDiv.on( "mouseout", selector, function() {
9187
+ $( this ).removeClass( "ui-state-hover" );
9188
+ if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9189
+ $( this ).removeClass( "ui-datepicker-prev-hover" );
9190
+ }
9191
+ if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9192
+ $( this ).removeClass( "ui-datepicker-next-hover" );
9193
+ }
9194
+ } )
9195
+ .on( "mouseover", selector, datepicker_handleMouseover );
9196
+ }
9197
+
9198
+ function datepicker_handleMouseover() {
9199
+ if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
9200
+ $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
9201
+ $( this ).addClass( "ui-state-hover" );
9202
+ if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9203
+ $( this ).addClass( "ui-datepicker-prev-hover" );
9204
+ }
9205
+ if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9206
+ $( this ).addClass( "ui-datepicker-next-hover" );
9207
+ }
9208
+ }
9209
+ }
9210
+
9211
+ /* jQuery extend now ignores nulls! */
9212
+ function datepicker_extendRemove( target, props ) {
9213
+ $.extend( target, props );
9214
+ for ( var name in props ) {
9215
+ if ( props[ name ] == null ) {
9216
+ target[ name ] = props[ name ];
9217
+ }
9218
+ }
9219
+ return target;
9220
+ }
9221
+
9222
+ /* Invoke the datepicker functionality.
9223
+ @param options string - a command, optionally followed by additional parameters or
9224
+ Object - settings for attaching new datepicker functionality
9225
+ @return jQuery object */
9226
+ $.fn.datepicker = function( options ) {
9227
+
9228
+ /* Verify an empty collection wasn't passed - Fixes #6976 */
9229
+ if ( !this.length ) {
9230
+ return this;
9231
+ }
9232
+
9233
+ /* Initialise the date picker. */
9234
+ if ( !$.datepicker.initialized ) {
9235
+ $( document ).on( "mousedown", $.datepicker._checkExternalClick );
9236
+ $.datepicker.initialized = true;
9237
+ }
9238
+
9239
+ /* Append datepicker main container to body if not exist. */
9240
+ if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
9241
+ $( "body" ).append( $.datepicker.dpDiv );
9242
+ }
9243
+
9244
+ var otherArgs = Array.prototype.slice.call( arguments, 1 );
9245
+ if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
9246
+ return $.datepicker[ "_" + options + "Datepicker" ].
9247
+ apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9248
+ }
9249
+ if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
9250
+ return $.datepicker[ "_" + options + "Datepicker" ].
9251
+ apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9252
+ }
9253
+ return this.each( function() {
9254
+ typeof options === "string" ?
9255
+ $.datepicker[ "_" + options + "Datepicker" ].
9256
+ apply( $.datepicker, [ this ].concat( otherArgs ) ) :
9257
+ $.datepicker._attachDatepicker( this, options );
9258
+ } );
9259
+ };
9260
+
9261
+ $.datepicker = new Datepicker(); // singleton instance
9262
+ $.datepicker.initialized = false;
9263
+ $.datepicker.uuid = new Date().getTime();
9264
+ $.datepicker.version = "1.12.1";
9265
+
9266
+ var widgetsDatepicker = $.datepicker;
9267
+
9268
+
9269
+
9270
+
9271
+ // This file is deprecated
9272
+ var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
9273
+
9274
+ /*!
9275
+ * jQuery UI Mouse 1.12.1
9276
+ * http://jqueryui.com
9277
+ *
9278
+ * Copyright jQuery Foundation and other contributors
9279
+ * Released under the MIT license.
9280
+ * http://jquery.org/license
9281
+ */
9282
+
9283
+ //>>label: Mouse
9284
+ //>>group: Widgets
9285
+ //>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9286
+ //>>docs: http://api.jqueryui.com/mouse/
9287
+
9288
+
9289
+
9290
+ var mouseHandled = false;
9291
+ $( document ).on( "mouseup", function() {
9292
+ mouseHandled = false;
9293
+ } );
9294
+
9295
+ var widgetsMouse = $.widget( "ui.mouse", {
9296
+ version: "1.12.1",
9297
+ options: {
9298
+ cancel: "input, textarea, button, select, option",
9299
+ distance: 1,
9300
+ delay: 0
9301
+ },
9302
+ _mouseInit: function() {
9303
+ var that = this;
9304
+
9305
+ this.element
9306
+ .on( "mousedown." + this.widgetName, function( event ) {
9307
+ return that._mouseDown( event );
9308
+ } )
9309
+ .on( "click." + this.widgetName, function( event ) {
9310
+ if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
9311
+ $.removeData( event.target, that.widgetName + ".preventClickEvent" );
9312
+ event.stopImmediatePropagation();
9313
+ return false;
9314
+ }
9315
+ } );
9316
+
9317
+ this.started = false;
9318
+ },
9319
+
9320
+ // TODO: make sure destroying one instance of mouse doesn't mess with
9321
+ // other instances of mouse
9322
+ _mouseDestroy: function() {
9323
+ this.element.off( "." + this.widgetName );
9324
+ if ( this._mouseMoveDelegate ) {
9325
+ this.document
9326
+ .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9327
+ .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9328
+ }
9329
+ },
9330
+
9331
+ _mouseDown: function( event ) {
9332
+
9333
+ // don't let more than one widget handle mouseStart
9334
+ if ( mouseHandled ) {
9335
+ return;
9336
+ }
9337
+
9338
+ this._mouseMoved = false;
9339
+
9340
+ // We may have missed mouseup (out of window)
9341
+ ( this._mouseStarted && this._mouseUp( event ) );
9342
+
9343
+ this._mouseDownEvent = event;
9344
+
9345
+ var that = this,
9346
+ btnIsLeft = ( event.which === 1 ),
9347
+
9348
+ // event.target.nodeName works around a bug in IE 8 with
9349
+ // disabled inputs (#7620)
9350
+ elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
9351
+ $( event.target ).closest( this.options.cancel ).length : false );
9352
+ if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
9353
+ return true;
9354
+ }
9355
+
9356
+ this.mouseDelayMet = !this.options.delay;
9357
+ if ( !this.mouseDelayMet ) {
9358
+ this._mouseDelayTimer = setTimeout( function() {
9359
+ that.mouseDelayMet = true;
9360
+ }, this.options.delay );
9361
+ }
9362
+
9363
+ if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9364
+ this._mouseStarted = ( this._mouseStart( event ) !== false );
9365
+ if ( !this._mouseStarted ) {
9366
+ event.preventDefault();
9367
+ return true;
9368
+ }
9369
+ }
9370
+
9371
+ // Click event may never have fired (Gecko & Opera)
9372
+ if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
9373
+ $.removeData( event.target, this.widgetName + ".preventClickEvent" );
9374
+ }
9375
+
9376
+ // These delegates are required to keep context
9377
+ this._mouseMoveDelegate = function( event ) {
9378
+ return that._mouseMove( event );
9379
+ };
9380
+ this._mouseUpDelegate = function( event ) {
9381
+ return that._mouseUp( event );
9382
+ };
9383
+
9384
+ this.document
9385
+ .on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9386
+ .on( "mouseup." + this.widgetName, this._mouseUpDelegate );
9387
+
9388
+ event.preventDefault();
9389
+
9390
+ mouseHandled = true;
9391
+ return true;
9392
+ },
9393
+
9394
+ _mouseMove: function( event ) {
9395
+
9396
+ // Only check for mouseups outside the document if you've moved inside the document
9397
+ // at least once. This prevents the firing of mouseup in the case of IE<9, which will
9398
+ // fire a mousemove event if content is placed under the cursor. See #7778
9399
+ // Support: IE <9
9400
+ if ( this._mouseMoved ) {
9401
+
9402
+ // IE mouseup check - mouseup happened when mouse was out of window
9403
+ if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
9404
+ !event.button ) {
9405
+ return this._mouseUp( event );
9406
+
9407
+ // Iframe mouseup check - mouseup occurred in another document
9408
+ } else if ( !event.which ) {
9409
+
9410
+ // Support: Safari <=8 - 9
9411
+ // Safari sets which to 0 if you press any of the following keys
9412
+ // during a drag (#14461)
9413
+ if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9414
+ event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
9415
+ this.ignoreMissingWhich = true;
9416
+ } else if ( !this.ignoreMissingWhich ) {
9417
+ return this._mouseUp( event );
9418
+ }
9419
+ }
9420
+ }
9421
+
9422
+ if ( event.which || event.button ) {
9423
+ this._mouseMoved = true;
9424
+ }
9425
+
9426
+ if ( this._mouseStarted ) {
9427
+ this._mouseDrag( event );
9428
+ return event.preventDefault();
9429
+ }
9430
+
9431
+ if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9432
+ this._mouseStarted =
9433
+ ( this._mouseStart( this._mouseDownEvent, event ) !== false );
9434
+ ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
9435
+ }
9436
+
9437
+ return !this._mouseStarted;
9438
+ },
9439
+
9440
+ _mouseUp: function( event ) {
9441
+ this.document
9442
+ .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9443
+ .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9444
+
9445
+ if ( this._mouseStarted ) {
9446
+ this._mouseStarted = false;
9447
+
9448
+ if ( event.target === this._mouseDownEvent.target ) {
9449
+ $.data( event.target, this.widgetName + ".preventClickEvent", true );
9450
+ }
9451
+
9452
+ this._mouseStop( event );
9453
+ }
9454
+
9455
+ if ( this._mouseDelayTimer ) {
9456
+ clearTimeout( this._mouseDelayTimer );
9457
+ delete this._mouseDelayTimer;
9458
+ }
9459
+
9460
+ this.ignoreMissingWhich = false;
9461
+ mouseHandled = false;
9462
+ event.preventDefault();
9463
+ },
9464
+
9465
+ _mouseDistanceMet: function( event ) {
9466
+ return ( Math.max(
9467
+ Math.abs( this._mouseDownEvent.pageX - event.pageX ),
9468
+ Math.abs( this._mouseDownEvent.pageY - event.pageY )
9469
+ ) >= this.options.distance
9470
+ );
9471
+ },
9472
+
9473
+ _mouseDelayMet: function( /* event */ ) {
9474
+ return this.mouseDelayMet;
9475
+ },
9476
+
9477
+ // These are placeholder methods, to be overriden by extending plugin
9478
+ _mouseStart: function( /* event */ ) {},
9479
+ _mouseDrag: function( /* event */ ) {},
9480
+ _mouseStop: function( /* event */ ) {},
9481
+ _mouseCapture: function( /* event */ ) { return true; }
9482
+ } );
9483
+
9484
+
9485
+
9486
+
9487
+ // $.ui.plugin is deprecated. Use $.widget() extensions instead.
9488
+ var plugin = $.ui.plugin = {
9489
+ add: function( module, option, set ) {
9490
+ var i,
9491
+ proto = $.ui[ module ].prototype;
9492
+ for ( i in set ) {
9493
+ proto.plugins[ i ] = proto.plugins[ i ] || [];
9494
+ proto.plugins[ i ].push( [ option, set[ i ] ] );
9495
+ }
9496
+ },
9497
+ call: function( instance, name, args, allowDisconnected ) {
9498
+ var i,
9499
+ set = instance.plugins[ name ];
9500
+
9501
+ if ( !set ) {
9502
+ return;
9503
+ }
9504
+
9505
+ if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
9506
+ instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
9507
+ return;
9508
+ }
9509
+
9510
+ for ( i = 0; i < set.length; i++ ) {
9511
+ if ( instance.options[ set[ i ][ 0 ] ] ) {
9512
+ set[ i ][ 1 ].apply( instance.element, args );
9513
+ }
9514
+ }
9515
+ }
9516
+ };
9517
+
9518
+
9519
+
9520
+ var safeBlur = $.ui.safeBlur = function( element ) {
9521
+
9522
+ // Support: IE9 - 10 only
9523
+ // If the <body> is blurred, IE will switch windows, see #9420
9524
+ if ( element && element.nodeName.toLowerCase() !== "body" ) {
9525
+ $( element ).trigger( "blur" );
9526
+ }
9527
+ };
9528
+
9529
+
9530
+ /*!
9531
+ * jQuery UI Draggable 1.12.1
9532
+ * http://jqueryui.com
9533
+ *
9534
+ * Copyright jQuery Foundation and other contributors
9535
+ * Released under the MIT license.
9536
+ * http://jquery.org/license
9537
+ */
9538
+
9539
+ //>>label: Draggable
9540
+ //>>group: Interactions
9541
+ //>>description: Enables dragging functionality for any element.
9542
+ //>>docs: http://api.jqueryui.com/draggable/
9543
+ //>>demos: http://jqueryui.com/draggable/
9544
+ //>>css.structure: ../../themes/base/draggable.css
9545
+
9546
+
9547
+
9548
+ $.widget( "ui.draggable", $.ui.mouse, {
9549
+ version: "1.12.1",
9550
+ widgetEventPrefix: "drag",
9551
+ options: {
9552
+ addClasses: true,
9553
+ appendTo: "parent",
9554
+ axis: false,
9555
+ connectToSortable: false,
9556
+ containment: false,
9557
+ cursor: "auto",
9558
+ cursorAt: false,
9559
+ grid: false,
9560
+ handle: false,
9561
+ helper: "original",
9562
+ iframeFix: false,
9563
+ opacity: false,
9564
+ refreshPositions: false,
9565
+ revert: false,
9566
+ revertDuration: 500,
9567
+ scope: "default",
9568
+ scroll: true,
9569
+ scrollSensitivity: 20,
9570
+ scrollSpeed: 20,
9571
+ snap: false,
9572
+ snapMode: "both",
9573
+ snapTolerance: 20,
9574
+ stack: false,
9575
+ zIndex: false,
9576
+
9577
+ // Callbacks
9578
+ drag: null,
9579
+ start: null,
9580
+ stop: null
9581
+ },
9582
+ _create: function() {
9583
+
9584
+ if ( this.options.helper === "original" ) {
9585
+ this._setPositionRelative();
9586
+ }
9587
+ if ( this.options.addClasses ) {
9588
+ this._addClass( "ui-draggable" );
9589
+ }
9590
+ this._setHandleClassName();
9591
+
9592
+ this._mouseInit();
9593
+ },
9594
+
9595
+ _setOption: function( key, value ) {
9596
+ this._super( key, value );
9597
+ if ( key === "handle" ) {
9598
+ this._removeHandleClassName();
9599
+ this._setHandleClassName();
9600
+ }
9601
+ },
9602
+
9603
+ _destroy: function() {
9604
+ if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
9605
+ this.destroyOnClear = true;
9606
+ return;
9607
+ }
9608
+ this._removeHandleClassName();
9609
+ this._mouseDestroy();
9610
+ },
9611
+
9612
+ _mouseCapture: function( event ) {
9613
+ var o = this.options;
9614
+
9615
+ // Among others, prevent a drag on a resizable-handle
9616
+ if ( this.helper || o.disabled ||
9617
+ $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
9618
+ return false;
9619
+ }
9620
+
9621
+ //Quit if we're not on a valid handle
9622
+ this.handle = this._getHandle( event );
9623
+ if ( !this.handle ) {
9624
+ return false;
9625
+ }
9626
+
9627
+ this._blurActiveElement( event );
9628
+
9629
+ this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
9630
+
9631
+ return true;
9632
+
9633
+ },
9634
+
9635
+ _blockFrames: function( selector ) {
9636
+ this.iframeBlocks = this.document.find( selector ).map( function() {
9637
+ var iframe = $( this );
9638
+
9639
+ return $( "<div>" )
9640
+ .css( "position", "absolute" )
9641
+ .appendTo( iframe.parent() )
9642
+ .outerWidth( iframe.outerWidth() )
9643
+ .outerHeight( iframe.outerHeight() )
9644
+ .offset( iframe.offset() )[ 0 ];
9645
+ } );
9646
+ },
9647
+
9648
+ _unblockFrames: function() {
9649
+ if ( this.iframeBlocks ) {
9650
+ this.iframeBlocks.remove();
9651
+ delete this.iframeBlocks;
9652
+ }
9653
+ },
9654
+
9655
+ _blurActiveElement: function( event ) {
9656
+ var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
9657
+ target = $( event.target );
9658
+
9659
+ // Don't blur if the event occurred on an element that is within
9660
+ // the currently focused element
9661
+ // See #10527, #12472
9662
+ if ( target.closest( activeElement ).length ) {
9663
+ return;
9664
+ }
9665
+
9666
+ // Blur any element that currently has focus, see #4261
9667
+ $.ui.safeBlur( activeElement );
9668
+ },
9669
+
9670
+ _mouseStart: function( event ) {
9671
+
9672
+ var o = this.options;
9673
+
9674
+ //Create and append the visible helper
9675
+ this.helper = this._createHelper( event );
9676
+
9677
+ this._addClass( this.helper, "ui-draggable-dragging" );
9678
+
9679
+ //Cache the helper size
9680
+ this._cacheHelperProportions();
9681
+
9682
+ //If ddmanager is used for droppables, set the global draggable
9683
+ if ( $.ui.ddmanager ) {
9684
+ $.ui.ddmanager.current = this;
9685
+ }
9686
+
9687
+ /*
9688
+ * - Position generation -
9689
+ * This block generates everything position related - it's the core of draggables.
9690
+ */
9691
+
9692
+ //Cache the margins of the original element
9693
+ this._cacheMargins();
9694
+
9695
+ //Store the helper's css position
9696
+ this.cssPosition = this.helper.css( "position" );
9697
+ this.scrollParent = this.helper.scrollParent( true );
9698
+ this.offsetParent = this.helper.offsetParent();
9699
+ this.hasFixedAncestor = this.helper.parents().filter( function() {
9700
+ return $( this ).css( "position" ) === "fixed";
9701
+ } ).length > 0;
9702
+
9703
+ //The element's absolute position on the page minus margins
9704
+ this.positionAbs = this.element.offset();
9705
+ this._refreshOffsets( event );
9706
+
9707
+ //Generate the original position
9708
+ this.originalPosition = this.position = this._generatePosition( event, false );
9709
+ this.originalPageX = event.pageX;
9710
+ this.originalPageY = event.pageY;
9711
+
9712
+ //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9713
+ ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
9714
+
9715
+ //Set a containment if given in the options
9716
+ this._setContainment();
9717
+
9718
+ //Trigger event + callbacks
9719
+ if ( this._trigger( "start", event ) === false ) {
9720
+ this._clear();
9721
+ return false;
9722
+ }
9723
+
9724
+ //Recache the helper size
9725
+ this._cacheHelperProportions();
9726
+
9727
+ //Prepare the droppable offsets
9728
+ if ( $.ui.ddmanager && !o.dropBehaviour ) {
9729
+ $.ui.ddmanager.prepareOffsets( this, event );
9730
+ }
9731
+
9732
+ // Execute the drag once - this causes the helper not to be visible before getting its
9733
+ // correct position
9734
+ this._mouseDrag( event, true );
9735
+
9736
+ // If the ddmanager is used for droppables, inform the manager that dragging has started
9737
+ // (see #5003)
9738
+ if ( $.ui.ddmanager ) {
9739
+ $.ui.ddmanager.dragStart( this, event );
9740
+ }
9741
+
9742
+ return true;
9743
+ },
9744
+
9745
+ _refreshOffsets: function( event ) {
9746
+ this.offset = {
9747
+ top: this.positionAbs.top - this.margins.top,
9748
+ left: this.positionAbs.left - this.margins.left,
9749
+ scroll: false,
9750
+ parent: this._getParentOffset(),
9751
+ relative: this._getRelativeOffset()
9752
+ };
9753
+
9754
+ this.offset.click = {
9755
+ left: event.pageX - this.offset.left,
9756
+ top: event.pageY - this.offset.top
9757
+ };
9758
+ },
9759
+
9760
+ _mouseDrag: function( event, noPropagation ) {
9761
+
9762
+ // reset any necessary cached properties (see #5009)
9763
+ if ( this.hasFixedAncestor ) {
9764
+ this.offset.parent = this._getParentOffset();
9765
+ }
9766
+
9767
+ //Compute the helpers position
9768
+ this.position = this._generatePosition( event, true );
9769
+ this.positionAbs = this._convertPositionTo( "absolute" );
9770
+
9771
+ //Call plugins and callbacks and use the resulting position if something is returned
9772
+ if ( !noPropagation ) {
9773
+ var ui = this._uiHash();
9774
+ if ( this._trigger( "drag", event, ui ) === false ) {
9775
+ this._mouseUp( new $.Event( "mouseup", event ) );
9776
+ return false;
9777
+ }
9778
+ this.position = ui.position;
9779
+ }
9780
+
9781
+ this.helper[ 0 ].style.left = this.position.left + "px";
9782
+ this.helper[ 0 ].style.top = this.position.top + "px";
9783
+
9784
+ if ( $.ui.ddmanager ) {
9785
+ $.ui.ddmanager.drag( this, event );
9786
+ }
9787
+
9788
+ return false;
9789
+ },
9790
+
9791
+ _mouseStop: function( event ) {
9792
+
9793
+ //If we are using droppables, inform the manager about the drop
9794
+ var that = this,
9795
+ dropped = false;
9796
+ if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
9797
+ dropped = $.ui.ddmanager.drop( this, event );
9798
+ }
9799
+
9800
+ //if a drop comes from outside (a sortable)
9801
+ if ( this.dropped ) {
9802
+ dropped = this.dropped;
9803
+ this.dropped = false;
9804
+ }
9805
+
9806
+ if ( ( this.options.revert === "invalid" && !dropped ) ||
9807
+ ( this.options.revert === "valid" && dropped ) ||
9808
+ this.options.revert === true || ( $.isFunction( this.options.revert ) &&
9809
+ this.options.revert.call( this.element, dropped ) )
9810
+ ) {
9811
+ $( this.helper ).animate(
9812
+ this.originalPosition,
9813
+ parseInt( this.options.revertDuration, 10 ),
9814
+ function() {
9815
+ if ( that._trigger( "stop", event ) !== false ) {
9816
+ that._clear();
9817
+ }
9818
+ }
9819
+ );
9820
+ } else {
9821
+ if ( this._trigger( "stop", event ) !== false ) {
9822
+ this._clear();
9823
+ }
9824
+ }
9825
+
9826
+ return false;
9827
+ },
9828
+
9829
+ _mouseUp: function( event ) {
9830
+ this._unblockFrames();
9831
+
9832
+ // If the ddmanager is used for droppables, inform the manager that dragging has stopped
9833
+ // (see #5003)
9834
+ if ( $.ui.ddmanager ) {
9835
+ $.ui.ddmanager.dragStop( this, event );
9836
+ }
9837
+
9838
+ // Only need to focus if the event occurred on the draggable itself, see #10527
9839
+ if ( this.handleElement.is( event.target ) ) {
9840
+
9841
+ // The interaction is over; whether or not the click resulted in a drag,
9842
+ // focus the element
9843
+ this.element.trigger( "focus" );
9844
+ }
9845
+
9846
+ return $.ui.mouse.prototype._mouseUp.call( this, event );
9847
+ },
9848
+
9849
+ cancel: function() {
9850
+
9851
+ if ( this.helper.is( ".ui-draggable-dragging" ) ) {
9852
+ this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
9853
+ } else {
9854
+ this._clear();
9855
+ }
9856
+
9857
+ return this;
9858
+
9859
+ },
9860
+
9861
+ _getHandle: function( event ) {
9862
+ return this.options.handle ?
9863
+ !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
9864
+ true;
9865
+ },
9866
+
9867
+ _setHandleClassName: function() {
9868
+ this.handleElement = this.options.handle ?
9869
+ this.element.find( this.options.handle ) : this.element;
9870
+ this._addClass( this.handleElement, "ui-draggable-handle" );
9871
+ },
9872
+
9873
+ _removeHandleClassName: function() {
9874
+ this._removeClass( this.handleElement, "ui-draggable-handle" );
9875
+ },
9876
+
9877
+ _createHelper: function( event ) {
9878
+
9879
+ var o = this.options,
9880
+ helperIsFunction = $.isFunction( o.helper ),
9881
+ helper = helperIsFunction ?
9882
+ $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
9883
+ ( o.helper === "clone" ?
9884
+ this.element.clone().removeAttr( "id" ) :
9885
+ this.element );
9886
+
9887
+ if ( !helper.parents( "body" ).length ) {
9888
+ helper.appendTo( ( o.appendTo === "parent" ?
9889
+ this.element[ 0 ].parentNode :
9890
+ o.appendTo ) );
9891
+ }
9892
+
9893
+ // Http://bugs.jqueryui.com/ticket/9446
9894
+ // a helper function can return the original element
9895
+ // which wouldn't have been set to relative in _create
9896
+ if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
9897
+ this._setPositionRelative();
9898
+ }
9899
+
9900
+ if ( helper[ 0 ] !== this.element[ 0 ] &&
9901
+ !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
9902
+ helper.css( "position", "absolute" );
9903
+ }
9904
+
9905
+ return helper;
9906
+
9907
+ },
9908
+
9909
+ _setPositionRelative: function() {
9910
+ if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
9911
+ this.element[ 0 ].style.position = "relative";
9912
+ }
9913
+ },
9914
+
9915
+ _adjustOffsetFromHelper: function( obj ) {
9916
+ if ( typeof obj === "string" ) {
9917
+ obj = obj.split( " " );
9918
+ }
9919
+ if ( $.isArray( obj ) ) {
9920
+ obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
9921
+ }
9922
+ if ( "left" in obj ) {
9923
+ this.offset.click.left = obj.left + this.margins.left;
9924
+ }
9925
+ if ( "right" in obj ) {
9926
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
9927
+ }
9928
+ if ( "top" in obj ) {
9929
+ this.offset.click.top = obj.top + this.margins.top;
9930
+ }
9931
+ if ( "bottom" in obj ) {
9932
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
9933
+ }
9934
+ },
9935
+
9936
+ _isRootNode: function( element ) {
9937
+ return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
9938
+ },
9939
+
9940
+ _getParentOffset: function() {
9941
+
9942
+ //Get the offsetParent and cache its position
9943
+ var po = this.offsetParent.offset(),
9944
+ document = this.document[ 0 ];
9945
+
9946
+ // This is a special case where we need to modify a offset calculated on start, since the
9947
+ // following happened:
9948
+ // 1. The position of the helper is absolute, so it's position is calculated based on the
9949
+ // next positioned parent
9950
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
9951
+ // the document, which means that the scroll is included in the initial calculation of the
9952
+ // offset of the parent, and never recalculated upon drag
9953
+ if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
9954
+ $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
9955
+ po.left += this.scrollParent.scrollLeft();
9956
+ po.top += this.scrollParent.scrollTop();
9957
+ }
9958
+
9959
+ if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
9960
+ po = { top: 0, left: 0 };
9961
+ }
9962
+
9963
+ return {
9964
+ top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
9965
+ left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
9966
+ };
9967
+
9968
+ },
9969
+
9970
+ _getRelativeOffset: function() {
9971
+ if ( this.cssPosition !== "relative" ) {
9972
+ return { top: 0, left: 0 };
9973
+ }
9974
+
9975
+ var p = this.element.position(),
9976
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
9977
+
9978
+ return {
9979
+ top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
9980
+ ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
9981
+ left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
9982
+ ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
9983
+ };
9984
+
9985
+ },
9986
+
9987
+ _cacheMargins: function() {
9988
+ this.margins = {
9989
+ left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
9990
+ top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
9991
+ right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
9992
+ bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
9993
+ };
9994
+ },
9995
+
9996
+ _cacheHelperProportions: function() {
9997
+ this.helperProportions = {
9998
+ width: this.helper.outerWidth(),
9999
+ height: this.helper.outerHeight()
10000
+ };
10001
+ },
10002
+
10003
+ _setContainment: function() {
10004
+
10005
+ var isUserScrollable, c, ce,
10006
+ o = this.options,
10007
+ document = this.document[ 0 ];
10008
+
10009
+ this.relativeContainer = null;
10010
+
10011
+ if ( !o.containment ) {
10012
+ this.containment = null;
10013
+ return;
10014
+ }
10015
+
10016
+ if ( o.containment === "window" ) {
10017
+ this.containment = [
10018
+ $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
10019
+ $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
10020
+ $( window ).scrollLeft() + $( window ).width() -
10021
+ this.helperProportions.width - this.margins.left,
10022
+ $( window ).scrollTop() +
10023
+ ( $( window ).height() || document.body.parentNode.scrollHeight ) -
10024
+ this.helperProportions.height - this.margins.top
10025
+ ];
10026
+ return;
10027
+ }
10028
+
10029
+ if ( o.containment === "document" ) {
10030
+ this.containment = [
10031
+ 0,
10032
+ 0,
10033
+ $( document ).width() - this.helperProportions.width - this.margins.left,
10034
+ ( $( document ).height() || document.body.parentNode.scrollHeight ) -
10035
+ this.helperProportions.height - this.margins.top
10036
+ ];
10037
+ return;
10038
+ }
10039
+
10040
+ if ( o.containment.constructor === Array ) {
10041
+ this.containment = o.containment;
10042
+ return;
10043
+ }
10044
+
10045
+ if ( o.containment === "parent" ) {
10046
+ o.containment = this.helper[ 0 ].parentNode;
10047
+ }
10048
+
10049
+ c = $( o.containment );
10050
+ ce = c[ 0 ];
10051
+
10052
+ if ( !ce ) {
10053
+ return;
10054
+ }
10055
+
10056
+ isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
10057
+
10058
+ this.containment = [
10059
+ ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
10060
+ ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
10061
+ ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
10062
+ ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
10063
+ ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
10064
+ ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
10065
+ ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
10066
+ this.helperProportions.width -
10067
+ this.margins.left -
10068
+ this.margins.right,
10069
+ ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
10070
+ ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
10071
+ ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
10072
+ this.helperProportions.height -
10073
+ this.margins.top -
10074
+ this.margins.bottom
10075
+ ];
10076
+ this.relativeContainer = c;
10077
+ },
10078
+
10079
+ _convertPositionTo: function( d, pos ) {
10080
+
10081
+ if ( !pos ) {
10082
+ pos = this.position;
10083
+ }
10084
+
10085
+ var mod = d === "absolute" ? 1 : -1,
10086
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10087
+
10088
+ return {
10089
+ top: (
10090
+
10091
+ // The absolute mouse position
10092
+ pos.top +
10093
+
10094
+ // Only for relative positioned nodes: Relative offset from element to offset parent
10095
+ this.offset.relative.top * mod +
10096
+
10097
+ // The offsetParent's offset without borders (offset + border)
10098
+ this.offset.parent.top * mod -
10099
+ ( ( this.cssPosition === "fixed" ?
10100
+ -this.offset.scroll.top :
10101
+ ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
10102
+ ),
10103
+ left: (
10104
+
10105
+ // The absolute mouse position
10106
+ pos.left +
10107
+
10108
+ // Only for relative positioned nodes: Relative offset from element to offset parent
10109
+ this.offset.relative.left * mod +
10110
+
10111
+ // The offsetParent's offset without borders (offset + border)
10112
+ this.offset.parent.left * mod -
10113
+ ( ( this.cssPosition === "fixed" ?
10114
+ -this.offset.scroll.left :
10115
+ ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
10116
+ )
10117
+ };
10118
+
10119
+ },
10120
+
10121
+ _generatePosition: function( event, constrainPosition ) {
10122
+
10123
+ var containment, co, top, left,
10124
+ o = this.options,
10125
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
10126
+ pageX = event.pageX,
10127
+ pageY = event.pageY;
10128
+
10129
+ // Cache the scroll
10130
+ if ( !scrollIsRootNode || !this.offset.scroll ) {
10131
+ this.offset.scroll = {
10132
+ top: this.scrollParent.scrollTop(),
10133
+ left: this.scrollParent.scrollLeft()
10134
+ };
10135
+ }
10136
+
10137
+ /*
10138
+ * - Position constraining -
10139
+ * Constrain the position to a mix of grid, containment.
10140
+ */
10141
+
10142
+ // If we are not dragging yet, we won't check for options
10143
+ if ( constrainPosition ) {
10144
+ if ( this.containment ) {
10145
+ if ( this.relativeContainer ) {
10146
+ co = this.relativeContainer.offset();
10147
+ containment = [
10148
+ this.containment[ 0 ] + co.left,
10149
+ this.containment[ 1 ] + co.top,
10150
+ this.containment[ 2 ] + co.left,
10151
+ this.containment[ 3 ] + co.top
10152
+ ];
10153
+ } else {
10154
+ containment = this.containment;
10155
+ }
10156
+
10157
+ if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
10158
+ pageX = containment[ 0 ] + this.offset.click.left;
10159
+ }
10160
+ if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
10161
+ pageY = containment[ 1 ] + this.offset.click.top;
10162
+ }
10163
+ if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
10164
+ pageX = containment[ 2 ] + this.offset.click.left;
10165
+ }
10166
+ if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
10167
+ pageY = containment[ 3 ] + this.offset.click.top;
10168
+ }
10169
+ }
10170
+
10171
+ if ( o.grid ) {
10172
+
10173
+ //Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10174
+ // argument errors in IE (see ticket #6950)
10175
+ top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
10176
+ this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
10177
+ pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
10178
+ top - this.offset.click.top > containment[ 3 ] ) ?
10179
+ top :
10180
+ ( ( top - this.offset.click.top >= containment[ 1 ] ) ?
10181
+ top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
10182
+
10183
+ left = o.grid[ 0 ] ? this.originalPageX +
10184
+ Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
10185
+ this.originalPageX;
10186
+ pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
10187
+ left - this.offset.click.left > containment[ 2 ] ) ?
10188
+ left :
10189
+ ( ( left - this.offset.click.left >= containment[ 0 ] ) ?
10190
+ left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
10191
+ }
10192
+
10193
+ if ( o.axis === "y" ) {
10194
+ pageX = this.originalPageX;
10195
+ }
10196
+
10197
+ if ( o.axis === "x" ) {
10198
+ pageY = this.originalPageY;
10199
+ }
10200
+ }
10201
+
10202
+ return {
10203
+ top: (
10204
+
10205
+ // The absolute mouse position
10206
+ pageY -
10207
+
10208
+ // Click offset (relative to the element)
10209
+ this.offset.click.top -
10210
+
10211
+ // Only for relative positioned nodes: Relative offset from element to offset parent
10212
+ this.offset.relative.top -
10213
+
10214
+ // The offsetParent's offset without borders (offset + border)
10215
+ this.offset.parent.top +
10216
+ ( this.cssPosition === "fixed" ?
10217
+ -this.offset.scroll.top :
10218
+ ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
10219
+ ),
10220
+ left: (
10221
+
10222
+ // The absolute mouse position
10223
+ pageX -
10224
+
10225
+ // Click offset (relative to the element)
10226
+ this.offset.click.left -
10227
+
10228
+ // Only for relative positioned nodes: Relative offset from element to offset parent
10229
+ this.offset.relative.left -
10230
+
10231
+ // The offsetParent's offset without borders (offset + border)
10232
+ this.offset.parent.left +
10233
+ ( this.cssPosition === "fixed" ?
10234
+ -this.offset.scroll.left :
10235
+ ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
10236
+ )
10237
+ };
10238
+
10239
+ },
10240
+
10241
+ _clear: function() {
10242
+ this._removeClass( this.helper, "ui-draggable-dragging" );
10243
+ if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
10244
+ this.helper.remove();
10245
+ }
10246
+ this.helper = null;
10247
+ this.cancelHelperRemoval = false;
10248
+ if ( this.destroyOnClear ) {
10249
+ this.destroy();
10250
+ }
10251
+ },
10252
+
10253
+ // From now on bulk stuff - mainly helpers
10254
+
10255
+ _trigger: function( type, event, ui ) {
10256
+ ui = ui || this._uiHash();
10257
+ $.ui.plugin.call( this, type, [ event, ui, this ], true );
10258
+
10259
+ // Absolute position and offset (see #6884 ) have to be recalculated after plugins
10260
+ if ( /^(drag|start|stop)/.test( type ) ) {
10261
+ this.positionAbs = this._convertPositionTo( "absolute" );
10262
+ ui.offset = this.positionAbs;
10263
+ }
10264
+ return $.Widget.prototype._trigger.call( this, type, event, ui );
10265
+ },
10266
+
10267
+ plugins: {},
10268
+
10269
+ _uiHash: function() {
10270
+ return {
10271
+ helper: this.helper,
10272
+ position: this.position,
10273
+ originalPosition: this.originalPosition,
10274
+ offset: this.positionAbs
10275
+ };
10276
+ }
10277
+
10278
+ } );
10279
+
10280
+ $.ui.plugin.add( "draggable", "connectToSortable", {
10281
+ start: function( event, ui, draggable ) {
10282
+ var uiSortable = $.extend( {}, ui, {
10283
+ item: draggable.element
10284
+ } );
10285
+
10286
+ draggable.sortables = [];
10287
+ $( draggable.options.connectToSortable ).each( function() {
10288
+ var sortable = $( this ).sortable( "instance" );
10289
+
10290
+ if ( sortable && !sortable.options.disabled ) {
10291
+ draggable.sortables.push( sortable );
10292
+
10293
+ // RefreshPositions is called at drag start to refresh the containerCache
10294
+ // which is used in drag. This ensures it's initialized and synchronized
10295
+ // with any changes that might have happened on the page since initialization.
10296
+ sortable.refreshPositions();
10297
+ sortable._trigger( "activate", event, uiSortable );
10298
+ }
10299
+ } );
10300
+ },
10301
+ stop: function( event, ui, draggable ) {
10302
+ var uiSortable = $.extend( {}, ui, {
10303
+ item: draggable.element
10304
+ } );
10305
+
10306
+ draggable.cancelHelperRemoval = false;
10307
+
10308
+ $.each( draggable.sortables, function() {
10309
+ var sortable = this;
10310
+
10311
+ if ( sortable.isOver ) {
10312
+ sortable.isOver = 0;
10313
+
10314
+ // Allow this sortable to handle removing the helper
10315
+ draggable.cancelHelperRemoval = true;
10316
+ sortable.cancelHelperRemoval = false;
10317
+
10318
+ // Use _storedCSS To restore properties in the sortable,
10319
+ // as this also handles revert (#9675) since the draggable
10320
+ // may have modified them in unexpected ways (#8809)
10321
+ sortable._storedCSS = {
10322
+ position: sortable.placeholder.css( "position" ),
10323
+ top: sortable.placeholder.css( "top" ),
10324
+ left: sortable.placeholder.css( "left" )
10325
+ };
10326
+
10327
+ sortable._mouseStop( event );
10328
+
10329
+ // Once drag has ended, the sortable should return to using
10330
+ // its original helper, not the shared helper from draggable
10331
+ sortable.options.helper = sortable.options._helper;
10332
+ } else {
10333
+
10334
+ // Prevent this Sortable from removing the helper.
10335
+ // However, don't set the draggable to remove the helper
10336
+ // either as another connected Sortable may yet handle the removal.
10337
+ sortable.cancelHelperRemoval = true;
10338
+
10339
+ sortable._trigger( "deactivate", event, uiSortable );
10340
+ }
10341
+ } );
10342
+ },
10343
+ drag: function( event, ui, draggable ) {
10344
+ $.each( draggable.sortables, function() {
10345
+ var innermostIntersecting = false,
10346
+ sortable = this;
10347
+
10348
+ // Copy over variables that sortable's _intersectsWith uses
10349
+ sortable.positionAbs = draggable.positionAbs;
10350
+ sortable.helperProportions = draggable.helperProportions;
10351
+ sortable.offset.click = draggable.offset.click;
10352
+
10353
+ if ( sortable._intersectsWith( sortable.containerCache ) ) {
10354
+ innermostIntersecting = true;
10355
+
10356
+ $.each( draggable.sortables, function() {
10357
+
10358
+ // Copy over variables that sortable's _intersectsWith uses
10359
+ this.positionAbs = draggable.positionAbs;
10360
+ this.helperProportions = draggable.helperProportions;
10361
+ this.offset.click = draggable.offset.click;
10362
+
10363
+ if ( this !== sortable &&
10364
+ this._intersectsWith( this.containerCache ) &&
10365
+ $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
10366
+ innermostIntersecting = false;
10367
+ }
10368
+
10369
+ return innermostIntersecting;
10370
+ } );
10371
+ }
10372
+
10373
+ if ( innermostIntersecting ) {
10374
+
10375
+ // If it intersects, we use a little isOver variable and set it once,
10376
+ // so that the move-in stuff gets fired only once.
10377
+ if ( !sortable.isOver ) {
10378
+ sortable.isOver = 1;
10379
+
10380
+ // Store draggable's parent in case we need to reappend to it later.
10381
+ draggable._parent = ui.helper.parent();
10382
+
10383
+ sortable.currentItem = ui.helper
10384
+ .appendTo( sortable.element )
10385
+ .data( "ui-sortable-item", true );
10386
+
10387
+ // Store helper option to later restore it
10388
+ sortable.options._helper = sortable.options.helper;
10389
+
10390
+ sortable.options.helper = function() {
10391
+ return ui.helper[ 0 ];
10392
+ };
10393
+
10394
+ // Fire the start events of the sortable with our passed browser event,
10395
+ // and our own helper (so it doesn't create a new one)
10396
+ event.target = sortable.currentItem[ 0 ];
10397
+ sortable._mouseCapture( event, true );
10398
+ sortable._mouseStart( event, true, true );
10399
+
10400
+ // Because the browser event is way off the new appended portlet,
10401
+ // modify necessary variables to reflect the changes
10402
+ sortable.offset.click.top = draggable.offset.click.top;
10403
+ sortable.offset.click.left = draggable.offset.click.left;
10404
+ sortable.offset.parent.left -= draggable.offset.parent.left -
10405
+ sortable.offset.parent.left;
10406
+ sortable.offset.parent.top -= draggable.offset.parent.top -
10407
+ sortable.offset.parent.top;
10408
+
10409
+ draggable._trigger( "toSortable", event );
10410
+
10411
+ // Inform draggable that the helper is in a valid drop zone,
10412
+ // used solely in the revert option to handle "valid/invalid".
10413
+ draggable.dropped = sortable.element;
10414
+
10415
+ // Need to refreshPositions of all sortables in the case that
10416
+ // adding to one sortable changes the location of the other sortables (#9675)
10417
+ $.each( draggable.sortables, function() {
10418
+ this.refreshPositions();
10419
+ } );
10420
+
10421
+ // Hack so receive/update callbacks work (mostly)
10422
+ draggable.currentItem = draggable.element;
10423
+ sortable.fromOutside = draggable;
10424
+ }
10425
+
10426
+ if ( sortable.currentItem ) {
10427
+ sortable._mouseDrag( event );
10428
+
10429
+ // Copy the sortable's position because the draggable's can potentially reflect
10430
+ // a relative position, while sortable is always absolute, which the dragged
10431
+ // element has now become. (#8809)
10432
+ ui.position = sortable.position;
10433
+ }
10434
+ } else {
10435
+
10436
+ // If it doesn't intersect with the sortable, and it intersected before,
10437
+ // we fake the drag stop of the sortable, but make sure it doesn't remove
10438
+ // the helper by using cancelHelperRemoval.
10439
+ if ( sortable.isOver ) {
10440
+
10441
+ sortable.isOver = 0;
10442
+ sortable.cancelHelperRemoval = true;
10443
+
10444
+ // Calling sortable's mouseStop would trigger a revert,
10445
+ // so revert must be temporarily false until after mouseStop is called.
10446
+ sortable.options._revert = sortable.options.revert;
10447
+ sortable.options.revert = false;
10448
+
10449
+ sortable._trigger( "out", event, sortable._uiHash( sortable ) );
10450
+ sortable._mouseStop( event, true );
10451
+
10452
+ // Restore sortable behaviors that were modfied
10453
+ // when the draggable entered the sortable area (#9481)
10454
+ sortable.options.revert = sortable.options._revert;
10455
+ sortable.options.helper = sortable.options._helper;
10456
+
10457
+ if ( sortable.placeholder ) {
10458
+ sortable.placeholder.remove();
10459
+ }
10460
+
10461
+ // Restore and recalculate the draggable's offset considering the sortable
10462
+ // may have modified them in unexpected ways. (#8809, #10669)
10463
+ ui.helper.appendTo( draggable._parent );
10464
+ draggable._refreshOffsets( event );
10465
+ ui.position = draggable._generatePosition( event, true );
10466
+
10467
+ draggable._trigger( "fromSortable", event );
10468
+
10469
+ // Inform draggable that the helper is no longer in a valid drop zone
10470
+ draggable.dropped = false;
10471
+
10472
+ // Need to refreshPositions of all sortables just in case removing
10473
+ // from one sortable changes the location of other sortables (#9675)
10474
+ $.each( draggable.sortables, function() {
10475
+ this.refreshPositions();
10476
+ } );
10477
+ }
10478
+ }
10479
+ } );
10480
+ }
10481
+ } );
10482
+
10483
+ $.ui.plugin.add( "draggable", "cursor", {
10484
+ start: function( event, ui, instance ) {
10485
+ var t = $( "body" ),
10486
+ o = instance.options;
10487
+
10488
+ if ( t.css( "cursor" ) ) {
10489
+ o._cursor = t.css( "cursor" );
10490
+ }
10491
+ t.css( "cursor", o.cursor );
10492
+ },
10493
+ stop: function( event, ui, instance ) {
10494
+ var o = instance.options;
10495
+ if ( o._cursor ) {
10496
+ $( "body" ).css( "cursor", o._cursor );
10497
+ }
10498
+ }
10499
+ } );
10500
+
10501
+ $.ui.plugin.add( "draggable", "opacity", {
10502
+ start: function( event, ui, instance ) {
10503
+ var t = $( ui.helper ),
10504
+ o = instance.options;
10505
+ if ( t.css( "opacity" ) ) {
10506
+ o._opacity = t.css( "opacity" );
10507
+ }
10508
+ t.css( "opacity", o.opacity );
10509
+ },
10510
+ stop: function( event, ui, instance ) {
10511
+ var o = instance.options;
10512
+ if ( o._opacity ) {
10513
+ $( ui.helper ).css( "opacity", o._opacity );
10514
+ }
10515
+ }
10516
+ } );
10517
+
10518
+ $.ui.plugin.add( "draggable", "scroll", {
10519
+ start: function( event, ui, i ) {
10520
+ if ( !i.scrollParentNotHidden ) {
10521
+ i.scrollParentNotHidden = i.helper.scrollParent( false );
10522
+ }
10523
+
10524
+ if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
10525
+ i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
10526
+ i.overflowOffset = i.scrollParentNotHidden.offset();
10527
+ }
10528
+ },
10529
+ drag: function( event, ui, i ) {
10530
+
10531
+ var o = i.options,
10532
+ scrolled = false,
10533
+ scrollParent = i.scrollParentNotHidden[ 0 ],
10534
+ document = i.document[ 0 ];
10535
+
10536
+ if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
10537
+ if ( !o.axis || o.axis !== "x" ) {
10538
+ if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
10539
+ o.scrollSensitivity ) {
10540
+ scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10541
+ } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
10542
+ scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10543
+ }
10544
+ }
10545
+
10546
+ if ( !o.axis || o.axis !== "y" ) {
10547
+ if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
10548
+ o.scrollSensitivity ) {
10549
+ scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10550
+ } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
10551
+ scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10552
+ }
10553
+ }
10554
+
10555
+ } else {
10556
+
10557
+ if ( !o.axis || o.axis !== "x" ) {
10558
+ if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
10559
+ scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
10560
+ } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
10561
+ o.scrollSensitivity ) {
10562
+ scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
10563
+ }
10564
+ }
10565
+
10566
+ if ( !o.axis || o.axis !== "y" ) {
10567
+ if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
10568
+ scrolled = $( document ).scrollLeft(
10569
+ $( document ).scrollLeft() - o.scrollSpeed
10570
+ );
10571
+ } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
10572
+ o.scrollSensitivity ) {
10573
+ scrolled = $( document ).scrollLeft(
10574
+ $( document ).scrollLeft() + o.scrollSpeed
10575
+ );
10576
+ }
10577
+ }
10578
+
10579
+ }
10580
+
10581
+ if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
10582
+ $.ui.ddmanager.prepareOffsets( i, event );
10583
+ }
10584
+
10585
+ }
10586
+ } );
10587
+
10588
+ $.ui.plugin.add( "draggable", "snap", {
10589
+ start: function( event, ui, i ) {
10590
+
10591
+ var o = i.options;
10592
+
10593
+ i.snapElements = [];
10594
+
10595
+ $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
10596
+ .each( function() {
10597
+ var $t = $( this ),
10598
+ $o = $t.offset();
10599
+ if ( this !== i.element[ 0 ] ) {
10600
+ i.snapElements.push( {
10601
+ item: this,
10602
+ width: $t.outerWidth(), height: $t.outerHeight(),
10603
+ top: $o.top, left: $o.left
10604
+ } );
10605
+ }
10606
+ } );
10607
+
10608
+ },
10609
+ drag: function( event, ui, inst ) {
10610
+
10611
+ var ts, bs, ls, rs, l, r, t, b, i, first,
10612
+ o = inst.options,
10613
+ d = o.snapTolerance,
10614
+ x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10615
+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10616
+
10617
+ for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
10618
+
10619
+ l = inst.snapElements[ i ].left - inst.margins.left;
10620
+ r = l + inst.snapElements[ i ].width;
10621
+ t = inst.snapElements[ i ].top - inst.margins.top;
10622
+ b = t + inst.snapElements[ i ].height;
10623
+
10624
+ if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10625
+ !$.contains( inst.snapElements[ i ].item.ownerDocument,
10626
+ inst.snapElements[ i ].item ) ) {
10627
+ if ( inst.snapElements[ i ].snapping ) {
10628
+ ( inst.options.snap.release &&
10629
+ inst.options.snap.release.call(
10630
+ inst.element,
10631
+ event,
10632
+ $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
10633
+ ) );
10634
+ }
10635
+ inst.snapElements[ i ].snapping = false;
10636
+ continue;
10637
+ }
10638
+
10639
+ if ( o.snapMode !== "inner" ) {
10640
+ ts = Math.abs( t - y2 ) <= d;
10641
+ bs = Math.abs( b - y1 ) <= d;
10642
+ ls = Math.abs( l - x2 ) <= d;
10643
+ rs = Math.abs( r - x1 ) <= d;
10644
+ if ( ts ) {
10645
+ ui.position.top = inst._convertPositionTo( "relative", {
10646
+ top: t - inst.helperProportions.height,
10647
+ left: 0
10648
+ } ).top;
10649
+ }
10650
+ if ( bs ) {
10651
+ ui.position.top = inst._convertPositionTo( "relative", {
10652
+ top: b,
10653
+ left: 0
10654
+ } ).top;
10655
+ }
10656
+ if ( ls ) {
10657
+ ui.position.left = inst._convertPositionTo( "relative", {
10658
+ top: 0,
10659
+ left: l - inst.helperProportions.width
10660
+ } ).left;
10661
+ }
10662
+ if ( rs ) {
10663
+ ui.position.left = inst._convertPositionTo( "relative", {
10664
+ top: 0,
10665
+ left: r
10666
+ } ).left;
10667
+ }
10668
+ }
10669
+
10670
+ first = ( ts || bs || ls || rs );
10671
+
10672
+ if ( o.snapMode !== "outer" ) {
10673
+ ts = Math.abs( t - y1 ) <= d;
10674
+ bs = Math.abs( b - y2 ) <= d;
10675
+ ls = Math.abs( l - x1 ) <= d;
10676
+ rs = Math.abs( r - x2 ) <= d;
10677
+ if ( ts ) {
10678
+ ui.position.top = inst._convertPositionTo( "relative", {
10679
+ top: t,
10680
+ left: 0
10681
+ } ).top;
10682
+ }
10683
+ if ( bs ) {
10684
+ ui.position.top = inst._convertPositionTo( "relative", {
10685
+ top: b - inst.helperProportions.height,
10686
+ left: 0
10687
+ } ).top;
10688
+ }
10689
+ if ( ls ) {
10690
+ ui.position.left = inst._convertPositionTo( "relative", {
10691
+ top: 0,
10692
+ left: l
10693
+ } ).left;
10694
+ }
10695
+ if ( rs ) {
10696
+ ui.position.left = inst._convertPositionTo( "relative", {
10697
+ top: 0,
10698
+ left: r - inst.helperProportions.width
10699
+ } ).left;
10700
+ }
10701
+ }
10702
+
10703
+ if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
10704
+ ( inst.options.snap.snap &&
10705
+ inst.options.snap.snap.call(
10706
+ inst.element,
10707
+ event,
10708
+ $.extend( inst._uiHash(), {
10709
+ snapItem: inst.snapElements[ i ].item
10710
+ } ) ) );
10711
+ }
10712
+ inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
10713
+
10714
+ }
10715
+
10716
+ }
10717
+ } );
10718
+
10719
+ $.ui.plugin.add( "draggable", "stack", {
10720
+ start: function( event, ui, instance ) {
10721
+ var min,
10722
+ o = instance.options,
10723
+ group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
10724
+ return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
10725
+ ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
10726
+ } );
10727
+
10728
+ if ( !group.length ) { return; }
10729
+
10730
+ min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
10731
+ $( group ).each( function( i ) {
10732
+ $( this ).css( "zIndex", min + i );
10733
+ } );
10734
+ this.css( "zIndex", ( min + group.length ) );
10735
+ }
10736
+ } );
10737
+
10738
+ $.ui.plugin.add( "draggable", "zIndex", {
10739
+ start: function( event, ui, instance ) {
10740
+ var t = $( ui.helper ),
10741
+ o = instance.options;
10742
+
10743
+ if ( t.css( "zIndex" ) ) {
10744
+ o._zIndex = t.css( "zIndex" );
10745
+ }
10746
+ t.css( "zIndex", o.zIndex );
10747
+ },
10748
+ stop: function( event, ui, instance ) {
10749
+ var o = instance.options;
10750
+
10751
+ if ( o._zIndex ) {
10752
+ $( ui.helper ).css( "zIndex", o._zIndex );
10753
+ }
10754
+ }
10755
+ } );
10756
+
10757
+ var widgetsDraggable = $.ui.draggable;
10758
+
10759
+
10760
+ /*!
10761
+ * jQuery UI Resizable 1.12.1
10762
+ * http://jqueryui.com
10763
+ *
10764
+ * Copyright jQuery Foundation and other contributors
10765
+ * Released under the MIT license.
10766
+ * http://jquery.org/license
10767
+ */
10768
+
10769
+ //>>label: Resizable
10770
+ //>>group: Interactions
10771
+ //>>description: Enables resize functionality for any element.
10772
+ //>>docs: http://api.jqueryui.com/resizable/
10773
+ //>>demos: http://jqueryui.com/resizable/
10774
+ //>>css.structure: ../../themes/base/core.css
10775
+ //>>css.structure: ../../themes/base/resizable.css
10776
+ //>>css.theme: ../../themes/base/theme.css
10777
+
10778
+
10779
+
10780
+ $.widget( "ui.resizable", $.ui.mouse, {
10781
+ version: "1.12.1",
10782
+ widgetEventPrefix: "resize",
10783
+ options: {
10784
+ alsoResize: false,
10785
+ animate: false,
10786
+ animateDuration: "slow",
10787
+ animateEasing: "swing",
10788
+ aspectRatio: false,
10789
+ autoHide: false,
10790
+ classes: {
10791
+ "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
10792
+ },
10793
+ containment: false,
10794
+ ghost: false,
10795
+ grid: false,
10796
+ handles: "e,s,se",
10797
+ helper: false,
10798
+ maxHeight: null,
10799
+ maxWidth: null,
10800
+ minHeight: 10,
10801
+ minWidth: 10,
10802
+
10803
+ // See #7960
10804
+ zIndex: 90,
10805
+
10806
+ // Callbacks
10807
+ resize: null,
10808
+ start: null,
10809
+ stop: null
10810
+ },
10811
+
10812
+ _num: function( value ) {
10813
+ return parseFloat( value ) || 0;
10814
+ },
10815
+
10816
+ _isNumber: function( value ) {
10817
+ return !isNaN( parseFloat( value ) );
10818
+ },
10819
+
10820
+ _hasScroll: function( el, a ) {
10821
+
10822
+ if ( $( el ).css( "overflow" ) === "hidden" ) {
10823
+ return false;
10824
+ }
10825
+
10826
+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
10827
+ has = false;
10828
+
10829
+ if ( el[ scroll ] > 0 ) {
10830
+ return true;
10831
+ }
10832
+
10833
+ // TODO: determine which cases actually cause this to happen
10834
+ // if the element doesn't have the scroll set, see if it's possible to
10835
+ // set the scroll
10836
+ el[ scroll ] = 1;
10837
+ has = ( el[ scroll ] > 0 );
10838
+ el[ scroll ] = 0;
10839
+ return has;
10840
+ },
10841
+
10842
+ _create: function() {
10843
+
10844
+ var margins,
10845
+ o = this.options,
10846
+ that = this;
10847
+ this._addClass( "ui-resizable" );
10848
+
10849
+ $.extend( this, {
10850
+ _aspectRatio: !!( o.aspectRatio ),
10851
+ aspectRatio: o.aspectRatio,
10852
+ originalElement: this.element,
10853
+ _proportionallyResizeElements: [],
10854
+ _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
10855
+ } );
10856
+
10857
+ // Wrap the element if it cannot hold child nodes
10858
+ if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
10859
+
10860
+ this.element.wrap(
10861
+ $( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
10862
+ position: this.element.css( "position" ),
10863
+ width: this.element.outerWidth(),
10864
+ height: this.element.outerHeight(),
10865
+ top: this.element.css( "top" ),
10866
+ left: this.element.css( "left" )
10867
+ } )
10868
+ );
10869
+
10870
+ this.element = this.element.parent().data(
10871
+ "ui-resizable", this.element.resizable( "instance" )
10872
+ );
10873
+
10874
+ this.elementIsWrapper = true;
10875
+
10876
+ margins = {
10877
+ marginTop: this.originalElement.css( "marginTop" ),
10878
+ marginRight: this.originalElement.css( "marginRight" ),
10879
+ marginBottom: this.originalElement.css( "marginBottom" ),
10880
+ marginLeft: this.originalElement.css( "marginLeft" )
10881
+ };
10882
+
10883
+ this.element.css( margins );
10884
+ this.originalElement.css( "margin", 0 );
10885
+
10886
+ // support: Safari
10887
+ // Prevent Safari textarea resize
10888
+ this.originalResizeStyle = this.originalElement.css( "resize" );
10889
+ this.originalElement.css( "resize", "none" );
10890
+
10891
+ this._proportionallyResizeElements.push( this.originalElement.css( {
10892
+ position: "static",
10893
+ zoom: 1,
10894
+ display: "block"
10895
+ } ) );
10896
+
10897
+ // Support: IE9
10898
+ // avoid IE jump (hard set the margin)
10899
+ this.originalElement.css( margins );
10900
+
10901
+ this._proportionallyResize();
10902
+ }
10903
+
10904
+ this._setupHandles();
10905
+
10906
+ if ( o.autoHide ) {
10907
+ $( this.element )
10908
+ .on( "mouseenter", function() {
10909
+ if ( o.disabled ) {
10910
+ return;
10911
+ }
10912
+ that._removeClass( "ui-resizable-autohide" );
10913
+ that._handles.show();
10914
+ } )
10915
+ .on( "mouseleave", function() {
10916
+ if ( o.disabled ) {
10917
+ return;
10918
+ }
10919
+ if ( !that.resizing ) {
10920
+ that._addClass( "ui-resizable-autohide" );
10921
+ that._handles.hide();
10922
+ }
10923
+ } );
10924
+ }
10925
+
10926
+ this._mouseInit();
10927
+ },
10928
+
10929
+ _destroy: function() {
10930
+
10931
+ this._mouseDestroy();
10932
+
10933
+ var wrapper,
10934
+ _destroy = function( exp ) {
10935
+ $( exp )
10936
+ .removeData( "resizable" )
10937
+ .removeData( "ui-resizable" )
10938
+ .off( ".resizable" )
10939
+ .find( ".ui-resizable-handle" )
10940
+ .remove();
10941
+ };
10942
+
10943
+ // TODO: Unwrap at same DOM position
10944
+ if ( this.elementIsWrapper ) {
10945
+ _destroy( this.element );
10946
+ wrapper = this.element;
10947
+ this.originalElement.css( {
10948
+ position: wrapper.css( "position" ),
10949
+ width: wrapper.outerWidth(),
10950
+ height: wrapper.outerHeight(),
10951
+ top: wrapper.css( "top" ),
10952
+ left: wrapper.css( "left" )
10953
+ } ).insertAfter( wrapper );
10954
+ wrapper.remove();
10955
+ }
10956
+
10957
+ this.originalElement.css( "resize", this.originalResizeStyle );
10958
+ _destroy( this.originalElement );
10959
+
10960
+ return this;
10961
+ },
10962
+
10963
+ _setOption: function( key, value ) {
10964
+ this._super( key, value );
10965
+
10966
+ switch ( key ) {
10967
+ case "handles":
10968
+ this._removeHandles();
10969
+ this._setupHandles();
10970
+ break;
10971
+ default:
10972
+ break;
10973
+ }
10974
+ },
10975
+
10976
+ _setupHandles: function() {
10977
+ var o = this.options, handle, i, n, hname, axis, that = this;
10978
+ this.handles = o.handles ||
10979
+ ( !$( ".ui-resizable-handle", this.element ).length ?
10980
+ "e,s,se" : {
10981
+ n: ".ui-resizable-n",
10982
+ e: ".ui-resizable-e",
10983
+ s: ".ui-resizable-s",
10984
+ w: ".ui-resizable-w",
10985
+ se: ".ui-resizable-se",
10986
+ sw: ".ui-resizable-sw",
10987
+ ne: ".ui-resizable-ne",
10988
+ nw: ".ui-resizable-nw"
10989
+ } );
10990
+
10991
+ this._handles = $();
10992
+ if ( this.handles.constructor === String ) {
10993
+
10994
+ if ( this.handles === "all" ) {
10995
+ this.handles = "n,e,s,w,se,sw,ne,nw";
10996
+ }
10997
+
10998
+ n = this.handles.split( "," );
10999
+ this.handles = {};
11000
+
11001
+ for ( i = 0; i < n.length; i++ ) {
11002
+
11003
+ handle = $.trim( n[ i ] );
11004
+ hname = "ui-resizable-" + handle;
11005
+ axis = $( "<div>" );
11006
+ this._addClass( axis, "ui-resizable-handle " + hname );
11007
+
11008
+ axis.css( { zIndex: o.zIndex } );
11009
+
11010
+ this.handles[ handle ] = ".ui-resizable-" + handle;
11011
+ this.element.append( axis );
11012
+ }
11013
+
11014
+ }
11015
+
11016
+ this._renderAxis = function( target ) {
11017
+
11018
+ var i, axis, padPos, padWrapper;
11019
+
11020
+ target = target || this.element;
11021
+
11022
+ for ( i in this.handles ) {
11023
+
11024
+ if ( this.handles[ i ].constructor === String ) {
11025
+ this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
11026
+ } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
11027
+ this.handles[ i ] = $( this.handles[ i ] );
11028
+ this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
11029
+ }
11030
+
11031
+ if ( this.elementIsWrapper &&
11032
+ this.originalElement[ 0 ]
11033
+ .nodeName
11034
+ .match( /^(textarea|input|select|button)$/i ) ) {
11035
+ axis = $( this.handles[ i ], this.element );
11036
+
11037
+ padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
11038
+ axis.outerHeight() :
11039
+ axis.outerWidth();
11040
+
11041
+ padPos = [ "padding",
11042
+ /ne|nw|n/.test( i ) ? "Top" :
11043
+ /se|sw|s/.test( i ) ? "Bottom" :
11044
+ /^e$/.test( i ) ? "Right" : "Left" ].join( "" );
11045
+
11046
+ target.css( padPos, padWrapper );
11047
+
11048
+ this._proportionallyResize();
11049
+ }
11050
+
11051
+ this._handles = this._handles.add( this.handles[ i ] );
11052
+ }
11053
+ };
11054
+
11055
+ // TODO: make renderAxis a prototype function
11056
+ this._renderAxis( this.element );
11057
+
11058
+ this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
11059
+ this._handles.disableSelection();
11060
+
11061
+ this._handles.on( "mouseover", function() {
11062
+ if ( !that.resizing ) {
11063
+ if ( this.className ) {
11064
+ axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
11065
+ }
11066
+ that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
11067
+ }
11068
+ } );
11069
+
11070
+ if ( o.autoHide ) {
11071
+ this._handles.hide();
11072
+ this._addClass( "ui-resizable-autohide" );
11073
+ }
11074
+ },
11075
+
11076
+ _removeHandles: function() {
11077
+ this._handles.remove();
11078
+ },
11079
+
11080
+ _mouseCapture: function( event ) {
11081
+ var i, handle,
11082
+ capture = false;
11083
+
11084
+ for ( i in this.handles ) {
11085
+ handle = $( this.handles[ i ] )[ 0 ];
11086
+ if ( handle === event.target || $.contains( handle, event.target ) ) {
11087
+ capture = true;
11088
+ }
11089
+ }
11090
+
11091
+ return !this.options.disabled && capture;
11092
+ },
11093
+
11094
+ _mouseStart: function( event ) {
11095
+
11096
+ var curleft, curtop, cursor,
11097
+ o = this.options,
11098
+ el = this.element;
11099
+
11100
+ this.resizing = true;
11101
+
11102
+ this._renderProxy();
11103
+
11104
+ curleft = this._num( this.helper.css( "left" ) );
11105
+ curtop = this._num( this.helper.css( "top" ) );
11106
+
11107
+ if ( o.containment ) {
11108
+ curleft += $( o.containment ).scrollLeft() || 0;
11109
+ curtop += $( o.containment ).scrollTop() || 0;
11110
+ }
11111
+
11112
+ this.offset = this.helper.offset();
11113
+ this.position = { left: curleft, top: curtop };
11114
+
11115
+ this.size = this._helper ? {
11116
+ width: this.helper.width(),
11117
+ height: this.helper.height()
11118
+ } : {
11119
+ width: el.width(),
11120
+ height: el.height()
11121
+ };
11122
+
11123
+ this.originalSize = this._helper ? {
11124
+ width: el.outerWidth(),
11125
+ height: el.outerHeight()
11126
+ } : {
11127
+ width: el.width(),
11128
+ height: el.height()
11129
+ };
11130
+
11131
+ this.sizeDiff = {
11132
+ width: el.outerWidth() - el.width(),
11133
+ height: el.outerHeight() - el.height()
11134
+ };
11135
+
11136
+ this.originalPosition = { left: curleft, top: curtop };
11137
+ this.originalMousePosition = { left: event.pageX, top: event.pageY };
11138
+
11139
+ this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
11140
+ o.aspectRatio :
11141
+ ( ( this.originalSize.width / this.originalSize.height ) || 1 );
11142
+
11143
+ cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
11144
+ $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
11145
+
11146
+ this._addClass( "ui-resizable-resizing" );
11147
+ this._propagate( "start", event );
11148
+ return true;
11149
+ },
11150
+
11151
+ _mouseDrag: function( event ) {
11152
+
11153
+ var data, props,
11154
+ smp = this.originalMousePosition,
11155
+ a = this.axis,
11156
+ dx = ( event.pageX - smp.left ) || 0,
11157
+ dy = ( event.pageY - smp.top ) || 0,
11158
+ trigger = this._change[ a ];
11159
+
11160
+ this._updatePrevProperties();
11161
+
11162
+ if ( !trigger ) {
11163
+ return false;
11164
+ }
11165
+
11166
+ data = trigger.apply( this, [ event, dx, dy ] );
11167
+
11168
+ this._updateVirtualBoundaries( event.shiftKey );
11169
+ if ( this._aspectRatio || event.shiftKey ) {
11170
+ data = this._updateRatio( data, event );
11171
+ }
11172
+
11173
+ data = this._respectSize( data, event );
11174
+
11175
+ this._updateCache( data );
11176
+
11177
+ this._propagate( "resize", event );
11178
+
11179
+ props = this._applyChanges();
11180
+
11181
+ if ( !this._helper && this._proportionallyResizeElements.length ) {
11182
+ this._proportionallyResize();
11183
+ }
11184
+
11185
+ if ( !$.isEmptyObject( props ) ) {
11186
+ this._updatePrevProperties();
11187
+ this._trigger( "resize", event, this.ui() );
11188
+ this._applyChanges();
11189
+ }
11190
+
11191
+ return false;
11192
+ },
11193
+
11194
+ _mouseStop: function( event ) {
11195
+
11196
+ this.resizing = false;
11197
+ var pr, ista, soffseth, soffsetw, s, left, top,
11198
+ o = this.options, that = this;
11199
+
11200
+ if ( this._helper ) {
11201
+
11202
+ pr = this._proportionallyResizeElements;
11203
+ ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
11204
+ soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
11205
+ soffsetw = ista ? 0 : that.sizeDiff.width;
11206
+
11207
+ s = {
11208
+ width: ( that.helper.width() - soffsetw ),
11209
+ height: ( that.helper.height() - soffseth )
11210
+ };
11211
+ left = ( parseFloat( that.element.css( "left" ) ) +
11212
+ ( that.position.left - that.originalPosition.left ) ) || null;
11213
+ top = ( parseFloat( that.element.css( "top" ) ) +
11214
+ ( that.position.top - that.originalPosition.top ) ) || null;
11215
+
11216
+ if ( !o.animate ) {
11217
+ this.element.css( $.extend( s, { top: top, left: left } ) );
11218
+ }
11219
+
11220
+ that.helper.height( that.size.height );
11221
+ that.helper.width( that.size.width );
11222
+
11223
+ if ( this._helper && !o.animate ) {
11224
+ this._proportionallyResize();
11225
+ }
11226
+ }
11227
+
11228
+ $( "body" ).css( "cursor", "auto" );
11229
+
11230
+ this._removeClass( "ui-resizable-resizing" );
11231
+
11232
+ this._propagate( "stop", event );
11233
+
11234
+ if ( this._helper ) {
11235
+ this.helper.remove();
11236
+ }
11237
+
11238
+ return false;
11239
+
11240
+ },
11241
+
11242
+ _updatePrevProperties: function() {
11243
+ this.prevPosition = {
11244
+ top: this.position.top,
11245
+ left: this.position.left
11246
+ };
11247
+ this.prevSize = {
11248
+ width: this.size.width,
11249
+ height: this.size.height
11250
+ };
11251
+ },
11252
+
11253
+ _applyChanges: function() {
11254
+ var props = {};
11255
+
11256
+ if ( this.position.top !== this.prevPosition.top ) {
11257
+ props.top = this.position.top + "px";
11258
+ }
11259
+ if ( this.position.left !== this.prevPosition.left ) {
11260
+ props.left = this.position.left + "px";
11261
+ }
11262
+ if ( this.size.width !== this.prevSize.width ) {
11263
+ props.width = this.size.width + "px";
11264
+ }
11265
+ if ( this.size.height !== this.prevSize.height ) {
11266
+ props.height = this.size.height + "px";
11267
+ }
11268
+
11269
+ this.helper.css( props );
11270
+
11271
+ return props;
11272
+ },
11273
+
11274
+ _updateVirtualBoundaries: function( forceAspectRatio ) {
11275
+ var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11276
+ o = this.options;
11277
+
11278
+ b = {
11279
+ minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
11280
+ maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
11281
+ minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
11282
+ maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
11283
+ };
11284
+
11285
+ if ( this._aspectRatio || forceAspectRatio ) {
11286
+ pMinWidth = b.minHeight * this.aspectRatio;
11287
+ pMinHeight = b.minWidth / this.aspectRatio;
11288
+ pMaxWidth = b.maxHeight * this.aspectRatio;
11289
+ pMaxHeight = b.maxWidth / this.aspectRatio;
11290
+
11291
+ if ( pMinWidth > b.minWidth ) {
11292
+ b.minWidth = pMinWidth;
11293
+ }
11294
+ if ( pMinHeight > b.minHeight ) {
11295
+ b.minHeight = pMinHeight;
11296
+ }
11297
+ if ( pMaxWidth < b.maxWidth ) {
11298
+ b.maxWidth = pMaxWidth;
11299
+ }
11300
+ if ( pMaxHeight < b.maxHeight ) {
11301
+ b.maxHeight = pMaxHeight;
11302
+ }
11303
+ }
11304
+ this._vBoundaries = b;
11305
+ },
11306
+
11307
+ _updateCache: function( data ) {
11308
+ this.offset = this.helper.offset();
11309
+ if ( this._isNumber( data.left ) ) {
11310
+ this.position.left = data.left;
11311
+ }
11312
+ if ( this._isNumber( data.top ) ) {
11313
+ this.position.top = data.top;
11314
+ }
11315
+ if ( this._isNumber( data.height ) ) {
11316
+ this.size.height = data.height;
11317
+ }
11318
+ if ( this._isNumber( data.width ) ) {
11319
+ this.size.width = data.width;
11320
+ }
11321
+ },
11322
+
11323
+ _updateRatio: function( data ) {
11324
+
11325
+ var cpos = this.position,
11326
+ csize = this.size,
11327
+ a = this.axis;
11328
+
11329
+ if ( this._isNumber( data.height ) ) {
11330
+ data.width = ( data.height * this.aspectRatio );
11331
+ } else if ( this._isNumber( data.width ) ) {
11332
+ data.height = ( data.width / this.aspectRatio );
11333
+ }
11334
+
11335
+ if ( a === "sw" ) {
11336
+ data.left = cpos.left + ( csize.width - data.width );
11337
+ data.top = null;
11338
+ }
11339
+ if ( a === "nw" ) {
11340
+ data.top = cpos.top + ( csize.height - data.height );
11341
+ data.left = cpos.left + ( csize.width - data.width );
11342
+ }
11343
+
11344
+ return data;
11345
+ },
11346
+
11347
+ _respectSize: function( data ) {
11348
+
11349
+ var o = this._vBoundaries,
11350
+ a = this.axis,
11351
+ ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
11352
+ ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
11353
+ isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
11354
+ isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
11355
+ dw = this.originalPosition.left + this.originalSize.width,
11356
+ dh = this.originalPosition.top + this.originalSize.height,
11357
+ cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
11358
+ if ( isminw ) {
11359
+ data.width = o.minWidth;
11360
+ }
11361
+ if ( isminh ) {
11362
+ data.height = o.minHeight;
11363
+ }
11364
+ if ( ismaxw ) {
11365
+ data.width = o.maxWidth;
11366
+ }
11367
+ if ( ismaxh ) {
11368
+ data.height = o.maxHeight;
11369
+ }
11370
+
11371
+ if ( isminw && cw ) {
11372
+ data.left = dw - o.minWidth;
11373
+ }
11374
+ if ( ismaxw && cw ) {
11375
+ data.left = dw - o.maxWidth;
11376
+ }
11377
+ if ( isminh && ch ) {
11378
+ data.top = dh - o.minHeight;
11379
+ }
11380
+ if ( ismaxh && ch ) {
11381
+ data.top = dh - o.maxHeight;
11382
+ }
11383
+
11384
+ // Fixing jump error on top/left - bug #2330
11385
+ if ( !data.width && !data.height && !data.left && data.top ) {
11386
+ data.top = null;
11387
+ } else if ( !data.width && !data.height && !data.top && data.left ) {
11388
+ data.left = null;
11389
+ }
11390
+
11391
+ return data;
11392
+ },
11393
+
11394
+ _getPaddingPlusBorderDimensions: function( element ) {
11395
+ var i = 0,
11396
+ widths = [],
11397
+ borders = [
11398
+ element.css( "borderTopWidth" ),
11399
+ element.css( "borderRightWidth" ),
11400
+ element.css( "borderBottomWidth" ),
11401
+ element.css( "borderLeftWidth" )
11402
+ ],
11403
+ paddings = [
11404
+ element.css( "paddingTop" ),
11405
+ element.css( "paddingRight" ),
11406
+ element.css( "paddingBottom" ),
11407
+ element.css( "paddingLeft" )
11408
+ ];
11409
+
11410
+ for ( ; i < 4; i++ ) {
11411
+ widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
11412
+ widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
11413
+ }
11414
+
11415
+ return {
11416
+ height: widths[ 0 ] + widths[ 2 ],
11417
+ width: widths[ 1 ] + widths[ 3 ]
11418
+ };
11419
+ },
11420
+
11421
+ _proportionallyResize: function() {
11422
+
11423
+ if ( !this._proportionallyResizeElements.length ) {
11424
+ return;
11425
+ }
11426
+
11427
+ var prel,
11428
+ i = 0,
11429
+ element = this.helper || this.element;
11430
+
11431
+ for ( ; i < this._proportionallyResizeElements.length; i++ ) {
11432
+
11433
+ prel = this._proportionallyResizeElements[ i ];
11434
+
11435
+ // TODO: Seems like a bug to cache this.outerDimensions
11436
+ // considering that we are in a loop.
11437
+ if ( !this.outerDimensions ) {
11438
+ this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
11439
+ }
11440
+
11441
+ prel.css( {
11442
+ height: ( element.height() - this.outerDimensions.height ) || 0,
11443
+ width: ( element.width() - this.outerDimensions.width ) || 0
11444
+ } );
11445
+
11446
+ }
11447
+
11448
+ },
11449
+
11450
+ _renderProxy: function() {
11451
+
11452
+ var el = this.element, o = this.options;
11453
+ this.elementOffset = el.offset();
11454
+
11455
+ if ( this._helper ) {
11456
+
11457
+ this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
11458
+
11459
+ this._addClass( this.helper, this._helper );
11460
+ this.helper.css( {
11461
+ width: this.element.outerWidth(),
11462
+ height: this.element.outerHeight(),
11463
+ position: "absolute",
11464
+ left: this.elementOffset.left + "px",
11465
+ top: this.elementOffset.top + "px",
11466
+ zIndex: ++o.zIndex //TODO: Don't modify option
11467
+ } );
11468
+
11469
+ this.helper
11470
+ .appendTo( "body" )
11471
+ .disableSelection();
11472
+
11473
+ } else {
11474
+ this.helper = this.element;
11475
+ }
11476
+
11477
+ },
11478
+
11479
+ _change: {
11480
+ e: function( event, dx ) {
11481
+ return { width: this.originalSize.width + dx };
11482
+ },
11483
+ w: function( event, dx ) {
11484
+ var cs = this.originalSize, sp = this.originalPosition;
11485
+ return { left: sp.left + dx, width: cs.width - dx };
11486
+ },
11487
+ n: function( event, dx, dy ) {
11488
+ var cs = this.originalSize, sp = this.originalPosition;
11489
+ return { top: sp.top + dy, height: cs.height - dy };
11490
+ },
11491
+ s: function( event, dx, dy ) {
11492
+ return { height: this.originalSize.height + dy };
11493
+ },
11494
+ se: function( event, dx, dy ) {
11495
+ return $.extend( this._change.s.apply( this, arguments ),
11496
+ this._change.e.apply( this, [ event, dx, dy ] ) );
11497
+ },
11498
+ sw: function( event, dx, dy ) {
11499
+ return $.extend( this._change.s.apply( this, arguments ),
11500
+ this._change.w.apply( this, [ event, dx, dy ] ) );
11501
+ },
11502
+ ne: function( event, dx, dy ) {
11503
+ return $.extend( this._change.n.apply( this, arguments ),
11504
+ this._change.e.apply( this, [ event, dx, dy ] ) );
11505
+ },
11506
+ nw: function( event, dx, dy ) {
11507
+ return $.extend( this._change.n.apply( this, arguments ),
11508
+ this._change.w.apply( this, [ event, dx, dy ] ) );
11509
+ }
11510
+ },
11511
+
11512
+ _propagate: function( n, event ) {
11513
+ $.ui.plugin.call( this, n, [ event, this.ui() ] );
11514
+ ( n !== "resize" && this._trigger( n, event, this.ui() ) );
11515
+ },
11516
+
11517
+ plugins: {},
11518
+
11519
+ ui: function() {
11520
+ return {
11521
+ originalElement: this.originalElement,
11522
+ element: this.element,
11523
+ helper: this.helper,
11524
+ position: this.position,
11525
+ size: this.size,
11526
+ originalSize: this.originalSize,
11527
+ originalPosition: this.originalPosition
11528
+ };
11529
+ }
11530
+
11531
+ } );
11532
+
11533
+ /*
11534
+ * Resizable Extensions
11535
+ */
11536
+
11537
+ $.ui.plugin.add( "resizable", "animate", {
11538
+
11539
+ stop: function( event ) {
11540
+ var that = $( this ).resizable( "instance" ),
11541
+ o = that.options,
11542
+ pr = that._proportionallyResizeElements,
11543
+ ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
11544
+ soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
11545
+ soffsetw = ista ? 0 : that.sizeDiff.width,
11546
+ style = {
11547
+ width: ( that.size.width - soffsetw ),
11548
+ height: ( that.size.height - soffseth )
11549
+ },
11550
+ left = ( parseFloat( that.element.css( "left" ) ) +
11551
+ ( that.position.left - that.originalPosition.left ) ) || null,
11552
+ top = ( parseFloat( that.element.css( "top" ) ) +
11553
+ ( that.position.top - that.originalPosition.top ) ) || null;
11554
+
11555
+ that.element.animate(
11556
+ $.extend( style, top && left ? { top: top, left: left } : {} ), {
11557
+ duration: o.animateDuration,
11558
+ easing: o.animateEasing,
11559
+ step: function() {
11560
+
11561
+ var data = {
11562
+ width: parseFloat( that.element.css( "width" ) ),
11563
+ height: parseFloat( that.element.css( "height" ) ),
11564
+ top: parseFloat( that.element.css( "top" ) ),
11565
+ left: parseFloat( that.element.css( "left" ) )
11566
+ };
11567
+
11568
+ if ( pr && pr.length ) {
11569
+ $( pr[ 0 ] ).css( { width: data.width, height: data.height } );
11570
+ }
11571
+
11572
+ // Propagating resize, and updating values for each animation step
11573
+ that._updateCache( data );
11574
+ that._propagate( "resize", event );
11575
+
11576
+ }
11577
+ }
11578
+ );
11579
+ }
11580
+
11581
+ } );
11582
+
11583
+ $.ui.plugin.add( "resizable", "containment", {
11584
+
11585
+ start: function() {
11586
+ var element, p, co, ch, cw, width, height,
11587
+ that = $( this ).resizable( "instance" ),
11588
+ o = that.options,
11589
+ el = that.element,
11590
+ oc = o.containment,
11591
+ ce = ( oc instanceof $ ) ?
11592
+ oc.get( 0 ) :
11593
+ ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
11594
+
11595
+ if ( !ce ) {
11596
+ return;
11597
+ }
11598
+
11599
+ that.containerElement = $( ce );
11600
+
11601
+ if ( /document/.test( oc ) || oc === document ) {
11602
+ that.containerOffset = {
11603
+ left: 0,
11604
+ top: 0
11605
+ };
11606
+ that.containerPosition = {
11607
+ left: 0,
11608
+ top: 0
11609
+ };
11610
+
11611
+ that.parentData = {
11612
+ element: $( document ),
11613
+ left: 0,
11614
+ top: 0,
11615
+ width: $( document ).width(),
11616
+ height: $( document ).height() || document.body.parentNode.scrollHeight
11617
+ };
11618
+ } else {
11619
+ element = $( ce );
11620
+ p = [];
11621
+ $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
11622
+ p[ i ] = that._num( element.css( "padding" + name ) );
11623
+ } );
11624
+
11625
+ that.containerOffset = element.offset();
11626
+ that.containerPosition = element.position();
11627
+ that.containerSize = {
11628
+ height: ( element.innerHeight() - p[ 3 ] ),
11629
+ width: ( element.innerWidth() - p[ 1 ] )
11630
+ };
11631
+
11632
+ co = that.containerOffset;
11633
+ ch = that.containerSize.height;
11634
+ cw = that.containerSize.width;
11635
+ width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
11636
+ height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
11637
+
11638
+ that.parentData = {
11639
+ element: ce,
11640
+ left: co.left,
11641
+ top: co.top,
11642
+ width: width,
11643
+ height: height
11644
+ };
11645
+ }
11646
+ },
11647
+
11648
+ resize: function( event ) {
11649
+ var woset, hoset, isParent, isOffsetRelative,
11650
+ that = $( this ).resizable( "instance" ),
11651
+ o = that.options,
11652
+ co = that.containerOffset,
11653
+ cp = that.position,
11654
+ pRatio = that._aspectRatio || event.shiftKey,
11655
+ cop = {
11656
+ top: 0,
11657
+ left: 0
11658
+ },
11659
+ ce = that.containerElement,
11660
+ continueResize = true;
11661
+
11662
+ if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
11663
+ cop = co;
11664
+ }
11665
+
11666
+ if ( cp.left < ( that._helper ? co.left : 0 ) ) {
11667
+ that.size.width = that.size.width +
11668
+ ( that._helper ?
11669
+ ( that.position.left - co.left ) :
11670
+ ( that.position.left - cop.left ) );
11671
+
11672
+ if ( pRatio ) {
11673
+ that.size.height = that.size.width / that.aspectRatio;
11674
+ continueResize = false;
11675
+ }
11676
+ that.position.left = o.helper ? co.left : 0;
11677
+ }
11678
+
11679
+ if ( cp.top < ( that._helper ? co.top : 0 ) ) {
11680
+ that.size.height = that.size.height +
11681
+ ( that._helper ?
11682
+ ( that.position.top - co.top ) :
11683
+ that.position.top );
11684
+
11685
+ if ( pRatio ) {
11686
+ that.size.width = that.size.height * that.aspectRatio;
11687
+ continueResize = false;
11688
+ }
11689
+ that.position.top = that._helper ? co.top : 0;
11690
+ }
11691
+
11692
+ isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
11693
+ isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
11694
+
11695
+ if ( isParent && isOffsetRelative ) {
11696
+ that.offset.left = that.parentData.left + that.position.left;
11697
+ that.offset.top = that.parentData.top + that.position.top;
11698
+ } else {
11699
+ that.offset.left = that.element.offset().left;
11700
+ that.offset.top = that.element.offset().top;
11701
+ }
11702
+
11703
+ woset = Math.abs( that.sizeDiff.width +
11704
+ ( that._helper ?
11705
+ that.offset.left - cop.left :
11706
+ ( that.offset.left - co.left ) ) );
11707
+
11708
+ hoset = Math.abs( that.sizeDiff.height +
11709
+ ( that._helper ?
11710
+ that.offset.top - cop.top :
11711
+ ( that.offset.top - co.top ) ) );
11712
+
11713
+ if ( woset + that.size.width >= that.parentData.width ) {
11714
+ that.size.width = that.parentData.width - woset;
11715
+ if ( pRatio ) {
11716
+ that.size.height = that.size.width / that.aspectRatio;
11717
+ continueResize = false;
11718
+ }
11719
+ }
11720
+
11721
+ if ( hoset + that.size.height >= that.parentData.height ) {
11722
+ that.size.height = that.parentData.height - hoset;
11723
+ if ( pRatio ) {
11724
+ that.size.width = that.size.height * that.aspectRatio;
11725
+ continueResize = false;
11726
+ }
11727
+ }
11728
+
11729
+ if ( !continueResize ) {
11730
+ that.position.left = that.prevPosition.left;
11731
+ that.position.top = that.prevPosition.top;
11732
+ that.size.width = that.prevSize.width;
11733
+ that.size.height = that.prevSize.height;
11734
+ }
11735
+ },
11736
+
11737
+ stop: function() {
11738
+ var that = $( this ).resizable( "instance" ),
11739
+ o = that.options,
11740
+ co = that.containerOffset,
11741
+ cop = that.containerPosition,
11742
+ ce = that.containerElement,
11743
+ helper = $( that.helper ),
11744
+ ho = helper.offset(),
11745
+ w = helper.outerWidth() - that.sizeDiff.width,
11746
+ h = helper.outerHeight() - that.sizeDiff.height;
11747
+
11748
+ if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
11749
+ $( this ).css( {
11750
+ left: ho.left - cop.left - co.left,
11751
+ width: w,
11752
+ height: h
11753
+ } );
11754
+ }
11755
+
11756
+ if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
11757
+ $( this ).css( {
11758
+ left: ho.left - cop.left - co.left,
11759
+ width: w,
11760
+ height: h
11761
+ } );
11762
+ }
11763
+ }
11764
+ } );
11765
+
11766
+ $.ui.plugin.add( "resizable", "alsoResize", {
11767
+
11768
+ start: function() {
11769
+ var that = $( this ).resizable( "instance" ),
11770
+ o = that.options;
11771
+
11772
+ $( o.alsoResize ).each( function() {
11773
+ var el = $( this );
11774
+ el.data( "ui-resizable-alsoresize", {
11775
+ width: parseFloat( el.width() ), height: parseFloat( el.height() ),
11776
+ left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
11777
+ } );
11778
+ } );
11779
+ },
11780
+
11781
+ resize: function( event, ui ) {
11782
+ var that = $( this ).resizable( "instance" ),
11783
+ o = that.options,
11784
+ os = that.originalSize,
11785
+ op = that.originalPosition,
11786
+ delta = {
11787
+ height: ( that.size.height - os.height ) || 0,
11788
+ width: ( that.size.width - os.width ) || 0,
11789
+ top: ( that.position.top - op.top ) || 0,
11790
+ left: ( that.position.left - op.left ) || 0
11791
+ };
11792
+
11793
+ $( o.alsoResize ).each( function() {
11794
+ var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
11795
+ css = el.parents( ui.originalElement[ 0 ] ).length ?
11796
+ [ "width", "height" ] :
11797
+ [ "width", "height", "top", "left" ];
11798
+
11799
+ $.each( css, function( i, prop ) {
11800
+ var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
11801
+ if ( sum && sum >= 0 ) {
11802
+ style[ prop ] = sum || null;
11803
+ }
11804
+ } );
11805
+
11806
+ el.css( style );
11807
+ } );
11808
+ },
11809
+
11810
+ stop: function() {
11811
+ $( this ).removeData( "ui-resizable-alsoresize" );
11812
+ }
11813
+ } );
11814
+
11815
+ $.ui.plugin.add( "resizable", "ghost", {
11816
+
11817
+ start: function() {
11818
+
11819
+ var that = $( this ).resizable( "instance" ), cs = that.size;
11820
+
11821
+ that.ghost = that.originalElement.clone();
11822
+ that.ghost.css( {
11823
+ opacity: 0.25,
11824
+ display: "block",
11825
+ position: "relative",
11826
+ height: cs.height,
11827
+ width: cs.width,
11828
+ margin: 0,
11829
+ left: 0,
11830
+ top: 0
11831
+ } );
11832
+
11833
+ that._addClass( that.ghost, "ui-resizable-ghost" );
11834
+
11835
+ // DEPRECATED
11836
+ // TODO: remove after 1.12
11837
+ if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
11838
+
11839
+ // Ghost option
11840
+ that.ghost.addClass( this.options.ghost );
11841
+ }
11842
+
11843
+ that.ghost.appendTo( that.helper );
11844
+
11845
+ },
11846
+
11847
+ resize: function() {
11848
+ var that = $( this ).resizable( "instance" );
11849
+ if ( that.ghost ) {
11850
+ that.ghost.css( {
11851
+ position: "relative",
11852
+ height: that.size.height,
11853
+ width: that.size.width
11854
+ } );
11855
+ }
11856
+ },
11857
+
11858
+ stop: function() {
11859
+ var that = $( this ).resizable( "instance" );
11860
+ if ( that.ghost && that.helper ) {
11861
+ that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
11862
+ }
11863
+ }
11864
+
11865
+ } );
11866
+
11867
+ $.ui.plugin.add( "resizable", "grid", {
11868
+
11869
+ resize: function() {
11870
+ var outerDimensions,
11871
+ that = $( this ).resizable( "instance" ),
11872
+ o = that.options,
11873
+ cs = that.size,
11874
+ os = that.originalSize,
11875
+ op = that.originalPosition,
11876
+ a = that.axis,
11877
+ grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
11878
+ gridX = ( grid[ 0 ] || 1 ),
11879
+ gridY = ( grid[ 1 ] || 1 ),
11880
+ ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
11881
+ oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
11882
+ newWidth = os.width + ox,
11883
+ newHeight = os.height + oy,
11884
+ isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
11885
+ isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
11886
+ isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
11887
+ isMinHeight = o.minHeight && ( o.minHeight > newHeight );
11888
+
11889
+ o.grid = grid;
11890
+
11891
+ if ( isMinWidth ) {
11892
+ newWidth += gridX;
11893
+ }
11894
+ if ( isMinHeight ) {
11895
+ newHeight += gridY;
11896
+ }
11897
+ if ( isMaxWidth ) {
11898
+ newWidth -= gridX;
11899
+ }
11900
+ if ( isMaxHeight ) {
11901
+ newHeight -= gridY;
11902
+ }
11903
+
11904
+ if ( /^(se|s|e)$/.test( a ) ) {
11905
+ that.size.width = newWidth;
11906
+ that.size.height = newHeight;
11907
+ } else if ( /^(ne)$/.test( a ) ) {
11908
+ that.size.width = newWidth;
11909
+ that.size.height = newHeight;
11910
+ that.position.top = op.top - oy;
11911
+ } else if ( /^(sw)$/.test( a ) ) {
11912
+ that.size.width = newWidth;
11913
+ that.size.height = newHeight;
11914
+ that.position.left = op.left - ox;
11915
+ } else {
11916
+ if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
11917
+ outerDimensions = that._getPaddingPlusBorderDimensions( this );
11918
+ }
11919
+
11920
+ if ( newHeight - gridY > 0 ) {
11921
+ that.size.height = newHeight;
11922
+ that.position.top = op.top - oy;
11923
+ } else {
11924
+ newHeight = gridY - outerDimensions.height;
11925
+ that.size.height = newHeight;
11926
+ that.position.top = op.top + os.height - newHeight;
11927
+ }
11928
+ if ( newWidth - gridX > 0 ) {
11929
+ that.size.width = newWidth;
11930
+ that.position.left = op.left - ox;
11931
+ } else {
11932
+ newWidth = gridX - outerDimensions.width;
11933
+ that.size.width = newWidth;
11934
+ that.position.left = op.left + os.width - newWidth;
11935
+ }
11936
+ }
11937
+ }
11938
+
11939
+ } );
11940
+
11941
+ var widgetsResizable = $.ui.resizable;
11942
+
11943
+
11944
+ /*!
11945
+ * jQuery UI Dialog 1.12.1
11946
+ * http://jqueryui.com
11947
+ *
11948
+ * Copyright jQuery Foundation and other contributors
11949
+ * Released under the MIT license.
11950
+ * http://jquery.org/license
11951
+ */
11952
+
11953
+ //>>label: Dialog
11954
+ //>>group: Widgets
11955
+ //>>description: Displays customizable dialog windows.
11956
+ //>>docs: http://api.jqueryui.com/dialog/
11957
+ //>>demos: http://jqueryui.com/dialog/
11958
+ //>>css.structure: ../../themes/base/core.css
11959
+ //>>css.structure: ../../themes/base/dialog.css
11960
+ //>>css.theme: ../../themes/base/theme.css
11961
+
11962
+
11963
+
11964
+ $.widget( "ui.dialog", {
11965
+ version: "1.12.1",
11966
+ options: {
11967
+ appendTo: "body",
11968
+ autoOpen: true,
11969
+ buttons: [],
11970
+ classes: {
11971
+ "ui-dialog": "ui-corner-all",
11972
+ "ui-dialog-titlebar": "ui-corner-all"
11973
+ },
11974
+ closeOnEscape: true,
11975
+ closeText: "Close",
11976
+ draggable: true,
11977
+ hide: null,
11978
+ height: "auto",
11979
+ maxHeight: null,
11980
+ maxWidth: null,
11981
+ minHeight: 150,
11982
+ minWidth: 150,
11983
+ modal: false,
11984
+ position: {
11985
+ my: "center",
11986
+ at: "center",
11987
+ of: window,
11988
+ collision: "fit",
11989
+
11990
+ // Ensure the titlebar is always visible
11991
+ using: function( pos ) {
11992
+ var topOffset = $( this ).css( pos ).offset().top;
11993
+ if ( topOffset < 0 ) {
11994
+ $( this ).css( "top", pos.top - topOffset );
11995
+ }
11996
+ }
11997
+ },
11998
+ resizable: true,
11999
+ show: null,
12000
+ title: null,
12001
+ width: 300,
12002
+
12003
+ // Callbacks
12004
+ beforeClose: null,
12005
+ close: null,
12006
+ drag: null,
12007
+ dragStart: null,
12008
+ dragStop: null,
12009
+ focus: null,
12010
+ open: null,
12011
+ resize: null,
12012
+ resizeStart: null,
12013
+ resizeStop: null
12014
+ },
12015
+
12016
+ sizeRelatedOptions: {
12017
+ buttons: true,
12018
+ height: true,
12019
+ maxHeight: true,
12020
+ maxWidth: true,
12021
+ minHeight: true,
12022
+ minWidth: true,
12023
+ width: true
12024
+ },
12025
+
12026
+ resizableRelatedOptions: {
12027
+ maxHeight: true,
12028
+ maxWidth: true,
12029
+ minHeight: true,
12030
+ minWidth: true
12031
+ },
12032
+
12033
+ _create: function() {
12034
+ this.originalCss = {
12035
+ display: this.element[ 0 ].style.display,
12036
+ width: this.element[ 0 ].style.width,
12037
+ minHeight: this.element[ 0 ].style.minHeight,
12038
+ maxHeight: this.element[ 0 ].style.maxHeight,
12039
+ height: this.element[ 0 ].style.height
12040
+ };
12041
+ this.originalPosition = {
12042
+ parent: this.element.parent(),
12043
+ index: this.element.parent().children().index( this.element )
12044
+ };
12045
+ this.originalTitle = this.element.attr( "title" );
12046
+ if ( this.options.title == null && this.originalTitle != null ) {
12047
+ this.options.title = this.originalTitle;
12048
+ }
12049
+
12050
+ // Dialogs can't be disabled
12051
+ if ( this.options.disabled ) {
12052
+ this.options.disabled = false;
12053
+ }
12054
+
12055
+ this._createWrapper();
12056
+
12057
+ this.element
12058
+ .show()
12059
+ .removeAttr( "title" )
12060
+ .appendTo( this.uiDialog );
12061
+
12062
+ this._addClass( "ui-dialog-content", "ui-widget-content" );
12063
+
12064
+ this._createTitlebar();
12065
+ this._createButtonPane();
12066
+
12067
+ if ( this.options.draggable && $.fn.draggable ) {
12068
+ this._makeDraggable();
12069
+ }
12070
+ if ( this.options.resizable && $.fn.resizable ) {
12071
+ this._makeResizable();
12072
+ }
12073
+
12074
+ this._isOpen = false;
12075
+
12076
+ this._trackFocus();
12077
+ },
12078
+
12079
+ _init: function() {
12080
+ if ( this.options.autoOpen ) {
12081
+ this.open();
12082
+ }
12083
+ },
12084
+
12085
+ _appendTo: function() {
12086
+ var element = this.options.appendTo;
12087
+ if ( element && ( element.jquery || element.nodeType ) ) {
12088
+ return $( element );
12089
+ }
12090
+ return this.document.find( element || "body" ).eq( 0 );
12091
+ },
12092
+
12093
+ _destroy: function() {
12094
+ var next,
12095
+ originalPosition = this.originalPosition;
12096
+
12097
+ this._untrackInstance();
12098
+ this._destroyOverlay();
12099
+
12100
+ this.element
12101
+ .removeUniqueId()
12102
+ .css( this.originalCss )
12103
+
12104
+ // Without detaching first, the following becomes really slow
12105
+ .detach();
12106
+
12107
+ this.uiDialog.remove();
12108
+
12109
+ if ( this.originalTitle ) {
12110
+ this.element.attr( "title", this.originalTitle );
12111
+ }
12112
+
12113
+ next = originalPosition.parent.children().eq( originalPosition.index );
12114
+
12115
+ // Don't try to place the dialog next to itself (#8613)
12116
+ if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12117
+ next.before( this.element );
12118
+ } else {
12119
+ originalPosition.parent.append( this.element );
12120
+ }
12121
+ },
12122
+
12123
+ widget: function() {
12124
+ return this.uiDialog;
12125
+ },
12126
+
12127
+ disable: $.noop,
12128
+ enable: $.noop,
12129
+
12130
+ close: function( event ) {
12131
+ var that = this;
12132
+
12133
+ if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12134
+ return;
12135
+ }
12136
+
12137
+ this._isOpen = false;
12138
+ this._focusedElement = null;
12139
+ this._destroyOverlay();
12140
+ this._untrackInstance();
12141
+
12142
+ if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12143
+
12144
+ // Hiding a focused element doesn't trigger blur in WebKit
12145
+ // so in case we have nothing to focus on, explicitly blur the active element
12146
+ // https://bugs.webkit.org/show_bug.cgi?id=47182
12147
+ $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
12148
+ }
12149
+
12150
+ this._hide( this.uiDialog, this.options.hide, function() {
12151
+ that._trigger( "close", event );
12152
+ } );
12153
+ },
12154
+
12155
+ isOpen: function() {
12156
+ return this._isOpen;
12157
+ },
12158
+
12159
+ moveToTop: function() {
12160
+ this._moveToTop();
12161
+ },
12162
+
12163
+ _moveToTop: function( event, silent ) {
12164
+ var moved = false,
12165
+ zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12166
+ return +$( this ).css( "z-index" );
12167
+ } ).get(),
12168
+ zIndexMax = Math.max.apply( null, zIndices );
12169
+
12170
+ if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12171
+ this.uiDialog.css( "z-index", zIndexMax + 1 );
12172
+ moved = true;
12173
+ }
12174
+
12175
+ if ( moved && !silent ) {
12176
+ this._trigger( "focus", event );
12177
+ }
12178
+ return moved;
12179
+ },
12180
+
12181
+ open: function() {
12182
+ var that = this;
12183
+ if ( this._isOpen ) {
12184
+ if ( this._moveToTop() ) {
12185
+ this._focusTabbable();
12186
+ }
12187
+ return;
12188
+ }
12189
+
12190
+ this._isOpen = true;
12191
+ this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
12192
+
12193
+ this._size();
12194
+ this._position();
12195
+ this._createOverlay();
12196
+ this._moveToTop( null, true );
12197
+
12198
+ // Ensure the overlay is moved to the top with the dialog, but only when
12199
+ // opening. The overlay shouldn't move after the dialog is open so that
12200
+ // modeless dialogs opened after the modal dialog stack properly.
12201
+ if ( this.overlay ) {
12202
+ this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12203
+ }
12204
+
12205
+ this._show( this.uiDialog, this.options.show, function() {
12206
+ that._focusTabbable();
12207
+ that._trigger( "focus" );
12208
+ } );
12209
+
12210
+ // Track the dialog immediately upon openening in case a focus event
12211
+ // somehow occurs outside of the dialog before an element inside the
12212
+ // dialog is focused (#10152)
12213
+ this._makeFocusTarget();
12214
+
12215
+ this._trigger( "open" );
12216
+ },
12217
+
12218
+ _focusTabbable: function() {
12219
+
12220
+ // Set focus to the first match:
12221
+ // 1. An element that was focused previously
12222
+ // 2. First element inside the dialog matching [autofocus]
12223
+ // 3. Tabbable element inside the content element
12224
+ // 4. Tabbable element inside the buttonpane
12225
+ // 5. The close button
12226
+ // 6. The dialog itself
12227
+ var hasFocus = this._focusedElement;
12228
+ if ( !hasFocus ) {
12229
+ hasFocus = this.element.find( "[autofocus]" );
12230
+ }
12231
+ if ( !hasFocus.length ) {
12232
+ hasFocus = this.element.find( ":tabbable" );
12233
+ }
12234
+ if ( !hasFocus.length ) {
12235
+ hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12236
+ }
12237
+ if ( !hasFocus.length ) {
12238
+ hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12239
+ }
12240
+ if ( !hasFocus.length ) {
12241
+ hasFocus = this.uiDialog;
12242
+ }
12243
+ hasFocus.eq( 0 ).trigger( "focus" );
12244
+ },
12245
+
12246
+ _keepFocus: function( event ) {
12247
+ function checkFocus() {
12248
+ var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
12249
+ isActive = this.uiDialog[ 0 ] === activeElement ||
12250
+ $.contains( this.uiDialog[ 0 ], activeElement );
12251
+ if ( !isActive ) {
12252
+ this._focusTabbable();
12253
+ }
12254
+ }
12255
+ event.preventDefault();
12256
+ checkFocus.call( this );
12257
+
12258
+ // support: IE
12259
+ // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
12260
+ // so we check again later
12261
+ this._delay( checkFocus );
12262
+ },
12263
+
12264
+ _createWrapper: function() {
12265
+ this.uiDialog = $( "<div>" )
12266
+ .hide()
12267
+ .attr( {
12268
+
12269
+ // Setting tabIndex makes the div focusable
12270
+ tabIndex: -1,
12271
+ role: "dialog"
12272
+ } )
12273
+ .appendTo( this._appendTo() );
12274
+
12275
+ this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12276
+ this._on( this.uiDialog, {
12277
+ keydown: function( event ) {
12278
+ if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12279
+ event.keyCode === $.ui.keyCode.ESCAPE ) {
12280
+ event.preventDefault();
12281
+ this.close( event );
12282
+ return;
12283
+ }
12284
+
12285
+ // Prevent tabbing out of dialogs
12286
+ if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12287
+ return;
12288
+ }
12289
+ var tabbables = this.uiDialog.find( ":tabbable" ),
12290
+ first = tabbables.filter( ":first" ),
12291
+ last = tabbables.filter( ":last" );
12292
+
12293
+ if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12294
+ !event.shiftKey ) {
12295
+ this._delay( function() {
12296
+ first.trigger( "focus" );
12297
+ } );
12298
+ event.preventDefault();
12299
+ } else if ( ( event.target === first[ 0 ] ||
12300
+ event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12301
+ this._delay( function() {
12302
+ last.trigger( "focus" );
12303
+ } );
12304
+ event.preventDefault();
12305
+ }
12306
+ },
12307
+ mousedown: function( event ) {
12308
+ if ( this._moveToTop( event ) ) {
12309
+ this._focusTabbable();
12310
+ }
12311
+ }
12312
+ } );
12313
+
12314
+ // We assume that any existing aria-describedby attribute means
12315
+ // that the dialog content is marked up properly
12316
+ // otherwise we brute force the content as the description
12317
+ if ( !this.element.find( "[aria-describedby]" ).length ) {
12318
+ this.uiDialog.attr( {
12319
+ "aria-describedby": this.element.uniqueId().attr( "id" )
12320
+ } );
12321
+ }
12322
+ },
12323
+
12324
+ _createTitlebar: function() {
12325
+ var uiDialogTitle;
12326
+
12327
+ this.uiDialogTitlebar = $( "<div>" );
12328
+ this._addClass( this.uiDialogTitlebar,
12329
+ "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12330
+ this._on( this.uiDialogTitlebar, {
12331
+ mousedown: function( event ) {
12332
+
12333
+ // Don't prevent click on close button (#8838)
12334
+ // Focusing a dialog that is partially scrolled out of view
12335
+ // causes the browser to scroll it into view, preventing the click event
12336
+ if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12337
+
12338
+ // Dialog isn't getting focus when dragging (#8063)
12339
+ this.uiDialog.trigger( "focus" );
12340
+ }
12341
+ }
12342
+ } );
12343
+
12344
+ // Support: IE
12345
+ // Use type="button" to prevent enter keypresses in textboxes from closing the
12346
+ // dialog in IE (#9312)
12347
+ this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12348
+ .button( {
12349
+ label: $( "<a>" ).text( this.options.closeText ).html(),
12350
+ icon: "ui-icon-closethick",
12351
+ showLabel: false
12352
+ } )
12353
+ .appendTo( this.uiDialogTitlebar );
12354
+
12355
+ this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12356
+ this._on( this.uiDialogTitlebarClose, {
12357
+ click: function( event ) {
12358
+ event.preventDefault();
12359
+ this.close( event );
12360
+ }
12361
+ } );
12362
+
12363
+ uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12364
+ this._addClass( uiDialogTitle, "ui-dialog-title" );
12365
+ this._title( uiDialogTitle );
12366
+
12367
+ this.uiDialogTitlebar.prependTo( this.uiDialog );
12368
+
12369
+ this.uiDialog.attr( {
12370
+ "aria-labelledby": uiDialogTitle.attr( "id" )
12371
+ } );
12372
+ },
12373
+
12374
+ _title: function( title ) {
12375
+ if ( this.options.title ) {
12376
+ title.text( this.options.title );
12377
+ } else {
12378
+ title.html( "&#160;" );
12379
+ }
12380
+ },
12381
+
12382
+ _createButtonPane: function() {
12383
+ this.uiDialogButtonPane = $( "<div>" );
12384
+ this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12385
+ "ui-widget-content ui-helper-clearfix" );
12386
+
12387
+ this.uiButtonSet = $( "<div>" )
12388
+ .appendTo( this.uiDialogButtonPane );
12389
+ this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12390
+
12391
+ this._createButtons();
12392
+ },
12393
+
12394
+ _createButtons: function() {
12395
+ var that = this,
12396
+ buttons = this.options.buttons;
12397
+
12398
+ // If we already have a button pane, remove it
12399
+ this.uiDialogButtonPane.remove();
12400
+ this.uiButtonSet.empty();
12401
+
12402
+ if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12403
+ this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12404
+ return;
12405
+ }
12406
+
12407
+ $.each( buttons, function( name, props ) {
12408
+ var click, buttonOptions;
12409
+ props = $.isFunction( props ) ?
12410
+ { click: props, text: name } :
12411
+ props;
12412
+
12413
+ // Default to a non-submitting button
12414
+ props = $.extend( { type: "button" }, props );
12415
+
12416
+ // Change the context for the click callback to be the main element
12417
+ click = props.click;
12418
+ buttonOptions = {
12419
+ icon: props.icon,
12420
+ iconPosition: props.iconPosition,
12421
+ showLabel: props.showLabel,
12422
+
12423
+ // Deprecated options
12424
+ icons: props.icons,
12425
+ text: props.text
12426
+ };
12427
+
12428
+ delete props.click;
12429
+ delete props.icon;
12430
+ delete props.iconPosition;
12431
+ delete props.showLabel;
12432
+
12433
+ // Deprecated options
12434
+ delete props.icons;
12435
+ if ( typeof props.text === "boolean" ) {
12436
+ delete props.text;
12437
+ }
12438
+
12439
+ $( "<button></button>", props )
12440
+ .button( buttonOptions )
12441
+ .appendTo( that.uiButtonSet )
12442
+ .on( "click", function() {
12443
+ click.apply( that.element[ 0 ], arguments );
12444
+ } );
12445
+ } );
12446
+ this._addClass( this.uiDialog, "ui-dialog-buttons" );
12447
+ this.uiDialogButtonPane.appendTo( this.uiDialog );
12448
+ },
12449
+
12450
+ _makeDraggable: function() {
12451
+ var that = this,
12452
+ options = this.options;
12453
+
12454
+ function filteredUi( ui ) {
12455
+ return {
12456
+ position: ui.position,
12457
+ offset: ui.offset
12458
+ };
12459
+ }
12460
+
12461
+ this.uiDialog.draggable( {
12462
+ cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12463
+ handle: ".ui-dialog-titlebar",
12464
+ containment: "document",
12465
+ start: function( event, ui ) {
12466
+ that._addClass( $( this ), "ui-dialog-dragging" );
12467
+ that._blockFrames();
12468
+ that._trigger( "dragStart", event, filteredUi( ui ) );
12469
+ },
12470
+ drag: function( event, ui ) {
12471
+ that._trigger( "drag", event, filteredUi( ui ) );
12472
+ },
12473
+ stop: function( event, ui ) {
12474
+ var left = ui.offset.left - that.document.scrollLeft(),
12475
+ top = ui.offset.top - that.document.scrollTop();
12476
+
12477
+ options.position = {
12478
+ my: "left top",
12479
+ at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12480
+ "top" + ( top >= 0 ? "+" : "" ) + top,
12481
+ of: that.window
12482
+ };
12483
+ that._removeClass( $( this ), "ui-dialog-dragging" );
12484
+ that._unblockFrames();
12485
+ that._trigger( "dragStop", event, filteredUi( ui ) );
12486
+ }
12487
+ } );
12488
+ },
12489
+
12490
+ _makeResizable: function() {
12491
+ var that = this,
12492
+ options = this.options,
12493
+ handles = options.resizable,
12494
+
12495
+ // .ui-resizable has position: relative defined in the stylesheet
12496
+ // but dialogs have to use absolute or fixed positioning
12497
+ position = this.uiDialog.css( "position" ),
12498
+ resizeHandles = typeof handles === "string" ?
12499
+ handles :
12500
+ "n,e,s,w,se,sw,ne,nw";
12501
+
12502
+ function filteredUi( ui ) {
12503
+ return {
12504
+ originalPosition: ui.originalPosition,
12505
+ originalSize: ui.originalSize,
12506
+ position: ui.position,
12507
+ size: ui.size
12508
+ };
12509
+ }
12510
+
12511
+ this.uiDialog.resizable( {
12512
+ cancel: ".ui-dialog-content",
12513
+ containment: "document",
12514
+ alsoResize: this.element,
12515
+ maxWidth: options.maxWidth,
12516
+ maxHeight: options.maxHeight,
12517
+ minWidth: options.minWidth,
12518
+ minHeight: this._minHeight(),
12519
+ handles: resizeHandles,
12520
+ start: function( event, ui ) {
12521
+ that._addClass( $( this ), "ui-dialog-resizing" );
12522
+ that._blockFrames();
12523
+ that._trigger( "resizeStart", event, filteredUi( ui ) );
12524
+ },
12525
+ resize: function( event, ui ) {
12526
+ that._trigger( "resize", event, filteredUi( ui ) );
12527
+ },
12528
+ stop: function( event, ui ) {
12529
+ var offset = that.uiDialog.offset(),
12530
+ left = offset.left - that.document.scrollLeft(),
12531
+ top = offset.top - that.document.scrollTop();
12532
+
12533
+ options.height = that.uiDialog.height();
12534
+ options.width = that.uiDialog.width();
12535
+ options.position = {
12536
+ my: "left top",
12537
+ at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12538
+ "top" + ( top >= 0 ? "+" : "" ) + top,
12539
+ of: that.window
12540
+ };
12541
+ that._removeClass( $( this ), "ui-dialog-resizing" );
12542
+ that._unblockFrames();
12543
+ that._trigger( "resizeStop", event, filteredUi( ui ) );
12544
+ }
12545
+ } )
12546
+ .css( "position", position );
12547
+ },
12548
+
12549
+ _trackFocus: function() {
12550
+ this._on( this.widget(), {
12551
+ focusin: function( event ) {
12552
+ this._makeFocusTarget();
12553
+ this._focusedElement = $( event.target );
12554
+ }
12555
+ } );
12556
+ },
12557
+
12558
+ _makeFocusTarget: function() {
12559
+ this._untrackInstance();
12560
+ this._trackingInstances().unshift( this );
12561
+ },
12562
+
12563
+ _untrackInstance: function() {
12564
+ var instances = this._trackingInstances(),
12565
+ exists = $.inArray( this, instances );
12566
+ if ( exists !== -1 ) {
12567
+ instances.splice( exists, 1 );
12568
+ }
12569
+ },
12570
+
12571
+ _trackingInstances: function() {
12572
+ var instances = this.document.data( "ui-dialog-instances" );
12573
+ if ( !instances ) {
12574
+ instances = [];
12575
+ this.document.data( "ui-dialog-instances", instances );
12576
+ }
12577
+ return instances;
12578
+ },
12579
+
12580
+ _minHeight: function() {
12581
+ var options = this.options;
12582
+
12583
+ return options.height === "auto" ?
12584
+ options.minHeight :
12585
+ Math.min( options.minHeight, options.height );
12586
+ },
12587
+
12588
+ _position: function() {
12589
+
12590
+ // Need to show the dialog to get the actual offset in the position plugin
12591
+ var isVisible = this.uiDialog.is( ":visible" );
12592
+ if ( !isVisible ) {
12593
+ this.uiDialog.show();
12594
+ }
12595
+ this.uiDialog.position( this.options.position );
12596
+ if ( !isVisible ) {
12597
+ this.uiDialog.hide();
12598
+ }
12599
+ },
12600
+
12601
+ _setOptions: function( options ) {
12602
+ var that = this,
12603
+ resize = false,
12604
+ resizableOptions = {};
12605
+
12606
+ $.each( options, function( key, value ) {
12607
+ that._setOption( key, value );
12608
+
12609
+ if ( key in that.sizeRelatedOptions ) {
12610
+ resize = true;
12611
+ }
12612
+ if ( key in that.resizableRelatedOptions ) {
12613
+ resizableOptions[ key ] = value;
12614
+ }
12615
+ } );
12616
+
12617
+ if ( resize ) {
12618
+ this._size();
12619
+ this._position();
12620
+ }
12621
+ if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12622
+ this.uiDialog.resizable( "option", resizableOptions );
12623
+ }
12624
+ },
12625
+
12626
+ _setOption: function( key, value ) {
12627
+ var isDraggable, isResizable,
12628
+ uiDialog = this.uiDialog;
12629
+
12630
+ if ( key === "disabled" ) {
12631
+ return;
12632
+ }
12633
+
12634
+ this._super( key, value );
12635
+
12636
+ if ( key === "appendTo" ) {
12637
+ this.uiDialog.appendTo( this._appendTo() );
12638
+ }
12639
+
12640
+ if ( key === "buttons" ) {
12641
+ this._createButtons();
12642
+ }
12643
+
12644
+ if ( key === "closeText" ) {
12645
+ this.uiDialogTitlebarClose.button( {
12646
+
12647
+ // Ensure that we always pass a string
12648
+ label: $( "<a>" ).text( "" + this.options.closeText ).html()
12649
+ } );
12650
+ }
12651
+
12652
+ if ( key === "draggable" ) {
12653
+ isDraggable = uiDialog.is( ":data(ui-draggable)" );
12654
+ if ( isDraggable && !value ) {
12655
+ uiDialog.draggable( "destroy" );
12656
+ }
12657
+
12658
+ if ( !isDraggable && value ) {
12659
+ this._makeDraggable();
12660
+ }
12661
+ }
12662
+
12663
+ if ( key === "position" ) {
12664
+ this._position();
12665
+ }
12666
+
12667
+ if ( key === "resizable" ) {
12668
+
12669
+ // currently resizable, becoming non-resizable
12670
+ isResizable = uiDialog.is( ":data(ui-resizable)" );
12671
+ if ( isResizable && !value ) {
12672
+ uiDialog.resizable( "destroy" );
12673
+ }
12674
+
12675
+ // Currently resizable, changing handles
12676
+ if ( isResizable && typeof value === "string" ) {
12677
+ uiDialog.resizable( "option", "handles", value );
12678
+ }
12679
+
12680
+ // Currently non-resizable, becoming resizable
12681
+ if ( !isResizable && value !== false ) {
12682
+ this._makeResizable();
12683
+ }
12684
+ }
12685
+
12686
+ if ( key === "title" ) {
12687
+ this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12688
+ }
12689
+ },
12690
+
12691
+ _size: function() {
12692
+
12693
+ // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12694
+ // divs will both have width and height set, so we need to reset them
12695
+ var nonContentHeight, minContentHeight, maxContentHeight,
12696
+ options = this.options;
12697
+
12698
+ // Reset content sizing
12699
+ this.element.show().css( {
12700
+ width: "auto",
12701
+ minHeight: 0,
12702
+ maxHeight: "none",
12703
+ height: 0
12704
+ } );
12705
+
12706
+ if ( options.minWidth > options.width ) {
12707
+ options.width = options.minWidth;
12708
+ }
12709
+
12710
+ // Reset wrapper sizing
12711
+ // determine the height of all the non-content elements
12712
+ nonContentHeight = this.uiDialog.css( {
12713
+ height: "auto",
12714
+ width: options.width
12715
+ } )
12716
+ .outerHeight();
12717
+ minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12718
+ maxContentHeight = typeof options.maxHeight === "number" ?
12719
+ Math.max( 0, options.maxHeight - nonContentHeight ) :
12720
+ "none";
12721
+
12722
+ if ( options.height === "auto" ) {
12723
+ this.element.css( {
12724
+ minHeight: minContentHeight,
12725
+ maxHeight: maxContentHeight,
12726
+ height: "auto"
12727
+ } );
12728
+ } else {
12729
+ this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12730
+ }
12731
+
12732
+ if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12733
+ this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12734
+ }
12735
+ },
12736
+
12737
+ _blockFrames: function() {
12738
+ this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12739
+ var iframe = $( this );
12740
+
12741
+ return $( "<div>" )
12742
+ .css( {
12743
+ position: "absolute",
12744
+ width: iframe.outerWidth(),
12745
+ height: iframe.outerHeight()
12746
+ } )
12747
+ .appendTo( iframe.parent() )
12748
+ .offset( iframe.offset() )[ 0 ];
12749
+ } );
12750
+ },
12751
+
12752
+ _unblockFrames: function() {
12753
+ if ( this.iframeBlocks ) {
12754
+ this.iframeBlocks.remove();
12755
+ delete this.iframeBlocks;
12756
+ }
12757
+ },
12758
+
12759
+ _allowInteraction: function( event ) {
12760
+ if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12761
+ return true;
12762
+ }
12763
+
12764
+ // TODO: Remove hack when datepicker implements
12765
+ // the .ui-front logic (#8989)
12766
+ return !!$( event.target ).closest( ".ui-datepicker" ).length;
12767
+ },
12768
+
12769
+ _createOverlay: function() {
12770
+ if ( !this.options.modal ) {
12771
+ return;
12772
+ }
12773
+
12774
+ // We use a delay in case the overlay is created from an
12775
+ // event that we're going to be cancelling (#2804)
12776
+ var isOpening = true;
12777
+ this._delay( function() {
12778
+ isOpening = false;
12779
+ } );
12780
+
12781
+ if ( !this.document.data( "ui-dialog-overlays" ) ) {
12782
+
12783
+ // Prevent use of anchors and inputs
12784
+ // Using _on() for an event handler shared across many instances is
12785
+ // safe because the dialogs stack and must be closed in reverse order
12786
+ this._on( this.document, {
12787
+ focusin: function( event ) {
12788
+ if ( isOpening ) {
12789
+ return;
12790
+ }
12791
+
12792
+ if ( !this._allowInteraction( event ) ) {
12793
+ event.preventDefault();
12794
+ this._trackingInstances()[ 0 ]._focusTabbable();
12795
+ }
12796
+ }
12797
+ } );
12798
+ }
12799
+
12800
+ this.overlay = $( "<div>" )
12801
+ .appendTo( this._appendTo() );
12802
+
12803
+ this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12804
+ this._on( this.overlay, {
12805
+ mousedown: "_keepFocus"
12806
+ } );
12807
+ this.document.data( "ui-dialog-overlays",
12808
+ ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12809
+ },
12810
+
12811
+ _destroyOverlay: function() {
12812
+ if ( !this.options.modal ) {
12813
+ return;
12814
+ }
12815
+
12816
+ if ( this.overlay ) {
12817
+ var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12818
+
12819
+ if ( !overlays ) {
12820
+ this._off( this.document, "focusin" );
12821
+ this.document.removeData( "ui-dialog-overlays" );
12822
+ } else {
12823
+ this.document.data( "ui-dialog-overlays", overlays );
12824
+ }
12825
+
12826
+ this.overlay.remove();
12827
+ this.overlay = null;
12828
+ }
12829
+ }
12830
+ } );
12831
+
12832
+ // DEPRECATED
12833
+ // TODO: switch return back to widget declaration at top of file when this is removed
12834
+ if ( $.uiBackCompat !== false ) {
12835
+
12836
+ // Backcompat for dialogClass option
12837
+ $.widget( "ui.dialog", $.ui.dialog, {
12838
+ options: {
12839
+ dialogClass: ""
12840
+ },
12841
+ _createWrapper: function() {
12842
+ this._super();
12843
+ this.uiDialog.addClass( this.options.dialogClass );
12844
+ },
12845
+ _setOption: function( key, value ) {
12846
+ if ( key === "dialogClass" ) {
12847
+ this.uiDialog
12848
+ .removeClass( this.options.dialogClass )
12849
+ .addClass( value );
12850
+ }
12851
+ this._superApply( arguments );
12852
+ }
12853
+ } );
12854
+ }
12855
+
12856
+ var widgetsDialog = $.ui.dialog;
12857
+
12858
+
12859
+ /*!
12860
+ * jQuery UI Droppable 1.12.1
12861
+ * http://jqueryui.com
12862
+ *
12863
+ * Copyright jQuery Foundation and other contributors
12864
+ * Released under the MIT license.
12865
+ * http://jquery.org/license
12866
+ */
12867
+
12868
+ //>>label: Droppable
12869
+ //>>group: Interactions
12870
+ //>>description: Enables drop targets for draggable elements.
12871
+ //>>docs: http://api.jqueryui.com/droppable/
12872
+ //>>demos: http://jqueryui.com/droppable/
12873
+
12874
+
12875
+
12876
+ $.widget( "ui.droppable", {
12877
+ version: "1.12.1",
12878
+ widgetEventPrefix: "drop",
12879
+ options: {
12880
+ accept: "*",
12881
+ addClasses: true,
12882
+ greedy: false,
12883
+ scope: "default",
12884
+ tolerance: "intersect",
12885
+
12886
+ // Callbacks
12887
+ activate: null,
12888
+ deactivate: null,
12889
+ drop: null,
12890
+ out: null,
12891
+ over: null
12892
+ },
12893
+ _create: function() {
12894
+
12895
+ var proportions,
12896
+ o = this.options,
12897
+ accept = o.accept;
12898
+
12899
+ this.isover = false;
12900
+ this.isout = true;
12901
+
12902
+ this.accept = $.isFunction( accept ) ? accept : function( d ) {
12903
+ return d.is( accept );
12904
+ };
12905
+
12906
+ this.proportions = function( /* valueToWrite */ ) {
12907
+ if ( arguments.length ) {
12908
+
12909
+ // Store the droppable's proportions
12910
+ proportions = arguments[ 0 ];
12911
+ } else {
12912
+
12913
+ // Retrieve or derive the droppable's proportions
12914
+ return proportions ?
12915
+ proportions :
12916
+ proportions = {
12917
+ width: this.element[ 0 ].offsetWidth,
12918
+ height: this.element[ 0 ].offsetHeight
12919
+ };
12920
+ }
12921
+ };
12922
+
12923
+ this._addToManager( o.scope );
12924
+
12925
+ o.addClasses && this._addClass( "ui-droppable" );
12926
+
12927
+ },
12928
+
12929
+ _addToManager: function( scope ) {
12930
+
12931
+ // Add the reference and positions to the manager
12932
+ $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
12933
+ $.ui.ddmanager.droppables[ scope ].push( this );
12934
+ },
12935
+
12936
+ _splice: function( drop ) {
12937
+ var i = 0;
12938
+ for ( ; i < drop.length; i++ ) {
12939
+ if ( drop[ i ] === this ) {
12940
+ drop.splice( i, 1 );
12941
+ }
12942
+ }
12943
+ },
12944
+
12945
+ _destroy: function() {
12946
+ var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12947
+
12948
+ this._splice( drop );
12949
+ },
12950
+
12951
+ _setOption: function( key, value ) {
12952
+
12953
+ if ( key === "accept" ) {
12954
+ this.accept = $.isFunction( value ) ? value : function( d ) {
12955
+ return d.is( value );
12956
+ };
12957
+ } else if ( key === "scope" ) {
12958
+ var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12959
+
12960
+ this._splice( drop );
12961
+ this._addToManager( value );
12962
+ }
12963
+
12964
+ this._super( key, value );
12965
+ },
12966
+
12967
+ _activate: function( event ) {
12968
+ var draggable = $.ui.ddmanager.current;
12969
+
12970
+ this._addActiveClass();
12971
+ if ( draggable ) {
12972
+ this._trigger( "activate", event, this.ui( draggable ) );
12973
+ }
12974
+ },
12975
+
12976
+ _deactivate: function( event ) {
12977
+ var draggable = $.ui.ddmanager.current;
12978
+
12979
+ this._removeActiveClass();
12980
+ if ( draggable ) {
12981
+ this._trigger( "deactivate", event, this.ui( draggable ) );
12982
+ }
12983
+ },
12984
+
12985
+ _over: function( event ) {
12986
+
12987
+ var draggable = $.ui.ddmanager.current;
12988
+
12989
+ // Bail if draggable and droppable are same element
12990
+ if ( !draggable || ( draggable.currentItem ||
12991
+ draggable.element )[ 0 ] === this.element[ 0 ] ) {
12992
+ return;
12993
+ }
12994
+
12995
+ if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
12996
+ draggable.element ) ) ) {
12997
+ this._addHoverClass();
12998
+ this._trigger( "over", event, this.ui( draggable ) );
12999
+ }
13000
+
13001
+ },
13002
+
13003
+ _out: function( event ) {
13004
+
13005
+ var draggable = $.ui.ddmanager.current;
13006
+
13007
+ // Bail if draggable and droppable are same element
13008
+ if ( !draggable || ( draggable.currentItem ||
13009
+ draggable.element )[ 0 ] === this.element[ 0 ] ) {
13010
+ return;
13011
+ }
13012
+
13013
+ if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13014
+ draggable.element ) ) ) {
13015
+ this._removeHoverClass();
13016
+ this._trigger( "out", event, this.ui( draggable ) );
13017
+ }
13018
+
13019
+ },
13020
+
13021
+ _drop: function( event, custom ) {
13022
+
13023
+ var draggable = custom || $.ui.ddmanager.current,
13024
+ childrenIntersection = false;
13025
+
13026
+ // Bail if draggable and droppable are same element
13027
+ if ( !draggable || ( draggable.currentItem ||
13028
+ draggable.element )[ 0 ] === this.element[ 0 ] ) {
13029
+ return false;
13030
+ }
13031
+
13032
+ this.element
13033
+ .find( ":data(ui-droppable)" )
13034
+ .not( ".ui-draggable-dragging" )
13035
+ .each( function() {
13036
+ var inst = $( this ).droppable( "instance" );
13037
+ if (
13038
+ inst.options.greedy &&
13039
+ !inst.options.disabled &&
13040
+ inst.options.scope === draggable.options.scope &&
13041
+ inst.accept.call(
13042
+ inst.element[ 0 ], ( draggable.currentItem || draggable.element )
13043
+ ) &&
13044
+ intersect(
13045
+ draggable,
13046
+ $.extend( inst, { offset: inst.element.offset() } ),
13047
+ inst.options.tolerance, event
13048
+ )
13049
+ ) {
13050
+ childrenIntersection = true;
13051
+ return false; }
13052
+ } );
13053
+ if ( childrenIntersection ) {
13054
+ return false;
13055
+ }
13056
+
13057
+ if ( this.accept.call( this.element[ 0 ],
13058
+ ( draggable.currentItem || draggable.element ) ) ) {
13059
+ this._removeActiveClass();
13060
+ this._removeHoverClass();
13061
+
13062
+ this._trigger( "drop", event, this.ui( draggable ) );
13063
+ return this.element;
13064
+ }
13065
+
13066
+ return false;
13067
+
13068
+ },
13069
+
13070
+ ui: function( c ) {
13071
+ return {
13072
+ draggable: ( c.currentItem || c.element ),
13073
+ helper: c.helper,
13074
+ position: c.position,
13075
+ offset: c.positionAbs
13076
+ };
13077
+ },
13078
+
13079
+ // Extension points just to make backcompat sane and avoid duplicating logic
13080
+ // TODO: Remove in 1.13 along with call to it below
13081
+ _addHoverClass: function() {
13082
+ this._addClass( "ui-droppable-hover" );
13083
+ },
13084
+
13085
+ _removeHoverClass: function() {
13086
+ this._removeClass( "ui-droppable-hover" );
13087
+ },
13088
+
13089
+ _addActiveClass: function() {
13090
+ this._addClass( "ui-droppable-active" );
13091
+ },
13092
+
13093
+ _removeActiveClass: function() {
13094
+ this._removeClass( "ui-droppable-active" );
13095
+ }
13096
+ } );
13097
+
13098
+ var intersect = $.ui.intersect = ( function() {
13099
+ function isOverAxis( x, reference, size ) {
13100
+ return ( x >= reference ) && ( x < ( reference + size ) );
13101
+ }
13102
+
13103
+ return function( draggable, droppable, toleranceMode, event ) {
13104
+
13105
+ if ( !droppable.offset ) {
13106
+ return false;
13107
+ }
13108
+
13109
+ var x1 = ( draggable.positionAbs ||
13110
+ draggable.position.absolute ).left + draggable.margins.left,
13111
+ y1 = ( draggable.positionAbs ||
13112
+ draggable.position.absolute ).top + draggable.margins.top,
13113
+ x2 = x1 + draggable.helperProportions.width,
13114
+ y2 = y1 + draggable.helperProportions.height,
13115
+ l = droppable.offset.left,
13116
+ t = droppable.offset.top,
13117
+ r = l + droppable.proportions().width,
13118
+ b = t + droppable.proportions().height;
13119
+
13120
+ switch ( toleranceMode ) {
13121
+ case "fit":
13122
+ return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
13123
+ case "intersect":
13124
+ return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
13125
+ x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
13126
+ t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
13127
+ y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
13128
+ case "pointer":
13129
+ return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
13130
+ isOverAxis( event.pageX, l, droppable.proportions().width );
13131
+ case "touch":
13132
+ return (
13133
+ ( y1 >= t && y1 <= b ) || // Top edge touching
13134
+ ( y2 >= t && y2 <= b ) || // Bottom edge touching
13135
+ ( y1 < t && y2 > b ) // Surrounded vertically
13136
+ ) && (
13137
+ ( x1 >= l && x1 <= r ) || // Left edge touching
13138
+ ( x2 >= l && x2 <= r ) || // Right edge touching
13139
+ ( x1 < l && x2 > r ) // Surrounded horizontally
13140
+ );
13141
+ default:
13142
+ return false;
13143
+ }
13144
+ };
13145
+ } )();
13146
+
13147
+ /*
13148
+ This manager tracks offsets of draggables and droppables
13149
+ */
13150
+ $.ui.ddmanager = {
13151
+ current: null,
13152
+ droppables: { "default": [] },
13153
+ prepareOffsets: function( t, event ) {
13154
+
13155
+ var i, j,
13156
+ m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
13157
+ type = event ? event.type : null, // workaround for #2317
13158
+ list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
13159
+
13160
+ droppablesLoop: for ( i = 0; i < m.length; i++ ) {
13161
+
13162
+ // No disabled and non-accepted
13163
+ if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
13164
+ ( t.currentItem || t.element ) ) ) ) {
13165
+ continue;
13166
+ }
13167
+
13168
+ // Filter out elements in the current dragged item
13169
+ for ( j = 0; j < list.length; j++ ) {
13170
+ if ( list[ j ] === m[ i ].element[ 0 ] ) {
13171
+ m[ i ].proportions().height = 0;
13172
+ continue droppablesLoop;
13173
+ }
13174
+ }
13175
+
13176
+ m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
13177
+ if ( !m[ i ].visible ) {
13178
+ continue;
13179
+ }
13180
+
13181
+ // Activate the droppable if used directly from draggables
13182
+ if ( type === "mousedown" ) {
13183
+ m[ i ]._activate.call( m[ i ], event );
13184
+ }
13185
+
13186
+ m[ i ].offset = m[ i ].element.offset();
13187
+ m[ i ].proportions( {
13188
+ width: m[ i ].element[ 0 ].offsetWidth,
13189
+ height: m[ i ].element[ 0 ].offsetHeight
13190
+ } );
13191
+
13192
+ }
13193
+
13194
+ },
13195
+ drop: function( draggable, event ) {
13196
+
13197
+ var dropped = false;
13198
+
13199
+ // Create a copy of the droppables in case the list changes during the drop (#9116)
13200
+ $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
13201
+
13202
+ if ( !this.options ) {
13203
+ return;
13204
+ }
13205
+ if ( !this.options.disabled && this.visible &&
13206
+ intersect( draggable, this, this.options.tolerance, event ) ) {
13207
+ dropped = this._drop.call( this, event ) || dropped;
13208
+ }
13209
+
13210
+ if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
13211
+ ( draggable.currentItem || draggable.element ) ) ) {
13212
+ this.isout = true;
13213
+ this.isover = false;
13214
+ this._deactivate.call( this, event );
13215
+ }
13216
+
13217
+ } );
13218
+ return dropped;
13219
+
13220
+ },
13221
+ dragStart: function( draggable, event ) {
13222
+
13223
+ // Listen for scrolling so that if the dragging causes scrolling the position of the
13224
+ // droppables can be recalculated (see #5003)
13225
+ draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
13226
+ if ( !draggable.options.refreshPositions ) {
13227
+ $.ui.ddmanager.prepareOffsets( draggable, event );
13228
+ }
13229
+ } );
13230
+ },
13231
+ drag: function( draggable, event ) {
13232
+
13233
+ // If you have a highly dynamic page, you might try this option. It renders positions
13234
+ // every time you move the mouse.
13235
+ if ( draggable.options.refreshPositions ) {
13236
+ $.ui.ddmanager.prepareOffsets( draggable, event );
13237
+ }
13238
+
13239
+ // Run through all droppables and check their positions based on specific tolerance options
13240
+ $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
13241
+
13242
+ if ( this.options.disabled || this.greedyChild || !this.visible ) {
13243
+ return;
13244
+ }
13245
+
13246
+ var parentInstance, scope, parent,
13247
+ intersects = intersect( draggable, this, this.options.tolerance, event ),
13248
+ c = !intersects && this.isover ?
13249
+ "isout" :
13250
+ ( intersects && !this.isover ? "isover" : null );
13251
+ if ( !c ) {
13252
+ return;
13253
+ }
13254
+
13255
+ if ( this.options.greedy ) {
13256
+
13257
+ // find droppable parents with same scope
13258
+ scope = this.options.scope;
13259
+ parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
13260
+ return $( this ).droppable( "instance" ).options.scope === scope;
13261
+ } );
13262
+
13263
+ if ( parent.length ) {
13264
+ parentInstance = $( parent[ 0 ] ).droppable( "instance" );
13265
+ parentInstance.greedyChild = ( c === "isover" );
13266
+ }
13267
+ }
13268
+
13269
+ // We just moved into a greedy child
13270
+ if ( parentInstance && c === "isover" ) {
13271
+ parentInstance.isover = false;
13272
+ parentInstance.isout = true;
13273
+ parentInstance._out.call( parentInstance, event );
13274
+ }
13275
+
13276
+ this[ c ] = true;
13277
+ this[ c === "isout" ? "isover" : "isout" ] = false;
13278
+ this[ c === "isover" ? "_over" : "_out" ].call( this, event );
13279
+
13280
+ // We just moved out of a greedy child
13281
+ if ( parentInstance && c === "isout" ) {
13282
+ parentInstance.isout = false;
13283
+ parentInstance.isover = true;
13284
+ parentInstance._over.call( parentInstance, event );
13285
+ }
13286
+ } );
13287
+
13288
+ },
13289
+ dragStop: function( draggable, event ) {
13290
+ draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
13291
+
13292
+ // Call prepareOffsets one final time since IE does not fire return scroll events when
13293
+ // overflow was caused by drag (see #5003)
13294
+ if ( !draggable.options.refreshPositions ) {
13295
+ $.ui.ddmanager.prepareOffsets( draggable, event );
13296
+ }
13297
+ }
13298
+ };
13299
+
13300
+ // DEPRECATED
13301
+ // TODO: switch return back to widget declaration at top of file when this is removed
13302
+ if ( $.uiBackCompat !== false ) {
13303
+
13304
+ // Backcompat for activeClass and hoverClass options
13305
+ $.widget( "ui.droppable", $.ui.droppable, {
13306
+ options: {
13307
+ hoverClass: false,
13308
+ activeClass: false
13309
+ },
13310
+ _addActiveClass: function() {
13311
+ this._super();
13312
+ if ( this.options.activeClass ) {
13313
+ this.element.addClass( this.options.activeClass );
13314
+ }
13315
+ },
13316
+ _removeActiveClass: function() {
13317
+ this._super();
13318
+ if ( this.options.activeClass ) {
13319
+ this.element.removeClass( this.options.activeClass );
13320
+ }
13321
+ },
13322
+ _addHoverClass: function() {
13323
+ this._super();
13324
+ if ( this.options.hoverClass ) {
13325
+ this.element.addClass( this.options.hoverClass );
13326
+ }
13327
+ },
13328
+ _removeHoverClass: function() {
13329
+ this._super();
13330
+ if ( this.options.hoverClass ) {
13331
+ this.element.removeClass( this.options.hoverClass );
13332
+ }
13333
+ }
13334
+ } );
13335
+ }
13336
+
13337
+ var widgetsDroppable = $.ui.droppable;
13338
+
13339
+
13340
+ /*!
13341
+ * jQuery UI Progressbar 1.12.1
13342
+ * http://jqueryui.com
13343
+ *
13344
+ * Copyright jQuery Foundation and other contributors
13345
+ * Released under the MIT license.
13346
+ * http://jquery.org/license
13347
+ */
13348
+
13349
+ //>>label: Progressbar
13350
+ //>>group: Widgets
13351
+ // jscs:disable maximumLineLength
13352
+ //>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13353
+ // jscs:enable maximumLineLength
13354
+ //>>docs: http://api.jqueryui.com/progressbar/
13355
+ //>>demos: http://jqueryui.com/progressbar/
13356
+ //>>css.structure: ../../themes/base/core.css
13357
+ //>>css.structure: ../../themes/base/progressbar.css
13358
+ //>>css.theme: ../../themes/base/theme.css
13359
+
13360
+
13361
+
13362
+ var widgetsProgressbar = $.widget( "ui.progressbar", {
13363
+ version: "1.12.1",
13364
+ options: {
13365
+ classes: {
13366
+ "ui-progressbar": "ui-corner-all",
13367
+ "ui-progressbar-value": "ui-corner-left",
13368
+ "ui-progressbar-complete": "ui-corner-right"
13369
+ },
13370
+ max: 100,
13371
+ value: 0,
13372
+
13373
+ change: null,
13374
+ complete: null
13375
+ },
13376
+
13377
+ min: 0,
13378
+
13379
+ _create: function() {
13380
+
13381
+ // Constrain initial value
13382
+ this.oldValue = this.options.value = this._constrainedValue();
13383
+
13384
+ this.element.attr( {
13385
+
13386
+ // Only set static values; aria-valuenow and aria-valuemax are
13387
+ // set inside _refreshValue()
13388
+ role: "progressbar",
13389
+ "aria-valuemin": this.min
13390
+ } );
13391
+ this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
13392
+
13393
+ this.valueDiv = $( "<div>" ).appendTo( this.element );
13394
+ this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
13395
+ this._refreshValue();
13396
+ },
13397
+
13398
+ _destroy: function() {
13399
+ this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
13400
+
13401
+ this.valueDiv.remove();
13402
+ },
13403
+
13404
+ value: function( newValue ) {
13405
+ if ( newValue === undefined ) {
13406
+ return this.options.value;
13407
+ }
13408
+
13409
+ this.options.value = this._constrainedValue( newValue );
13410
+ this._refreshValue();
13411
+ },
13412
+
13413
+ _constrainedValue: function( newValue ) {
13414
+ if ( newValue === undefined ) {
13415
+ newValue = this.options.value;
13416
+ }
13417
+
13418
+ this.indeterminate = newValue === false;
13419
+
13420
+ // Sanitize value
13421
+ if ( typeof newValue !== "number" ) {
13422
+ newValue = 0;
13423
+ }
13424
+
13425
+ return this.indeterminate ? false :
13426
+ Math.min( this.options.max, Math.max( this.min, newValue ) );
13427
+ },
13428
+
13429
+ _setOptions: function( options ) {
13430
+
13431
+ // Ensure "value" option is set after other values (like max)
13432
+ var value = options.value;
13433
+ delete options.value;
13434
+
13435
+ this._super( options );
13436
+
13437
+ this.options.value = this._constrainedValue( value );
13438
+ this._refreshValue();
13439
+ },
13440
+
13441
+ _setOption: function( key, value ) {
13442
+ if ( key === "max" ) {
13443
+
13444
+ // Don't allow a max less than min
13445
+ value = Math.max( this.min, value );
13446
+ }
13447
+ this._super( key, value );
13448
+ },
13449
+
13450
+ _setOptionDisabled: function( value ) {
13451
+ this._super( value );
13452
+
13453
+ this.element.attr( "aria-disabled", value );
13454
+ this._toggleClass( null, "ui-state-disabled", !!value );
13455
+ },
13456
+
13457
+ _percentage: function() {
13458
+ return this.indeterminate ?
13459
+ 100 :
13460
+ 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13461
+ },
13462
+
13463
+ _refreshValue: function() {
13464
+ var value = this.options.value,
13465
+ percentage = this._percentage();
13466
+
13467
+ this.valueDiv
13468
+ .toggle( this.indeterminate || value > this.min )
13469
+ .width( percentage.toFixed( 0 ) + "%" );
13470
+
13471
+ this
13472
+ ._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
13473
+ value === this.options.max )
13474
+ ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
13475
+
13476
+ if ( this.indeterminate ) {
13477
+ this.element.removeAttr( "aria-valuenow" );
13478
+ if ( !this.overlayDiv ) {
13479
+ this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
13480
+ this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
13481
+ }
13482
+ } else {
13483
+ this.element.attr( {
13484
+ "aria-valuemax": this.options.max,
13485
+ "aria-valuenow": value
13486
+ } );
13487
+ if ( this.overlayDiv ) {
13488
+ this.overlayDiv.remove();
13489
+ this.overlayDiv = null;
13490
+ }
13491
+ }
13492
+
13493
+ if ( this.oldValue !== value ) {
13494
+ this.oldValue = value;
13495
+ this._trigger( "change" );
13496
+ }
13497
+ if ( value === this.options.max ) {
13498
+ this._trigger( "complete" );
13499
+ }
13500
+ }
13501
+ } );
13502
+
13503
+
13504
+ /*!
13505
+ * jQuery UI Selectable 1.12.1
13506
+ * http://jqueryui.com
13507
+ *
13508
+ * Copyright jQuery Foundation and other contributors
13509
+ * Released under the MIT license.
13510
+ * http://jquery.org/license
13511
+ */
13512
+
13513
+ //>>label: Selectable
13514
+ //>>group: Interactions
13515
+ //>>description: Allows groups of elements to be selected with the mouse.
13516
+ //>>docs: http://api.jqueryui.com/selectable/
13517
+ //>>demos: http://jqueryui.com/selectable/
13518
+ //>>css.structure: ../../themes/base/selectable.css
13519
+
13520
+
13521
+
13522
+ var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
13523
+ version: "1.12.1",
13524
+ options: {
13525
+ appendTo: "body",
13526
+ autoRefresh: true,
13527
+ distance: 0,
13528
+ filter: "*",
13529
+ tolerance: "touch",
13530
+
13531
+ // Callbacks
13532
+ selected: null,
13533
+ selecting: null,
13534
+ start: null,
13535
+ stop: null,
13536
+ unselected: null,
13537
+ unselecting: null
13538
+ },
13539
+ _create: function() {
13540
+ var that = this;
13541
+
13542
+ this._addClass( "ui-selectable" );
13543
+
13544
+ this.dragged = false;
13545
+
13546
+ // Cache selectee children based on filter
13547
+ this.refresh = function() {
13548
+ that.elementPos = $( that.element[ 0 ] ).offset();
13549
+ that.selectees = $( that.options.filter, that.element[ 0 ] );
13550
+ that._addClass( that.selectees, "ui-selectee" );
13551
+ that.selectees.each( function() {
13552
+ var $this = $( this ),
13553
+ selecteeOffset = $this.offset(),
13554
+ pos = {
13555
+ left: selecteeOffset.left - that.elementPos.left,
13556
+ top: selecteeOffset.top - that.elementPos.top
13557
+ };
13558
+ $.data( this, "selectable-item", {
13559
+ element: this,
13560
+ $element: $this,
13561
+ left: pos.left,
13562
+ top: pos.top,
13563
+ right: pos.left + $this.outerWidth(),
13564
+ bottom: pos.top + $this.outerHeight(),
13565
+ startselected: false,
13566
+ selected: $this.hasClass( "ui-selected" ),
13567
+ selecting: $this.hasClass( "ui-selecting" ),
13568
+ unselecting: $this.hasClass( "ui-unselecting" )
13569
+ } );
13570
+ } );
13571
+ };
13572
+ this.refresh();
13573
+
13574
+ this._mouseInit();
13575
+
13576
+ this.helper = $( "<div>" );
13577
+ this._addClass( this.helper, "ui-selectable-helper" );
13578
+ },
13579
+
13580
+ _destroy: function() {
13581
+ this.selectees.removeData( "selectable-item" );
13582
+ this._mouseDestroy();
13583
+ },
13584
+
13585
+ _mouseStart: function( event ) {
13586
+ var that = this,
13587
+ options = this.options;
13588
+
13589
+ this.opos = [ event.pageX, event.pageY ];
13590
+ this.elementPos = $( this.element[ 0 ] ).offset();
13591
+
13592
+ if ( this.options.disabled ) {
13593
+ return;
13594
+ }
13595
+
13596
+ this.selectees = $( options.filter, this.element[ 0 ] );
13597
+
13598
+ this._trigger( "start", event );
13599
+
13600
+ $( options.appendTo ).append( this.helper );
13601
+
13602
+ // position helper (lasso)
13603
+ this.helper.css( {
13604
+ "left": event.pageX,
13605
+ "top": event.pageY,
13606
+ "width": 0,
13607
+ "height": 0
13608
+ } );
13609
+
13610
+ if ( options.autoRefresh ) {
13611
+ this.refresh();
13612
+ }
13613
+
13614
+ this.selectees.filter( ".ui-selected" ).each( function() {
13615
+ var selectee = $.data( this, "selectable-item" );
13616
+ selectee.startselected = true;
13617
+ if ( !event.metaKey && !event.ctrlKey ) {
13618
+ that._removeClass( selectee.$element, "ui-selected" );
13619
+ selectee.selected = false;
13620
+ that._addClass( selectee.$element, "ui-unselecting" );
13621
+ selectee.unselecting = true;
13622
+
13623
+ // selectable UNSELECTING callback
13624
+ that._trigger( "unselecting", event, {
13625
+ unselecting: selectee.element
13626
+ } );
13627
+ }
13628
+ } );
13629
+
13630
+ $( event.target ).parents().addBack().each( function() {
13631
+ var doSelect,
13632
+ selectee = $.data( this, "selectable-item" );
13633
+ if ( selectee ) {
13634
+ doSelect = ( !event.metaKey && !event.ctrlKey ) ||
13635
+ !selectee.$element.hasClass( "ui-selected" );
13636
+ that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
13637
+ ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
13638
+ selectee.unselecting = !doSelect;
13639
+ selectee.selecting = doSelect;
13640
+ selectee.selected = doSelect;
13641
+
13642
+ // selectable (UN)SELECTING callback
13643
+ if ( doSelect ) {
13644
+ that._trigger( "selecting", event, {
13645
+ selecting: selectee.element
13646
+ } );
13647
+ } else {
13648
+ that._trigger( "unselecting", event, {
13649
+ unselecting: selectee.element
13650
+ } );
13651
+ }
13652
+ return false;
13653
+ }
13654
+ } );
13655
+
13656
+ },
13657
+
13658
+ _mouseDrag: function( event ) {
13659
+
13660
+ this.dragged = true;
13661
+
13662
+ if ( this.options.disabled ) {
13663
+ return;
13664
+ }
13665
+
13666
+ var tmp,
13667
+ that = this,
13668
+ options = this.options,
13669
+ x1 = this.opos[ 0 ],
13670
+ y1 = this.opos[ 1 ],
13671
+ x2 = event.pageX,
13672
+ y2 = event.pageY;
13673
+
13674
+ if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
13675
+ if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
13676
+ this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
13677
+
13678
+ this.selectees.each( function() {
13679
+ var selectee = $.data( this, "selectable-item" ),
13680
+ hit = false,
13681
+ offset = {};
13682
+
13683
+ //prevent helper from being selected if appendTo: selectable
13684
+ if ( !selectee || selectee.element === that.element[ 0 ] ) {
13685
+ return;
13686
+ }
13687
+
13688
+ offset.left = selectee.left + that.elementPos.left;
13689
+ offset.right = selectee.right + that.elementPos.left;
13690
+ offset.top = selectee.top + that.elementPos.top;
13691
+ offset.bottom = selectee.bottom + that.elementPos.top;
13692
+
13693
+ if ( options.tolerance === "touch" ) {
13694
+ hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13695
+ offset.bottom < y1 ) );
13696
+ } else if ( options.tolerance === "fit" ) {
13697
+ hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13698
+ offset.bottom < y2 );
13699
+ }
13700
+
13701
+ if ( hit ) {
13702
+
13703
+ // SELECT
13704
+ if ( selectee.selected ) {
13705
+ that._removeClass( selectee.$element, "ui-selected" );
13706
+ selectee.selected = false;
13707
+ }
13708
+ if ( selectee.unselecting ) {
13709
+ that._removeClass( selectee.$element, "ui-unselecting" );
13710
+ selectee.unselecting = false;
13711
+ }
13712
+ if ( !selectee.selecting ) {
13713
+ that._addClass( selectee.$element, "ui-selecting" );
13714
+ selectee.selecting = true;
13715
+
13716
+ // selectable SELECTING callback
13717
+ that._trigger( "selecting", event, {
13718
+ selecting: selectee.element
13719
+ } );
13720
+ }
13721
+ } else {
13722
+
13723
+ // UNSELECT
13724
+ if ( selectee.selecting ) {
13725
+ if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
13726
+ that._removeClass( selectee.$element, "ui-selecting" );
13727
+ selectee.selecting = false;
13728
+ that._addClass( selectee.$element, "ui-selected" );
13729
+ selectee.selected = true;
13730
+ } else {
13731
+ that._removeClass( selectee.$element, "ui-selecting" );
13732
+ selectee.selecting = false;
13733
+ if ( selectee.startselected ) {
13734
+ that._addClass( selectee.$element, "ui-unselecting" );
13735
+ selectee.unselecting = true;
13736
+ }
13737
+
13738
+ // selectable UNSELECTING callback
13739
+ that._trigger( "unselecting", event, {
13740
+ unselecting: selectee.element
13741
+ } );
13742
+ }
13743
+ }
13744
+ if ( selectee.selected ) {
13745
+ if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
13746
+ that._removeClass( selectee.$element, "ui-selected" );
13747
+ selectee.selected = false;
13748
+
13749
+ that._addClass( selectee.$element, "ui-unselecting" );
13750
+ selectee.unselecting = true;
13751
+
13752
+ // selectable UNSELECTING callback
13753
+ that._trigger( "unselecting", event, {
13754
+ unselecting: selectee.element
13755
+ } );
13756
+ }
13757
+ }
13758
+ }
13759
+ } );
13760
+
13761
+ return false;
13762
+ },
13763
+
13764
+ _mouseStop: function( event ) {
13765
+ var that = this;
13766
+
13767
+ this.dragged = false;
13768
+
13769
+ $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
13770
+ var selectee = $.data( this, "selectable-item" );
13771
+ that._removeClass( selectee.$element, "ui-unselecting" );
13772
+ selectee.unselecting = false;
13773
+ selectee.startselected = false;
13774
+ that._trigger( "unselected", event, {
13775
+ unselected: selectee.element
13776
+ } );
13777
+ } );
13778
+ $( ".ui-selecting", this.element[ 0 ] ).each( function() {
13779
+ var selectee = $.data( this, "selectable-item" );
13780
+ that._removeClass( selectee.$element, "ui-selecting" )
13781
+ ._addClass( selectee.$element, "ui-selected" );
13782
+ selectee.selecting = false;
13783
+ selectee.selected = true;
13784
+ selectee.startselected = true;
13785
+ that._trigger( "selected", event, {
13786
+ selected: selectee.element
13787
+ } );
13788
+ } );
13789
+ this._trigger( "stop", event );
13790
+
13791
+ this.helper.remove();
13792
+
13793
+ return false;
13794
+ }
13795
+
13796
+ } );
13797
+
13798
+
13799
+ /*!
13800
+ * jQuery UI Selectmenu 1.12.1
13801
+ * http://jqueryui.com
13802
+ *
13803
+ * Copyright jQuery Foundation and other contributors
13804
+ * Released under the MIT license.
13805
+ * http://jquery.org/license
13806
+ */
13807
+
13808
+ //>>label: Selectmenu
13809
+ //>>group: Widgets
13810
+ // jscs:disable maximumLineLength
13811
+ //>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
13812
+ // jscs:enable maximumLineLength
13813
+ //>>docs: http://api.jqueryui.com/selectmenu/
13814
+ //>>demos: http://jqueryui.com/selectmenu/
13815
+ //>>css.structure: ../../themes/base/core.css
13816
+ //>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
13817
+ //>>css.theme: ../../themes/base/theme.css
13818
+
13819
+
13820
+
13821
+ var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
13822
+ version: "1.12.1",
13823
+ defaultElement: "<select>",
13824
+ options: {
13825
+ appendTo: null,
13826
+ classes: {
13827
+ "ui-selectmenu-button-open": "ui-corner-top",
13828
+ "ui-selectmenu-button-closed": "ui-corner-all"
13829
+ },
13830
+ disabled: null,
13831
+ icons: {
13832
+ button: "ui-icon-triangle-1-s"
13833
+ },
13834
+ position: {
13835
+ my: "left top",
13836
+ at: "left bottom",
13837
+ collision: "none"
13838
+ },
13839
+ width: false,
13840
+
13841
+ // Callbacks
13842
+ change: null,
13843
+ close: null,
13844
+ focus: null,
13845
+ open: null,
13846
+ select: null
13847
+ },
13848
+
13849
+ _create: function() {
13850
+ var selectmenuId = this.element.uniqueId().attr( "id" );
13851
+ this.ids = {
13852
+ element: selectmenuId,
13853
+ button: selectmenuId + "-button",
13854
+ menu: selectmenuId + "-menu"
13855
+ };
13856
+
13857
+ this._drawButton();
13858
+ this._drawMenu();
13859
+ this._bindFormResetHandler();
13860
+
13861
+ this._rendered = false;
13862
+ this.menuItems = $();
13863
+ },
13864
+
13865
+ _drawButton: function() {
13866
+ var icon,
13867
+ that = this,
13868
+ item = this._parseOption(
13869
+ this.element.find( "option:selected" ),
13870
+ this.element[ 0 ].selectedIndex
13871
+ );
13872
+
13873
+ // Associate existing label with the new button
13874
+ this.labels = this.element.labels().attr( "for", this.ids.button );
13875
+ this._on( this.labels, {
13876
+ click: function( event ) {
13877
+ this.button.focus();
13878
+ event.preventDefault();
13879
+ }
13880
+ } );
13881
+
13882
+ // Hide original select element
13883
+ this.element.hide();
13884
+
13885
+ // Create button
13886
+ this.button = $( "<span>", {
13887
+ tabindex: this.options.disabled ? -1 : 0,
13888
+ id: this.ids.button,
13889
+ role: "combobox",
13890
+ "aria-expanded": "false",
13891
+ "aria-autocomplete": "list",
13892
+ "aria-owns": this.ids.menu,
13893
+ "aria-haspopup": "true",
13894
+ title: this.element.attr( "title" )
13895
+ } )
13896
+ .insertAfter( this.element );
13897
+
13898
+ this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
13899
+ "ui-button ui-widget" );
13900
+
13901
+ icon = $( "<span>" ).appendTo( this.button );
13902
+ this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
13903
+ this.buttonItem = this._renderButtonItem( item )
13904
+ .appendTo( this.button );
13905
+
13906
+ if ( this.options.width !== false ) {
13907
+ this._resizeButton();
13908
+ }
13909
+
13910
+ this._on( this.button, this._buttonEvents );
13911
+ this.button.one( "focusin", function() {
13912
+
13913
+ // Delay rendering the menu items until the button receives focus.
13914
+ // The menu may have already been rendered via a programmatic open.
13915
+ if ( !that._rendered ) {
13916
+ that._refreshMenu();
13917
+ }
13918
+ } );
13919
+ },
13920
+
13921
+ _drawMenu: function() {
13922
+ var that = this;
13923
+
13924
+ // Create menu
13925
+ this.menu = $( "<ul>", {
13926
+ "aria-hidden": "true",
13927
+ "aria-labelledby": this.ids.button,
13928
+ id: this.ids.menu
13929
+ } );
13930
+
13931
+ // Wrap menu
13932
+ this.menuWrap = $( "<div>" ).append( this.menu );
13933
+ this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
13934
+ this.menuWrap.appendTo( this._appendTo() );
13935
+
13936
+ // Initialize menu widget
13937
+ this.menuInstance = this.menu
13938
+ .menu( {
13939
+ classes: {
13940
+ "ui-menu": "ui-corner-bottom"
13941
+ },
13942
+ role: "listbox",
13943
+ select: function( event, ui ) {
13944
+ event.preventDefault();
13945
+
13946
+ // Support: IE8
13947
+ // If the item was selected via a click, the text selection
13948
+ // will be destroyed in IE
13949
+ that._setSelection();
13950
+
13951
+ that._select( ui.item.data( "ui-selectmenu-item" ), event );
13952
+ },
13953
+ focus: function( event, ui ) {
13954
+ var item = ui.item.data( "ui-selectmenu-item" );
13955
+
13956
+ // Prevent inital focus from firing and check if its a newly focused item
13957
+ if ( that.focusIndex != null && item.index !== that.focusIndex ) {
13958
+ that._trigger( "focus", event, { item: item } );
13959
+ if ( !that.isOpen ) {
13960
+ that._select( item, event );
13961
+ }
13962
+ }
13963
+ that.focusIndex = item.index;
13964
+
13965
+ that.button.attr( "aria-activedescendant",
13966
+ that.menuItems.eq( item.index ).attr( "id" ) );
13967
+ }
13968
+ } )
13969
+ .menu( "instance" );
13970
+
13971
+ // Don't close the menu on mouseleave
13972
+ this.menuInstance._off( this.menu, "mouseleave" );
13973
+
13974
+ // Cancel the menu's collapseAll on document click
13975
+ this.menuInstance._closeOnDocumentClick = function() {
13976
+ return false;
13977
+ };
13978
+
13979
+ // Selects often contain empty items, but never contain dividers
13980
+ this.menuInstance._isDivider = function() {
13981
+ return false;
13982
+ };
13983
+ },
13984
+
13985
+ refresh: function() {
13986
+ this._refreshMenu();
13987
+ this.buttonItem.replaceWith(
13988
+ this.buttonItem = this._renderButtonItem(
13989
+
13990
+ // Fall back to an empty object in case there are no options
13991
+ this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
13992
+ )
13993
+ );
13994
+ if ( this.options.width === null ) {
13995
+ this._resizeButton();
13996
+ }
13997
+ },
13998
+
13999
+ _refreshMenu: function() {
14000
+ var item,
14001
+ options = this.element.find( "option" );
14002
+
14003
+ this.menu.empty();
14004
+
14005
+ this._parseOptions( options );
14006
+ this._renderMenu( this.menu, this.items );
14007
+
14008
+ this.menuInstance.refresh();
14009
+ this.menuItems = this.menu.find( "li" )
14010
+ .not( ".ui-selectmenu-optgroup" )
14011
+ .find( ".ui-menu-item-wrapper" );
14012
+
14013
+ this._rendered = true;
14014
+
14015
+ if ( !options.length ) {
14016
+ return;
14017
+ }
14018
+
14019
+ item = this._getSelectedItem();
14020
+
14021
+ // Update the menu to have the correct item focused
14022
+ this.menuInstance.focus( null, item );
14023
+ this._setAria( item.data( "ui-selectmenu-item" ) );
14024
+
14025
+ // Set disabled state
14026
+ this._setOption( "disabled", this.element.prop( "disabled" ) );
14027
+ },
14028
+
14029
+ open: function( event ) {
14030
+ if ( this.options.disabled ) {
14031
+ return;
14032
+ }
14033
+
14034
+ // If this is the first time the menu is being opened, render the items
14035
+ if ( !this._rendered ) {
14036
+ this._refreshMenu();
14037
+ } else {
14038
+
14039
+ // Menu clears focus on close, reset focus to selected item
14040
+ this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
14041
+ this.menuInstance.focus( null, this._getSelectedItem() );
14042
+ }
14043
+
14044
+ // If there are no options, don't open the menu
14045
+ if ( !this.menuItems.length ) {
14046
+ return;
14047
+ }
14048
+
14049
+ this.isOpen = true;
14050
+ this._toggleAttr();
14051
+ this._resizeMenu();
14052
+ this._position();
14053
+
14054
+ this._on( this.document, this._documentClick );
14055
+
14056
+ this._trigger( "open", event );
14057
+ },
14058
+
14059
+ _position: function() {
14060
+ this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
14061
+ },
14062
+
14063
+ close: function( event ) {
14064
+ if ( !this.isOpen ) {
14065
+ return;
14066
+ }
14067
+
14068
+ this.isOpen = false;
14069
+ this._toggleAttr();
14070
+
14071
+ this.range = null;
14072
+ this._off( this.document );
14073
+
14074
+ this._trigger( "close", event );
14075
+ },
14076
+
14077
+ widget: function() {
14078
+ return this.button;
14079
+ },
14080
+
14081
+ menuWidget: function() {
14082
+ return this.menu;
14083
+ },
14084
+
14085
+ _renderButtonItem: function( item ) {
14086
+ var buttonItem = $( "<span>" );
14087
+
14088
+ this._setText( buttonItem, item.label );
14089
+ this._addClass( buttonItem, "ui-selectmenu-text" );
14090
+
14091
+ return buttonItem;
14092
+ },
14093
+
14094
+ _renderMenu: function( ul, items ) {
14095
+ var that = this,
14096
+ currentOptgroup = "";
14097
+
14098
+ $.each( items, function( index, item ) {
14099
+ var li;
14100
+
14101
+ if ( item.optgroup !== currentOptgroup ) {
14102
+ li = $( "<li>", {
14103
+ text: item.optgroup
14104
+ } );
14105
+ that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14106
+ ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
14107
+ " ui-state-disabled" :
14108
+ "" ) );
14109
+
14110
+ li.appendTo( ul );
14111
+
14112
+ currentOptgroup = item.optgroup;
14113
+ }
14114
+
14115
+ that._renderItemData( ul, item );
14116
+ } );
14117
+ },
14118
+
14119
+ _renderItemData: function( ul, item ) {
14120
+ return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
14121
+ },
14122
+
14123
+ _renderItem: function( ul, item ) {
14124
+ var li = $( "<li>" ),
14125
+ wrapper = $( "<div>", {
14126
+ title: item.element.attr( "title" )
14127
+ } );
14128
+
14129
+ if ( item.disabled ) {
14130
+ this._addClass( li, null, "ui-state-disabled" );
14131
+ }
14132
+ this._setText( wrapper, item.label );
14133
+
14134
+ return li.append( wrapper ).appendTo( ul );
14135
+ },
14136
+
14137
+ _setText: function( element, value ) {
14138
+ if ( value ) {
14139
+ element.text( value );
14140
+ } else {
14141
+ element.html( "&#160;" );
14142
+ }
14143
+ },
14144
+
14145
+ _move: function( direction, event ) {
14146
+ var item, next,
14147
+ filter = ".ui-menu-item";
14148
+
14149
+ if ( this.isOpen ) {
14150
+ item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14151
+ } else {
14152
+ item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14153
+ filter += ":not(.ui-state-disabled)";
14154
+ }
14155
+
14156
+ if ( direction === "first" || direction === "last" ) {
14157
+ next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
14158
+ } else {
14159
+ next = item[ direction + "All" ]( filter ).eq( 0 );
14160
+ }
14161
+
14162
+ if ( next.length ) {
14163
+ this.menuInstance.focus( event, next );
14164
+ }
14165
+ },
14166
+
14167
+ _getSelectedItem: function() {
14168
+ return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14169
+ },
14170
+
14171
+ _toggle: function( event ) {
14172
+ this[ this.isOpen ? "close" : "open" ]( event );
14173
+ },
14174
+
14175
+ _setSelection: function() {
14176
+ var selection;
14177
+
14178
+ if ( !this.range ) {
14179
+ return;
14180
+ }
14181
+
14182
+ if ( window.getSelection ) {
14183
+ selection = window.getSelection();
14184
+ selection.removeAllRanges();
14185
+ selection.addRange( this.range );
14186
+
14187
+ // Support: IE8
14188
+ } else {
14189
+ this.range.select();
14190
+ }
14191
+
14192
+ // Support: IE
14193
+ // Setting the text selection kills the button focus in IE, but
14194
+ // restoring the focus doesn't kill the selection.
14195
+ this.button.focus();
14196
+ },
14197
+
14198
+ _documentClick: {
14199
+ mousedown: function( event ) {
14200
+ if ( !this.isOpen ) {
14201
+ return;
14202
+ }
14203
+
14204
+ if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
14205
+ $.ui.escapeSelector( this.ids.button ) ).length ) {
14206
+ this.close( event );
14207
+ }
14208
+ }
14209
+ },
14210
+
14211
+ _buttonEvents: {
14212
+
14213
+ // Prevent text selection from being reset when interacting with the selectmenu (#10144)
14214
+ mousedown: function() {
14215
+ var selection;
14216
+
14217
+ if ( window.getSelection ) {
14218
+ selection = window.getSelection();
14219
+ if ( selection.rangeCount ) {
14220
+ this.range = selection.getRangeAt( 0 );
14221
+ }
14222
+
14223
+ // Support: IE8
14224
+ } else {
14225
+ this.range = document.selection.createRange();
14226
+ }
14227
+ },
14228
+
14229
+ click: function( event ) {
14230
+ this._setSelection();
14231
+ this._toggle( event );
14232
+ },
14233
+
14234
+ keydown: function( event ) {
14235
+ var preventDefault = true;
14236
+ switch ( event.keyCode ) {
14237
+ case $.ui.keyCode.TAB:
14238
+ case $.ui.keyCode.ESCAPE:
14239
+ this.close( event );
14240
+ preventDefault = false;
14241
+ break;
14242
+ case $.ui.keyCode.ENTER:
14243
+ if ( this.isOpen ) {
14244
+ this._selectFocusedItem( event );
14245
+ }
14246
+ break;
14247
+ case $.ui.keyCode.UP:
14248
+ if ( event.altKey ) {
14249
+ this._toggle( event );
14250
+ } else {
14251
+ this._move( "prev", event );
14252
+ }
14253
+ break;
14254
+ case $.ui.keyCode.DOWN:
14255
+ if ( event.altKey ) {
14256
+ this._toggle( event );
14257
+ } else {
14258
+ this._move( "next", event );
14259
+ }
14260
+ break;
14261
+ case $.ui.keyCode.SPACE:
14262
+ if ( this.isOpen ) {
14263
+ this._selectFocusedItem( event );
14264
+ } else {
14265
+ this._toggle( event );
14266
+ }
14267
+ break;
14268
+ case $.ui.keyCode.LEFT:
14269
+ this._move( "prev", event );
14270
+ break;
14271
+ case $.ui.keyCode.RIGHT:
14272
+ this._move( "next", event );
14273
+ break;
14274
+ case $.ui.keyCode.HOME:
14275
+ case $.ui.keyCode.PAGE_UP:
14276
+ this._move( "first", event );
14277
+ break;
14278
+ case $.ui.keyCode.END:
14279
+ case $.ui.keyCode.PAGE_DOWN:
14280
+ this._move( "last", event );
14281
+ break;
14282
+ default:
14283
+ this.menu.trigger( event );
14284
+ preventDefault = false;
14285
+ }
14286
+
14287
+ if ( preventDefault ) {
14288
+ event.preventDefault();
14289
+ }
14290
+ }
14291
+ },
14292
+
14293
+ _selectFocusedItem: function( event ) {
14294
+ var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14295
+ if ( !item.hasClass( "ui-state-disabled" ) ) {
14296
+ this._select( item.data( "ui-selectmenu-item" ), event );
14297
+ }
14298
+ },
14299
+
14300
+ _select: function( item, event ) {
14301
+ var oldIndex = this.element[ 0 ].selectedIndex;
14302
+
14303
+ // Change native select element
14304
+ this.element[ 0 ].selectedIndex = item.index;
14305
+ this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
14306
+ this._setAria( item );
14307
+ this._trigger( "select", event, { item: item } );
14308
+
14309
+ if ( item.index !== oldIndex ) {
14310
+ this._trigger( "change", event, { item: item } );
14311
+ }
14312
+
14313
+ this.close( event );
14314
+ },
14315
+
14316
+ _setAria: function( item ) {
14317
+ var id = this.menuItems.eq( item.index ).attr( "id" );
14318
+
14319
+ this.button.attr( {
14320
+ "aria-labelledby": id,
14321
+ "aria-activedescendant": id
14322
+ } );
14323
+ this.menu.attr( "aria-activedescendant", id );
14324
+ },
14325
+
14326
+ _setOption: function( key, value ) {
14327
+ if ( key === "icons" ) {
14328
+ var icon = this.button.find( "span.ui-icon" );
14329
+ this._removeClass( icon, null, this.options.icons.button )
14330
+ ._addClass( icon, null, value.button );
14331
+ }
14332
+
14333
+ this._super( key, value );
14334
+
14335
+ if ( key === "appendTo" ) {
14336
+ this.menuWrap.appendTo( this._appendTo() );
14337
+ }
14338
+
14339
+ if ( key === "width" ) {
14340
+ this._resizeButton();
14341
+ }
14342
+ },
14343
+
14344
+ _setOptionDisabled: function( value ) {
14345
+ this._super( value );
14346
+
14347
+ this.menuInstance.option( "disabled", value );
14348
+ this.button.attr( "aria-disabled", value );
14349
+ this._toggleClass( this.button, null, "ui-state-disabled", value );
14350
+
14351
+ this.element.prop( "disabled", value );
14352
+ if ( value ) {
14353
+ this.button.attr( "tabindex", -1 );
14354
+ this.close();
14355
+ } else {
14356
+ this.button.attr( "tabindex", 0 );
14357
+ }
14358
+ },
14359
+
14360
+ _appendTo: function() {
14361
+ var element = this.options.appendTo;
14362
+
14363
+ if ( element ) {
14364
+ element = element.jquery || element.nodeType ?
14365
+ $( element ) :
14366
+ this.document.find( element ).eq( 0 );
14367
+ }
14368
+
14369
+ if ( !element || !element[ 0 ] ) {
14370
+ element = this.element.closest( ".ui-front, dialog" );
14371
+ }
14372
+
14373
+ if ( !element.length ) {
14374
+ element = this.document[ 0 ].body;
14375
+ }
14376
+
14377
+ return element;
14378
+ },
14379
+
14380
+ _toggleAttr: function() {
14381
+ this.button.attr( "aria-expanded", this.isOpen );
14382
+
14383
+ // We can't use two _toggleClass() calls here, because we need to make sure
14384
+ // we always remove classes first and add them second, otherwise if both classes have the
14385
+ // same theme class, it will be removed after we add it.
14386
+ this._removeClass( this.button, "ui-selectmenu-button-" +
14387
+ ( this.isOpen ? "closed" : "open" ) )
14388
+ ._addClass( this.button, "ui-selectmenu-button-" +
14389
+ ( this.isOpen ? "open" : "closed" ) )
14390
+ ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
14391
+
14392
+ this.menu.attr( "aria-hidden", !this.isOpen );
14393
+ },
14394
+
14395
+ _resizeButton: function() {
14396
+ var width = this.options.width;
14397
+
14398
+ // For `width: false`, just remove inline style and stop
14399
+ if ( width === false ) {
14400
+ this.button.css( "width", "" );
14401
+ return;
14402
+ }
14403
+
14404
+ // For `width: null`, match the width of the original element
14405
+ if ( width === null ) {
14406
+ width = this.element.show().outerWidth();
14407
+ this.element.hide();
14408
+ }
14409
+
14410
+ this.button.outerWidth( width );
14411
+ },
14412
+
14413
+ _resizeMenu: function() {
14414
+ this.menu.outerWidth( Math.max(
14415
+ this.button.outerWidth(),
14416
+
14417
+ // Support: IE10
14418
+ // IE10 wraps long text (possibly a rounding bug)
14419
+ // so we add 1px to avoid the wrapping
14420
+ this.menu.width( "" ).outerWidth() + 1
14421
+ ) );
14422
+ },
14423
+
14424
+ _getCreateOptions: function() {
14425
+ var options = this._super();
14426
+
14427
+ options.disabled = this.element.prop( "disabled" );
14428
+
14429
+ return options;
14430
+ },
14431
+
14432
+ _parseOptions: function( options ) {
14433
+ var that = this,
14434
+ data = [];
14435
+ options.each( function( index, item ) {
14436
+ data.push( that._parseOption( $( item ), index ) );
14437
+ } );
14438
+ this.items = data;
14439
+ },
14440
+
14441
+ _parseOption: function( option, index ) {
14442
+ var optgroup = option.parent( "optgroup" );
14443
+
14444
+ return {
14445
+ element: option,
14446
+ index: index,
14447
+ value: option.val(),
14448
+ label: option.text(),
14449
+ optgroup: optgroup.attr( "label" ) || "",
14450
+ disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
14451
+ };
14452
+ },
14453
+
14454
+ _destroy: function() {
14455
+ this._unbindFormResetHandler();
14456
+ this.menuWrap.remove();
14457
+ this.button.remove();
14458
+ this.element.show();
14459
+ this.element.removeUniqueId();
14460
+ this.labels.attr( "for", this.ids.element );
14461
+ }
14462
+ } ] );
14463
+
14464
+
14465
+ /*!
14466
+ * jQuery UI Slider 1.12.1
14467
+ * http://jqueryui.com
14468
+ *
14469
+ * Copyright jQuery Foundation and other contributors
14470
+ * Released under the MIT license.
14471
+ * http://jquery.org/license
14472
+ */
14473
+
14474
+ //>>label: Slider
14475
+ //>>group: Widgets
14476
+ //>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14477
+ //>>docs: http://api.jqueryui.com/slider/
14478
+ //>>demos: http://jqueryui.com/slider/
14479
+ //>>css.structure: ../../themes/base/core.css
14480
+ //>>css.structure: ../../themes/base/slider.css
14481
+ //>>css.theme: ../../themes/base/theme.css
14482
+
14483
+
14484
+
14485
+ var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
14486
+ version: "1.12.1",
14487
+ widgetEventPrefix: "slide",
14488
+
14489
+ options: {
14490
+ animate: false,
14491
+ classes: {
14492
+ "ui-slider": "ui-corner-all",
14493
+ "ui-slider-handle": "ui-corner-all",
14494
+
14495
+ // Note: ui-widget-header isn't the most fittingly semantic framework class for this
14496
+ // element, but worked best visually with a variety of themes
14497
+ "ui-slider-range": "ui-corner-all ui-widget-header"
14498
+ },
14499
+ distance: 0,
14500
+ max: 100,
14501
+ min: 0,
14502
+ orientation: "horizontal",
14503
+ range: false,
14504
+ step: 1,
14505
+ value: 0,
14506
+ values: null,
14507
+
14508
+ // Callbacks
14509
+ change: null,
14510
+ slide: null,
14511
+ start: null,
14512
+ stop: null
14513
+ },
14514
+
14515
+ // Number of pages in a slider
14516
+ // (how many times can you page up/down to go through the whole range)
14517
+ numPages: 5,
14518
+
14519
+ _create: function() {
14520
+ this._keySliding = false;
14521
+ this._mouseSliding = false;
14522
+ this._animateOff = true;
14523
+ this._handleIndex = null;
14524
+ this._detectOrientation();
14525
+ this._mouseInit();
14526
+ this._calculateNewMax();
14527
+
14528
+ this._addClass( "ui-slider ui-slider-" + this.orientation,
14529
+ "ui-widget ui-widget-content" );
14530
+
14531
+ this._refresh();
14532
+
14533
+ this._animateOff = false;
14534
+ },
14535
+
14536
+ _refresh: function() {
14537
+ this._createRange();
14538
+ this._createHandles();
14539
+ this._setupEvents();
14540
+ this._refreshValue();
14541
+ },
14542
+
14543
+ _createHandles: function() {
14544
+ var i, handleCount,
14545
+ options = this.options,
14546
+ existingHandles = this.element.find( ".ui-slider-handle" ),
14547
+ handle = "<span tabindex='0'></span>",
14548
+ handles = [];
14549
+
14550
+ handleCount = ( options.values && options.values.length ) || 1;
14551
+
14552
+ if ( existingHandles.length > handleCount ) {
14553
+ existingHandles.slice( handleCount ).remove();
14554
+ existingHandles = existingHandles.slice( 0, handleCount );
14555
+ }
14556
+
14557
+ for ( i = existingHandles.length; i < handleCount; i++ ) {
14558
+ handles.push( handle );
14559
+ }
14560
+
14561
+ this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14562
+
14563
+ this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
14564
+
14565
+ this.handle = this.handles.eq( 0 );
14566
+
14567
+ this.handles.each( function( i ) {
14568
+ $( this )
14569
+ .data( "ui-slider-handle-index", i )
14570
+ .attr( "tabIndex", 0 );
14571
+ } );
14572
+ },
14573
+
14574
+ _createRange: function() {
14575
+ var options = this.options;
14576
+
14577
+ if ( options.range ) {
14578
+ if ( options.range === true ) {
14579
+ if ( !options.values ) {
14580
+ options.values = [ this._valueMin(), this._valueMin() ];
14581
+ } else if ( options.values.length && options.values.length !== 2 ) {
14582
+ options.values = [ options.values[ 0 ], options.values[ 0 ] ];
14583
+ } else if ( $.isArray( options.values ) ) {
14584
+ options.values = options.values.slice( 0 );
14585
+ }
14586
+ }
14587
+
14588
+ if ( !this.range || !this.range.length ) {
14589
+ this.range = $( "<div>" )
14590
+ .appendTo( this.element );
14591
+
14592
+ this._addClass( this.range, "ui-slider-range" );
14593
+ } else {
14594
+ this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
14595
+
14596
+ // Handle range switching from true to min/max
14597
+ this.range.css( {
14598
+ "left": "",
14599
+ "bottom": ""
14600
+ } );
14601
+ }
14602
+ if ( options.range === "min" || options.range === "max" ) {
14603
+ this._addClass( this.range, "ui-slider-range-" + options.range );
14604
+ }
14605
+ } else {
14606
+ if ( this.range ) {
14607
+ this.range.remove();
14608
+ }
14609
+ this.range = null;
14610
+ }
14611
+ },
14612
+
14613
+ _setupEvents: function() {
14614
+ this._off( this.handles );
14615
+ this._on( this.handles, this._handleEvents );
14616
+ this._hoverable( this.handles );
14617
+ this._focusable( this.handles );
14618
+ },
14619
+
14620
+ _destroy: function() {
14621
+ this.handles.remove();
14622
+ if ( this.range ) {
14623
+ this.range.remove();
14624
+ }
14625
+
14626
+ this._mouseDestroy();
14627
+ },
14628
+
14629
+ _mouseCapture: function( event ) {
14630
+ var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
14631
+ that = this,
14632
+ o = this.options;
14633
+
14634
+ if ( o.disabled ) {
14635
+ return false;
14636
+ }
14637
+
14638
+ this.elementSize = {
14639
+ width: this.element.outerWidth(),
14640
+ height: this.element.outerHeight()
14641
+ };
14642
+ this.elementOffset = this.element.offset();
14643
+
14644
+ position = { x: event.pageX, y: event.pageY };
14645
+ normValue = this._normValueFromMouse( position );
14646
+ distance = this._valueMax() - this._valueMin() + 1;
14647
+ this.handles.each( function( i ) {
14648
+ var thisDistance = Math.abs( normValue - that.values( i ) );
14649
+ if ( ( distance > thisDistance ) ||
14650
+ ( distance === thisDistance &&
14651
+ ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
14652
+ distance = thisDistance;
14653
+ closestHandle = $( this );
14654
+ index = i;
14655
+ }
14656
+ } );
14657
+
14658
+ allowed = this._start( event, index );
14659
+ if ( allowed === false ) {
14660
+ return false;
14661
+ }
14662
+ this._mouseSliding = true;
14663
+
14664
+ this._handleIndex = index;
14665
+
14666
+ this._addClass( closestHandle, null, "ui-state-active" );
14667
+ closestHandle.trigger( "focus" );
14668
+
14669
+ offset = closestHandle.offset();
14670
+ mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
14671
+ this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14672
+ left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
14673
+ top: event.pageY - offset.top -
14674
+ ( closestHandle.height() / 2 ) -
14675
+ ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
14676
+ ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
14677
+ ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
14678
+ };
14679
+
14680
+ if ( !this.handles.hasClass( "ui-state-hover" ) ) {
14681
+ this._slide( event, index, normValue );
14682
+ }
14683
+ this._animateOff = true;
14684
+ return true;
14685
+ },
14686
+
14687
+ _mouseStart: function() {
14688
+ return true;
14689
+ },
14690
+
14691
+ _mouseDrag: function( event ) {
14692
+ var position = { x: event.pageX, y: event.pageY },
14693
+ normValue = this._normValueFromMouse( position );
14694
+
14695
+ this._slide( event, this._handleIndex, normValue );
14696
+
14697
+ return false;
14698
+ },
14699
+
14700
+ _mouseStop: function( event ) {
14701
+ this._removeClass( this.handles, null, "ui-state-active" );
14702
+ this._mouseSliding = false;
14703
+
14704
+ this._stop( event, this._handleIndex );
14705
+ this._change( event, this._handleIndex );
14706
+
14707
+ this._handleIndex = null;
14708
+ this._clickOffset = null;
14709
+ this._animateOff = false;
14710
+
14711
+ return false;
14712
+ },
14713
+
14714
+ _detectOrientation: function() {
14715
+ this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
14716
+ },
14717
+
14718
+ _normValueFromMouse: function( position ) {
14719
+ var pixelTotal,
14720
+ pixelMouse,
14721
+ percentMouse,
14722
+ valueTotal,
14723
+ valueMouse;
14724
+
14725
+ if ( this.orientation === "horizontal" ) {
14726
+ pixelTotal = this.elementSize.width;
14727
+ pixelMouse = position.x - this.elementOffset.left -
14728
+ ( this._clickOffset ? this._clickOffset.left : 0 );
14729
+ } else {
14730
+ pixelTotal = this.elementSize.height;
14731
+ pixelMouse = position.y - this.elementOffset.top -
14732
+ ( this._clickOffset ? this._clickOffset.top : 0 );
14733
+ }
14734
+
14735
+ percentMouse = ( pixelMouse / pixelTotal );
14736
+ if ( percentMouse > 1 ) {
14737
+ percentMouse = 1;
14738
+ }
14739
+ if ( percentMouse < 0 ) {
14740
+ percentMouse = 0;
14741
+ }
14742
+ if ( this.orientation === "vertical" ) {
14743
+ percentMouse = 1 - percentMouse;
14744
+ }
14745
+
14746
+ valueTotal = this._valueMax() - this._valueMin();
14747
+ valueMouse = this._valueMin() + percentMouse * valueTotal;
14748
+
14749
+ return this._trimAlignValue( valueMouse );
14750
+ },
14751
+
14752
+ _uiHash: function( index, value, values ) {
14753
+ var uiHash = {
14754
+ handle: this.handles[ index ],
14755
+ handleIndex: index,
14756
+ value: value !== undefined ? value : this.value()
14757
+ };
14758
+
14759
+ if ( this._hasMultipleValues() ) {
14760
+ uiHash.value = value !== undefined ? value : this.values( index );
14761
+ uiHash.values = values || this.values();
14762
+ }
14763
+
14764
+ return uiHash;
14765
+ },
14766
+
14767
+ _hasMultipleValues: function() {
14768
+ return this.options.values && this.options.values.length;
14769
+ },
14770
+
14771
+ _start: function( event, index ) {
14772
+ return this._trigger( "start", event, this._uiHash( index ) );
14773
+ },
14774
+
14775
+ _slide: function( event, index, newVal ) {
14776
+ var allowed, otherVal,
14777
+ currentValue = this.value(),
14778
+ newValues = this.values();
14779
+
14780
+ if ( this._hasMultipleValues() ) {
14781
+ otherVal = this.values( index ? 0 : 1 );
14782
+ currentValue = this.values( index );
14783
+
14784
+ if ( this.options.values.length === 2 && this.options.range === true ) {
14785
+ newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
14786
+ }
14787
+
14788
+ newValues[ index ] = newVal;
14789
+ }
14790
+
14791
+ if ( newVal === currentValue ) {
14792
+ return;
14793
+ }
14794
+
14795
+ allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
14796
+
14797
+ // A slide can be canceled by returning false from the slide callback
14798
+ if ( allowed === false ) {
14799
+ return;
14800
+ }
14801
+
14802
+ if ( this._hasMultipleValues() ) {
14803
+ this.values( index, newVal );
14804
+ } else {
14805
+ this.value( newVal );
14806
+ }
14807
+ },
14808
+
14809
+ _stop: function( event, index ) {
14810
+ this._trigger( "stop", event, this._uiHash( index ) );
14811
+ },
14812
+
14813
+ _change: function( event, index ) {
14814
+ if ( !this._keySliding && !this._mouseSliding ) {
14815
+
14816
+ //store the last changed value index for reference when handles overlap
14817
+ this._lastChangedValue = index;
14818
+ this._trigger( "change", event, this._uiHash( index ) );
14819
+ }
14820
+ },
14821
+
14822
+ value: function( newValue ) {
14823
+ if ( arguments.length ) {
14824
+ this.options.value = this._trimAlignValue( newValue );
14825
+ this._refreshValue();
14826
+ this._change( null, 0 );
14827
+ return;
14828
+ }
14829
+
14830
+ return this._value();
14831
+ },
14832
+
14833
+ values: function( index, newValue ) {
14834
+ var vals,
14835
+ newValues,
14836
+ i;
14837
+
14838
+ if ( arguments.length > 1 ) {
14839
+ this.options.values[ index ] = this._trimAlignValue( newValue );
14840
+ this._refreshValue();
14841
+ this._change( null, index );
14842
+ return;
14843
+ }
14844
+
14845
+ if ( arguments.length ) {
14846
+ if ( $.isArray( arguments[ 0 ] ) ) {
14847
+ vals = this.options.values;
14848
+ newValues = arguments[ 0 ];
14849
+ for ( i = 0; i < vals.length; i += 1 ) {
14850
+ vals[ i ] = this._trimAlignValue( newValues[ i ] );
14851
+ this._change( null, i );
14852
+ }
14853
+ this._refreshValue();
14854
+ } else {
14855
+ if ( this._hasMultipleValues() ) {
14856
+ return this._values( index );
14857
+ } else {
14858
+ return this.value();
14859
+ }
14860
+ }
14861
+ } else {
14862
+ return this._values();
14863
+ }
14864
+ },
14865
+
14866
+ _setOption: function( key, value ) {
14867
+ var i,
14868
+ valsLength = 0;
14869
+
14870
+ if ( key === "range" && this.options.range === true ) {
14871
+ if ( value === "min" ) {
14872
+ this.options.value = this._values( 0 );
14873
+ this.options.values = null;
14874
+ } else if ( value === "max" ) {
14875
+ this.options.value = this._values( this.options.values.length - 1 );
14876
+ this.options.values = null;
14877
+ }
14878
+ }
14879
+
14880
+ if ( $.isArray( this.options.values ) ) {
14881
+ valsLength = this.options.values.length;
14882
+ }
14883
+
14884
+ this._super( key, value );
14885
+
14886
+ switch ( key ) {
14887
+ case "orientation":
14888
+ this._detectOrientation();
14889
+ this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
14890
+ ._addClass( "ui-slider-" + this.orientation );
14891
+ this._refreshValue();
14892
+ if ( this.options.range ) {
14893
+ this._refreshRange( value );
14894
+ }
14895
+
14896
+ // Reset positioning from previous orientation
14897
+ this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
14898
+ break;
14899
+ case "value":
14900
+ this._animateOff = true;
14901
+ this._refreshValue();
14902
+ this._change( null, 0 );
14903
+ this._animateOff = false;
14904
+ break;
14905
+ case "values":
14906
+ this._animateOff = true;
14907
+ this._refreshValue();
14908
+
14909
+ // Start from the last handle to prevent unreachable handles (#9046)
14910
+ for ( i = valsLength - 1; i >= 0; i-- ) {
14911
+ this._change( null, i );
14912
+ }
14913
+ this._animateOff = false;
14914
+ break;
14915
+ case "step":
14916
+ case "min":
14917
+ case "max":
14918
+ this._animateOff = true;
14919
+ this._calculateNewMax();
14920
+ this._refreshValue();
14921
+ this._animateOff = false;
14922
+ break;
14923
+ case "range":
14924
+ this._animateOff = true;
14925
+ this._refresh();
14926
+ this._animateOff = false;
14927
+ break;
14928
+ }
14929
+ },
14930
+
14931
+ _setOptionDisabled: function( value ) {
14932
+ this._super( value );
14933
+
14934
+ this._toggleClass( null, "ui-state-disabled", !!value );
14935
+ },
14936
+
14937
+ //internal value getter
14938
+ // _value() returns value trimmed by min and max, aligned by step
14939
+ _value: function() {
14940
+ var val = this.options.value;
14941
+ val = this._trimAlignValue( val );
14942
+
14943
+ return val;
14944
+ },
14945
+
14946
+ //internal values getter
14947
+ // _values() returns array of values trimmed by min and max, aligned by step
14948
+ // _values( index ) returns single value trimmed by min and max, aligned by step
14949
+ _values: function( index ) {
14950
+ var val,
14951
+ vals,
14952
+ i;
14953
+
14954
+ if ( arguments.length ) {
14955
+ val = this.options.values[ index ];
14956
+ val = this._trimAlignValue( val );
14957
+
14958
+ return val;
14959
+ } else if ( this._hasMultipleValues() ) {
14960
+
14961
+ // .slice() creates a copy of the array
14962
+ // this copy gets trimmed by min and max and then returned
14963
+ vals = this.options.values.slice();
14964
+ for ( i = 0; i < vals.length; i += 1 ) {
14965
+ vals[ i ] = this._trimAlignValue( vals[ i ] );
14966
+ }
14967
+
14968
+ return vals;
14969
+ } else {
14970
+ return [];
14971
+ }
14972
+ },
14973
+
14974
+ // Returns the step-aligned value that val is closest to, between (inclusive) min and max
14975
+ _trimAlignValue: function( val ) {
14976
+ if ( val <= this._valueMin() ) {
14977
+ return this._valueMin();
14978
+ }
14979
+ if ( val >= this._valueMax() ) {
14980
+ return this._valueMax();
14981
+ }
14982
+ var step = ( this.options.step > 0 ) ? this.options.step : 1,
14983
+ valModStep = ( val - this._valueMin() ) % step,
14984
+ alignValue = val - valModStep;
14985
+
14986
+ if ( Math.abs( valModStep ) * 2 >= step ) {
14987
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
14988
+ }
14989
+
14990
+ // Since JavaScript has problems with large floats, round
14991
+ // the final value to 5 digits after the decimal point (see #4124)
14992
+ return parseFloat( alignValue.toFixed( 5 ) );
14993
+ },
14994
+
14995
+ _calculateNewMax: function() {
14996
+ var max = this.options.max,
14997
+ min = this._valueMin(),
14998
+ step = this.options.step,
14999
+ aboveMin = Math.round( ( max - min ) / step ) * step;
15000
+ max = aboveMin + min;
15001
+ if ( max > this.options.max ) {
15002
+
15003
+ //If max is not divisible by step, rounding off may increase its value
15004
+ max -= step;
15005
+ }
15006
+ this.max = parseFloat( max.toFixed( this._precision() ) );
15007
+ },
15008
+
15009
+ _precision: function() {
15010
+ var precision = this._precisionOf( this.options.step );
15011
+ if ( this.options.min !== null ) {
15012
+ precision = Math.max( precision, this._precisionOf( this.options.min ) );
15013
+ }
15014
+ return precision;
15015
+ },
15016
+
15017
+ _precisionOf: function( num ) {
15018
+ var str = num.toString(),
15019
+ decimal = str.indexOf( "." );
15020
+ return decimal === -1 ? 0 : str.length - decimal - 1;
15021
+ },
15022
+
15023
+ _valueMin: function() {
15024
+ return this.options.min;
15025
+ },
15026
+
15027
+ _valueMax: function() {
15028
+ return this.max;
15029
+ },
15030
+
15031
+ _refreshRange: function( orientation ) {
15032
+ if ( orientation === "vertical" ) {
15033
+ this.range.css( { "width": "", "left": "" } );
15034
+ }
15035
+ if ( orientation === "horizontal" ) {
15036
+ this.range.css( { "height": "", "bottom": "" } );
15037
+ }
15038
+ },
15039
+
15040
+ _refreshValue: function() {
15041
+ var lastValPercent, valPercent, value, valueMin, valueMax,
15042
+ oRange = this.options.range,
15043
+ o = this.options,
15044
+ that = this,
15045
+ animate = ( !this._animateOff ) ? o.animate : false,
15046
+ _set = {};
15047
+
15048
+ if ( this._hasMultipleValues() ) {
15049
+ this.handles.each( function( i ) {
15050
+ valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
15051
+ that._valueMin() ) * 100;
15052
+ _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15053
+ $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15054
+ if ( that.options.range === true ) {
15055
+ if ( that.orientation === "horizontal" ) {
15056
+ if ( i === 0 ) {
15057
+ that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15058
+ left: valPercent + "%"
15059
+ }, o.animate );
15060
+ }
15061
+ if ( i === 1 ) {
15062
+ that.range[ animate ? "animate" : "css" ]( {
15063
+ width: ( valPercent - lastValPercent ) + "%"
15064
+ }, {
15065
+ queue: false,
15066
+ duration: o.animate
15067
+ } );
15068
+ }
15069
+ } else {
15070
+ if ( i === 0 ) {
15071
+ that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15072
+ bottom: ( valPercent ) + "%"
15073
+ }, o.animate );
15074
+ }
15075
+ if ( i === 1 ) {
15076
+ that.range[ animate ? "animate" : "css" ]( {
15077
+ height: ( valPercent - lastValPercent ) + "%"
15078
+ }, {
15079
+ queue: false,
15080
+ duration: o.animate
15081
+ } );
15082
+ }
15083
+ }
15084
+ }
15085
+ lastValPercent = valPercent;
15086
+ } );
15087
+ } else {
15088
+ value = this.value();
15089
+ valueMin = this._valueMin();
15090
+ valueMax = this._valueMax();
15091
+ valPercent = ( valueMax !== valueMin ) ?
15092
+ ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15093
+ 0;
15094
+ _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15095
+ this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15096
+
15097
+ if ( oRange === "min" && this.orientation === "horizontal" ) {
15098
+ this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15099
+ width: valPercent + "%"
15100
+ }, o.animate );
15101
+ }
15102
+ if ( oRange === "max" && this.orientation === "horizontal" ) {
15103
+ this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15104
+ width: ( 100 - valPercent ) + "%"
15105
+ }, o.animate );
15106
+ }
15107
+ if ( oRange === "min" && this.orientation === "vertical" ) {
15108
+ this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15109
+ height: valPercent + "%"
15110
+ }, o.animate );
15111
+ }
15112
+ if ( oRange === "max" && this.orientation === "vertical" ) {
15113
+ this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15114
+ height: ( 100 - valPercent ) + "%"
15115
+ }, o.animate );
15116
+ }
15117
+ }
15118
+ },
15119
+
15120
+ _handleEvents: {
15121
+ keydown: function( event ) {
15122
+ var allowed, curVal, newVal, step,
15123
+ index = $( event.target ).data( "ui-slider-handle-index" );
15124
+
15125
+ switch ( event.keyCode ) {
15126
+ case $.ui.keyCode.HOME:
15127
+ case $.ui.keyCode.END:
15128
+ case $.ui.keyCode.PAGE_UP:
15129
+ case $.ui.keyCode.PAGE_DOWN:
15130
+ case $.ui.keyCode.UP:
15131
+ case $.ui.keyCode.RIGHT:
15132
+ case $.ui.keyCode.DOWN:
15133
+ case $.ui.keyCode.LEFT:
15134
+ event.preventDefault();
15135
+ if ( !this._keySliding ) {
15136
+ this._keySliding = true;
15137
+ this._addClass( $( event.target ), null, "ui-state-active" );
15138
+ allowed = this._start( event, index );
15139
+ if ( allowed === false ) {
15140
+ return;
15141
+ }
15142
+ }
15143
+ break;
15144
+ }
15145
+
15146
+ step = this.options.step;
15147
+ if ( this._hasMultipleValues() ) {
15148
+ curVal = newVal = this.values( index );
15149
+ } else {
15150
+ curVal = newVal = this.value();
15151
+ }
15152
+
15153
+ switch ( event.keyCode ) {
15154
+ case $.ui.keyCode.HOME:
15155
+ newVal = this._valueMin();
15156
+ break;
15157
+ case $.ui.keyCode.END:
15158
+ newVal = this._valueMax();
15159
+ break;
15160
+ case $.ui.keyCode.PAGE_UP:
15161
+ newVal = this._trimAlignValue(
15162
+ curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
15163
+ );
15164
+ break;
15165
+ case $.ui.keyCode.PAGE_DOWN:
15166
+ newVal = this._trimAlignValue(
15167
+ curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
15168
+ break;
15169
+ case $.ui.keyCode.UP:
15170
+ case $.ui.keyCode.RIGHT:
15171
+ if ( curVal === this._valueMax() ) {
15172
+ return;
15173
+ }
15174
+ newVal = this._trimAlignValue( curVal + step );
15175
+ break;
15176
+ case $.ui.keyCode.DOWN:
15177
+ case $.ui.keyCode.LEFT:
15178
+ if ( curVal === this._valueMin() ) {
15179
+ return;
15180
+ }
15181
+ newVal = this._trimAlignValue( curVal - step );
15182
+ break;
15183
+ }
15184
+
15185
+ this._slide( event, index, newVal );
15186
+ },
15187
+ keyup: function( event ) {
15188
+ var index = $( event.target ).data( "ui-slider-handle-index" );
15189
+
15190
+ if ( this._keySliding ) {
15191
+ this._keySliding = false;
15192
+ this._stop( event, index );
15193
+ this._change( event, index );
15194
+ this._removeClass( $( event.target ), null, "ui-state-active" );
15195
+ }
15196
+ }
15197
+ }
15198
+ } );
15199
+
15200
+
15201
+ /*!
15202
+ * jQuery UI Sortable 1.12.1
15203
+ * http://jqueryui.com
15204
+ *
15205
+ * Copyright jQuery Foundation and other contributors
15206
+ * Released under the MIT license.
15207
+ * http://jquery.org/license
15208
+ */
15209
+
15210
+ //>>label: Sortable
15211
+ //>>group: Interactions
15212
+ //>>description: Enables items in a list to be sorted using the mouse.
15213
+ //>>docs: http://api.jqueryui.com/sortable/
15214
+ //>>demos: http://jqueryui.com/sortable/
15215
+ //>>css.structure: ../../themes/base/sortable.css
15216
+
15217
+
15218
+
15219
+ var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
15220
+ version: "1.12.1",
15221
+ widgetEventPrefix: "sort",
15222
+ ready: false,
15223
+ options: {
15224
+ appendTo: "parent",
15225
+ axis: false,
15226
+ connectWith: false,
15227
+ containment: false,
15228
+ cursor: "auto",
15229
+ cursorAt: false,
15230
+ dropOnEmpty: true,
15231
+ forcePlaceholderSize: false,
15232
+ forceHelperSize: false,
15233
+ grid: false,
15234
+ handle: false,
15235
+ helper: "original",
15236
+ items: "> *",
15237
+ opacity: false,
15238
+ placeholder: false,
15239
+ revert: false,
15240
+ scroll: true,
15241
+ scrollSensitivity: 20,
15242
+ scrollSpeed: 20,
15243
+ scope: "default",
15244
+ tolerance: "intersect",
15245
+ zIndex: 1000,
15246
+
15247
+ // Callbacks
15248
+ activate: null,
15249
+ beforeStop: null,
15250
+ change: null,
15251
+ deactivate: null,
15252
+ out: null,
15253
+ over: null,
15254
+ receive: null,
15255
+ remove: null,
15256
+ sort: null,
15257
+ start: null,
15258
+ stop: null,
15259
+ update: null
15260
+ },
15261
+
15262
+ _isOverAxis: function( x, reference, size ) {
15263
+ return ( x >= reference ) && ( x < ( reference + size ) );
15264
+ },
15265
+
15266
+ _isFloating: function( item ) {
15267
+ return ( /left|right/ ).test( item.css( "float" ) ) ||
15268
+ ( /inline|table-cell/ ).test( item.css( "display" ) );
15269
+ },
15270
+
15271
+ _create: function() {
15272
+ this.containerCache = {};
15273
+ this._addClass( "ui-sortable" );
15274
+
15275
+ //Get the items
15276
+ this.refresh();
15277
+
15278
+ //Let's determine the parent's offset
15279
+ this.offset = this.element.offset();
15280
+
15281
+ //Initialize mouse events for interaction
15282
+ this._mouseInit();
15283
+
15284
+ this._setHandleClassName();
15285
+
15286
+ //We're ready to go
15287
+ this.ready = true;
15288
+
15289
+ },
15290
+
15291
+ _setOption: function( key, value ) {
15292
+ this._super( key, value );
15293
+
15294
+ if ( key === "handle" ) {
15295
+ this._setHandleClassName();
15296
+ }
15297
+ },
15298
+
15299
+ _setHandleClassName: function() {
15300
+ var that = this;
15301
+ this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
15302
+ $.each( this.items, function() {
15303
+ that._addClass(
15304
+ this.instance.options.handle ?
15305
+ this.item.find( this.instance.options.handle ) :
15306
+ this.item,
15307
+ "ui-sortable-handle"
15308
+ );
15309
+ } );
15310
+ },
15311
+
15312
+ _destroy: function() {
15313
+ this._mouseDestroy();
15314
+
15315
+ for ( var i = this.items.length - 1; i >= 0; i-- ) {
15316
+ this.items[ i ].item.removeData( this.widgetName + "-item" );
15317
+ }
15318
+
15319
+ return this;
15320
+ },
15321
+
15322
+ _mouseCapture: function( event, overrideHandle ) {
15323
+ var currentItem = null,
15324
+ validHandle = false,
15325
+ that = this;
15326
+
15327
+ if ( this.reverting ) {
15328
+ return false;
15329
+ }
15330
+
15331
+ if ( this.options.disabled || this.options.type === "static" ) {
15332
+ return false;
15333
+ }
15334
+
15335
+ //We have to refresh the items data once first
15336
+ this._refreshItems( event );
15337
+
15338
+ //Find out if the clicked node (or one of its parents) is a actual item in this.items
15339
+ $( event.target ).parents().each( function() {
15340
+ if ( $.data( this, that.widgetName + "-item" ) === that ) {
15341
+ currentItem = $( this );
15342
+ return false;
15343
+ }
15344
+ } );
15345
+ if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
15346
+ currentItem = $( event.target );
15347
+ }
15348
+
15349
+ if ( !currentItem ) {
15350
+ return false;
15351
+ }
15352
+ if ( this.options.handle && !overrideHandle ) {
15353
+ $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
15354
+ if ( this === event.target ) {
15355
+ validHandle = true;
15356
+ }
15357
+ } );
15358
+ if ( !validHandle ) {
15359
+ return false;
15360
+ }
15361
+ }
15362
+
15363
+ this.currentItem = currentItem;
15364
+ this._removeCurrentsFromItems();
15365
+ return true;
15366
+
15367
+ },
15368
+
15369
+ _mouseStart: function( event, overrideHandle, noActivation ) {
15370
+
15371
+ var i, body,
15372
+ o = this.options;
15373
+
15374
+ this.currentContainer = this;
15375
+
15376
+ //We only need to call refreshPositions, because the refreshItems call has been moved to
15377
+ // mouseCapture
15378
+ this.refreshPositions();
15379
+
15380
+ //Create and append the visible helper
15381
+ this.helper = this._createHelper( event );
15382
+
15383
+ //Cache the helper size
15384
+ this._cacheHelperProportions();
15385
+
15386
+ /*
15387
+ * - Position generation -
15388
+ * This block generates everything position related - it's the core of draggables.
15389
+ */
15390
+
15391
+ //Cache the margins of the original element
15392
+ this._cacheMargins();
15393
+
15394
+ //Get the next scrolling parent
15395
+ this.scrollParent = this.helper.scrollParent();
15396
+
15397
+ //The element's absolute position on the page minus margins
15398
+ this.offset = this.currentItem.offset();
15399
+ this.offset = {
15400
+ top: this.offset.top - this.margins.top,
15401
+ left: this.offset.left - this.margins.left
15402
+ };
15403
+
15404
+ $.extend( this.offset, {
15405
+ click: { //Where the click happened, relative to the element
15406
+ left: event.pageX - this.offset.left,
15407
+ top: event.pageY - this.offset.top
15408
+ },
15409
+ parent: this._getParentOffset(),
15410
+
15411
+ // This is a relative to absolute position minus the actual position calculation -
15412
+ // only used for relative positioned helper
15413
+ relative: this._getRelativeOffset()
15414
+ } );
15415
+
15416
+ // Only after we got the offset, we can change the helper's position to absolute
15417
+ // TODO: Still need to figure out a way to make relative sorting possible
15418
+ this.helper.css( "position", "absolute" );
15419
+ this.cssPosition = this.helper.css( "position" );
15420
+
15421
+ //Generate the original position
15422
+ this.originalPosition = this._generatePosition( event );
15423
+ this.originalPageX = event.pageX;
15424
+ this.originalPageY = event.pageY;
15425
+
15426
+ //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15427
+ ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
15428
+
15429
+ //Cache the former DOM position
15430
+ this.domPosition = {
15431
+ prev: this.currentItem.prev()[ 0 ],
15432
+ parent: this.currentItem.parent()[ 0 ]
15433
+ };
15434
+
15435
+ // If the helper is not the original, hide the original so it's not playing any role during
15436
+ // the drag, won't cause anything bad this way
15437
+ if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
15438
+ this.currentItem.hide();
15439
+ }
15440
+
15441
+ //Create the placeholder
15442
+ this._createPlaceholder();
15443
+
15444
+ //Set a containment if given in the options
15445
+ if ( o.containment ) {
15446
+ this._setContainment();
15447
+ }
15448
+
15449
+ if ( o.cursor && o.cursor !== "auto" ) { // cursor option
15450
+ body = this.document.find( "body" );
15451
+
15452
+ // Support: IE
15453
+ this.storedCursor = body.css( "cursor" );
15454
+ body.css( "cursor", o.cursor );
15455
+
15456
+ this.storedStylesheet =
15457
+ $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
15458
+ }
15459
+
15460
+ if ( o.opacity ) { // opacity option
15461
+ if ( this.helper.css( "opacity" ) ) {
15462
+ this._storedOpacity = this.helper.css( "opacity" );
15463
+ }
15464
+ this.helper.css( "opacity", o.opacity );
15465
+ }
15466
+
15467
+ if ( o.zIndex ) { // zIndex option
15468
+ if ( this.helper.css( "zIndex" ) ) {
15469
+ this._storedZIndex = this.helper.css( "zIndex" );
15470
+ }
15471
+ this.helper.css( "zIndex", o.zIndex );
15472
+ }
15473
+
15474
+ //Prepare scrolling
15475
+ if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15476
+ this.scrollParent[ 0 ].tagName !== "HTML" ) {
15477
+ this.overflowOffset = this.scrollParent.offset();
15478
+ }
15479
+
15480
+ //Call callbacks
15481
+ this._trigger( "start", event, this._uiHash() );
15482
+
15483
+ //Recache the helper size
15484
+ if ( !this._preserveHelperProportions ) {
15485
+ this._cacheHelperProportions();
15486
+ }
15487
+
15488
+ //Post "activate" events to possible containers
15489
+ if ( !noActivation ) {
15490
+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
15491
+ this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
15492
+ }
15493
+ }
15494
+
15495
+ //Prepare possible droppables
15496
+ if ( $.ui.ddmanager ) {
15497
+ $.ui.ddmanager.current = this;
15498
+ }
15499
+
15500
+ if ( $.ui.ddmanager && !o.dropBehaviour ) {
15501
+ $.ui.ddmanager.prepareOffsets( this, event );
15502
+ }
15503
+
15504
+ this.dragging = true;
15505
+
15506
+ this._addClass( this.helper, "ui-sortable-helper" );
15507
+
15508
+ // Execute the drag once - this causes the helper not to be visiblebefore getting its
15509
+ // correct position
15510
+ this._mouseDrag( event );
15511
+ return true;
15512
+
15513
+ },
15514
+
15515
+ _mouseDrag: function( event ) {
15516
+ var i, item, itemElement, intersection,
15517
+ o = this.options,
15518
+ scrolled = false;
15519
+
15520
+ //Compute the helpers position
15521
+ this.position = this._generatePosition( event );
15522
+ this.positionAbs = this._convertPositionTo( "absolute" );
15523
+
15524
+ if ( !this.lastPositionAbs ) {
15525
+ this.lastPositionAbs = this.positionAbs;
15526
+ }
15527
+
15528
+ //Do scrolling
15529
+ if ( this.options.scroll ) {
15530
+ if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15531
+ this.scrollParent[ 0 ].tagName !== "HTML" ) {
15532
+
15533
+ if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
15534
+ event.pageY < o.scrollSensitivity ) {
15535
+ this.scrollParent[ 0 ].scrollTop =
15536
+ scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
15537
+ } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
15538
+ this.scrollParent[ 0 ].scrollTop =
15539
+ scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
15540
+ }
15541
+
15542
+ if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
15543
+ event.pageX < o.scrollSensitivity ) {
15544
+ this.scrollParent[ 0 ].scrollLeft = scrolled =
15545
+ this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
15546
+ } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
15547
+ this.scrollParent[ 0 ].scrollLeft = scrolled =
15548
+ this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
15549
+ }
15550
+
15551
+ } else {
15552
+
15553
+ if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
15554
+ scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
15555
+ } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
15556
+ o.scrollSensitivity ) {
15557
+ scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
15558
+ }
15559
+
15560
+ if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
15561
+ scrolled = this.document.scrollLeft(
15562
+ this.document.scrollLeft() - o.scrollSpeed
15563
+ );
15564
+ } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
15565
+ o.scrollSensitivity ) {
15566
+ scrolled = this.document.scrollLeft(
15567
+ this.document.scrollLeft() + o.scrollSpeed
15568
+ );
15569
+ }
15570
+
15571
+ }
15572
+
15573
+ if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
15574
+ $.ui.ddmanager.prepareOffsets( this, event );
15575
+ }
15576
+ }
15577
+
15578
+ //Regenerate the absolute position used for position checks
15579
+ this.positionAbs = this._convertPositionTo( "absolute" );
15580
+
15581
+ //Set the helper position
15582
+ if ( !this.options.axis || this.options.axis !== "y" ) {
15583
+ this.helper[ 0 ].style.left = this.position.left + "px";
15584
+ }
15585
+ if ( !this.options.axis || this.options.axis !== "x" ) {
15586
+ this.helper[ 0 ].style.top = this.position.top + "px";
15587
+ }
15588
+
15589
+ //Rearrange
15590
+ for ( i = this.items.length - 1; i >= 0; i-- ) {
15591
+
15592
+ //Cache variables and intersection, continue if no intersection
15593
+ item = this.items[ i ];
15594
+ itemElement = item.item[ 0 ];
15595
+ intersection = this._intersectsWithPointer( item );
15596
+ if ( !intersection ) {
15597
+ continue;
15598
+ }
15599
+
15600
+ // Only put the placeholder inside the current Container, skip all
15601
+ // items from other containers. This works because when moving
15602
+ // an item from one container to another the
15603
+ // currentContainer is switched before the placeholder is moved.
15604
+ //
15605
+ // Without this, moving items in "sub-sortables" can cause
15606
+ // the placeholder to jitter between the outer and inner container.
15607
+ if ( item.instance !== this.currentContainer ) {
15608
+ continue;
15609
+ }
15610
+
15611
+ // Cannot intersect with itself
15612
+ // no useless actions that have been done before
15613
+ // no action if the item moved is the parent of the item checked
15614
+ if ( itemElement !== this.currentItem[ 0 ] &&
15615
+ this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
15616
+ !$.contains( this.placeholder[ 0 ], itemElement ) &&
15617
+ ( this.options.type === "semi-dynamic" ?
15618
+ !$.contains( this.element[ 0 ], itemElement ) :
15619
+ true
15620
+ )
15621
+ ) {
15622
+
15623
+ this.direction = intersection === 1 ? "down" : "up";
15624
+
15625
+ if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
15626
+ this._rearrange( event, item );
15627
+ } else {
15628
+ break;
15629
+ }
15630
+
15631
+ this._trigger( "change", event, this._uiHash() );
15632
+ break;
15633
+ }
15634
+ }
15635
+
15636
+ //Post events to containers
15637
+ this._contactContainers( event );
15638
+
15639
+ //Interconnect with droppables
15640
+ if ( $.ui.ddmanager ) {
15641
+ $.ui.ddmanager.drag( this, event );
15642
+ }
15643
+
15644
+ //Call callbacks
15645
+ this._trigger( "sort", event, this._uiHash() );
15646
+
15647
+ this.lastPositionAbs = this.positionAbs;
15648
+ return false;
15649
+
15650
+ },
15651
+
15652
+ _mouseStop: function( event, noPropagation ) {
15653
+
15654
+ if ( !event ) {
15655
+ return;
15656
+ }
15657
+
15658
+ //If we are using droppables, inform the manager about the drop
15659
+ if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
15660
+ $.ui.ddmanager.drop( this, event );
15661
+ }
15662
+
15663
+ if ( this.options.revert ) {
15664
+ var that = this,
15665
+ cur = this.placeholder.offset(),
15666
+ axis = this.options.axis,
15667
+ animation = {};
15668
+
15669
+ if ( !axis || axis === "x" ) {
15670
+ animation.left = cur.left - this.offset.parent.left - this.margins.left +
15671
+ ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15672
+ 0 :
15673
+ this.offsetParent[ 0 ].scrollLeft
15674
+ );
15675
+ }
15676
+ if ( !axis || axis === "y" ) {
15677
+ animation.top = cur.top - this.offset.parent.top - this.margins.top +
15678
+ ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15679
+ 0 :
15680
+ this.offsetParent[ 0 ].scrollTop
15681
+ );
15682
+ }
15683
+ this.reverting = true;
15684
+ $( this.helper ).animate(
15685
+ animation,
15686
+ parseInt( this.options.revert, 10 ) || 500,
15687
+ function() {
15688
+ that._clear( event );
15689
+ }
15690
+ );
15691
+ } else {
15692
+ this._clear( event, noPropagation );
15693
+ }
15694
+
15695
+ return false;
15696
+
15697
+ },
15698
+
15699
+ cancel: function() {
15700
+
15701
+ if ( this.dragging ) {
15702
+
15703
+ this._mouseUp( new $.Event( "mouseup", { target: null } ) );
15704
+
15705
+ if ( this.options.helper === "original" ) {
15706
+ this.currentItem.css( this._storedCSS );
15707
+ this._removeClass( this.currentItem, "ui-sortable-helper" );
15708
+ } else {
15709
+ this.currentItem.show();
15710
+ }
15711
+
15712
+ //Post deactivating events to containers
15713
+ for ( var i = this.containers.length - 1; i >= 0; i-- ) {
15714
+ this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
15715
+ if ( this.containers[ i ].containerCache.over ) {
15716
+ this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
15717
+ this.containers[ i ].containerCache.over = 0;
15718
+ }
15719
+ }
15720
+
15721
+ }
15722
+
15723
+ if ( this.placeholder ) {
15724
+
15725
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
15726
+ // it unbinds ALL events from the original node!
15727
+ if ( this.placeholder[ 0 ].parentNode ) {
15728
+ this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
15729
+ }
15730
+ if ( this.options.helper !== "original" && this.helper &&
15731
+ this.helper[ 0 ].parentNode ) {
15732
+ this.helper.remove();
15733
+ }
15734
+
15735
+ $.extend( this, {
15736
+ helper: null,
15737
+ dragging: false,
15738
+ reverting: false,
15739
+ _noFinalSort: null
15740
+ } );
15741
+
15742
+ if ( this.domPosition.prev ) {
15743
+ $( this.domPosition.prev ).after( this.currentItem );
15744
+ } else {
15745
+ $( this.domPosition.parent ).prepend( this.currentItem );
15746
+ }
15747
+ }
15748
+
15749
+ return this;
15750
+
15751
+ },
15752
+
15753
+ serialize: function( o ) {
15754
+
15755
+ var items = this._getItemsAsjQuery( o && o.connected ),
15756
+ str = [];
15757
+ o = o || {};
15758
+
15759
+ $( items ).each( function() {
15760
+ var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
15761
+ .match( o.expression || ( /(.+)[\-=_](.+)/ ) );
15762
+ if ( res ) {
15763
+ str.push(
15764
+ ( o.key || res[ 1 ] + "[]" ) +
15765
+ "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
15766
+ }
15767
+ } );
15768
+
15769
+ if ( !str.length && o.key ) {
15770
+ str.push( o.key + "=" );
15771
+ }
15772
+
15773
+ return str.join( "&" );
15774
+
15775
+ },
15776
+
15777
+ toArray: function( o ) {
15778
+
15779
+ var items = this._getItemsAsjQuery( o && o.connected ),
15780
+ ret = [];
15781
+
15782
+ o = o || {};
15783
+
15784
+ items.each( function() {
15785
+ ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
15786
+ } );
15787
+ return ret;
15788
+
15789
+ },
15790
+
15791
+ /* Be careful with the following core functions */
15792
+ _intersectsWith: function( item ) {
15793
+
15794
+ var x1 = this.positionAbs.left,
15795
+ x2 = x1 + this.helperProportions.width,
15796
+ y1 = this.positionAbs.top,
15797
+ y2 = y1 + this.helperProportions.height,
15798
+ l = item.left,
15799
+ r = l + item.width,
15800
+ t = item.top,
15801
+ b = t + item.height,
15802
+ dyClick = this.offset.click.top,
15803
+ dxClick = this.offset.click.left,
15804
+ isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
15805
+ ( y1 + dyClick ) < b ),
15806
+ isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
15807
+ ( x1 + dxClick ) < r ),
15808
+ isOverElement = isOverElementHeight && isOverElementWidth;
15809
+
15810
+ if ( this.options.tolerance === "pointer" ||
15811
+ this.options.forcePointerForContainers ||
15812
+ ( this.options.tolerance !== "pointer" &&
15813
+ this.helperProportions[ this.floating ? "width" : "height" ] >
15814
+ item[ this.floating ? "width" : "height" ] )
15815
+ ) {
15816
+ return isOverElement;
15817
+ } else {
15818
+
15819
+ return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
15820
+ x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
15821
+ t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
15822
+ y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
15823
+
15824
+ }
15825
+ },
15826
+
15827
+ _intersectsWithPointer: function( item ) {
15828
+ var verticalDirection, horizontalDirection,
15829
+ isOverElementHeight = ( this.options.axis === "x" ) ||
15830
+ this._isOverAxis(
15831
+ this.positionAbs.top + this.offset.click.top, item.top, item.height ),
15832
+ isOverElementWidth = ( this.options.axis === "y" ) ||
15833
+ this._isOverAxis(
15834
+ this.positionAbs.left + this.offset.click.left, item.left, item.width ),
15835
+ isOverElement = isOverElementHeight && isOverElementWidth;
15836
+
15837
+ if ( !isOverElement ) {
15838
+ return false;
15839
+ }
15840
+
15841
+ verticalDirection = this._getDragVerticalDirection();
15842
+ horizontalDirection = this._getDragHorizontalDirection();
15843
+
15844
+ return this.floating ?
15845
+ ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
15846
+ : ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
15847
+
15848
+ },
15849
+
15850
+ _intersectsWithSides: function( item ) {
15851
+
15852
+ var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
15853
+ this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
15854
+ isOverRightHalf = this._isOverAxis( this.positionAbs.left +
15855
+ this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
15856
+ verticalDirection = this._getDragVerticalDirection(),
15857
+ horizontalDirection = this._getDragHorizontalDirection();
15858
+
15859
+ if ( this.floating && horizontalDirection ) {
15860
+ return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
15861
+ ( horizontalDirection === "left" && !isOverRightHalf ) );
15862
+ } else {
15863
+ return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
15864
+ ( verticalDirection === "up" && !isOverBottomHalf ) );
15865
+ }
15866
+
15867
+ },
15868
+
15869
+ _getDragVerticalDirection: function() {
15870
+ var delta = this.positionAbs.top - this.lastPositionAbs.top;
15871
+ return delta !== 0 && ( delta > 0 ? "down" : "up" );
15872
+ },
15873
+
15874
+ _getDragHorizontalDirection: function() {
15875
+ var delta = this.positionAbs.left - this.lastPositionAbs.left;
15876
+ return delta !== 0 && ( delta > 0 ? "right" : "left" );
15877
+ },
15878
+
15879
+ refresh: function( event ) {
15880
+ this._refreshItems( event );
15881
+ this._setHandleClassName();
15882
+ this.refreshPositions();
15883
+ return this;
15884
+ },
15885
+
15886
+ _connectWith: function() {
15887
+ var options = this.options;
15888
+ return options.connectWith.constructor === String ?
15889
+ [ options.connectWith ] :
15890
+ options.connectWith;
15891
+ },
15892
+
15893
+ _getItemsAsjQuery: function( connected ) {
15894
+
15895
+ var i, j, cur, inst,
15896
+ items = [],
15897
+ queries = [],
15898
+ connectWith = this._connectWith();
15899
+
15900
+ if ( connectWith && connected ) {
15901
+ for ( i = connectWith.length - 1; i >= 0; i-- ) {
15902
+ cur = $( connectWith[ i ], this.document[ 0 ] );
15903
+ for ( j = cur.length - 1; j >= 0; j-- ) {
15904
+ inst = $.data( cur[ j ], this.widgetFullName );
15905
+ if ( inst && inst !== this && !inst.options.disabled ) {
15906
+ queries.push( [ $.isFunction( inst.options.items ) ?
15907
+ inst.options.items.call( inst.element ) :
15908
+ $( inst.options.items, inst.element )
15909
+ .not( ".ui-sortable-helper" )
15910
+ .not( ".ui-sortable-placeholder" ), inst ] );
15911
+ }
15912
+ }
15913
+ }
15914
+ }
15915
+
15916
+ queries.push( [ $.isFunction( this.options.items ) ?
15917
+ this.options.items
15918
+ .call( this.element, null, { options: this.options, item: this.currentItem } ) :
15919
+ $( this.options.items, this.element )
15920
+ .not( ".ui-sortable-helper" )
15921
+ .not( ".ui-sortable-placeholder" ), this ] );
15922
+
15923
+ function addItems() {
15924
+ items.push( this );
15925
+ }
15926
+ for ( i = queries.length - 1; i >= 0; i-- ) {
15927
+ queries[ i ][ 0 ].each( addItems );
15928
+ }
15929
+
15930
+ return $( items );
15931
+
15932
+ },
15933
+
15934
+ _removeCurrentsFromItems: function() {
15935
+
15936
+ var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
15937
+
15938
+ this.items = $.grep( this.items, function( item ) {
15939
+ for ( var j = 0; j < list.length; j++ ) {
15940
+ if ( list[ j ] === item.item[ 0 ] ) {
15941
+ return false;
15942
+ }
15943
+ }
15944
+ return true;
15945
+ } );
15946
+
15947
+ },
15948
+
15949
+ _refreshItems: function( event ) {
15950
+
15951
+ this.items = [];
15952
+ this.containers = [ this ];
15953
+
15954
+ var i, j, cur, inst, targetData, _queries, item, queriesLength,
15955
+ items = this.items,
15956
+ queries = [ [ $.isFunction( this.options.items ) ?
15957
+ this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
15958
+ $( this.options.items, this.element ), this ] ],
15959
+ connectWith = this._connectWith();
15960
+
15961
+ //Shouldn't be run the first time through due to massive slow-down
15962
+ if ( connectWith && this.ready ) {
15963
+ for ( i = connectWith.length - 1; i >= 0; i-- ) {
15964
+ cur = $( connectWith[ i ], this.document[ 0 ] );
15965
+ for ( j = cur.length - 1; j >= 0; j-- ) {
15966
+ inst = $.data( cur[ j ], this.widgetFullName );
15967
+ if ( inst && inst !== this && !inst.options.disabled ) {
15968
+ queries.push( [ $.isFunction( inst.options.items ) ?
15969
+ inst.options.items
15970
+ .call( inst.element[ 0 ], event, { item: this.currentItem } ) :
15971
+ $( inst.options.items, inst.element ), inst ] );
15972
+ this.containers.push( inst );
15973
+ }
15974
+ }
15975
+ }
15976
+ }
15977
+
15978
+ for ( i = queries.length - 1; i >= 0; i-- ) {
15979
+ targetData = queries[ i ][ 1 ];
15980
+ _queries = queries[ i ][ 0 ];
15981
+
15982
+ for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
15983
+ item = $( _queries[ j ] );
15984
+
15985
+ // Data for target checking (mouse manager)
15986
+ item.data( this.widgetName + "-item", targetData );
15987
+
15988
+ items.push( {
15989
+ item: item,
15990
+ instance: targetData,
15991
+ width: 0, height: 0,
15992
+ left: 0, top: 0
15993
+ } );
15994
+ }
15995
+ }
15996
+
15997
+ },
15998
+
15999
+ refreshPositions: function( fast ) {
16000
+
16001
+ // Determine whether items are being displayed horizontally
16002
+ this.floating = this.items.length ?
16003
+ this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
16004
+ false;
16005
+
16006
+ //This has to be redone because due to the item being moved out/into the offsetParent,
16007
+ // the offsetParent's position will change
16008
+ if ( this.offsetParent && this.helper ) {
16009
+ this.offset.parent = this._getParentOffset();
16010
+ }
16011
+
16012
+ var i, item, t, p;
16013
+
16014
+ for ( i = this.items.length - 1; i >= 0; i-- ) {
16015
+ item = this.items[ i ];
16016
+
16017
+ //We ignore calculating positions of all connected containers when we're not over them
16018
+ if ( item.instance !== this.currentContainer && this.currentContainer &&
16019
+ item.item[ 0 ] !== this.currentItem[ 0 ] ) {
16020
+ continue;
16021
+ }
16022
+
16023
+ t = this.options.toleranceElement ?
16024
+ $( this.options.toleranceElement, item.item ) :
16025
+ item.item;
16026
+
16027
+ if ( !fast ) {
16028
+ item.width = t.outerWidth();
16029
+ item.height = t.outerHeight();
16030
+ }
16031
+
16032
+ p = t.offset();
16033
+ item.left = p.left;
16034
+ item.top = p.top;
16035
+ }
16036
+
16037
+ if ( this.options.custom && this.options.custom.refreshContainers ) {
16038
+ this.options.custom.refreshContainers.call( this );
16039
+ } else {
16040
+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
16041
+ p = this.containers[ i ].element.offset();
16042
+ this.containers[ i ].containerCache.left = p.left;
16043
+ this.containers[ i ].containerCache.top = p.top;
16044
+ this.containers[ i ].containerCache.width =
16045
+ this.containers[ i ].element.outerWidth();
16046
+ this.containers[ i ].containerCache.height =
16047
+ this.containers[ i ].element.outerHeight();
16048
+ }
16049
+ }
16050
+
16051
+ return this;
16052
+ },
16053
+
16054
+ _createPlaceholder: function( that ) {
16055
+ that = that || this;
16056
+ var className,
16057
+ o = that.options;
16058
+
16059
+ if ( !o.placeholder || o.placeholder.constructor === String ) {
16060
+ className = o.placeholder;
16061
+ o.placeholder = {
16062
+ element: function() {
16063
+
16064
+ var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
16065
+ element = $( "<" + nodeName + ">", that.document[ 0 ] );
16066
+
16067
+ that._addClass( element, "ui-sortable-placeholder",
16068
+ className || that.currentItem[ 0 ].className )
16069
+ ._removeClass( element, "ui-sortable-helper" );
16070
+
16071
+ if ( nodeName === "tbody" ) {
16072
+ that._createTrPlaceholder(
16073
+ that.currentItem.find( "tr" ).eq( 0 ),
16074
+ $( "<tr>", that.document[ 0 ] ).appendTo( element )
16075
+ );
16076
+ } else if ( nodeName === "tr" ) {
16077
+ that._createTrPlaceholder( that.currentItem, element );
16078
+ } else if ( nodeName === "img" ) {
16079
+ element.attr( "src", that.currentItem.attr( "src" ) );
16080
+ }
16081
+
16082
+ if ( !className ) {
16083
+ element.css( "visibility", "hidden" );
16084
+ }
16085
+
16086
+ return element;
16087
+ },
16088
+ update: function( container, p ) {
16089
+
16090
+ // 1. If a className is set as 'placeholder option, we don't force sizes -
16091
+ // the class is responsible for that
16092
+ // 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16093
+ // class name is specified
16094
+ if ( className && !o.forcePlaceholderSize ) {
16095
+ return;
16096
+ }
16097
+
16098
+ //If the element doesn't have a actual height by itself (without styles coming
16099
+ // from a stylesheet), it receives the inline height from the dragged item
16100
+ if ( !p.height() ) {
16101
+ p.height(
16102
+ that.currentItem.innerHeight() -
16103
+ parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
16104
+ parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
16105
+ }
16106
+ if ( !p.width() ) {
16107
+ p.width(
16108
+ that.currentItem.innerWidth() -
16109
+ parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
16110
+ parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
16111
+ }
16112
+ }
16113
+ };
16114
+ }
16115
+
16116
+ //Create the placeholder
16117
+ that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
16118
+
16119
+ //Append it after the actual current item
16120
+ that.currentItem.after( that.placeholder );
16121
+
16122
+ //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16123
+ o.placeholder.update( that, that.placeholder );
16124
+
16125
+ },
16126
+
16127
+ _createTrPlaceholder: function( sourceTr, targetTr ) {
16128
+ var that = this;
16129
+
16130
+ sourceTr.children().each( function() {
16131
+ $( "<td>&#160;</td>", that.document[ 0 ] )
16132
+ .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
16133
+ .appendTo( targetTr );
16134
+ } );
16135
+ },
16136
+
16137
+ _contactContainers: function( event ) {
16138
+ var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16139
+ floating, axis,
16140
+ innermostContainer = null,
16141
+ innermostIndex = null;
16142
+
16143
+ // Get innermost container that intersects with item
16144
+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
16145
+
16146
+ // Never consider a container that's located within the item itself
16147
+ if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
16148
+ continue;
16149
+ }
16150
+
16151
+ if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
16152
+
16153
+ // If we've already found a container and it's more "inner" than this, then continue
16154
+ if ( innermostContainer &&
16155
+ $.contains(
16156
+ this.containers[ i ].element[ 0 ],
16157
+ innermostContainer.element[ 0 ] ) ) {
16158
+ continue;
16159
+ }
16160
+
16161
+ innermostContainer = this.containers[ i ];
16162
+ innermostIndex = i;
16163
+
16164
+ } else {
16165
+
16166
+ // container doesn't intersect. trigger "out" event if necessary
16167
+ if ( this.containers[ i ].containerCache.over ) {
16168
+ this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
16169
+ this.containers[ i ].containerCache.over = 0;
16170
+ }
16171
+ }
16172
+
16173
+ }
16174
+
16175
+ // If no intersecting containers found, return
16176
+ if ( !innermostContainer ) {
16177
+ return;
16178
+ }
16179
+
16180
+ // Move the item into the container if it's not there already
16181
+ if ( this.containers.length === 1 ) {
16182
+ if ( !this.containers[ innermostIndex ].containerCache.over ) {
16183
+ this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16184
+ this.containers[ innermostIndex ].containerCache.over = 1;
16185
+ }
16186
+ } else {
16187
+
16188
+ // When entering a new container, we will find the item with the least distance and
16189
+ // append our item near it
16190
+ dist = 10000;
16191
+ itemWithLeastDistance = null;
16192
+ floating = innermostContainer.floating || this._isFloating( this.currentItem );
16193
+ posProperty = floating ? "left" : "top";
16194
+ sizeProperty = floating ? "width" : "height";
16195
+ axis = floating ? "pageX" : "pageY";
16196
+
16197
+ for ( j = this.items.length - 1; j >= 0; j-- ) {
16198
+ if ( !$.contains(
16199
+ this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
16200
+ ) {
16201
+ continue;
16202
+ }
16203
+ if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
16204
+ continue;
16205
+ }
16206
+
16207
+ cur = this.items[ j ].item.offset()[ posProperty ];
16208
+ nearBottom = false;
16209
+ if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
16210
+ nearBottom = true;
16211
+ }
16212
+
16213
+ if ( Math.abs( event[ axis ] - cur ) < dist ) {
16214
+ dist = Math.abs( event[ axis ] - cur );
16215
+ itemWithLeastDistance = this.items[ j ];
16216
+ this.direction = nearBottom ? "up" : "down";
16217
+ }
16218
+ }
16219
+
16220
+ //Check if dropOnEmpty is enabled
16221
+ if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
16222
+ return;
16223
+ }
16224
+
16225
+ if ( this.currentContainer === this.containers[ innermostIndex ] ) {
16226
+ if ( !this.currentContainer.containerCache.over ) {
16227
+ this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
16228
+ this.currentContainer.containerCache.over = 1;
16229
+ }
16230
+ return;
16231
+ }
16232
+
16233
+ itemWithLeastDistance ?
16234
+ this._rearrange( event, itemWithLeastDistance, null, true ) :
16235
+ this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
16236
+ this._trigger( "change", event, this._uiHash() );
16237
+ this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
16238
+ this.currentContainer = this.containers[ innermostIndex ];
16239
+
16240
+ //Update the placeholder
16241
+ this.options.placeholder.update( this.currentContainer, this.placeholder );
16242
+
16243
+ this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16244
+ this.containers[ innermostIndex ].containerCache.over = 1;
16245
+ }
16246
+
16247
+ },
16248
+
16249
+ _createHelper: function( event ) {
16250
+
16251
+ var o = this.options,
16252
+ helper = $.isFunction( o.helper ) ?
16253
+ $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
16254
+ ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
16255
+
16256
+ //Add the helper to the DOM if that didn't happen already
16257
+ if ( !helper.parents( "body" ).length ) {
16258
+ $( o.appendTo !== "parent" ?
16259
+ o.appendTo :
16260
+ this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
16261
+ }
16262
+
16263
+ if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
16264
+ this._storedCSS = {
16265
+ width: this.currentItem[ 0 ].style.width,
16266
+ height: this.currentItem[ 0 ].style.height,
16267
+ position: this.currentItem.css( "position" ),
16268
+ top: this.currentItem.css( "top" ),
16269
+ left: this.currentItem.css( "left" )
16270
+ };
16271
+ }
16272
+
16273
+ if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
16274
+ helper.width( this.currentItem.width() );
16275
+ }
16276
+ if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
16277
+ helper.height( this.currentItem.height() );
16278
+ }
16279
+
16280
+ return helper;
16281
+
16282
+ },
16283
+
16284
+ _adjustOffsetFromHelper: function( obj ) {
16285
+ if ( typeof obj === "string" ) {
16286
+ obj = obj.split( " " );
16287
+ }
16288
+ if ( $.isArray( obj ) ) {
16289
+ obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
16290
+ }
16291
+ if ( "left" in obj ) {
16292
+ this.offset.click.left = obj.left + this.margins.left;
16293
+ }
16294
+ if ( "right" in obj ) {
16295
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16296
+ }
16297
+ if ( "top" in obj ) {
16298
+ this.offset.click.top = obj.top + this.margins.top;
16299
+ }
16300
+ if ( "bottom" in obj ) {
16301
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16302
+ }
16303
+ },
16304
+
16305
+ _getParentOffset: function() {
16306
+
16307
+ //Get the offsetParent and cache its position
16308
+ this.offsetParent = this.helper.offsetParent();
16309
+ var po = this.offsetParent.offset();
16310
+
16311
+ // This is a special case where we need to modify a offset calculated on start, since the
16312
+ // following happened:
16313
+ // 1. The position of the helper is absolute, so it's position is calculated based on the
16314
+ // next positioned parent
16315
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16316
+ // the document, which means that the scroll is included in the initial calculation of the
16317
+ // offset of the parent, and never recalculated upon drag
16318
+ if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16319
+ $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
16320
+ po.left += this.scrollParent.scrollLeft();
16321
+ po.top += this.scrollParent.scrollTop();
16322
+ }
16323
+
16324
+ // This needs to be actually done for all browsers, since pageX/pageY includes this
16325
+ // information with an ugly IE fix
16326
+ if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
16327
+ ( this.offsetParent[ 0 ].tagName &&
16328
+ this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
16329
+ po = { top: 0, left: 0 };
16330
+ }
16331
+
16332
+ return {
16333
+ top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
16334
+ left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
16335
+ };
16336
+
16337
+ },
16338
+
16339
+ _getRelativeOffset: function() {
16340
+
16341
+ if ( this.cssPosition === "relative" ) {
16342
+ var p = this.currentItem.position();
16343
+ return {
16344
+ top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
16345
+ this.scrollParent.scrollTop(),
16346
+ left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
16347
+ this.scrollParent.scrollLeft()
16348
+ };
16349
+ } else {
16350
+ return { top: 0, left: 0 };
16351
+ }
16352
+
16353
+ },
16354
+
16355
+ _cacheMargins: function() {
16356
+ this.margins = {
16357
+ left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
16358
+ top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
16359
+ };
16360
+ },
16361
+
16362
+ _cacheHelperProportions: function() {
16363
+ this.helperProportions = {
16364
+ width: this.helper.outerWidth(),
16365
+ height: this.helper.outerHeight()
16366
+ };
16367
+ },
16368
+
16369
+ _setContainment: function() {
16370
+
16371
+ var ce, co, over,
16372
+ o = this.options;
16373
+ if ( o.containment === "parent" ) {
16374
+ o.containment = this.helper[ 0 ].parentNode;
16375
+ }
16376
+ if ( o.containment === "document" || o.containment === "window" ) {
16377
+ this.containment = [
16378
+ 0 - this.offset.relative.left - this.offset.parent.left,
16379
+ 0 - this.offset.relative.top - this.offset.parent.top,
16380
+ o.containment === "document" ?
16381
+ this.document.width() :
16382
+ this.window.width() - this.helperProportions.width - this.margins.left,
16383
+ ( o.containment === "document" ?
16384
+ ( this.document.height() || document.body.parentNode.scrollHeight ) :
16385
+ this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
16386
+ ) - this.helperProportions.height - this.margins.top
16387
+ ];
16388
+ }
16389
+
16390
+ if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
16391
+ ce = $( o.containment )[ 0 ];
16392
+ co = $( o.containment ).offset();
16393
+ over = ( $( ce ).css( "overflow" ) !== "hidden" );
16394
+
16395
+ this.containment = [
16396
+ co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
16397
+ ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
16398
+ co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
16399
+ ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
16400
+ co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
16401
+ ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
16402
+ ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
16403
+ this.helperProportions.width - this.margins.left,
16404
+ co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16405
+ ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
16406
+ ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
16407
+ this.helperProportions.height - this.margins.top
16408
+ ];
16409
+ }
16410
+
16411
+ },
16412
+
16413
+ _convertPositionTo: function( d, pos ) {
16414
+
16415
+ if ( !pos ) {
16416
+ pos = this.position;
16417
+ }
16418
+ var mod = d === "absolute" ? 1 : -1,
16419
+ scroll = this.cssPosition === "absolute" &&
16420
+ !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16421
+ $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16422
+ this.offsetParent :
16423
+ this.scrollParent,
16424
+ scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16425
+
16426
+ return {
16427
+ top: (
16428
+
16429
+ // The absolute mouse position
16430
+ pos.top +
16431
+
16432
+ // Only for relative positioned nodes: Relative offset from element to offset parent
16433
+ this.offset.relative.top * mod +
16434
+
16435
+ // The offsetParent's offset without borders (offset + border)
16436
+ this.offset.parent.top * mod -
16437
+ ( ( this.cssPosition === "fixed" ?
16438
+ -this.scrollParent.scrollTop() :
16439
+ ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
16440
+ ),
16441
+ left: (
16442
+
16443
+ // The absolute mouse position
16444
+ pos.left +
16445
+
16446
+ // Only for relative positioned nodes: Relative offset from element to offset parent
16447
+ this.offset.relative.left * mod +
16448
+
16449
+ // The offsetParent's offset without borders (offset + border)
16450
+ this.offset.parent.left * mod -
16451
+ ( ( this.cssPosition === "fixed" ?
16452
+ -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
16453
+ scroll.scrollLeft() ) * mod )
16454
+ )
16455
+ };
16456
+
16457
+ },
16458
+
16459
+ _generatePosition: function( event ) {
16460
+
16461
+ var top, left,
16462
+ o = this.options,
16463
+ pageX = event.pageX,
16464
+ pageY = event.pageY,
16465
+ scroll = this.cssPosition === "absolute" &&
16466
+ !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16467
+ $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16468
+ this.offsetParent :
16469
+ this.scrollParent,
16470
+ scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16471
+
16472
+ // This is another very weird special case that only happens for relative elements:
16473
+ // 1. If the css position is relative
16474
+ // 2. and the scroll parent is the document or similar to the offset parent
16475
+ // we have to refresh the relative offset during the scroll so there are no jumps
16476
+ if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16477
+ this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
16478
+ this.offset.relative = this._getRelativeOffset();
16479
+ }
16480
+
16481
+ /*
16482
+ * - Position constraining -
16483
+ * Constrain the position to a mix of grid, containment.
16484
+ */
16485
+
16486
+ if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
16487
+
16488
+ if ( this.containment ) {
16489
+ if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
16490
+ pageX = this.containment[ 0 ] + this.offset.click.left;
16491
+ }
16492
+ if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
16493
+ pageY = this.containment[ 1 ] + this.offset.click.top;
16494
+ }
16495
+ if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
16496
+ pageX = this.containment[ 2 ] + this.offset.click.left;
16497
+ }
16498
+ if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
16499
+ pageY = this.containment[ 3 ] + this.offset.click.top;
16500
+ }
16501
+ }
16502
+
16503
+ if ( o.grid ) {
16504
+ top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
16505
+ o.grid[ 1 ] ) * o.grid[ 1 ];
16506
+ pageY = this.containment ?
16507
+ ( ( top - this.offset.click.top >= this.containment[ 1 ] &&
16508
+ top - this.offset.click.top <= this.containment[ 3 ] ) ?
16509
+ top :
16510
+ ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
16511
+ top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
16512
+ top;
16513
+
16514
+ left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
16515
+ o.grid[ 0 ] ) * o.grid[ 0 ];
16516
+ pageX = this.containment ?
16517
+ ( ( left - this.offset.click.left >= this.containment[ 0 ] &&
16518
+ left - this.offset.click.left <= this.containment[ 2 ] ) ?
16519
+ left :
16520
+ ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
16521
+ left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
16522
+ left;
16523
+ }
16524
+
16525
+ }
16526
+
16527
+ return {
16528
+ top: (
16529
+
16530
+ // The absolute mouse position
16531
+ pageY -
16532
+
16533
+ // Click offset (relative to the element)
16534
+ this.offset.click.top -
16535
+
16536
+ // Only for relative positioned nodes: Relative offset from element to offset parent
16537
+ this.offset.relative.top -
16538
+
16539
+ // The offsetParent's offset without borders (offset + border)
16540
+ this.offset.parent.top +
16541
+ ( ( this.cssPosition === "fixed" ?
16542
+ -this.scrollParent.scrollTop() :
16543
+ ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
16544
+ ),
16545
+ left: (
16546
+
16547
+ // The absolute mouse position
16548
+ pageX -
16549
+
16550
+ // Click offset (relative to the element)
16551
+ this.offset.click.left -
16552
+
16553
+ // Only for relative positioned nodes: Relative offset from element to offset parent
16554
+ this.offset.relative.left -
16555
+
16556
+ // The offsetParent's offset without borders (offset + border)
16557
+ this.offset.parent.left +
16558
+ ( ( this.cssPosition === "fixed" ?
16559
+ -this.scrollParent.scrollLeft() :
16560
+ scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
16561
+ )
16562
+ };
16563
+
16564
+ },
16565
+
16566
+ _rearrange: function( event, i, a, hardRefresh ) {
16567
+
16568
+ a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
16569
+ i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
16570
+ ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
16571
+
16572
+ //Various things done here to improve the performance:
16573
+ // 1. we create a setTimeout, that calls refreshPositions
16574
+ // 2. on the instance, we have a counter variable, that get's higher after every append
16575
+ // 3. on the local scope, we copy the counter variable, and check in the timeout,
16576
+ // if it's still the same
16577
+ // 4. this lets only the last addition to the timeout stack through
16578
+ this.counter = this.counter ? ++this.counter : 1;
16579
+ var counter = this.counter;
16580
+
16581
+ this._delay( function() {
16582
+ if ( counter === this.counter ) {
16583
+
16584
+ //Precompute after each DOM insertion, NOT on mousemove
16585
+ this.refreshPositions( !hardRefresh );
16586
+ }
16587
+ } );
16588
+
16589
+ },
16590
+
16591
+ _clear: function( event, noPropagation ) {
16592
+
16593
+ this.reverting = false;
16594
+
16595
+ // We delay all events that have to be triggered to after the point where the placeholder
16596
+ // has been removed and everything else normalized again
16597
+ var i,
16598
+ delayedTriggers = [];
16599
+
16600
+ // We first have to update the dom position of the actual currentItem
16601
+ // Note: don't do it if the current item is already removed (by a user), or it gets
16602
+ // reappended (see #4088)
16603
+ if ( !this._noFinalSort && this.currentItem.parent().length ) {
16604
+ this.placeholder.before( this.currentItem );
16605
+ }
16606
+ this._noFinalSort = null;
16607
+
16608
+ if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
16609
+ for ( i in this._storedCSS ) {
16610
+ if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
16611
+ this._storedCSS[ i ] = "";
16612
+ }
16613
+ }
16614
+ this.currentItem.css( this._storedCSS );
16615
+ this._removeClass( this.currentItem, "ui-sortable-helper" );
16616
+ } else {
16617
+ this.currentItem.show();
16618
+ }
16619
+
16620
+ if ( this.fromOutside && !noPropagation ) {
16621
+ delayedTriggers.push( function( event ) {
16622
+ this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
16623
+ } );
16624
+ }
16625
+ if ( ( this.fromOutside ||
16626
+ this.domPosition.prev !==
16627
+ this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
16628
+ this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
16629
+
16630
+ // Trigger update callback if the DOM position has changed
16631
+ delayedTriggers.push( function( event ) {
16632
+ this._trigger( "update", event, this._uiHash() );
16633
+ } );
16634
+ }
16635
+
16636
+ // Check if the items Container has Changed and trigger appropriate
16637
+ // events.
16638
+ if ( this !== this.currentContainer ) {
16639
+ if ( !noPropagation ) {
16640
+ delayedTriggers.push( function( event ) {
16641
+ this._trigger( "remove", event, this._uiHash() );
16642
+ } );
16643
+ delayedTriggers.push( ( function( c ) {
16644
+ return function( event ) {
16645
+ c._trigger( "receive", event, this._uiHash( this ) );
16646
+ };
16647
+ } ).call( this, this.currentContainer ) );
16648
+ delayedTriggers.push( ( function( c ) {
16649
+ return function( event ) {
16650
+ c._trigger( "update", event, this._uiHash( this ) );
16651
+ };
16652
+ } ).call( this, this.currentContainer ) );
16653
+ }
16654
+ }
16655
+
16656
+ //Post events to containers
16657
+ function delayEvent( type, instance, container ) {
16658
+ return function( event ) {
16659
+ container._trigger( type, event, instance._uiHash( instance ) );
16660
+ };
16661
+ }
16662
+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
16663
+ if ( !noPropagation ) {
16664
+ delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
16665
+ }
16666
+ if ( this.containers[ i ].containerCache.over ) {
16667
+ delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
16668
+ this.containers[ i ].containerCache.over = 0;
16669
+ }
16670
+ }
16671
+
16672
+ //Do what was originally in plugins
16673
+ if ( this.storedCursor ) {
16674
+ this.document.find( "body" ).css( "cursor", this.storedCursor );
16675
+ this.storedStylesheet.remove();
16676
+ }
16677
+ if ( this._storedOpacity ) {
16678
+ this.helper.css( "opacity", this._storedOpacity );
16679
+ }
16680
+ if ( this._storedZIndex ) {
16681
+ this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
16682
+ }
16683
+
16684
+ this.dragging = false;
16685
+
16686
+ if ( !noPropagation ) {
16687
+ this._trigger( "beforeStop", event, this._uiHash() );
16688
+ }
16689
+
16690
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16691
+ // it unbinds ALL events from the original node!
16692
+ this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
16693
+
16694
+ if ( !this.cancelHelperRemoval ) {
16695
+ if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
16696
+ this.helper.remove();
16697
+ }
16698
+ this.helper = null;
16699
+ }
16700
+
16701
+ if ( !noPropagation ) {
16702
+ for ( i = 0; i < delayedTriggers.length; i++ ) {
16703
+
16704
+ // Trigger all delayed events
16705
+ delayedTriggers[ i ].call( this, event );
16706
+ }
16707
+ this._trigger( "stop", event, this._uiHash() );
16708
+ }
16709
+
16710
+ this.fromOutside = false;
16711
+ return !this.cancelHelperRemoval;
16712
+
16713
+ },
16714
+
16715
+ _trigger: function() {
16716
+ if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
16717
+ this.cancel();
16718
+ }
16719
+ },
16720
+
16721
+ _uiHash: function( _inst ) {
16722
+ var inst = _inst || this;
16723
+ return {
16724
+ helper: inst.helper,
16725
+ placeholder: inst.placeholder || $( [] ),
16726
+ position: inst.position,
16727
+ originalPosition: inst.originalPosition,
16728
+ offset: inst.positionAbs,
16729
+ item: inst.currentItem,
16730
+ sender: _inst ? _inst.element : null
16731
+ };
16732
+ }
16733
+
16734
+ } );
16735
+
16736
+
16737
+ /*!
16738
+ * jQuery UI Spinner 1.12.1
16739
+ * http://jqueryui.com
16740
+ *
16741
+ * Copyright jQuery Foundation and other contributors
16742
+ * Released under the MIT license.
16743
+ * http://jquery.org/license
16744
+ */
16745
+
16746
+ //>>label: Spinner
16747
+ //>>group: Widgets
16748
+ //>>description: Displays buttons to easily input numbers via the keyboard or mouse.
16749
+ //>>docs: http://api.jqueryui.com/spinner/
16750
+ //>>demos: http://jqueryui.com/spinner/
16751
+ //>>css.structure: ../../themes/base/core.css
16752
+ //>>css.structure: ../../themes/base/spinner.css
16753
+ //>>css.theme: ../../themes/base/theme.css
16754
+
16755
+
16756
+
16757
+ function spinnerModifer( fn ) {
16758
+ return function() {
16759
+ var previous = this.element.val();
16760
+ fn.apply( this, arguments );
16761
+ this._refresh();
16762
+ if ( previous !== this.element.val() ) {
16763
+ this._trigger( "change" );
16764
+ }
16765
+ };
16766
+ }
16767
+
16768
+ $.widget( "ui.spinner", {
16769
+ version: "1.12.1",
16770
+ defaultElement: "<input>",
16771
+ widgetEventPrefix: "spin",
16772
+ options: {
16773
+ classes: {
16774
+ "ui-spinner": "ui-corner-all",
16775
+ "ui-spinner-down": "ui-corner-br",
16776
+ "ui-spinner-up": "ui-corner-tr"
16777
+ },
16778
+ culture: null,
16779
+ icons: {
16780
+ down: "ui-icon-triangle-1-s",
16781
+ up: "ui-icon-triangle-1-n"
16782
+ },
16783
+ incremental: true,
16784
+ max: null,
16785
+ min: null,
16786
+ numberFormat: null,
16787
+ page: 10,
16788
+ step: 1,
16789
+
16790
+ change: null,
16791
+ spin: null,
16792
+ start: null,
16793
+ stop: null
16794
+ },
16795
+
16796
+ _create: function() {
16797
+
16798
+ // handle string values that need to be parsed
16799
+ this._setOption( "max", this.options.max );
16800
+ this._setOption( "min", this.options.min );
16801
+ this._setOption( "step", this.options.step );
16802
+
16803
+ // Only format if there is a value, prevents the field from being marked
16804
+ // as invalid in Firefox, see #9573.
16805
+ if ( this.value() !== "" ) {
16806
+
16807
+ // Format the value, but don't constrain.
16808
+ this._value( this.element.val(), true );
16809
+ }
16810
+
16811
+ this._draw();
16812
+ this._on( this._events );
16813
+ this._refresh();
16814
+
16815
+ // Turning off autocomplete prevents the browser from remembering the
16816
+ // value when navigating through history, so we re-enable autocomplete
16817
+ // if the page is unloaded before the widget is destroyed. #7790
16818
+ this._on( this.window, {
16819
+ beforeunload: function() {
16820
+ this.element.removeAttr( "autocomplete" );
16821
+ }
16822
+ } );
16823
+ },
16824
+
16825
+ _getCreateOptions: function() {
16826
+ var options = this._super();
16827
+ var element = this.element;
16828
+
16829
+ $.each( [ "min", "max", "step" ], function( i, option ) {
16830
+ var value = element.attr( option );
16831
+ if ( value != null && value.length ) {
16832
+ options[ option ] = value;
16833
+ }
16834
+ } );
16835
+
16836
+ return options;
16837
+ },
16838
+
16839
+ _events: {
16840
+ keydown: function( event ) {
16841
+ if ( this._start( event ) && this._keydown( event ) ) {
16842
+ event.preventDefault();
16843
+ }
16844
+ },
16845
+ keyup: "_stop",
16846
+ focus: function() {
16847
+ this.previous = this.element.val();
16848
+ },
16849
+ blur: function( event ) {
16850
+ if ( this.cancelBlur ) {
16851
+ delete this.cancelBlur;
16852
+ return;
16853
+ }
16854
+
16855
+ this._stop();
16856
+ this._refresh();
16857
+ if ( this.previous !== this.element.val() ) {
16858
+ this._trigger( "change", event );
16859
+ }
16860
+ },
16861
+ mousewheel: function( event, delta ) {
16862
+ if ( !delta ) {
16863
+ return;
16864
+ }
16865
+ if ( !this.spinning && !this._start( event ) ) {
16866
+ return false;
16867
+ }
16868
+
16869
+ this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
16870
+ clearTimeout( this.mousewheelTimer );
16871
+ this.mousewheelTimer = this._delay( function() {
16872
+ if ( this.spinning ) {
16873
+ this._stop( event );
16874
+ }
16875
+ }, 100 );
16876
+ event.preventDefault();
16877
+ },
16878
+ "mousedown .ui-spinner-button": function( event ) {
16879
+ var previous;
16880
+
16881
+ // We never want the buttons to have focus; whenever the user is
16882
+ // interacting with the spinner, the focus should be on the input.
16883
+ // If the input is focused then this.previous is properly set from
16884
+ // when the input first received focus. If the input is not focused
16885
+ // then we need to set this.previous based on the value before spinning.
16886
+ previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
16887
+ this.previous : this.element.val();
16888
+ function checkFocus() {
16889
+ var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
16890
+ if ( !isActive ) {
16891
+ this.element.trigger( "focus" );
16892
+ this.previous = previous;
16893
+
16894
+ // support: IE
16895
+ // IE sets focus asynchronously, so we need to check if focus
16896
+ // moved off of the input because the user clicked on the button.
16897
+ this._delay( function() {
16898
+ this.previous = previous;
16899
+ } );
16900
+ }
16901
+ }
16902
+
16903
+ // Ensure focus is on (or stays on) the text field
16904
+ event.preventDefault();
16905
+ checkFocus.call( this );
16906
+
16907
+ // Support: IE
16908
+ // IE doesn't prevent moving focus even with event.preventDefault()
16909
+ // so we set a flag to know when we should ignore the blur event
16910
+ // and check (again) if focus moved off of the input.
16911
+ this.cancelBlur = true;
16912
+ this._delay( function() {
16913
+ delete this.cancelBlur;
16914
+ checkFocus.call( this );
16915
+ } );
16916
+
16917
+ if ( this._start( event ) === false ) {
16918
+ return;
16919
+ }
16920
+
16921
+ this._repeat( null, $( event.currentTarget )
16922
+ .hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16923
+ },
16924
+ "mouseup .ui-spinner-button": "_stop",
16925
+ "mouseenter .ui-spinner-button": function( event ) {
16926
+
16927
+ // button will add ui-state-active if mouse was down while mouseleave and kept down
16928
+ if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
16929
+ return;
16930
+ }
16931
+
16932
+ if ( this._start( event ) === false ) {
16933
+ return false;
16934
+ }
16935
+ this._repeat( null, $( event.currentTarget )
16936
+ .hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16937
+ },
16938
+
16939
+ // TODO: do we really want to consider this a stop?
16940
+ // shouldn't we just stop the repeater and wait until mouseup before
16941
+ // we trigger the stop event?
16942
+ "mouseleave .ui-spinner-button": "_stop"
16943
+ },
16944
+
16945
+ // Support mobile enhanced option and make backcompat more sane
16946
+ _enhance: function() {
16947
+ this.uiSpinner = this.element
16948
+ .attr( "autocomplete", "off" )
16949
+ .wrap( "<span>" )
16950
+ .parent()
16951
+
16952
+ // Add buttons
16953
+ .append(
16954
+ "<a></a><a></a>"
16955
+ );
16956
+ },
16957
+
16958
+ _draw: function() {
16959
+ this._enhance();
16960
+
16961
+ this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
16962
+ this._addClass( "ui-spinner-input" );
16963
+
16964
+ this.element.attr( "role", "spinbutton" );
16965
+
16966
+ // Button bindings
16967
+ this.buttons = this.uiSpinner.children( "a" )
16968
+ .attr( "tabIndex", -1 )
16969
+ .attr( "aria-hidden", true )
16970
+ .button( {
16971
+ classes: {
16972
+ "ui-button": ""
16973
+ }
16974
+ } );
16975
+
16976
+ // TODO: Right now button does not support classes this is already updated in button PR
16977
+ this._removeClass( this.buttons, "ui-corner-all" );
16978
+
16979
+ this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
16980
+ this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
16981
+ this.buttons.first().button( {
16982
+ "icon": this.options.icons.up,
16983
+ "showLabel": false
16984
+ } );
16985
+ this.buttons.last().button( {
16986
+ "icon": this.options.icons.down,
16987
+ "showLabel": false
16988
+ } );
16989
+
16990
+ // IE 6 doesn't understand height: 50% for the buttons
16991
+ // unless the wrapper has an explicit height
16992
+ if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
16993
+ this.uiSpinner.height() > 0 ) {
16994
+ this.uiSpinner.height( this.uiSpinner.height() );
16995
+ }
16996
+ },
16997
+
16998
+ _keydown: function( event ) {
16999
+ var options = this.options,
17000
+ keyCode = $.ui.keyCode;
17001
+
17002
+ switch ( event.keyCode ) {
17003
+ case keyCode.UP:
17004
+ this._repeat( null, 1, event );
17005
+ return true;
17006
+ case keyCode.DOWN:
17007
+ this._repeat( null, -1, event );
17008
+ return true;
17009
+ case keyCode.PAGE_UP:
17010
+ this._repeat( null, options.page, event );
17011
+ return true;
17012
+ case keyCode.PAGE_DOWN:
17013
+ this._repeat( null, -options.page, event );
17014
+ return true;
17015
+ }
17016
+
17017
+ return false;
17018
+ },
17019
+
17020
+ _start: function( event ) {
17021
+ if ( !this.spinning && this._trigger( "start", event ) === false ) {
17022
+ return false;
17023
+ }
17024
+
17025
+ if ( !this.counter ) {
17026
+ this.counter = 1;
17027
+ }
17028
+ this.spinning = true;
17029
+ return true;
17030
+ },
17031
+
17032
+ _repeat: function( i, steps, event ) {
17033
+ i = i || 500;
17034
+
17035
+ clearTimeout( this.timer );
17036
+ this.timer = this._delay( function() {
17037
+ this._repeat( 40, steps, event );
17038
+ }, i );
17039
+
17040
+ this._spin( steps * this.options.step, event );
17041
+ },
17042
+
17043
+ _spin: function( step, event ) {
17044
+ var value = this.value() || 0;
17045
+
17046
+ if ( !this.counter ) {
17047
+ this.counter = 1;
17048
+ }
17049
+
17050
+ value = this._adjustValue( value + step * this._increment( this.counter ) );
17051
+
17052
+ if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
17053
+ this._value( value );
17054
+ this.counter++;
17055
+ }
17056
+ },
17057
+
17058
+ _increment: function( i ) {
17059
+ var incremental = this.options.incremental;
17060
+
17061
+ if ( incremental ) {
17062
+ return $.isFunction( incremental ) ?
17063
+ incremental( i ) :
17064
+ Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
17065
+ }
17066
+
17067
+ return 1;
17068
+ },
17069
+
17070
+ _precision: function() {
17071
+ var precision = this._precisionOf( this.options.step );
17072
+ if ( this.options.min !== null ) {
17073
+ precision = Math.max( precision, this._precisionOf( this.options.min ) );
17074
+ }
17075
+ return precision;
17076
+ },
17077
+
17078
+ _precisionOf: function( num ) {
17079
+ var str = num.toString(),
17080
+ decimal = str.indexOf( "." );
17081
+ return decimal === -1 ? 0 : str.length - decimal - 1;
17082
+ },
17083
+
17084
+ _adjustValue: function( value ) {
17085
+ var base, aboveMin,
17086
+ options = this.options;
17087
+
17088
+ // Make sure we're at a valid step
17089
+ // - find out where we are relative to the base (min or 0)
17090
+ base = options.min !== null ? options.min : 0;
17091
+ aboveMin = value - base;
17092
+
17093
+ // - round to the nearest step
17094
+ aboveMin = Math.round( aboveMin / options.step ) * options.step;
17095
+
17096
+ // - rounding is based on 0, so adjust back to our base
17097
+ value = base + aboveMin;
17098
+
17099
+ // Fix precision from bad JS floating point math
17100
+ value = parseFloat( value.toFixed( this._precision() ) );
17101
+
17102
+ // Clamp the value
17103
+ if ( options.max !== null && value > options.max ) {
17104
+ return options.max;
17105
+ }
17106
+ if ( options.min !== null && value < options.min ) {
17107
+ return options.min;
17108
+ }
17109
+
17110
+ return value;
17111
+ },
17112
+
17113
+ _stop: function( event ) {
17114
+ if ( !this.spinning ) {
17115
+ return;
17116
+ }
17117
+
17118
+ clearTimeout( this.timer );
17119
+ clearTimeout( this.mousewheelTimer );
17120
+ this.counter = 0;
17121
+ this.spinning = false;
17122
+ this._trigger( "stop", event );
17123
+ },
17124
+
17125
+ _setOption: function( key, value ) {
17126
+ var prevValue, first, last;
17127
+
17128
+ if ( key === "culture" || key === "numberFormat" ) {
17129
+ prevValue = this._parse( this.element.val() );
17130
+ this.options[ key ] = value;
17131
+ this.element.val( this._format( prevValue ) );
17132
+ return;
17133
+ }
17134
+
17135
+ if ( key === "max" || key === "min" || key === "step" ) {
17136
+ if ( typeof value === "string" ) {
17137
+ value = this._parse( value );
17138
+ }
17139
+ }
17140
+ if ( key === "icons" ) {
17141
+ first = this.buttons.first().find( ".ui-icon" );
17142
+ this._removeClass( first, null, this.options.icons.up );
17143
+ this._addClass( first, null, value.up );
17144
+ last = this.buttons.last().find( ".ui-icon" );
17145
+ this._removeClass( last, null, this.options.icons.down );
17146
+ this._addClass( last, null, value.down );
17147
+ }
17148
+
17149
+ this._super( key, value );
17150
+ },
17151
+
17152
+ _setOptionDisabled: function( value ) {
17153
+ this._super( value );
17154
+
17155
+ this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
17156
+ this.element.prop( "disabled", !!value );
17157
+ this.buttons.button( value ? "disable" : "enable" );
17158
+ },
17159
+
17160
+ _setOptions: spinnerModifer( function( options ) {
17161
+ this._super( options );
17162
+ } ),
17163
+
17164
+ _parse: function( val ) {
17165
+ if ( typeof val === "string" && val !== "" ) {
17166
+ val = window.Globalize && this.options.numberFormat ?
17167
+ Globalize.parseFloat( val, 10, this.options.culture ) : +val;
17168
+ }
17169
+ return val === "" || isNaN( val ) ? null : val;
17170
+ },
17171
+
17172
+ _format: function( value ) {
17173
+ if ( value === "" ) {
17174
+ return "";
17175
+ }
17176
+ return window.Globalize && this.options.numberFormat ?
17177
+ Globalize.format( value, this.options.numberFormat, this.options.culture ) :
17178
+ value;
17179
+ },
17180
+
17181
+ _refresh: function() {
17182
+ this.element.attr( {
17183
+ "aria-valuemin": this.options.min,
17184
+ "aria-valuemax": this.options.max,
17185
+
17186
+ // TODO: what should we do with values that can't be parsed?
17187
+ "aria-valuenow": this._parse( this.element.val() )
17188
+ } );
17189
+ },
17190
+
17191
+ isValid: function() {
17192
+ var value = this.value();
17193
+
17194
+ // Null is invalid
17195
+ if ( value === null ) {
17196
+ return false;
17197
+ }
17198
+
17199
+ // If value gets adjusted, it's invalid
17200
+ return value === this._adjustValue( value );
17201
+ },
17202
+
17203
+ // Update the value without triggering change
17204
+ _value: function( value, allowAny ) {
17205
+ var parsed;
17206
+ if ( value !== "" ) {
17207
+ parsed = this._parse( value );
17208
+ if ( parsed !== null ) {
17209
+ if ( !allowAny ) {
17210
+ parsed = this._adjustValue( parsed );
17211
+ }
17212
+ value = this._format( parsed );
17213
+ }
17214
+ }
17215
+ this.element.val( value );
17216
+ this._refresh();
17217
+ },
17218
+
17219
+ _destroy: function() {
17220
+ this.element
17221
+ .prop( "disabled", false )
17222
+ .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
17223
+
17224
+ this.uiSpinner.replaceWith( this.element );
17225
+ },
17226
+
17227
+ stepUp: spinnerModifer( function( steps ) {
17228
+ this._stepUp( steps );
17229
+ } ),
17230
+ _stepUp: function( steps ) {
17231
+ if ( this._start() ) {
17232
+ this._spin( ( steps || 1 ) * this.options.step );
17233
+ this._stop();
17234
+ }
17235
+ },
17236
+
17237
+ stepDown: spinnerModifer( function( steps ) {
17238
+ this._stepDown( steps );
17239
+ } ),
17240
+ _stepDown: function( steps ) {
17241
+ if ( this._start() ) {
17242
+ this._spin( ( steps || 1 ) * -this.options.step );
17243
+ this._stop();
17244
+ }
17245
+ },
17246
+
17247
+ pageUp: spinnerModifer( function( pages ) {
17248
+ this._stepUp( ( pages || 1 ) * this.options.page );
17249
+ } ),
17250
+
17251
+ pageDown: spinnerModifer( function( pages ) {
17252
+ this._stepDown( ( pages || 1 ) * this.options.page );
17253
+ } ),
17254
+
17255
+ value: function( newVal ) {
17256
+ if ( !arguments.length ) {
17257
+ return this._parse( this.element.val() );
17258
+ }
17259
+ spinnerModifer( this._value ).call( this, newVal );
17260
+ },
17261
+
17262
+ widget: function() {
17263
+ return this.uiSpinner;
17264
+ }
17265
+ } );
17266
+
17267
+ // DEPRECATED
17268
+ // TODO: switch return back to widget declaration at top of file when this is removed
17269
+ if ( $.uiBackCompat !== false ) {
17270
+
17271
+ // Backcompat for spinner html extension points
17272
+ $.widget( "ui.spinner", $.ui.spinner, {
17273
+ _enhance: function() {
17274
+ this.uiSpinner = this.element
17275
+ .attr( "autocomplete", "off" )
17276
+ .wrap( this._uiSpinnerHtml() )
17277
+ .parent()
17278
+
17279
+ // Add buttons
17280
+ .append( this._buttonHtml() );
17281
+ },
17282
+ _uiSpinnerHtml: function() {
17283
+ return "<span>";
17284
+ },
17285
+
17286
+ _buttonHtml: function() {
17287
+ return "<a></a><a></a>";
17288
+ }
17289
+ } );
17290
+ }
17291
+
17292
+ var widgetsSpinner = $.ui.spinner;
17293
+
17294
+
17295
+ /*!
17296
+ * jQuery UI Tabs 1.12.1
17297
+ * http://jqueryui.com
17298
+ *
17299
+ * Copyright jQuery Foundation and other contributors
17300
+ * Released under the MIT license.
17301
+ * http://jquery.org/license
17302
+ */
17303
+
17304
+ //>>label: Tabs
17305
+ //>>group: Widgets
17306
+ //>>description: Transforms a set of container elements into a tab structure.
17307
+ //>>docs: http://api.jqueryui.com/tabs/
17308
+ //>>demos: http://jqueryui.com/tabs/
17309
+ //>>css.structure: ../../themes/base/core.css
17310
+ //>>css.structure: ../../themes/base/tabs.css
17311
+ //>>css.theme: ../../themes/base/theme.css
17312
+
17313
+
17314
+
17315
+ $.widget( "ui.tabs", {
17316
+ version: "1.12.1",
17317
+ delay: 300,
17318
+ options: {
17319
+ active: null,
17320
+ classes: {
17321
+ "ui-tabs": "ui-corner-all",
17322
+ "ui-tabs-nav": "ui-corner-all",
17323
+ "ui-tabs-panel": "ui-corner-bottom",
17324
+ "ui-tabs-tab": "ui-corner-top"
17325
+ },
17326
+ collapsible: false,
17327
+ event: "click",
17328
+ heightStyle: "content",
17329
+ hide: null,
17330
+ show: null,
17331
+
17332
+ // Callbacks
17333
+ activate: null,
17334
+ beforeActivate: null,
17335
+ beforeLoad: null,
17336
+ load: null
17337
+ },
17338
+
17339
+ _isLocal: ( function() {
17340
+ var rhash = /#.*$/;
17341
+
17342
+ return function( anchor ) {
17343
+ var anchorUrl, locationUrl;
17344
+
17345
+ anchorUrl = anchor.href.replace( rhash, "" );
17346
+ locationUrl = location.href.replace( rhash, "" );
17347
+
17348
+ // Decoding may throw an error if the URL isn't UTF-8 (#9518)
17349
+ try {
17350
+ anchorUrl = decodeURIComponent( anchorUrl );
17351
+ } catch ( error ) {}
17352
+ try {
17353
+ locationUrl = decodeURIComponent( locationUrl );
17354
+ } catch ( error ) {}
17355
+
17356
+ return anchor.hash.length > 1 && anchorUrl === locationUrl;
17357
+ };
17358
+ } )(),
17359
+
17360
+ _create: function() {
17361
+ var that = this,
17362
+ options = this.options;
17363
+
17364
+ this.running = false;
17365
+
17366
+ this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
17367
+ this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
17368
+
17369
+ this._processTabs();
17370
+ options.active = this._initialActive();
17371
+
17372
+ // Take disabling tabs via class attribute from HTML
17373
+ // into account and update option properly.
17374
+ if ( $.isArray( options.disabled ) ) {
17375
+ options.disabled = $.unique( options.disabled.concat(
17376
+ $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
17377
+ return that.tabs.index( li );
17378
+ } )
17379
+ ) ).sort();
17380
+ }
17381
+
17382
+ // Check for length avoids error when initializing empty list
17383
+ if ( this.options.active !== false && this.anchors.length ) {
17384
+ this.active = this._findActive( options.active );
17385
+ } else {
17386
+ this.active = $();
17387
+ }
17388
+
17389
+ this._refresh();
17390
+
17391
+ if ( this.active.length ) {
17392
+ this.load( options.active );
17393
+ }
17394
+ },
17395
+
17396
+ _initialActive: function() {
17397
+ var active = this.options.active,
17398
+ collapsible = this.options.collapsible,
17399
+ locationHash = location.hash.substring( 1 );
17400
+
17401
+ if ( active === null ) {
17402
+
17403
+ // check the fragment identifier in the URL
17404
+ if ( locationHash ) {
17405
+ this.tabs.each( function( i, tab ) {
17406
+ if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
17407
+ active = i;
17408
+ return false;
17409
+ }
17410
+ } );
17411
+ }
17412
+
17413
+ // Check for a tab marked active via a class
17414
+ if ( active === null ) {
17415
+ active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
17416
+ }
17417
+
17418
+ // No active tab, set to false
17419
+ if ( active === null || active === -1 ) {
17420
+ active = this.tabs.length ? 0 : false;
17421
+ }
17422
+ }
17423
+
17424
+ // Handle numbers: negative, out of range
17425
+ if ( active !== false ) {
17426
+ active = this.tabs.index( this.tabs.eq( active ) );
17427
+ if ( active === -1 ) {
17428
+ active = collapsible ? false : 0;
17429
+ }
17430
+ }
17431
+
17432
+ // Don't allow collapsible: false and active: false
17433
+ if ( !collapsible && active === false && this.anchors.length ) {
17434
+ active = 0;
17435
+ }
17436
+
17437
+ return active;
17438
+ },
17439
+
17440
+ _getCreateEventData: function() {
17441
+ return {
17442
+ tab: this.active,
17443
+ panel: !this.active.length ? $() : this._getPanelForTab( this.active )
17444
+ };
17445
+ },
17446
+
17447
+ _tabKeydown: function( event ) {
17448
+ var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
17449
+ selectedIndex = this.tabs.index( focusedTab ),
17450
+ goingForward = true;
17451
+
17452
+ if ( this._handlePageNav( event ) ) {
17453
+ return;
17454
+ }
17455
+
17456
+ switch ( event.keyCode ) {
17457
+ case $.ui.keyCode.RIGHT:
17458
+ case $.ui.keyCode.DOWN:
17459
+ selectedIndex++;
17460
+ break;
17461
+ case $.ui.keyCode.UP:
17462
+ case $.ui.keyCode.LEFT:
17463
+ goingForward = false;
17464
+ selectedIndex--;
17465
+ break;
17466
+ case $.ui.keyCode.END:
17467
+ selectedIndex = this.anchors.length - 1;
17468
+ break;
17469
+ case $.ui.keyCode.HOME:
17470
+ selectedIndex = 0;
17471
+ break;
17472
+ case $.ui.keyCode.SPACE:
17473
+
17474
+ // Activate only, no collapsing
17475
+ event.preventDefault();
17476
+ clearTimeout( this.activating );
17477
+ this._activate( selectedIndex );
17478
+ return;
17479
+ case $.ui.keyCode.ENTER:
17480
+
17481
+ // Toggle (cancel delayed activation, allow collapsing)
17482
+ event.preventDefault();
17483
+ clearTimeout( this.activating );
17484
+
17485
+ // Determine if we should collapse or activate
17486
+ this._activate( selectedIndex === this.options.active ? false : selectedIndex );
17487
+ return;
17488
+ default:
17489
+ return;
17490
+ }
17491
+
17492
+ // Focus the appropriate tab, based on which key was pressed
17493
+ event.preventDefault();
17494
+ clearTimeout( this.activating );
17495
+ selectedIndex = this._focusNextTab( selectedIndex, goingForward );
17496
+
17497
+ // Navigating with control/command key will prevent automatic activation
17498
+ if ( !event.ctrlKey && !event.metaKey ) {
17499
+
17500
+ // Update aria-selected immediately so that AT think the tab is already selected.
17501
+ // Otherwise AT may confuse the user by stating that they need to activate the tab,
17502
+ // but the tab will already be activated by the time the announcement finishes.
17503
+ focusedTab.attr( "aria-selected", "false" );
17504
+ this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
17505
+
17506
+ this.activating = this._delay( function() {
17507
+ this.option( "active", selectedIndex );
17508
+ }, this.delay );
17509
+ }
17510
+ },
17511
+
17512
+ _panelKeydown: function( event ) {
17513
+ if ( this._handlePageNav( event ) ) {
17514
+ return;
17515
+ }
17516
+
17517
+ // Ctrl+up moves focus to the current tab
17518
+ if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
17519
+ event.preventDefault();
17520
+ this.active.trigger( "focus" );
17521
+ }
17522
+ },
17523
+
17524
+ // Alt+page up/down moves focus to the previous/next tab (and activates)
17525
+ _handlePageNav: function( event ) {
17526
+ if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
17527
+ this._activate( this._focusNextTab( this.options.active - 1, false ) );
17528
+ return true;
17529
+ }
17530
+ if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
17531
+ this._activate( this._focusNextTab( this.options.active + 1, true ) );
17532
+ return true;
17533
+ }
17534
+ },
17535
+
17536
+ _findNextTab: function( index, goingForward ) {
17537
+ var lastTabIndex = this.tabs.length - 1;
17538
+
17539
+ function constrain() {
17540
+ if ( index > lastTabIndex ) {
17541
+ index = 0;
17542
+ }
17543
+ if ( index < 0 ) {
17544
+ index = lastTabIndex;
17545
+ }
17546
+ return index;
17547
+ }
17548
+
17549
+ while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
17550
+ index = goingForward ? index + 1 : index - 1;
17551
+ }
17552
+
17553
+ return index;
17554
+ },
17555
+
17556
+ _focusNextTab: function( index, goingForward ) {
17557
+ index = this._findNextTab( index, goingForward );
17558
+ this.tabs.eq( index ).trigger( "focus" );
17559
+ return index;
17560
+ },
17561
+
17562
+ _setOption: function( key, value ) {
17563
+ if ( key === "active" ) {
17564
+
17565
+ // _activate() will handle invalid values and update this.options
17566
+ this._activate( value );
17567
+ return;
17568
+ }
17569
+
17570
+ this._super( key, value );
17571
+
17572
+ if ( key === "collapsible" ) {
17573
+ this._toggleClass( "ui-tabs-collapsible", null, value );
17574
+
17575
+ // Setting collapsible: false while collapsed; open first panel
17576
+ if ( !value && this.options.active === false ) {
17577
+ this._activate( 0 );
17578
+ }
17579
+ }
17580
+
17581
+ if ( key === "event" ) {
17582
+ this._setupEvents( value );
17583
+ }
17584
+
17585
+ if ( key === "heightStyle" ) {
17586
+ this._setupHeightStyle( value );
17587
+ }
17588
+ },
17589
+
17590
+ _sanitizeSelector: function( hash ) {
17591
+ return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
17592
+ },
17593
+
17594
+ refresh: function() {
17595
+ var options = this.options,
17596
+ lis = this.tablist.children( ":has(a[href])" );
17597
+
17598
+ // Get disabled tabs from class attribute from HTML
17599
+ // this will get converted to a boolean if needed in _refresh()
17600
+ options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
17601
+ return lis.index( tab );
17602
+ } );
17603
+
17604
+ this._processTabs();
17605
+
17606
+ // Was collapsed or no tabs
17607
+ if ( options.active === false || !this.anchors.length ) {
17608
+ options.active = false;
17609
+ this.active = $();
17610
+
17611
+ // was active, but active tab is gone
17612
+ } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
17613
+
17614
+ // all remaining tabs are disabled
17615
+ if ( this.tabs.length === options.disabled.length ) {
17616
+ options.active = false;
17617
+ this.active = $();
17618
+
17619
+ // activate previous tab
17620
+ } else {
17621
+ this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
17622
+ }
17623
+
17624
+ // was active, active tab still exists
17625
+ } else {
17626
+
17627
+ // make sure active index is correct
17628
+ options.active = this.tabs.index( this.active );
17629
+ }
17630
+
17631
+ this._refresh();
17632
+ },
17633
+
17634
+ _refresh: function() {
17635
+ this._setOptionDisabled( this.options.disabled );
17636
+ this._setupEvents( this.options.event );
17637
+ this._setupHeightStyle( this.options.heightStyle );
17638
+
17639
+ this.tabs.not( this.active ).attr( {
17640
+ "aria-selected": "false",
17641
+ "aria-expanded": "false",
17642
+ tabIndex: -1
17643
+ } );
17644
+ this.panels.not( this._getPanelForTab( this.active ) )
17645
+ .hide()
17646
+ .attr( {
17647
+ "aria-hidden": "true"
17648
+ } );
17649
+
17650
+ // Make sure one tab is in the tab order
17651
+ if ( !this.active.length ) {
17652
+ this.tabs.eq( 0 ).attr( "tabIndex", 0 );
17653
+ } else {
17654
+ this.active
17655
+ .attr( {
17656
+ "aria-selected": "true",
17657
+ "aria-expanded": "true",
17658
+ tabIndex: 0
17659
+ } );
17660
+ this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
17661
+ this._getPanelForTab( this.active )
17662
+ .show()
17663
+ .attr( {
17664
+ "aria-hidden": "false"
17665
+ } );
17666
+ }
17667
+ },
17668
+
17669
+ _processTabs: function() {
17670
+ var that = this,
17671
+ prevTabs = this.tabs,
17672
+ prevAnchors = this.anchors,
17673
+ prevPanels = this.panels;
17674
+
17675
+ this.tablist = this._getList().attr( "role", "tablist" );
17676
+ this._addClass( this.tablist, "ui-tabs-nav",
17677
+ "ui-helper-reset ui-helper-clearfix ui-widget-header" );
17678
+
17679
+ // Prevent users from focusing disabled tabs via click
17680
+ this.tablist
17681
+ .on( "mousedown" + this.eventNamespace, "> li", function( event ) {
17682
+ if ( $( this ).is( ".ui-state-disabled" ) ) {
17683
+ event.preventDefault();
17684
+ }
17685
+ } )
17686
+
17687
+ // Support: IE <9
17688
+ // Preventing the default action in mousedown doesn't prevent IE
17689
+ // from focusing the element, so if the anchor gets focused, blur.
17690
+ // We don't have to worry about focusing the previously focused
17691
+ // element since clicking on a non-focusable element should focus
17692
+ // the body anyway.
17693
+ .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
17694
+ if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
17695
+ this.blur();
17696
+ }
17697
+ } );
17698
+
17699
+ this.tabs = this.tablist.find( "> li:has(a[href])" )
17700
+ .attr( {
17701
+ role: "tab",
17702
+ tabIndex: -1
17703
+ } );
17704
+ this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
17705
+
17706
+ this.anchors = this.tabs.map( function() {
17707
+ return $( "a", this )[ 0 ];
17708
+ } )
17709
+ .attr( {
17710
+ role: "presentation",
17711
+ tabIndex: -1
17712
+ } );
17713
+ this._addClass( this.anchors, "ui-tabs-anchor" );
17714
+
17715
+ this.panels = $();
17716
+
17717
+ this.anchors.each( function( i, anchor ) {
17718
+ var selector, panel, panelId,
17719
+ anchorId = $( anchor ).uniqueId().attr( "id" ),
17720
+ tab = $( anchor ).closest( "li" ),
17721
+ originalAriaControls = tab.attr( "aria-controls" );
17722
+
17723
+ // Inline tab
17724
+ if ( that._isLocal( anchor ) ) {
17725
+ selector = anchor.hash;
17726
+ panelId = selector.substring( 1 );
17727
+ panel = that.element.find( that._sanitizeSelector( selector ) );
17728
+
17729
+ // remote tab
17730
+ } else {
17731
+
17732
+ // If the tab doesn't already have aria-controls,
17733
+ // generate an id by using a throw-away element
17734
+ panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
17735
+ selector = "#" + panelId;
17736
+ panel = that.element.find( selector );
17737
+ if ( !panel.length ) {
17738
+ panel = that._createPanel( panelId );
17739
+ panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
17740
+ }
17741
+ panel.attr( "aria-live", "polite" );
17742
+ }
17743
+
17744
+ if ( panel.length ) {
17745
+ that.panels = that.panels.add( panel );
17746
+ }
17747
+ if ( originalAriaControls ) {
17748
+ tab.data( "ui-tabs-aria-controls", originalAriaControls );
17749
+ }
17750
+ tab.attr( {
17751
+ "aria-controls": panelId,
17752
+ "aria-labelledby": anchorId
17753
+ } );
17754
+ panel.attr( "aria-labelledby", anchorId );
17755
+ } );
17756
+
17757
+ this.panels.attr( "role", "tabpanel" );
17758
+ this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
17759
+
17760
+ // Avoid memory leaks (#10056)
17761
+ if ( prevTabs ) {
17762
+ this._off( prevTabs.not( this.tabs ) );
17763
+ this._off( prevAnchors.not( this.anchors ) );
17764
+ this._off( prevPanels.not( this.panels ) );
17765
+ }
17766
+ },
17767
+
17768
+ // Allow overriding how to find the list for rare usage scenarios (#7715)
17769
+ _getList: function() {
17770
+ return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
17771
+ },
17772
+
17773
+ _createPanel: function( id ) {
17774
+ return $( "<div>" )
17775
+ .attr( "id", id )
17776
+ .data( "ui-tabs-destroy", true );
17777
+ },
17778
+
17779
+ _setOptionDisabled: function( disabled ) {
17780
+ var currentItem, li, i;
17781
+
17782
+ if ( $.isArray( disabled ) ) {
17783
+ if ( !disabled.length ) {
17784
+ disabled = false;
17785
+ } else if ( disabled.length === this.anchors.length ) {
17786
+ disabled = true;
17787
+ }
17788
+ }
17789
+
17790
+ // Disable tabs
17791
+ for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
17792
+ currentItem = $( li );
17793
+ if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
17794
+ currentItem.attr( "aria-disabled", "true" );
17795
+ this._addClass( currentItem, null, "ui-state-disabled" );
17796
+ } else {
17797
+ currentItem.removeAttr( "aria-disabled" );
17798
+ this._removeClass( currentItem, null, "ui-state-disabled" );
17799
+ }
17800
+ }
17801
+
17802
+ this.options.disabled = disabled;
17803
+
17804
+ this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
17805
+ disabled === true );
17806
+ },
17807
+
17808
+ _setupEvents: function( event ) {
17809
+ var events = {};
17810
+ if ( event ) {
17811
+ $.each( event.split( " " ), function( index, eventName ) {
17812
+ events[ eventName ] = "_eventHandler";
17813
+ } );
17814
+ }
17815
+
17816
+ this._off( this.anchors.add( this.tabs ).add( this.panels ) );
17817
+
17818
+ // Always prevent the default action, even when disabled
17819
+ this._on( true, this.anchors, {
17820
+ click: function( event ) {
17821
+ event.preventDefault();
17822
+ }
17823
+ } );
17824
+ this._on( this.anchors, events );
17825
+ this._on( this.tabs, { keydown: "_tabKeydown" } );
17826
+ this._on( this.panels, { keydown: "_panelKeydown" } );
17827
+
17828
+ this._focusable( this.tabs );
17829
+ this._hoverable( this.tabs );
17830
+ },
17831
+
17832
+ _setupHeightStyle: function( heightStyle ) {
17833
+ var maxHeight,
17834
+ parent = this.element.parent();
17835
+
17836
+ if ( heightStyle === "fill" ) {
17837
+ maxHeight = parent.height();
17838
+ maxHeight -= this.element.outerHeight() - this.element.height();
17839
+
17840
+ this.element.siblings( ":visible" ).each( function() {
17841
+ var elem = $( this ),
17842
+ position = elem.css( "position" );
17843
+
17844
+ if ( position === "absolute" || position === "fixed" ) {
17845
+ return;
17846
+ }
17847
+ maxHeight -= elem.outerHeight( true );
17848
+ } );
17849
+
17850
+ this.element.children().not( this.panels ).each( function() {
17851
+ maxHeight -= $( this ).outerHeight( true );
17852
+ } );
17853
+
17854
+ this.panels.each( function() {
17855
+ $( this ).height( Math.max( 0, maxHeight -
17856
+ $( this ).innerHeight() + $( this ).height() ) );
17857
+ } )
17858
+ .css( "overflow", "auto" );
17859
+ } else if ( heightStyle === "auto" ) {
17860
+ maxHeight = 0;
17861
+ this.panels.each( function() {
17862
+ maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
17863
+ } ).height( maxHeight );
17864
+ }
17865
+ },
17866
+
17867
+ _eventHandler: function( event ) {
17868
+ var options = this.options,
17869
+ active = this.active,
17870
+ anchor = $( event.currentTarget ),
17871
+ tab = anchor.closest( "li" ),
17872
+ clickedIsActive = tab[ 0 ] === active[ 0 ],
17873
+ collapsing = clickedIsActive && options.collapsible,
17874
+ toShow = collapsing ? $() : this._getPanelForTab( tab ),
17875
+ toHide = !active.length ? $() : this._getPanelForTab( active ),
17876
+ eventData = {
17877
+ oldTab: active,
17878
+ oldPanel: toHide,
17879
+ newTab: collapsing ? $() : tab,
17880
+ newPanel: toShow
17881
+ };
17882
+
17883
+ event.preventDefault();
17884
+
17885
+ if ( tab.hasClass( "ui-state-disabled" ) ||
17886
+
17887
+ // tab is already loading
17888
+ tab.hasClass( "ui-tabs-loading" ) ||
17889
+
17890
+ // can't switch durning an animation
17891
+ this.running ||
17892
+
17893
+ // click on active header, but not collapsible
17894
+ ( clickedIsActive && !options.collapsible ) ||
17895
+
17896
+ // allow canceling activation
17897
+ ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
17898
+ return;
17899
+ }
17900
+
17901
+ options.active = collapsing ? false : this.tabs.index( tab );
17902
+
17903
+ this.active = clickedIsActive ? $() : tab;
17904
+ if ( this.xhr ) {
17905
+ this.xhr.abort();
17906
+ }
17907
+
17908
+ if ( !toHide.length && !toShow.length ) {
17909
+ $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
17910
+ }
17911
+
17912
+ if ( toShow.length ) {
17913
+ this.load( this.tabs.index( tab ), event );
17914
+ }
17915
+ this._toggle( event, eventData );
17916
+ },
17917
+
17918
+ // Handles show/hide for selecting tabs
17919
+ _toggle: function( event, eventData ) {
17920
+ var that = this,
17921
+ toShow = eventData.newPanel,
17922
+ toHide = eventData.oldPanel;
17923
+
17924
+ this.running = true;
17925
+
17926
+ function complete() {
17927
+ that.running = false;
17928
+ that._trigger( "activate", event, eventData );
17929
+ }
17930
+
17931
+ function show() {
17932
+ that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
17933
+
17934
+ if ( toShow.length && that.options.show ) {
17935
+ that._show( toShow, that.options.show, complete );
17936
+ } else {
17937
+ toShow.show();
17938
+ complete();
17939
+ }
17940
+ }
17941
+
17942
+ // Start out by hiding, then showing, then completing
17943
+ if ( toHide.length && this.options.hide ) {
17944
+ this._hide( toHide, this.options.hide, function() {
17945
+ that._removeClass( eventData.oldTab.closest( "li" ),
17946
+ "ui-tabs-active", "ui-state-active" );
17947
+ show();
17948
+ } );
17949
+ } else {
17950
+ this._removeClass( eventData.oldTab.closest( "li" ),
17951
+ "ui-tabs-active", "ui-state-active" );
17952
+ toHide.hide();
17953
+ show();
17954
+ }
17955
+
17956
+ toHide.attr( "aria-hidden", "true" );
17957
+ eventData.oldTab.attr( {
17958
+ "aria-selected": "false",
17959
+ "aria-expanded": "false"
17960
+ } );
17961
+
17962
+ // If we're switching tabs, remove the old tab from the tab order.
17963
+ // If we're opening from collapsed state, remove the previous tab from the tab order.
17964
+ // If we're collapsing, then keep the collapsing tab in the tab order.
17965
+ if ( toShow.length && toHide.length ) {
17966
+ eventData.oldTab.attr( "tabIndex", -1 );
17967
+ } else if ( toShow.length ) {
17968
+ this.tabs.filter( function() {
17969
+ return $( this ).attr( "tabIndex" ) === 0;
17970
+ } )
17971
+ .attr( "tabIndex", -1 );
17972
+ }
17973
+
17974
+ toShow.attr( "aria-hidden", "false" );
17975
+ eventData.newTab.attr( {
17976
+ "aria-selected": "true",
17977
+ "aria-expanded": "true",
17978
+ tabIndex: 0
17979
+ } );
17980
+ },
17981
+
17982
+ _activate: function( index ) {
17983
+ var anchor,
17984
+ active = this._findActive( index );
17985
+
17986
+ // Trying to activate the already active panel
17987
+ if ( active[ 0 ] === this.active[ 0 ] ) {
17988
+ return;
17989
+ }
17990
+
17991
+ // Trying to collapse, simulate a click on the current active header
17992
+ if ( !active.length ) {
17993
+ active = this.active;
17994
+ }
17995
+
17996
+ anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
17997
+ this._eventHandler( {
17998
+ target: anchor,
17999
+ currentTarget: anchor,
18000
+ preventDefault: $.noop
18001
+ } );
18002
+ },
18003
+
18004
+ _findActive: function( index ) {
18005
+ return index === false ? $() : this.tabs.eq( index );
18006
+ },
18007
+
18008
+ _getIndex: function( index ) {
18009
+
18010
+ // meta-function to give users option to provide a href string instead of a numerical index.
18011
+ if ( typeof index === "string" ) {
18012
+ index = this.anchors.index( this.anchors.filter( "[href$='" +
18013
+ $.ui.escapeSelector( index ) + "']" ) );
18014
+ }
18015
+
18016
+ return index;
18017
+ },
18018
+
18019
+ _destroy: function() {
18020
+ if ( this.xhr ) {
18021
+ this.xhr.abort();
18022
+ }
18023
+
18024
+ this.tablist
18025
+ .removeAttr( "role" )
18026
+ .off( this.eventNamespace );
18027
+
18028
+ this.anchors
18029
+ .removeAttr( "role tabIndex" )
18030
+ .removeUniqueId();
18031
+
18032
+ this.tabs.add( this.panels ).each( function() {
18033
+ if ( $.data( this, "ui-tabs-destroy" ) ) {
18034
+ $( this ).remove();
18035
+ } else {
18036
+ $( this ).removeAttr( "role tabIndex " +
18037
+ "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
18038
+ }
18039
+ } );
18040
+
18041
+ this.tabs.each( function() {
18042
+ var li = $( this ),
18043
+ prev = li.data( "ui-tabs-aria-controls" );
18044
+ if ( prev ) {
18045
+ li
18046
+ .attr( "aria-controls", prev )
18047
+ .removeData( "ui-tabs-aria-controls" );
18048
+ } else {
18049
+ li.removeAttr( "aria-controls" );
18050
+ }
18051
+ } );
18052
+
18053
+ this.panels.show();
18054
+
18055
+ if ( this.options.heightStyle !== "content" ) {
18056
+ this.panels.css( "height", "" );
18057
+ }
18058
+ },
18059
+
18060
+ enable: function( index ) {
18061
+ var disabled = this.options.disabled;
18062
+ if ( disabled === false ) {
18063
+ return;
18064
+ }
18065
+
18066
+ if ( index === undefined ) {
18067
+ disabled = false;
18068
+ } else {
18069
+ index = this._getIndex( index );
18070
+ if ( $.isArray( disabled ) ) {
18071
+ disabled = $.map( disabled, function( num ) {
18072
+ return num !== index ? num : null;
18073
+ } );
18074
+ } else {
18075
+ disabled = $.map( this.tabs, function( li, num ) {
18076
+ return num !== index ? num : null;
18077
+ } );
18078
+ }
18079
+ }
18080
+ this._setOptionDisabled( disabled );
18081
+ },
18082
+
18083
+ disable: function( index ) {
18084
+ var disabled = this.options.disabled;
18085
+ if ( disabled === true ) {
18086
+ return;
18087
+ }
18088
+
18089
+ if ( index === undefined ) {
18090
+ disabled = true;
18091
+ } else {
18092
+ index = this._getIndex( index );
18093
+ if ( $.inArray( index, disabled ) !== -1 ) {
18094
+ return;
18095
+ }
18096
+ if ( $.isArray( disabled ) ) {
18097
+ disabled = $.merge( [ index ], disabled ).sort();
18098
+ } else {
18099
+ disabled = [ index ];
18100
+ }
18101
+ }
18102
+ this._setOptionDisabled( disabled );
18103
+ },
18104
+
18105
+ load: function( index, event ) {
18106
+ index = this._getIndex( index );
18107
+ var that = this,
18108
+ tab = this.tabs.eq( index ),
18109
+ anchor = tab.find( ".ui-tabs-anchor" ),
18110
+ panel = this._getPanelForTab( tab ),
18111
+ eventData = {
18112
+ tab: tab,
18113
+ panel: panel
18114
+ },
18115
+ complete = function( jqXHR, status ) {
18116
+ if ( status === "abort" ) {
18117
+ that.panels.stop( false, true );
18118
+ }
18119
+
18120
+ that._removeClass( tab, "ui-tabs-loading" );
18121
+ panel.removeAttr( "aria-busy" );
18122
+
18123
+ if ( jqXHR === that.xhr ) {
18124
+ delete that.xhr;
18125
+ }
18126
+ };
18127
+
18128
+ // Not remote
18129
+ if ( this._isLocal( anchor[ 0 ] ) ) {
18130
+ return;
18131
+ }
18132
+
18133
+ this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
18134
+
18135
+ // Support: jQuery <1.8
18136
+ // jQuery <1.8 returns false if the request is canceled in beforeSend,
18137
+ // but as of 1.8, $.ajax() always returns a jqXHR object.
18138
+ if ( this.xhr && this.xhr.statusText !== "canceled" ) {
18139
+ this._addClass( tab, "ui-tabs-loading" );
18140
+ panel.attr( "aria-busy", "true" );
18141
+
18142
+ this.xhr
18143
+ .done( function( response, status, jqXHR ) {
18144
+
18145
+ // support: jQuery <1.8
18146
+ // http://bugs.jquery.com/ticket/11778
18147
+ setTimeout( function() {
18148
+ panel.html( response );
18149
+ that._trigger( "load", event, eventData );
18150
+
18151
+ complete( jqXHR, status );
18152
+ }, 1 );
18153
+ } )
18154
+ .fail( function( jqXHR, status ) {
18155
+
18156
+ // support: jQuery <1.8
18157
+ // http://bugs.jquery.com/ticket/11778
18158
+ setTimeout( function() {
18159
+ complete( jqXHR, status );
18160
+ }, 1 );
18161
+ } );
18162
+ }
18163
+ },
18164
+
18165
+ _ajaxSettings: function( anchor, event, eventData ) {
18166
+ var that = this;
18167
+ return {
18168
+
18169
+ // Support: IE <11 only
18170
+ // Strip any hash that exists to prevent errors with the Ajax request
18171
+ url: anchor.attr( "href" ).replace( /#.*$/, "" ),
18172
+ beforeSend: function( jqXHR, settings ) {
18173
+ return that._trigger( "beforeLoad", event,
18174
+ $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
18175
+ }
18176
+ };
18177
+ },
18178
+
18179
+ _getPanelForTab: function( tab ) {
18180
+ var id = $( tab ).attr( "aria-controls" );
18181
+ return this.element.find( this._sanitizeSelector( "#" + id ) );
18182
+ }
18183
+ } );
18184
+
18185
+ // DEPRECATED
18186
+ // TODO: Switch return back to widget declaration at top of file when this is removed
18187
+ if ( $.uiBackCompat !== false ) {
18188
+
18189
+ // Backcompat for ui-tab class (now ui-tabs-tab)
18190
+ $.widget( "ui.tabs", $.ui.tabs, {
18191
+ _processTabs: function() {
18192
+ this._superApply( arguments );
18193
+ this._addClass( this.tabs, "ui-tab" );
18194
+ }
18195
+ } );
18196
+ }
18197
+
18198
+ var widgetsTabs = $.ui.tabs;
18199
+
18200
+
18201
+ /*!
18202
+ * jQuery UI Tooltip 1.12.1
18203
+ * http://jqueryui.com
18204
+ *
18205
+ * Copyright jQuery Foundation and other contributors
18206
+ * Released under the MIT license.
18207
+ * http://jquery.org/license
18208
+ */
18209
+
18210
+ //>>label: Tooltip
18211
+ //>>group: Widgets
18212
+ //>>description: Shows additional information for any element on hover or focus.
18213
+ //>>docs: http://api.jqueryui.com/tooltip/
18214
+ //>>demos: http://jqueryui.com/tooltip/
18215
+ //>>css.structure: ../../themes/base/core.css
18216
+ //>>css.structure: ../../themes/base/tooltip.css
18217
+ //>>css.theme: ../../themes/base/theme.css
18218
+
18219
+
18220
+
18221
+ $.widget( "ui.tooltip", {
18222
+ version: "1.12.1",
18223
+ options: {
18224
+ classes: {
18225
+ "ui-tooltip": "ui-corner-all ui-widget-shadow"
18226
+ },
18227
+ content: function() {
18228
+
18229
+ // support: IE<9, Opera in jQuery <1.7
18230
+ // .text() can't accept undefined, so coerce to a string
18231
+ var title = $( this ).attr( "title" ) || "";
18232
+
18233
+ // Escape title, since we're going from an attribute to raw HTML
18234
+ return $( "<a>" ).text( title ).html();
18235
+ },
18236
+ hide: true,
18237
+
18238
+ // Disabled elements have inconsistent behavior across browsers (#8661)
18239
+ items: "[title]:not([disabled])",
18240
+ position: {
18241
+ my: "left top+15",
18242
+ at: "left bottom",
18243
+ collision: "flipfit flip"
18244
+ },
18245
+ show: true,
18246
+ track: false,
18247
+
18248
+ // Callbacks
18249
+ close: null,
18250
+ open: null
18251
+ },
18252
+
18253
+ _addDescribedBy: function( elem, id ) {
18254
+ var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
18255
+ describedby.push( id );
18256
+ elem
18257
+ .data( "ui-tooltip-id", id )
18258
+ .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
18259
+ },
18260
+
18261
+ _removeDescribedBy: function( elem ) {
18262
+ var id = elem.data( "ui-tooltip-id" ),
18263
+ describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
18264
+ index = $.inArray( id, describedby );
18265
+
18266
+ if ( index !== -1 ) {
18267
+ describedby.splice( index, 1 );
18268
+ }
18269
+
18270
+ elem.removeData( "ui-tooltip-id" );
18271
+ describedby = $.trim( describedby.join( " " ) );
18272
+ if ( describedby ) {
18273
+ elem.attr( "aria-describedby", describedby );
18274
+ } else {
18275
+ elem.removeAttr( "aria-describedby" );
18276
+ }
18277
+ },
18278
+
18279
+ _create: function() {
18280
+ this._on( {
18281
+ mouseover: "open",
18282
+ focusin: "open"
18283
+ } );
18284
+
18285
+ // IDs of generated tooltips, needed for destroy
18286
+ this.tooltips = {};
18287
+
18288
+ // IDs of parent tooltips where we removed the title attribute
18289
+ this.parents = {};
18290
+
18291
+ // Append the aria-live region so tooltips announce correctly
18292
+ this.liveRegion = $( "<div>" )
18293
+ .attr( {
18294
+ role: "log",
18295
+ "aria-live": "assertive",
18296
+ "aria-relevant": "additions"
18297
+ } )
18298
+ .appendTo( this.document[ 0 ].body );
18299
+ this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
18300
+
18301
+ this.disabledTitles = $( [] );
18302
+ },
18303
+
18304
+ _setOption: function( key, value ) {
18305
+ var that = this;
18306
+
18307
+ this._super( key, value );
18308
+
18309
+ if ( key === "content" ) {
18310
+ $.each( this.tooltips, function( id, tooltipData ) {
18311
+ that._updateContent( tooltipData.element );
18312
+ } );
18313
+ }
18314
+ },
18315
+
18316
+ _setOptionDisabled: function( value ) {
18317
+ this[ value ? "_disable" : "_enable" ]();
18318
+ },
18319
+
18320
+ _disable: function() {
18321
+ var that = this;
18322
+
18323
+ // Close open tooltips
18324
+ $.each( this.tooltips, function( id, tooltipData ) {
18325
+ var event = $.Event( "blur" );
18326
+ event.target = event.currentTarget = tooltipData.element[ 0 ];
18327
+ that.close( event, true );
18328
+ } );
18329
+
18330
+ // Remove title attributes to prevent native tooltips
18331
+ this.disabledTitles = this.disabledTitles.add(
18332
+ this.element.find( this.options.items ).addBack()
18333
+ .filter( function() {
18334
+ var element = $( this );
18335
+ if ( element.is( "[title]" ) ) {
18336
+ return element
18337
+ .data( "ui-tooltip-title", element.attr( "title" ) )
18338
+ .removeAttr( "title" );
18339
+ }
18340
+ } )
18341
+ );
18342
+ },
18343
+
18344
+ _enable: function() {
18345
+
18346
+ // restore title attributes
18347
+ this.disabledTitles.each( function() {
18348
+ var element = $( this );
18349
+ if ( element.data( "ui-tooltip-title" ) ) {
18350
+ element.attr( "title", element.data( "ui-tooltip-title" ) );
18351
+ }
18352
+ } );
18353
+ this.disabledTitles = $( [] );
18354
+ },
18355
+
18356
+ open: function( event ) {
18357
+ var that = this,
18358
+ target = $( event ? event.target : this.element )
18359
+
18360
+ // we need closest here due to mouseover bubbling,
18361
+ // but always pointing at the same event target
18362
+ .closest( this.options.items );
18363
+
18364
+ // No element to show a tooltip for or the tooltip is already open
18365
+ if ( !target.length || target.data( "ui-tooltip-id" ) ) {
18366
+ return;
18367
+ }
18368
+
18369
+ if ( target.attr( "title" ) ) {
18370
+ target.data( "ui-tooltip-title", target.attr( "title" ) );
18371
+ }
18372
+
18373
+ target.data( "ui-tooltip-open", true );
18374
+
18375
+ // Kill parent tooltips, custom or native, for hover
18376
+ if ( event && event.type === "mouseover" ) {
18377
+ target.parents().each( function() {
18378
+ var parent = $( this ),
18379
+ blurEvent;
18380
+ if ( parent.data( "ui-tooltip-open" ) ) {
18381
+ blurEvent = $.Event( "blur" );
18382
+ blurEvent.target = blurEvent.currentTarget = this;
18383
+ that.close( blurEvent, true );
18384
+ }
18385
+ if ( parent.attr( "title" ) ) {
18386
+ parent.uniqueId();
18387
+ that.parents[ this.id ] = {
18388
+ element: this,
18389
+ title: parent.attr( "title" )
18390
+ };
18391
+ parent.attr( "title", "" );
18392
+ }
18393
+ } );
18394
+ }
18395
+
18396
+ this._registerCloseHandlers( event, target );
18397
+ this._updateContent( target, event );
18398
+ },
18399
+
18400
+ _updateContent: function( target, event ) {
18401
+ var content,
18402
+ contentOption = this.options.content,
18403
+ that = this,
18404
+ eventType = event ? event.type : null;
18405
+
18406
+ if ( typeof contentOption === "string" || contentOption.nodeType ||
18407
+ contentOption.jquery ) {
18408
+ return this._open( event, target, contentOption );
18409
+ }
18410
+
18411
+ content = contentOption.call( target[ 0 ], function( response ) {
18412
+
18413
+ // IE may instantly serve a cached response for ajax requests
18414
+ // delay this call to _open so the other call to _open runs first
18415
+ that._delay( function() {
18416
+
18417
+ // Ignore async response if tooltip was closed already
18418
+ if ( !target.data( "ui-tooltip-open" ) ) {
18419
+ return;
18420
+ }
18421
+
18422
+ // JQuery creates a special event for focusin when it doesn't
18423
+ // exist natively. To improve performance, the native event
18424
+ // object is reused and the type is changed. Therefore, we can't
18425
+ // rely on the type being correct after the event finished
18426
+ // bubbling, so we set it back to the previous value. (#8740)
18427
+ if ( event ) {
18428
+ event.type = eventType;
18429
+ }
18430
+ this._open( event, target, response );
18431
+ } );
18432
+ } );
18433
+ if ( content ) {
18434
+ this._open( event, target, content );
18435
+ }
18436
+ },
18437
+
18438
+ _open: function( event, target, content ) {
18439
+ var tooltipData, tooltip, delayedShow, a11yContent,
18440
+ positionOption = $.extend( {}, this.options.position );
18441
+
18442
+ if ( !content ) {
18443
+ return;
18444
+ }
18445
+
18446
+ // Content can be updated multiple times. If the tooltip already
18447
+ // exists, then just update the content and bail.
18448
+ tooltipData = this._find( target );
18449
+ if ( tooltipData ) {
18450
+ tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
18451
+ return;
18452
+ }
18453
+
18454
+ // If we have a title, clear it to prevent the native tooltip
18455
+ // we have to check first to avoid defining a title if none exists
18456
+ // (we don't want to cause an element to start matching [title])
18457
+ //
18458
+ // We use removeAttr only for key events, to allow IE to export the correct
18459
+ // accessible attributes. For mouse events, set to empty string to avoid
18460
+ // native tooltip showing up (happens only when removing inside mouseover).
18461
+ if ( target.is( "[title]" ) ) {
18462
+ if ( event && event.type === "mouseover" ) {
18463
+ target.attr( "title", "" );
18464
+ } else {
18465
+ target.removeAttr( "title" );
18466
+ }
18467
+ }
18468
+
18469
+ tooltipData = this._tooltip( target );
18470
+ tooltip = tooltipData.tooltip;
18471
+ this._addDescribedBy( target, tooltip.attr( "id" ) );
18472
+ tooltip.find( ".ui-tooltip-content" ).html( content );
18473
+
18474
+ // Support: Voiceover on OS X, JAWS on IE <= 9
18475
+ // JAWS announces deletions even when aria-relevant="additions"
18476
+ // Voiceover will sometimes re-read the entire log region's contents from the beginning
18477
+ this.liveRegion.children().hide();
18478
+ a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
18479
+ a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
18480
+ a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
18481
+ a11yContent.appendTo( this.liveRegion );
18482
+
18483
+ function position( event ) {
18484
+ positionOption.of = event;
18485
+ if ( tooltip.is( ":hidden" ) ) {
18486
+ return;
18487
+ }
18488
+ tooltip.position( positionOption );
18489
+ }
18490
+ if ( this.options.track && event && /^mouse/.test( event.type ) ) {
18491
+ this._on( this.document, {
18492
+ mousemove: position
18493
+ } );
18494
+
18495
+ // trigger once to override element-relative positioning
18496
+ position( event );
18497
+ } else {
18498
+ tooltip.position( $.extend( {
18499
+ of: target
18500
+ }, this.options.position ) );
18501
+ }
18502
+
18503
+ tooltip.hide();
18504
+
18505
+ this._show( tooltip, this.options.show );
18506
+
18507
+ // Handle tracking tooltips that are shown with a delay (#8644). As soon
18508
+ // as the tooltip is visible, position the tooltip using the most recent
18509
+ // event.
18510
+ // Adds the check to add the timers only when both delay and track options are set (#14682)
18511
+ if ( this.options.track && this.options.show && this.options.show.delay ) {
18512
+ delayedShow = this.delayedShow = setInterval( function() {
18513
+ if ( tooltip.is( ":visible" ) ) {
18514
+ position( positionOption.of );
18515
+ clearInterval( delayedShow );
18516
+ }
18517
+ }, $.fx.interval );
18518
+ }
18519
+
18520
+ this._trigger( "open", event, { tooltip: tooltip } );
18521
+ },
18522
+
18523
+ _registerCloseHandlers: function( event, target ) {
18524
+ var events = {
18525
+ keyup: function( event ) {
18526
+ if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
18527
+ var fakeEvent = $.Event( event );
18528
+ fakeEvent.currentTarget = target[ 0 ];
18529
+ this.close( fakeEvent, true );
18530
+ }
18531
+ }
18532
+ };
18533
+
18534
+ // Only bind remove handler for delegated targets. Non-delegated
18535
+ // tooltips will handle this in destroy.
18536
+ if ( target[ 0 ] !== this.element[ 0 ] ) {
18537
+ events.remove = function() {
18538
+ this._removeTooltip( this._find( target ).tooltip );
18539
+ };
18540
+ }
18541
+
18542
+ if ( !event || event.type === "mouseover" ) {
18543
+ events.mouseleave = "close";
18544
+ }
18545
+ if ( !event || event.type === "focusin" ) {
18546
+ events.focusout = "close";
18547
+ }
18548
+ this._on( true, target, events );
18549
+ },
18550
+
18551
+ close: function( event ) {
18552
+ var tooltip,
18553
+ that = this,
18554
+ target = $( event ? event.currentTarget : this.element ),
18555
+ tooltipData = this._find( target );
18556
+
18557
+ // The tooltip may already be closed
18558
+ if ( !tooltipData ) {
18559
+
18560
+ // We set ui-tooltip-open immediately upon open (in open()), but only set the
18561
+ // additional data once there's actually content to show (in _open()). So even if the
18562
+ // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
18563
+ // the period between open() and _open().
18564
+ target.removeData( "ui-tooltip-open" );
18565
+ return;
18566
+ }
18567
+
18568
+ tooltip = tooltipData.tooltip;
18569
+
18570
+ // Disabling closes the tooltip, so we need to track when we're closing
18571
+ // to avoid an infinite loop in case the tooltip becomes disabled on close
18572
+ if ( tooltipData.closing ) {
18573
+ return;
18574
+ }
18575
+
18576
+ // Clear the interval for delayed tracking tooltips
18577
+ clearInterval( this.delayedShow );
18578
+
18579
+ // Only set title if we had one before (see comment in _open())
18580
+ // If the title attribute has changed since open(), don't restore
18581
+ if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
18582
+ target.attr( "title", target.data( "ui-tooltip-title" ) );
18583
+ }
18584
+
18585
+ this._removeDescribedBy( target );
18586
+
18587
+ tooltipData.hiding = true;
18588
+ tooltip.stop( true );
18589
+ this._hide( tooltip, this.options.hide, function() {
18590
+ that._removeTooltip( $( this ) );
18591
+ } );
18592
+
18593
+ target.removeData( "ui-tooltip-open" );
18594
+ this._off( target, "mouseleave focusout keyup" );
18595
+
18596
+ // Remove 'remove' binding only on delegated targets
18597
+ if ( target[ 0 ] !== this.element[ 0 ] ) {
18598
+ this._off( target, "remove" );
18599
+ }
18600
+ this._off( this.document, "mousemove" );
18601
+
18602
+ if ( event && event.type === "mouseleave" ) {
18603
+ $.each( this.parents, function( id, parent ) {
18604
+ $( parent.element ).attr( "title", parent.title );
18605
+ delete that.parents[ id ];
18606
+ } );
18607
+ }
18608
+
18609
+ tooltipData.closing = true;
18610
+ this._trigger( "close", event, { tooltip: tooltip } );
18611
+ if ( !tooltipData.hiding ) {
18612
+ tooltipData.closing = false;
18613
+ }
18614
+ },
18615
+
18616
+ _tooltip: function( element ) {
18617
+ var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
18618
+ content = $( "<div>" ).appendTo( tooltip ),
18619
+ id = tooltip.uniqueId().attr( "id" );
18620
+
18621
+ this._addClass( content, "ui-tooltip-content" );
18622
+ this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
18623
+
18624
+ tooltip.appendTo( this._appendTo( element ) );
18625
+
18626
+ return this.tooltips[ id ] = {
18627
+ element: element,
18628
+ tooltip: tooltip
18629
+ };
18630
+ },
18631
+
18632
+ _find: function( target ) {
18633
+ var id = target.data( "ui-tooltip-id" );
18634
+ return id ? this.tooltips[ id ] : null;
18635
+ },
18636
+
18637
+ _removeTooltip: function( tooltip ) {
18638
+ tooltip.remove();
18639
+ delete this.tooltips[ tooltip.attr( "id" ) ];
18640
+ },
18641
+
18642
+ _appendTo: function( target ) {
18643
+ var element = target.closest( ".ui-front, dialog" );
18644
+
18645
+ if ( !element.length ) {
18646
+ element = this.document[ 0 ].body;
18647
+ }
18648
+
18649
+ return element;
18650
+ },
18651
+
18652
+ _destroy: function() {
18653
+ var that = this;
18654
+
18655
+ // Close open tooltips
18656
+ $.each( this.tooltips, function( id, tooltipData ) {
18657
+
18658
+ // Delegate to close method to handle common cleanup
18659
+ var event = $.Event( "blur" ),
18660
+ element = tooltipData.element;
18661
+ event.target = event.currentTarget = element[ 0 ];
18662
+ that.close( event, true );
18663
+
18664
+ // Remove immediately; destroying an open tooltip doesn't use the
18665
+ // hide animation
18666
+ $( "#" + id ).remove();
18667
+
18668
+ // Restore the title
18669
+ if ( element.data( "ui-tooltip-title" ) ) {
18670
+
18671
+ // If the title attribute has changed since open(), don't restore
18672
+ if ( !element.attr( "title" ) ) {
18673
+ element.attr( "title", element.data( "ui-tooltip-title" ) );
18674
+ }
18675
+ element.removeData( "ui-tooltip-title" );
18676
+ }
18677
+ } );
18678
+ this.liveRegion.remove();
18679
+ }
18680
+ } );
18681
+
18682
+ // DEPRECATED
18683
+ // TODO: Switch return back to widget declaration at top of file when this is removed
18684
+ if ( $.uiBackCompat !== false ) {
18685
+
18686
+ // Backcompat for tooltipClass option
18687
+ $.widget( "ui.tooltip", $.ui.tooltip, {
18688
+ options: {
18689
+ tooltipClass: null
18690
+ },
18691
+ _tooltip: function() {
18692
+ var tooltipData = this._superApply( arguments );
18693
+ if ( this.options.tooltipClass ) {
18694
+ tooltipData.tooltip.addClass( this.options.tooltipClass );
18695
+ }
18696
+ return tooltipData;
18697
+ }
18698
+ } );
18699
+ }
18700
+
18701
+ var widgetsTooltip = $.ui.tooltip;
18702
+
18703
+
18704
+
18705
+
18706
+ }));
admin/js/mycustom.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ jQuery(document).ready(function ($) {
2
+ $('input#subscriber-search-input').select2();
3
+ });
admin/js/select2.min.js ADDED
@@ -0,0 +1 @@
 
1
+ /*! Select2 4.0.6-rc.1 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=function(b,c){return void 0===c&&(c="undefined"!=typeof window?require("jquery"):require("jquery")(b)),a(c),c}:a(jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return v.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o=b&&b.split("/"),p=t.map,q=p&&p["*"]||{};if(a){for(a=a.split("/"),g=a.length-1,t.nodeIdCompat&&x.test(a[g])&&(a[g]=a[g].replace(x,"")),"."===a[0].charAt(0)&&o&&(n=o.slice(0,o.length-1),a=n.concat(a)),k=0;k<a.length;k++)if("."===(m=a[k]))a.splice(k,1),k-=1;else if(".."===m){if(0===k||1===k&&".."===a[2]||".."===a[k-1])continue;k>0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}if((o||q)&&p){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),o)for(l=o.length;l>0;l-=1)if((e=p[o.slice(0,l).join("/")])&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&q&&q[d]&&(i=q[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=w.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),o.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){r[a]=b}}function j(a){if(e(s,a)){var c=s[a];delete s[a],u[a]=!0,n.apply(b,c)}if(!e(r,a)&&!e(u,a))throw new Error("No "+a);return r[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return a?k(a):[]}function m(a){return function(){return t&&t.config&&t.config[a]||{}}}var n,o,p,q,r={},s={},t={},u={},v=Object.prototype.hasOwnProperty,w=[].slice,x=/\.js$/;p=function(a,b){var c,d=k(a),e=d[0],g=b[1];return a=d[1],e&&(e=f(e,g),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(g)):f(a,g):(a=f(a,g),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},q={require:function(a){return g(a)},exports:function(a){var b=r[a];return void 0!==b?b:r[a]={}},module:function(a){return{id:a,uri:"",exports:r[a],config:m(a)}}},n=function(a,c,d,f){var h,k,m,n,o,t,v,w=[],x=typeof d;if(f=f||a,t=l(f),"undefined"===x||"function"===x){for(c=!c.length&&d.length?["require","exports","module"]:c,o=0;o<c.length;o+=1)if(n=p(c[o],t),"require"===(k=n.f))w[o]=q.require(a);else if("exports"===k)w[o]=q.exports(a),v=!0;else if("module"===k)h=w[o]=q.module(a);else if(e(r,k)||e(s,k)||e(u,k))w[o]=j(k);else{if(!n.p)throw new Error(a+" missing "+k);n.p.load(n.n,g(f,!0),i(k),{}),w[o]=r[k]}m=d?d.apply(r[a],w):void 0,a&&(h&&h.exports!==b&&h.exports!==r[a]?r[a]=h.exports:m===b&&v||(r[a]=m))}else a&&(r[a]=d)},a=c=o=function(a,c,d,e,f){if("string"==typeof a)return q[a]?q[a](c):j(p(a,l(c)).f);if(!a.splice){if(t=a,t.deps&&o(t.deps,t.callback),!c)return;c.splice?(a=c,c=d,d=null):a=b}return c=c||function(){},"function"==typeof d&&(d=e,e=f),e?n(b,a,c,d):setTimeout(function(){n(b,a,c,d)},4),o},o.config=function(a){return o(a)},a._defined=r,d=function(a,b,c){if("string"!=typeof a)throw new Error("See almond README: incorrect module build, no module name");b.splice||(c=b,b=[]),e(r,a)||e(s,a)||(s[a]=[a,b,c])},d.amd={jQuery:!0}}(),b.requirejs=a,b.require=c,b.define=d}}(),b.define("almond",function(){}),b.define("jquery",[],function(){var b=a||$;return null==b&&console&&console.error&&console.error("Select2: An instance of jQuery or a jQuery-compatible library was not found. Make sure that you are including jQuery before Select2 on your web page."),b}),b.define("select2/utils",["jquery"],function(a){function b(a){var b=a.prototype,c=[];for(var d in b){"function"==typeof b[d]&&("constructor"!==d&&c.push(d))}return c}var c={};c.Extend=function(a,b){function c(){this.constructor=a}var d={}.hasOwnProperty;for(var e in b)d.call(b,e)&&(a[e]=b[e]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},c.Decorate=function(a,c){function d(){var b=Array.prototype.unshift,d=c.prototype.constructor.length,e=a.prototype.constructor;d>0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h<g.length;h++){var i=g[h];d.prototype[i]=a.prototype[i]}for(var j=(function(a){var b=function(){};a in d.prototype&&(b=d.prototype[a]);var e=c.prototype[a];return function(){return Array.prototype.unshift.call(arguments,b),e.apply(this,arguments)}}),k=0;k<f.length;k++){var l=f[k];d.prototype[l]=j(l)}return d};var d=function(){this.listeners={}};d.prototype.on=function(a,b){this.listeners=this.listeners||{},a in this.listeners?this.listeners[a].push(b):this.listeners[a]=[b]},d.prototype.trigger=function(a){var b=Array.prototype.slice,c=b.call(arguments,1);this.listeners=this.listeners||{},null==c&&(c=[]),0===c.length&&c.push({}),c[0]._type=a,a in this.listeners&&this.invoke(this.listeners[a],b.call(arguments,1)),"*"in this.listeners&&this.invoke(this.listeners["*"],arguments)},d.prototype.invoke=function(a,b){for(var c=0,d=a.length;c<d;c++)a[c].apply(this,b)},c.Observable=d,c.generateChars=function(a){for(var b="",c=0;c<a;c++){b+=Math.floor(36*Math.random()).toString(36)}return b},c.bind=function(a,b){return function(){a.apply(b,arguments)}},c._convertData=function(a){for(var b in a){var c=b.split("-"),d=a;if(1!==c.length){for(var e=0;e<c.length;e++){var f=c[e];f=f.substring(0,1).toLowerCase()+f.substring(1),f in d||(d[f]={}),e==c.length-1&&(d[f]=a[b]),d=d[f]}delete a[b]}}return a},c.hasScroll=function(b,c){var d=a(c),e=c.style.overflowX,f=c.style.overflowY;return(e!==f||"hidden"!==f&&"visible"!==f)&&("scroll"===e||"scroll"===f||(d.innerHeight()<c.scrollHeight||d.innerWidth()<c.scrollWidth))},c.escapeMarkup=function(a){var b={"\\":"&#92;","&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#47;"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c.__cache={};var e=0;return c.GetUniqueElementId=function(a){var b=a.getAttribute("data-select2-id");return null==b&&(a.id?(b=a.id,a.setAttribute("data-select2-id",b)):(a.setAttribute("data-select2-id",++e),b=e.toString())),b},c.StoreData=function(a,b,d){var e=c.GetUniqueElementId(a);c.__cache[e]||(c.__cache[e]={}),c.__cache[e][b]=d},c.GetData=function(b,d){var e=c.GetUniqueElementId(b);return d?c.__cache[e]&&null!=c.__cache[e][d]?c.__cache[e][d]:a(b).data(d):c.__cache[e]},c.RemoveData=function(a){var b=c.GetUniqueElementId(a);null!=c.__cache[b]&&delete c.__cache[b]},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<ul class="select2-results__options" role="tree"></ul>');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a('<li role="treeitem" aria-live="assertive" class="select2-results__option"></li>'),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c<a.results.length;c++){var d=a.results[c],e=this.option(d);b.push(e)}this.$results.append(b)},c.prototype.position=function(a,b){b.find(".select2-results").append(a)},c.prototype.sort=function(a){return this.options.get("sorter")(a)},c.prototype.highlightFirstItem=function(){var a=this.$results.find(".select2-results__option[aria-selected]"),b=a.filter("[aria-selected=true]");b.length>0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var c=this;this.data.current(function(d){var e=a.map(d,function(a){return a.id.toString()});c.$results.find(".select2-results__option[aria-selected]").each(function(){var c=a(this),d=b.GetData(this,"data"),f=""+d.id;null!=d.element&&d.element.selected||null==d.element&&a.inArray(f,e)>-1?c.attr("aria-selected","true"):c.attr("aria-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(c){var d=document.createElement("li");d.className="select2-results__option";var e={role:"treeitem","aria-selected":"false"};c.disabled&&(delete e["aria-selected"],e["aria-disabled"]="true"),null==c.id&&delete e["aria-selected"],null!=c._resultId&&(d.id=c._resultId),c.title&&(d.title=c.title),c.children&&(e.role="group",e["aria-label"]=c.text,delete e["aria-selected"]);for(var f in e){var g=e[f];d.setAttribute(f,g)}if(c.children){var h=a(d),i=document.createElement("strong");i.className="select2-results__group";a(i);this.template(c,i);for(var j=[],k=0;k<c.children.length;k++){var l=c.children[k],m=this.option(l);j.push(m)}var n=a("<ul></ul>",{class:"select2-results__options select2-results__options--nested"});n.append(j),h.append(i),h.append(n)}else this.template(c,d);return b.StoreData(d,"data",c),d},c.prototype.bind=function(c,d){var e=this,f=c.id+"-results";this.$results.attr("id",f),c.on("results:all",function(a){e.clear(),e.append(a.data),c.isOpen()&&(e.setClasses(),e.highlightFirstItem())}),c.on("results:append",function(a){e.append(a.data),c.isOpen()&&e.setClasses()}),c.on("query",function(a){e.hideMessages(),e.showLoading(a)}),c.on("select",function(){c.isOpen()&&(e.setClasses(),e.highlightFirstItem())}),c.on("unselect",function(){c.isOpen()&&(e.setClasses(),e.highlightFirstItem())}),c.on("open",function(){e.$results.attr("aria-expanded","true"),e.$results.attr("aria-hidden","false"),e.setClasses(),e.ensureHighlightVisible()}),c.on("close",function(){e.$results.attr("aria-expanded","false"),e.$results.attr("aria-hidden","true"),e.$results.removeAttr("aria-activedescendant")}),c.on("results:toggle",function(){var a=e.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),c.on("results:select",function(){var a=e.getHighlightedResults();if(0!==a.length){var c=b.GetData(a[0],"data");"true"==a.attr("aria-selected")?e.trigger("close",{}):e.trigger("select",{data:c})}}),c.on("results:previous",function(){var a=e.getHighlightedResults(),b=e.$results.find("[aria-selected]"),c=b.index(a);if(!(c<=0)){var d=c-1;0===a.length&&(d=0);var f=b.eq(d);f.trigger("mouseenter");var g=e.$results.offset().top,h=f.offset().top,i=e.$results.scrollTop()+(h-g);0===d?e.$results.scrollTop(0):h-g<0&&e.$results.scrollTop(i)}}),c.on("results:next",function(){var a=e.getHighlightedResults(),b=e.$results.find("[aria-selected]"),c=b.index(a),d=c+1;if(!(d>=b.length)){var f=b.eq(d);f.trigger("mouseenter");var g=e.$results.offset().top+e.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=e.$results.scrollTop()+h-g;0===d?e.$results.scrollTop(0):h>g&&e.$results.scrollTop(i)}}),c.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),c.on("results:message",function(a){e.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=e.$results.scrollTop(),c=e.$results.get(0).scrollHeight-b+a.deltaY,d=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=e.$results.height();d?(e.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(e.$results.scrollTop(e.$results.get(0).scrollHeight-e.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(c){var d=a(this),f=b.GetData(this,"data");if("true"===d.attr("aria-selected"))return void(e.options.get("multiple")?e.trigger("unselect",{originalEvent:c,data:f}):e.trigger("close",{}));e.trigger("select",{originalEvent:c,data:f})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(c){var d=b.GetData(this,"data");e.getHighlightedResults().removeClass("select2-results__option--highlighted"),e.trigger("results:focus",{data:d,element:a(this)})})},c.prototype.getHighlightedResults=function(){return this.$results.find(".select2-results__option--highlighted")},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),c<=2?this.$results.scrollTop(0):(g>this.$results.outerHeight()||g<0)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var c=a('<span class="select2-selection" role="combobox" aria-haspopup="true" aria-expanded="false"></span>');return this._tabindex=0,null!=b.GetData(this.$element[0],"old-tabindex")?this._tabindex=b.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),c.attr("title",this.$element.attr("title")),c.attr("tabindex",this._tabindex),this.$selection=c,c},d.prototype.bind=function(a,b){var d=this,e=(a.id,a.id+"-results");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),d.$selection.focus(),window.setTimeout(function(){d.$selection.focus()},0),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(c){a(document.body).on("mousedown.select2."+c.id,function(c){var d=a(c.target),e=d.closest(".select2");a(".select2.select2-container--open").each(function(){a(this),this!=e[0]&&b.GetData(this,"element").select2("close")})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){b.find(".selection").append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html('<span class="select2-selection__rendered"></span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span>'),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()})},e.prototype.clear=function(){var a=this.$selection.find(".select2-selection__rendered");a.empty(),a.removeAttr("title")},e.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},e.prototype.selectionContainer=function(){return a("<span></span>")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.attr("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('<ul class="select2-selection__rendered"></ul>'),a},d.prototype.bind=function(b,e){var f=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){f.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!f.options.get("disabled")){var d=a(this),e=d.parent(),g=c.GetData(e[0],"data");f.trigger("unselect",{originalEvent:b,data:g})}})},d.prototype.clear=function(){var a=this.$selection.find(".select2-selection__rendered");a.empty(),a.removeAttr("title")},d.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},d.prototype.selectionContainer=function(){return a('<li class="select2-selection__choice"><span class="select2-selection__choice__remove" role="presentation">&times;</span></li>')},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d<a.length;d++){var e=a[d],f=this.selectionContainer(),g=this.display(e,f);f.append(g),f.attr("title",e.title||e.text),c.StoreData(f[0],"data",e),b.push(f)}var h=this.$selection.find(".select2-selection__rendered");c.appendMany(h,b)}},d}),b.define("select2/selection/placeholder",["../utils"],function(a){function b(a,b,c){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c)}return b.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},b.prototype.createPlaceholder=function(a,b){var c=this.selectionContainer();return c.html(this.display(b)),c.addClass("select2-selection__placeholder").removeClass("select2-selection__choice"),c},b.prototype.update=function(a,b){var c=1==b.length&&b[0].id!=this.placeholder.id;if(b.length>1||c)return a.call(this,b);this.clear();var d=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(d)},b}),b.define("select2/selection/allowClear",["jquery","../keys","../utils"],function(a,b,c){function d(){}return d.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},d.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var d=this.$selection.find(".select2-selection__clear");if(0!==d.length){b.stopPropagation();var e=c.GetData(d[0],"data"),f=this.$element.val();this.$element.val(this.placeholder.id);var g={data:e};if(this.trigger("clear",g),g.prevented)return void this.$element.val(f);for(var h=0;h<e.length;h++)if(g={data:e[h]},this.trigger("unselect",g),g.prevented)return void this.$element.val(f);this.$element.trigger("change"),this.trigger("toggle",{})}}},d.prototype._handleKeyboardClear=function(a,c,d){d.isOpen()||c.which!=b.DELETE&&c.which!=b.BACKSPACE||this._handleClear(c)},d.prototype.update=function(b,d){if(b.call(this,d),!(this.$selection.find(".select2-selection__placeholder").length>0||0===d.length)){var e=a('<span class="select2-selection__clear">&times;</span>');c.StoreData(e[0],"data",d),this.$selection.find(".select2-selection__rendered").prepend(e)}},d}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('<li class="select2-search select2-search--inline"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="textbox" aria-autocomplete="list" /></li>');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,d,e){var f=this;a.call(this,d,e),d.on("open",function(){f.$search.trigger("focus")}),d.on("close",function(){f.$search.val(""),f.$search.removeAttr("aria-activedescendant"),f.$search.trigger("focus")}),d.on("enable",function(){f.$search.prop("disabled",!1),f._transferTabIndex()}),d.on("disable",function(){f.$search.prop("disabled",!0)}),d.on("focus",function(a){f.$search.trigger("focus")}),d.on("results:focus",function(a){f.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){f.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){f._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),f.trigger("keypress",a),f._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===f.$search.val()){var d=f.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var e=b.GetData(d[0],"data");f.searchRemoveChoice(e),a.preventDefault()}}});var g=document.documentMode,h=g&&g<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){if(h)return void f.$selection.off("input.search input.searchcheck");f.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(h&&"input"===a.type)return void f.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&f.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;if(this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c){this.$element.find("[data-select2-tag]").length?this.$element.focus():this.$search.focus()}},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{a=.75*(this.$search.val().length+1)+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting","clear","clearing"],g=["opening","closing","selecting","unselecting","clearing"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"}}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),null!=c.id?d+="-"+c.id.toString():d+="-"+a.generateChars(4),d},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f<a.length;f++){var g=a[f].id;-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")});else{var d=a.id;this.$element.val(d),this.$element.trigger("change")}},d.prototype.unselect=function(a){var b=this;if(this.$element.prop("multiple")){if(a.selected=!1,c(a.element).is("option"))return a.element.selected=!1,void this.$element.trigger("change");this.current(function(d){for(var e=[],f=0;f<d.length;f++){var g=d[f].id;g!==a.id&&-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")})}},d.prototype.bind=function(a,b){var c=this;this.container=a,a.on("select",function(a){c.select(a.data)}),a.on("unselect",function(a){c.unselect(a.data)})},d.prototype.destroy=function(){this.$element.find("*").each(function(){b.RemoveData(this)})},d.prototype.query=function(a,b){var d=[],e=this;this.$element.children().each(function(){var b=c(this);if(b.is("option")||b.is("optgroup")){var f=e.item(b),g=e.matches(a,f);null!==g&&d.push(g)}}),b({results:d})},d.prototype.addOptions=function(a){b.appendMany(this.$element,a)},d.prototype.option=function(a){var d;a.children?(d=document.createElement("optgroup"),d.label=a.text):(d=document.createElement("option"),void 0!==d.textContent?d.textContent=a.text:d.innerText=a.text),void 0!==a.id&&(d.value=a.id),a.disabled&&(d.disabled=!0),a.selected&&(d.selected=!0),a.title&&(d.title=a.title);var e=c(d),f=this._normalizeItem(a);return f.element=d,b.StoreData(d,"data",f),e},d.prototype.item=function(a){var d={};if(null!=(d=b.GetData(a[0],"data")))return d;if(a.is("option"))d={id:a.val(),text:a.text(),disabled:a.prop("disabled"),selected:a.prop("selected"),title:a.prop("title")};else if(a.is("optgroup")){d={text:a.prop("label"),children:[],title:a.prop("title")};for(var e=a.children("option"),f=[],g=0;g<e.length;g++){var h=c(e[g]),i=this.item(h);f.push(i)}d.children=f}return d=this._normalizeItem(d),d.element=a[0],b.StoreData(a[0],"data",d),d},d.prototype._normalizeItem=function(a){a!==Object(a)&&(a={id:a,text:a}),a=c.extend({},{text:""},a);var b={selected:!1,disabled:!1};return null!=a.id&&(a.id=a.id.toString()),null!=a.text&&(a.text=a.text.toString()),null==a._resultId&&a.id&&null!=this.container&&(a._resultId=this.generateResultId(this.container,a)),c.extend({},b,a)},d.prototype.matches=function(a,b){return this.options.get("matcher")(a,b)},d}),b.define("select2/data/array",["./select","../utils","jquery"],function(a,b,c){function d(a,b){var c=b.get("data")||[];d.__super__.constructor.call(this,a,b),this.addOptions(this.convertToOptions(c))}return b.Extend(d,a),d.prototype.select=function(a){var b=this.$element.find("option").filter(function(b,c){return c.value==a.id.toString()});0===b.length&&(b=this.option(a),this.addOptions(b)),d.__super__.select.call(this,a)},d.prototype.convertToOptions=function(a){function d(a){return function(){return c(this).val()==a.id}}for(var e=this,f=this.$element.find("option"),g=f.map(function(){return e.item(c(this)).id}).get(),h=[],i=0;i<a.length;i++){var j=this._normalizeItem(a[i]);if(c.inArray(j.id,g)>=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){"status"in d&&(0===d.status||"0"===d.status)||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h<e.length;h++){var i=e[h],j=this._normalizeItem(i),k=this.option(j);this.$element.append(k)}}return b.prototype.query=function(a,b,c){function d(a,f){for(var g=a.results,h=0;h<g.length;h++){var i=g[h],j=null!=i.children&&!d({results:i.children},!0);if((i.text||"").toUpperCase()===(b.term||"").toUpperCase()||j)return!f&&(a.data=g,void c(a))}if(f)return!0;var k=e.createTag(b);if(null!=k){var l=e.option(k);l.attr("data-select2-tag",!0),e.addOptions([l]),e.insertTag(g,k)}a.results=g,c(a)}var e=this;if(this._removeOldTags(),null==b.term||null!=b.page)return void a.call(this,b,c);a.call(this,b,d)},b.prototype.createTag=function(b,c){var d=a.trim(c.term);return""===d?null:{id:d,text:d}},b.prototype.insertTag=function(a,b,c){b.unshift(c)},b.prototype._removeOldTags=function(b){this._lastTag;this.$element.find("option[data-select2-tag]").each(function(){this.selected||a(this).remove()})},b}),b.define("select2/data/tokenizer",["jquery"],function(a){function b(a,b,c){var d=c.get("tokenizer");void 0!==d&&(this.tokenizer=d),a.call(this,b,c)}return b.prototype.bind=function(a,b,c){a.call(this,b,c),this.$search=b.dropdown.$search||b.selection.$search||c.find(".select2-search__field")},b.prototype.query=function(b,c,d){function e(b){var c=g._normalizeItem(b);if(!g.$element.find("option").filter(function(){return a(this).val()===c.id}).length){var d=g.option(c);d.attr("data-select2-tag",!0),g._removeOldTags(),g.addOptions([d])}f(c)}function f(a){g.trigger("select",{data:a})}var g=this;c.term=c.term||"";var h=this.tokenizer(c,this.options,e);h.term!==c.term&&(this.$search.length&&(this.$search.val(h.term),this.$search.focus()),c.term=h.term),b.call(this,c,d)},b.prototype.tokenizer=function(b,c,d,e){for(var f=d.get("tokenSeparators")||[],g=c.term,h=0,i=this.createTag||function(a){return{id:a.term,text:a.term}};h<g.length;){var j=g[h];if(-1!==a.inArray(j,f)){var k=g.substr(0,h),l=a.extend({},c,{term:k}),m=i(l);null!=m?(e(m),g=g.substr(h+1)||"",h=0):h++}else h++}return{term:g}},b}),b.define("select2/data/minimumInputLength",[],function(){function a(a,b,c){this.minimumInputLength=c.get("minimumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){if(b.term=b.term||"",b.term.length<this.minimumInputLength)return void this.trigger("results:message",{message:"inputTooShort",args:{minimum:this.minimumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumInputLength",[],function(){function a(a,b,c){this.maximumInputLength=c.get("maximumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){if(b.term=b.term||"",this.maximumInputLength>0&&b.term.length>this.maximumInputLength)return void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;if(d.maximumSelectionLength>0&&f>=d.maximumSelectionLength)return void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}});a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<span class="select2-dropdown"><span class="select2-results"></span></span>');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('<span class="select2-search select2-search--dropdown"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="textbox" /></span>');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val(""),e.$search.blur()}),c.on("focus",function(){c.isOpen()||e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('<li class="select2-results__option select2-results__option--load-more"role="treeitem" aria-disabled="true"></li>'),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a("<span></span>"),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){b.StoreData(this,"select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(c){var d=b.GetData(this,"select2-scroll-position");a(this).scrollTop(d.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.top<f.top-h.height,k=i.bottom>f.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d<b.length;d++){var e=b[d];e.children?c+=a(e.children):c++}return c}function b(a,b,c,d){this.minimumResultsForSearch=c.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),a.call(this,b,c,d)}return b.prototype.showSearch=function(b,c){return!(a(c.data.results)<this.minimumResultsForSearch)&&b.call(this,c)},b}),b.define("select2/dropdown/selectOnClose",["../utils"],function(a){function b(){}return b.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("close",function(a){d._handleSelectOnClose(a)})},b.prototype._handleSelectOnClose=function(b,c){if(c&&null!=c.originalSelect2Event){var d=c.originalSelect2Event;if("select"===d._type||"unselect"===d._type)return}var e=this.getHighlightedResults();if(!(e.length<1)){var f=a.GetData(e[0],"data");null!=f.element&&f.element.selected||null==f.element&&f.selected||this.trigger("select",{data:f})}},b}),b.define("select2/dropdown/closeOnSelect",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("select",function(a){d._selectTriggered(a)}),b.on("unselect",function(a){d._selectTriggered(a)})},a.prototype._selectTriggered=function(a,b){var c=b.originalEvent;c&&c.ctrlKey||this.trigger("close",{originalEvent:c,originalSelect2Event:b})},a}),b.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(a){var b=a.input.length-a.maximum,c="Please delete "+b+" character";return 1!=b&&(c+="s"),c},inputTooShort:function(a){return"Please enter "+(a.minimum-a.input.length)+" or more characters"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(a){var b="You can only select "+a.maximum+" item";return 1!=a.maximum&&(b+="s"),b},noResults:function(){return"No results found"},searching:function(){return"Searching…"}}}),b.define("select2/defaults",["jquery","require","./results","./selection/single","./selection/multiple","./selection/placeholder","./selection/allowClear","./selection/search","./selection/eventRelay","./utils","./translation","./diacritics","./data/select","./data/array","./data/ajax","./data/tags","./data/tokenizer","./data/minimumInputLength","./data/maximumInputLength","./data/maximumSelectionLength","./dropdown","./dropdown/search","./dropdown/hidePlaceholder","./dropdown/infiniteScroll","./dropdown/attachBody","./dropdown/minimumResultsForSearch","./dropdown/selectOnClose","./dropdown/closeOnSelect","./i18n/en"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C){function D(){this.reset()}return D.prototype.apply=function(l){if(l=a.extend(!0,{},this.defaults,l),null==l.dataAdapter){if(null!=l.ajax?l.dataAdapter=o:null!=l.data?l.dataAdapter=n:l.dataAdapter=m,l.minimumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),null==l.tokenSeparators&&null==l.tokenizer||(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L<K.length;L++){var M=K[L],N={};try{N=k.loadPath(M)}catch(a){try{M=this.defaults.amdLanguageBase+M,N=k.loadPath(M)}catch(a){l.debug&&window.console&&console.warn&&console.warn('Select2: The language file for "'+M+'" could not be automatically loaded. A fallback will be used instead.');continue}}J.extend(N)}l.translations=J}else{var O=k.loadPath(this.defaults.amdLanguageBase+"en"),P=new k(l.language);P.extend(O),l.translations=P}return l},D.prototype.reset=function(){function b(a){function b(a){return l[a]||a}return a.replace(/[^\u0000-\u007E]/g,b)}function c(d,e){if(""===a.trim(d.term))return e;if(e.children&&e.children.length>0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){null==c(d,e.children[g])&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var h=b(e.text).toUpperCase(),i=b(d.term).toUpperCase();return h.indexOf(i)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(!0,this.defaults,f)},new D}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),d.GetData(a[0],"select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),d.StoreData(a[0],"data",d.GetData(a[0],"select2Tags")),d.StoreData(a[0],"tags",!0)),d.GetData(a[0],"ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",d.GetData(a[0],"ajaxUrl")),d.StoreData(a[0],"ajax-Url",d.GetData(a[0],"ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,d.GetData(a[0])):d.GetData(a[0]);var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,d){null!=c.GetData(a[0],"select2")&&c.GetData(a[0],"select2").destroy(),this.$element=a,this.id=this._generateId(a),d=d||{},this.options=new b(d,a),e.__super__.constructor.call(this);var f=a.attr("tabindex")||0;c.StoreData(a[0],"old-tabindex",f),a.attr("tabindex","-1");var g=this.options.get("dataAdapter");this.dataAdapter=new g(a,this.options);var h=this.render();this._placeContainer(h);var i=this.options.get("selectionAdapter");this.selection=new i(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,h);var j=this.options.get("dropdownAdapter");this.dropdown=new j(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,h);var k=this.options.get("resultsAdapter");this.results=new k(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var l=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){l.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),c.StoreData(a[0],"select2",this),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return e<=0?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;h<i;h+=1){var j=g[h].replace(/\s/g,""),k=j.match(c);if(null!==k&&k.length>=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e<b.addedNodes.length;e++){var f=b.addedNodes[e];f.selected&&(c=!0)}else b.removedNodes&&b.removedNodes.length>0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting",clear:"clearing"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=a&&0!==a.length||(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",c.GetData(this.$element[0],"old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),c.RemoveData(this.$element[0]),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('<span class="select2 select2-container"><span class="selection"></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),c.StoreData(b[0],"element",this.$element),b},e}),b.define("jquery-mousewheel",["jquery"],function(a){return a}),b.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],function(a,b,c,d,e){if(null==a.fn.select2){var f=["open","close","destroy"];a.fn.select2=function(b){if("object"==typeof(b=b||{}))return this.each(function(){var d=a.extend(!0,{},b);new c(a(this),d)}),this;if("string"==typeof b){var d,g=Array.prototype.slice.call(arguments,1);return this.each(function(){var a=e.GetData(this,"select2");null==a&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2."),d=a[b].apply(a,g)}),a.inArray(b,f)>-1?this:d}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c});
admin/js/tabs.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ jQuery(function() {
2
+ jQuery( "#tabs" ).tabs().addClass( "ui-tabs-vertical ui-helper-clearfix" );
3
+ jQuery( "#tabs li" ).removeClass( "ui-corner-top" ).addClass( "ui-corner-left" );
4
+ } );
admin/partials/admin-header.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ exit;
6
+ }
7
+
8
+ function header_part() {
9
+ $screen = get_current_screen();
10
+ if ( $screen->parent_base == 'es_dashboard' || $screen->id == 'es_template' || $screen->parent_base == 'admin_page_es_template_preview' ) {
11
+ ?>
12
+
13
+ <div class="headerpart">
14
+ <div class="esbgheader">
15
+ <h1>Email Subscribers V4.0</h1>
16
+ </div>
17
+ </div>
18
+ <?php
19
+ }
20
+ }
21
+
22
+ // add_action( 'admin_notices', 'header_part' );
23
+
24
+
25
+ ?>
admin/partials/dashboard.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
+
7
+ ?>
8
+ <script type="text/javascript">
9
+ jQuery(function () {
10
+ jQuery("form[name=klawoo_subscribe]").submit(function (e) {
11
+
12
+ e.preventDefault();
13
+
14
+ jQuery('#klawoo_response').html('');
15
+ jQuery('#klawoo_response').show();
16
+
17
+ params = jQuery("form[name=klawoo_subscribe]").serializeArray();
18
+ params.push( {name: 'action', value: 'es_klawoo_subscribe' });
19
+
20
+ jQuery.ajax({
21
+ method: 'POST',
22
+ type: 'text',
23
+ url: "<?php echo admin_url( 'admin-ajax.php' ); ?>",
24
+ async: false,
25
+ data: params,
26
+ success: function(response) {
27
+
28
+ if (response != '') {
29
+ var parser = new DOMParser()
30
+ var el = parser.parseFromString(response, "text/xml");
31
+
32
+ jQuery('#klawoo_response').html(el.childNodes[0].firstChild.nextElementSibling.innerHTML);
33
+
34
+ jQuery('.es-emm-optin #name').val('');
35
+ jQuery('.es-emm-optin #email').val('');
36
+ jQuery('.es-emm-optin #es-gdpr-agree').attr('checked', false);
37
+ setTimeout(function() {
38
+ jQuery('#klawoo_response').hide('slow');
39
+ }, 2000);
40
+
41
+ } else {
42
+ jQuery('#klawoo_response').html('error!');
43
+ }
44
+ }
45
+ });
46
+
47
+ });
48
+ });
49
+ </script>
50
+
51
+ <div class="wrap">
52
+ <div class="about-header">
53
+ <div class="es-upper">
54
+ <div class="es-info">
55
+ <?php
56
+ $es_upgrade_to_4 = get_option('current_sa_email_subscribers_db_version');
57
+ if(empty($es_upgrade_to_4)){?>
58
+ <h2><?php echo __( 'Congratulations! You\'ve successfully upgraded to 4.0!', 'email-subscribers' ); ?></h2>
59
+ <ul><strong><?php _e('Here\'s a quick look at changes within the plugin:', 'email-subscribers'); ?></strong>
60
+ <li class="es-notify-about-new-post-2"><?php echo sprintf( __( '1. Newsletters are now <b>Broadcasts</b>. Broadcasts and Post notifications are now merged in <a href="%s" target="_blank">Campaigns</a>', 'email-subscribers' ), admin_url( 'admin.php?page=es_campaigns' )); ?></li>
61
+ <li class="es-notify-about-new-post-2"><?php echo sprintf( __( '2. Subscribers are now called <b>Contacts</b> and part of an <a href="%s" target="_blank">Audience</a>', 'email-subscribers' ), admin_url( 'admin.php?page=es_subscribers' )); ?></li>
62
+ <li class="es-notify-about-new-post-2"><?php echo sprintf( __( '3. Groups are now called <a href="%s" target="_blank">Lists</a>', 'email-subscribers' ), admin_url( 'admin.php?page=es_lists' )); ?></li>
63
+ <li class="es-notify-about-new-post-2"><?php echo sprintf( __( '4. Find <a href="%s" target="_blank">Forms</a> here', 'email-subscribers' ), admin_url( 'admin.php?page=es_forms' )); ?></li>
64
+ </ul>
65
+ <a href="https://www.icegram.com/email-subscribers-plugin-redesign/?utm_source=es&utm_medium=in_app&utm_campaign=es_4" target="_blank" class="button button-main"><?php _e('Explore all changes', 'email-subscribers'); ?></a>
66
+ <?php }else{?>
67
+ <h2><?php echo __( 'Welcome to the Email Subscribers Community!', 'email-subscribers' ); ?></h2>
68
+ <div class="es-about-line"><?php _e('Email Subscribers is a complete newsletter plugin which lets you collect leads, send automated new blog post notification emails, create & send newsletters and manage all this in one single place.', 'email-subscribers')?></div>
69
+ <div class="es-about-text"><?php echo __( 'We hope our plugin adds to your success <img draggable="false" class="emoji" alt="🏆" src="https://s.w.org/images/core/emoji/11/svg/1f3c6.svg">', 'email-subscribers' ); ?></div>
70
+ <div class="es-notify-about-new-post-1"><?php echo __( 'To get started, we did some initial setup to save your time <img draggable="false" class="emoji" alt="😊" src="https://s.w.org/images/core/emoji/11/svg/1f60a.svg">', 'email-subscribers' ); ?></div>
71
+ <ul>
72
+ <li class="es-notify-about-new-post-2"><?php echo __( '1. Created a lead collecting form and added it the default widget area in your WP admin', 'email-subscribers' ); ?></li>
73
+ <li class="es-notify-about-new-post-2"><?php echo __( '2. Created a "Test" subscriber list and added "', 'email-subscribers' ) . $admin_email . __( '" to it.', 'email-subscribers' ); ?></li>
74
+ <li class="es-notify-about-new-post-2"><?php echo __( '3. Sent a test post notification, test broadcasts to the test subscriber list.', 'email-subscribers' ); ?></li>
75
+ <li class="es-notify-about-new-post-2"><?php echo __( '4. Created a first form.', 'email-subscribers' ); ?></li>
76
+ </ul>
77
+
78
+ <?php }?>
79
+ <div class="es-quick-links-wrapper" >
80
+ <h3><?php _e('Here are some quick links', 'email-subscribers'); ?></h3>
81
+ <span class="es-quick-links"><a target="_blank" href="<?php echo admin_url( 'admin.php?page=es_subscribers' )?>" ><?php _e('Audience', 'email-subscribers')?></a></span>
82
+ <span class="es-quick-links"><a target="_blank" href="<?php echo admin_url( 'admin.php?page=es_forms' )?>" ><?php _e('Forms', 'email-subscribers')?></a></span>
83
+ <span class="es-quick-links"><a target="_blank" href="<?php echo admin_url( 'admin.php?page=es_campaigns' )?>" ><?php _e('Campaigns', 'email-subscribers')?></a></span>
84
+ <span class="es-quick-links"><a target="_blank" href="<?php echo admin_url( 'admin.php?page=es_lists' )?>" ><?php _e('Lists', 'email-subscribers')?></a></span>
85
+ <span class="es-quick-links"><a target="_blank" href="<?php echo admin_url( 'admin.php?page=es_reports' )?>" ><?php _e('Reports', 'email-subscribers')?></a></span>
86
+ </div>
87
+ <div class="es-help-wrap" >
88
+ <div class="subscribe-form">
89
+ <h3><?php echo __( 'Add Subscribe form', 'email-subscribers' ); ?></h3>
90
+ <p><?php echo __( 'Use any of the following 3 methods :', 'email-subscribers' ); ?></p>
91
+ <ul>
92
+ <li><?php echo __( 'Shortcode in any page/post : <code>[email-subscribers-form id="{form-id}"]</code> ', 'email-subscribers' ); ?></li>
93
+ <li><?php echo __( 'Go to Appearance -> Widgets. Click on widget Email subscribers and drag it to the widget area', 'email-subscribers' ); ?></li>
94
+ <li><?php echo __( 'Paste below PHP code to your desired location :', 'email-subscribers' ); ?> <p><code><?php echo esc_html( '<?php es_subbox($namefield = "YES", $desc = "", $group = "Public"); ?>' ); ?></code></p></li>
95
+ </ul>
96
+ </div>
97
+ </div>
98
+
99
+ </div>
100
+
101
+ <div class="wrap klawoo-form">
102
+ <table class="form-table">
103
+ <tr>
104
+ <td colspan="3" class="es-optin-headline"><?php echo __( 'Build your list and succeed with email marketing <div>in 5 short weeks</div>', 'email-subscribers' ); ?></td>
105
+ </tr>
106
+ <tr>
107
+ <td colspan="3" class="es-emm-image"><img alt="Email Marketing Mastery" src="<?php echo plugin_dir_url( dirname( __FILE__ ) ); ?>images/email-marketing-mastery.png"/></td>
108
+ </tr>
109
+ <tr>
110
+ <td colspan="3" class="es-emm-text">
111
+ <p><?php echo __( 'Do you want to build your list, keep off spam, write emails that people open and click through? Do you want to build your brand and nurture an amazing tribe?', 'email-subscribers' ); ?></p>
112
+ <p><b><?php echo __( 'Enter your name and email on the form to get it all.', 'email-subscribers' ); ?></b></p>
113
+ </td>
114
+ </tr>
115
+ <tr>
116
+ <td colspan="3" class="es-emm-optin">
117
+ <form name="klawoo_subscribe" action="#" method="POST" accept-charset="utf-8">
118
+ <input class="es-ltr" type="text" name="name" id="name" placeholder="Your Name" />
119
+ <input class="es-ltr" type="text" name="email" id="email" placeholder="Your Email" /> <br />
120
+ <input type="hidden" name="list" value="hN8OkYzujUlKgDgfCTEcIA"/>
121
+ <input type="checkbox" name="es-gdpr-agree" id ="es-gdpr-agree" value="1" required="required">
122
+ <label for="es-gdpr-agree"><?php echo sprintf(__( 'I have read and agreed to your %s.', 'email-subscribers' ), '<a href="https://www.icegram.com/privacy-policy/" target="_blank">' . __( 'Privacy Policy', 'email-subscribers' ) . '</a>' ); ?></label>
123
+ <br /><br />
124
+ <input type="submit" name="submit" id="submit" class="button button-hero" value="<?php echo __( 'Subscribe', 'email-subscribers' ); ?>">
125
+ <br><br>
126
+ <p id="klawoo_response"></p>
127
+ </form>
128
+ </td>
129
+ </tr>
130
+ <tr>
131
+ <td colspan="3" class="es-emm-text">
132
+ <div class="column">
133
+ <p><strong><?php _e('<span style="color:#ff6f7b">Join our</span> Email Subscribers Secret Club!','email-subscribers'); ?></strong></p>
134
+ <p><?php _e('Be a part of development, share your valuable feedback and get early access to our upcoming <strong>Email Subscribers 5.0</>', 'email-subscribers'); ?></p>
135
+ <p><a style="text-decoration: none" target="_blank" href="https://www.facebook.com/groups/2298909487017349/"><i class="dashicons dashicons-es dashicons-facebook"></i></a></p>
136
+ </div>
137
+ </td>
138
+ </tr>
139
+ </table>
140
+
141
+ </div>
142
+ </div>
143
+ <div class="es-lower">
144
+ <div class="es-version">
145
+ <h3><?php echo __( 'Questions? Need Help?', 'email-subscribers' ); ?></h3>
146
+ <a href="https://wordpress.org/support/plugin/email-subscribers" target="_blank"><?php echo __( 'Contact Us', 'email-subscribers' ); ?></a>
147
+ <h5 class="es-badge"><?php echo sprintf( __( 'Version: %s', 'email-subscribers' ), $es_current_version ); ?></h5>
148
+ </div>
149
+ </div>
150
+
151
+
152
+ </div>
153
+ </div>
admin/partials/help.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ exit;
6
+ }
7
+
8
+ ?>
9
+ <div class="wrap">
10
+ <h1><?php echo __( 'Help & Info', 'email-subscribers' ); ?></h1>
11
+
12
+ <div class="help-info-content">
13
+ <div class="left-blog">
14
+ <div class="feature-overview">
15
+ <h3><?php echo __( 'Feature Overview', 'email-subscribers' ); ?></h3>
16
+ <ul>
17
+ <li><?php echo __( 'Collect customer emails by adding a subscription box (Widget/Shortcode/PHP Code).', 'email-subscribers' ); ?></li>
18
+ <li><?php echo __( 'Configure double Opt-In and Single Opt-In facility for subscribers.', 'email-subscribers' ); ?></li>
19
+ <li><?php echo __( 'Send automatic welcome email to subscribers.', 'email-subscribers' ); ?></li>
20
+ <li><?php echo __( 'Send new post notification emails to subscribers when new posts are published on your website.', 'email-subscribers' ); ?></li>
21
+ <li><?php echo __( 'Send email notification to admin when a new user signs up.', 'email-subscribers' ); ?></li>
22
+ <li><?php echo __( 'Automatically add Unsubscribe link in the email.', 'email-subscribers' ); ?></li>
23
+ <li><?php echo __( 'Easily migrate subscribers from another app using Import & Export.', 'email-subscribers' ); ?></li>
24
+ <li><?php echo __( 'Use HTML editor to create broadcast (Newsletters) and post notifications.', 'email-subscribers' ); ?></li>
25
+ <li><?php echo __( 'Send broadcast to different lists.', 'email-subscribers' ); ?></li>
26
+ <li><?php echo __( 'Get detailed sent email reports.', 'email-subscribers' ); ?></li>
27
+ <li><?php echo __( 'Supports localization and internationalization.', 'email-subscribers' ); ?></li>
28
+ </ul>
29
+ </div>
30
+ </div>
31
+ <div class="right-blog">
32
+ <div class="subscribe-form">
33
+ <h4><?php echo __( 'Additional form settings', 'email-subscribers' ); ?></h4>
34
+ <ul>
35
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-redirect-subscribers-to-a-new-page-url-after-successful-sign-up/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'How to Redirect Subscribers to a new page/url after successful sign up?', 'email-subscribers' ); ?></a></li>
36
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-add-captcha-in-subscribe-form-of-email-subscribers/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'How to add captcha in Subscribe form of Email Subscribers?', 'email-subscribers' ); ?></a></li>
37
+ </ul>
38
+ </div>
39
+ <div class="general-plugin-configuration">
40
+ <h3><?php echo __( 'General Plugin Configuration', 'email-subscribers' ); ?></h3>
41
+ <ul>
42
+ <li><?php echo __( 'Modify ', 'email-subscribers' ); ?><a target="_blank" href="https://www.icegram.com/documentation/es-general-plugin-settings/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'default text, email contents',
43
+ 'email-subscribers' ); ?></a><?php echo __( ' (like Confirmation, Welcome, Admin emails), Cron Settings and Assign User Roles', 'email-subscribers' ); ?></li>
44
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-does-sync-work/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'How does Sync work?', 'email-subscribers' ); ?></a></li>
45
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-import-or-export-email-addresses/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'How to Import or Export Email Addresses?', 'email-subscribers' ); ?></a></li>
46
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-add-update-existing-subscribers-group/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'How to Add/Update Existing Subscribers List & Status?', 'email-subscribers' ); ?></a></li>
47
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-change-update-translate-any-texts-from-email-subscribers/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'How to change/update/translate any texts from the plugin?', 'email-subscribers' ); ?></a></li>
48
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-add-unsubscribe-link-in-emails/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'How to add Unsubscribe link in emails?', 'email-subscribers' ); ?></a></li>
49
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-check-sent-emails/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'How to check sent emails?', 'email-subscribers' ); ?></a></li>
50
+ </ul>
51
+ </div>
52
+ </div>
53
+ </div>
54
+
55
+ <div class="feature-section">
56
+ <div class="feature-blog">
57
+ <h3><?php echo __( 'Newsletters', 'email-subscribers' ); ?></h3>
58
+ <ul>
59
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-create-and-send-newsletter-emails/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'Create and Send Newsletter Emails', 'email-subscribers' ); ?></a></li>
60
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-what-are-the-available-keywords-in-the-newsletters/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'Keywords in the Newsletters', 'email-subscribers' ); ?></a></li>
61
+ </ul>
62
+ </div>
63
+ <div class="feature-blog">
64
+ <h3><?php echo __( 'Cron Job Setup', 'email-subscribers' ); ?></h3>
65
+ <ul>
66
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-schedule-cron-emails/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'What is Cron and how to Schedule Cron Emails?', 'email-subscribers' ); ?></a></li>
67
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-schedule-cron-emails-in-cpanel/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'Schedule Cron Emails in cPanel', 'email-subscribers' ); ?></a></li>
68
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-schedule-cron-emails-in-parallels-plesk/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'Schedule Cron Emails in Parallels Plesk', 'email-subscribers' ); ?></a></li>
69
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-what-to-do-if-hosting-doesnt-support-cron-jobs/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'Hosting doesn’t support Cron Jobs?', 'email-subscribers' ); ?></a></li>
70
+ </ul>
71
+ </div>
72
+ <div class="feature-blog">
73
+ <h3><?php echo __( '[GDPR] Email Subscribers', 'email-subscribers' ); ?></h3>
74
+ <ul>
75
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-gdpr-how-to-enable-consent-checkbox-in-the-subscription-form/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'How to enable consent checkbox in the subscribe form?', 'email-subscribers' ); ?></a></li>
76
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-gdpr-what-data-email-subscribers-stores-on-your-end/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'What data Email Subscribers stores on your end?', 'email-subscribers' ); ?></a></li>
77
+ </ul>
78
+ </div>
79
+ <div class="feature-blog">
80
+ <h3><?php echo __( 'Post Notifications', 'email-subscribers' ); ?></h3>
81
+ <ul>
82
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-create-and-send-post-notification-emails-when-new-posts-are-published/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'Create and Send Post Notification Emails when new posts are published', 'email-subscribers' ); ?></a></li>
83
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-what-are-the-available-keywords-in-the-post-notifications/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'Keywords in the Post Notifications', 'email-subscribers' ); ?></a></li>
84
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-how-to-send-a-sample-new-post-notification-email-to-testgroup-myself/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'Send a test post notification email to myself/testgroup', 'email-subscribers' ); ?></a></li>
85
+ </ul>
86
+ </div>
87
+ <div class="feature-blog">
88
+ <h3><?php echo __( 'Troubleshooting Steps', 'email-subscribers' ); ?></h3>
89
+ <ul>
90
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-subscribers-are-not-receiving-emails/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'Subscribers are not receiving Emails?', 'email-subscribers' ); ?></a></li>
91
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-css-help/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( 'CSS Help', 'email-subscribers' ); ?></a></li>
92
+ <li><a target="_blank" href="https://www.icegram.com/documentation/es-faq/?utm_source=es&utm_medium=in_app&utm_campaign=view_docs_help_page"><?php echo __( "FAQ's", 'email-subscribers' ); ?></a></li>
93
+ </ul>
94
+ </div>
95
+ </div>
96
+ <div class="feature-section feature-section-last">
97
+ <div class="feature-header"><h2><?php echo __( "Want to do more? Here's how..", 'email-subscribers' ); ?></h2></div>
98
+ <div class="feature-blog-wrapper">
99
+ <div class="feature-blog">
100
+ <h3><?php echo __( 'Show your subscribe form inside attractive popups', 'email-subscribers' ); ?></h3>
101
+ <img src="<?php echo plugin_dir_url( dirname( __FILE__ ) ); ?>/images/es-ig-integration.png" alt="feature-img">
102
+