Admin Menu Editor - Version 1.8.6

Version Description

  • Fixed a PHP warning being thrown when the WPMU_PLUGIN_DIR constant is not a valid path or the full path cannot be determined.
  • Fixed a rare PHP warning "parameter 1 to be array, null given in menu-editor-core.php on line 4254" that was most likely caused by an unidentified plugin conflict.
  • Fixed a rare warning about a class being redefined.
  • Updated a number of internal dependencies.
  • Tested with WP 5.0.
Download this release

Release Info

Developer whiteshadow
Plugin Icon 128x128 Admin Menu Editor
Version 1.8.6
Comparing to
See all releases

Code changes from version 1.8.5 to 1.8.6

css/jquery.qtip.css CHANGED
@@ -1,26 +1,16 @@
1
- /*! qTip2 - Pretty powerful tooltips - v2.0.0 - 2012-09-10
2
- * http://craigsworks.com/projects/qtip2/
3
- * Copyright (c) 2012 Craig Michael Thompson; Licensed MIT, GPL */
4
-
5
- /* Fluid class for determining actual width in IE */
6
- #qtip-rcontainer{
7
- position: absolute;
8
- left: -28000px;
9
- top: -28000px;
10
- display: block;
11
- visibility: hidden;
12
- }
13
-
14
- /* Fluid class for determining actual width in IE */
15
- #qtip-rcontainer .ui-tooltip{
16
- display: block !important;
17
- visibility: hidden !important;
18
- position: static !important;
19
- float: left !important;
20
- }
21
-
22
- /* Core qTip styles */
23
- .ui-tooltip, .qtip{
24
  position: absolute;
25
  left: -28000px;
26
  top: -28000px;
@@ -28,12 +18,17 @@
28
 
29
  max-width: 280px;
30
  min-width: 50px;
31
-
32
  font-size: 10.5px;
33
  line-height: 12px;
 
 
 
 
 
34
  }
35
 
36
- .ui-tooltip-content{
37
  position: relative;
38
  padding: 5px 9px;
39
  overflow: hidden;
@@ -42,9 +37,8 @@
42
  word-wrap: break-word;
43
  }
44
 
45
- .ui-tooltip-titlebar{
46
  position: relative;
47
- min-height: 14px;
48
  padding: 5px 35px 5px 10px;
49
  overflow: hidden;
50
 
@@ -52,42 +46,46 @@
52
  font-weight: bold;
53
  }
54
 
55
- .ui-tooltip-titlebar + .ui-tooltip-content{ border-top-width: 0 !important; }
56
 
57
- /* Default close button class */
58
- .ui-tooltip-titlebar .ui-state-default{
59
- position: absolute;
60
- right: 4px;
61
- top: 50%;
62
- margin-top: -9px;
63
 
64
- cursor: pointer;
65
- outline: medium none;
 
 
 
66
 
67
- border-width: 1px;
68
- border-style: solid;
 
69
  }
70
-
71
- * html .ui-tooltip-titlebar .ui-state-default{ top: 16px; } /* IE fix */
72
 
73
- .ui-tooltip-titlebar .ui-icon,
74
- .ui-tooltip-icon .ui-icon{
 
 
75
  display: block;
76
  text-indent: -1000em;
77
  direction: ltr;
78
  }
79
 
80
- .ui-tooltip-icon, .ui-tooltip-icon .ui-icon{
81
  -moz-border-radius: 3px;
82
  -webkit-border-radius: 3px;
83
  border-radius: 3px;
84
  text-decoration: none;
85
  }
86
 
87
- .ui-tooltip-icon .ui-icon{
88
  width: 18px;
89
  height: 14px;
90
 
 
91
  text-align: center;
92
  text-indent: 0;
93
  font: normal bold 10px/13px Tahoma,sans-serif;
@@ -96,171 +94,173 @@
96
  background: transparent none no-repeat -100em -100em;
97
  }
98
 
99
-
100
  /* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */
101
- .ui-tooltip-focus{}
102
 
103
  /* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */
104
- .ui-tooltip-hover{}
105
 
106
  /* Default tooltip style */
107
- .ui-tooltip-default{
108
- border-width: 1px;
109
- border-style: solid;
110
- border-color: #F1D031;
111
 
112
  background-color: #FFFFA3;
113
  color: #555;
114
  }
115
 
116
- .ui-tooltip-default .ui-tooltip-titlebar{
117
  background-color: #FFEF93;
118
  }
119
 
120
- .ui-tooltip-default .ui-tooltip-icon{
121
  border-color: #CCC;
122
  background: #F1F1F1;
123
  color: #777;
124
  }
125
-
126
- .ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{
127
  border-color: #AAA;
128
  color: #111;
129
  }
130
 
131
 
132
  /*! Light tooltip style */
133
- .ui-tooltip-light{
134
  background-color: white;
135
  border-color: #E2E2E2;
136
  color: #454545;
137
  }
138
 
139
- .ui-tooltip-light .ui-tooltip-titlebar{
140
  background-color: #f1f1f1;
141
  }
142
 
143
 
144
  /*! Dark tooltip style */
145
- .ui-tooltip-dark{
146
  background-color: #505050;
147
  border-color: #303030;
148
  color: #f3f3f3;
149
  }
150
 
151
- .ui-tooltip-dark .ui-tooltip-titlebar{
152
  background-color: #404040;
153
  }
154
 
155
- .ui-tooltip-dark .ui-tooltip-icon{
156
  border-color: #444;
157
  }
158
 
159
- .ui-tooltip-dark .ui-tooltip-titlebar .ui-state-hover{
160
  border-color: #303030;
161
  }
162
 
163
 
164
  /*! Cream tooltip style */
165
- .ui-tooltip-cream{
166
  background-color: #FBF7AA;
167
  border-color: #F9E98E;
168
  color: #A27D35;
169
  }
170
 
171
- .ui-tooltip-cream .ui-tooltip-titlebar{
172
  background-color: #F0DE7D;
173
  }
174
 
175
- .ui-tooltip-cream .ui-state-default .ui-tooltip-icon{
176
  background-position: -82px 0;
177
  }
178
 
179
 
180
  /*! Red tooltip style */
181
- .ui-tooltip-red{
182
  background-color: #F78B83;
183
  border-color: #D95252;
184
  color: #912323;
185
  }
186
 
187
- .ui-tooltip-red .ui-tooltip-titlebar{
188
  background-color: #F06D65;
189
  }
190
 
191
- .ui-tooltip-red .ui-state-default .ui-tooltip-icon{
192
  background-position: -102px 0;
193
  }
194
 
195
- .ui-tooltip-red .ui-tooltip-icon{
196
  border-color: #D95252;
197
  }
198
 
199
- .ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{
200
  border-color: #D95252;
201
  }
202
 
203
 
204
  /*! Green tooltip style */
205
- .ui-tooltip-green{
206
  background-color: #CAED9E;
207
  border-color: #90D93F;
208
  color: #3F6219;
209
  }
210
 
211
- .ui-tooltip-green .ui-tooltip-titlebar{
212
  background-color: #B0DE78;
213
  }
214
 
215
- .ui-tooltip-green .ui-state-default .ui-tooltip-icon{
216
  background-position: -42px 0;
217
  }
218
 
219
 
220
  /*! Blue tooltip style */
221
- .ui-tooltip-blue{
222
  background-color: #E5F6FE;
223
  border-color: #ADD9ED;
224
  color: #5E99BD;
225
  }
226
 
227
- .ui-tooltip-blue .ui-tooltip-titlebar{
228
  background-color: #D0E9F5;
229
  }
230
 
231
- .ui-tooltip-blue .ui-state-default .ui-tooltip-icon{
232
  background-position: -2px 0;
233
  }
234
 
235
 
236
- /* Add shadows to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */
237
- .ui-tooltip-shadow{
238
  -webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
239
  -moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
240
  box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
241
  }
242
 
243
  /* Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */
244
- .ui-tooltip-rounded,
245
- .ui-tooltip-tipsy,
246
- .ui-tooltip-bootstrap{
247
  -moz-border-radius: 5px;
248
  -webkit-border-radius: 5px;
249
  border-radius: 5px;
250
  }
251
 
 
 
 
 
 
 
252
  /* Youtube tooltip style */
253
- .ui-tooltip-youtube{
254
  -moz-border-radius: 2px;
255
  -webkit-border-radius: 2px;
256
  border-radius: 2px;
257
-
258
  -webkit-box-shadow: 0 0 3px #333;
259
  -moz-box-shadow: 0 0 3px #333;
260
  box-shadow: 0 0 3px #333;
261
 
262
  color: white;
263
- border-width: 0;
264
 
265
  background: #4A4A4A;
266
  background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,black));
@@ -270,30 +270,30 @@
270
  background-image: -o-linear-gradient(top,#4A4A4A 0,black 100%);
271
  }
272
 
273
- .ui-tooltip-youtube .ui-tooltip-titlebar{
274
  background-color: #4A4A4A;
275
  background-color: rgba(0,0,0,0);
276
  }
277
-
278
- .ui-tooltip-youtube .ui-tooltip-content{
279
  padding: .75em;
280
  font: 12px arial,sans-serif;
281
-
282
  filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);
283
  -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);";
284
  }
285
 
286
- .ui-tooltip-youtube .ui-tooltip-icon{
287
  border-color: #222;
288
  }
289
 
290
- .ui-tooltip-youtube .ui-tooltip-titlebar .ui-state-hover{
291
  border-color: #303030;
292
  }
293
 
294
 
295
  /* jQuery TOOLS Tooltip style */
296
- .ui-tooltip-jtools{
297
  background: #232323;
298
  background: rgba(0, 0, 0, 0.7);
299
  background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323));
@@ -315,34 +315,34 @@
315
  }
316
 
317
  /* IE Specific */
318
- .ui-tooltip-jtools .ui-tooltip-titlebar{
319
  background-color: transparent;
320
  filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);
321
  -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)";
322
  }
323
- .ui-tooltip-jtools .ui-tooltip-content{
324
  filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);
325
  -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)";
326
  }
327
 
328
- .ui-tooltip-jtools .ui-tooltip-titlebar,
329
- .ui-tooltip-jtools .ui-tooltip-content{
330
  background: transparent;
331
  color: white;
332
  border: 0 dashed transparent;
333
  }
334
 
335
- .ui-tooltip-jtools .ui-tooltip-icon{
336
  border-color: #555;
337
  }
338
 
339
- .ui-tooltip-jtools .ui-tooltip-titlebar .ui-state-hover{
340
  border-color: #333;
341
  }
342
 
343
 
344
  /* Cluetip style */
345
- .ui-tooltip-cluetip{
346
  -webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
347
  -moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
348
  box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
@@ -352,24 +352,24 @@
352
  border: 0 dashed transparent;
353
  }
354
 
355
- .ui-tooltip-cluetip .ui-tooltip-titlebar{
356
  background-color: #87876A;
357
  color: white;
358
  border: 0 dashed transparent;
359
  }
360
-
361
- .ui-tooltip-cluetip .ui-tooltip-icon{
362
  border-color: #808064;
363
  }
364
-
365
- .ui-tooltip-cluetip .ui-tooltip-titlebar .ui-state-hover{
366
  border-color: #696952;
367
  color: #696952;
368
  }
369
 
370
 
371
  /* Tipsy style */
372
- .ui-tooltip-tipsy{
373
  background: black;
374
  background: rgba(0, 0, 0, .87);
375
 
@@ -383,27 +383,27 @@
383
  text-shadow: 0 1px black;
384
  }
385
 
386
- .ui-tooltip-tipsy .ui-tooltip-titlebar{
387
- padding: 6px 35px 0 10;
388
  background-color: transparent;
389
  }
390
 
391
- .ui-tooltip-tipsy .ui-tooltip-content{
392
- padding: 6px 10;
393
  }
394
-
395
- .ui-tooltip-tipsy .ui-tooltip-icon{
396
  border-color: #222;
397
  text-shadow: none;
398
  }
399
 
400
- .ui-tooltip-tipsy .ui-tooltip-titlebar .ui-state-hover{
401
  border-color: #303030;
402
  }
403
 
404
 
405
  /* Tipped style */
406
- .ui-tooltip-tipped{
407
  border: 3px solid #959FA9;
408
 
409
  -moz-border-radius: 3px;
@@ -417,7 +417,7 @@
417
  font-family: serif;
418
  }
419
 
420
- .ui-tooltip-tipped .ui-tooltip-titlebar{
421
  border-bottom-width: 0;
422
 
423
  color: white;
@@ -431,12 +431,12 @@
431
  -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)";
432
  }
433
 
434
- .ui-tooltip-tipped .ui-tooltip-icon{
435
  border: 2px solid #285589;
436
  background: #285589;
437
  }
438
 
439
- .ui-tooltip-tipped .ui-tooltip-icon .ui-icon{
440
  background-color: #FBFBFB;
441
  color: #555;
442
  }
@@ -448,53 +448,87 @@
448
  * Tested with IE 8, IE 9, Chrome 18, Firefox 9, Opera 11.
449
  * Does not work with IE 7.
450
  */
451
- .ui-tooltip-bootstrap{
452
- font-size: 13px;
453
- line-height: 18px;
454
-
455
  color: #333333;
456
- background-color: #ffffff;
457
-
458
 
 
 
 
459
  border: 1px solid #ccc;
460
  border: 1px solid rgba(0, 0, 0, 0.2);
461
-
462
- *border-right-width: 2px;
463
- *border-bottom-width: 2px;
464
-
465
- -webkit-border-radius: 5px;
466
- -moz-border-radius: 5px;
467
- border-radius: 5px;
468
-
469
  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
470
  -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
471
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
472
-
473
  -webkit-background-clip: padding-box;
474
  -moz-background-clip: padding;
475
  background-clip: padding-box;
476
  }
477
 
478
- .ui-tooltip-bootstrap .ui-tooltip-titlebar{
479
- font-size: 18px;
480
- line-height: 22px;
481
-
482
- border-bottom: 1px solid #ccc;
483
- background-color: transparent;
484
- }
485
-
486
- .ui-tooltip-bootstrap .ui-tooltip-titlebar .ui-state-default{
487
- right: 9px; top: 49%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  border-style: none;
489
  }
490
 
491
- .ui-tooltip-bootstrap .ui-tooltip-icon{
492
- background: white;
 
 
 
 
 
 
 
 
 
 
 
 
 
493
  }
494
 
495
- .ui-tooltip-bootstrap .ui-tooltip-icon .ui-icon{
 
 
 
 
 
 
 
496
  width: auto;
497
  height: auto;
 
 
498
  float: right;
499
  font-size: 20px;
500
  font-weight: bold;
@@ -505,7 +539,8 @@
505
  filter: alpha(opacity=20);
506
  }
507
 
508
- .ui-tooltip-bootstrap .ui-tooltip-icon .ui-icon:hover{
 
509
  color: #000000;
510
  text-decoration: none;
511
  cursor: pointer;
@@ -515,44 +550,49 @@
515
 
516
 
517
  /* IE9 fix - removes all filters */
518
- .ui-tooltip:not(.ie9haxors) div.ui-tooltip-content,
519
- .ui-tooltip:not(.ie9haxors) div.ui-tooltip-titlebar{
520
  filter: none;
521
  -ms-filter: none;
522
  }
523
 
524
 
525
- /* Tips plugin */
526
- .ui-tooltip .ui-tooltip-tip{
527
  margin: 0 auto;
528
  overflow: hidden;
529
  z-index: 10;
 
530
  }
531
 
532
- .ui-tooltip .ui-tooltip-tip,
533
- .ui-tooltip .ui-tooltip-tip .qtip-vml{
 
 
 
 
 
 
 
534
  position: absolute;
535
-
536
- line-height: 0.1px !important;
537
- font-size: 0.1px !important;
538
- color: #123456;
539
 
 
540
  background: transparent;
541
  border: 0 dashed transparent;
542
  }
543
-
544
- .ui-tooltip .ui-tooltip-tip canvas{ top: 0; left: 0; }
545
 
546
- .ui-tooltip .ui-tooltip-tip .qtip-vml{
 
 
547
  behavior: url(#default#VML);
548
  display: inline-block;
549
  visibility: visible;
550
  }
551
- /* Modal plugin */
 
552
  #qtip-overlay{
553
  position: fixed;
554
- left: -10000em;
555
- top: -10000em;
556
  }
557
 
558
  /* Applied to modals with show.modal.blur set to true */
@@ -571,3 +611,7 @@
571
  -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
572
  }
573
 
 
 
 
 
1
+ /*
2
+ * qTip2 - Pretty powerful tooltips - v3.0.3
3
+ * http://qtip2.com
4
+ *
5
+ * Copyright (c) 2016
6
+ * Released under the MIT licenses
7
+ * http://jquery.org/license
8
+ *
9
+ * Date: Wed May 11 2016 10:31 GMT+0100+0100
10
+ * Plugins: tips modal viewport svg imagemap ie6
11
+ * Styles: core basic css3
12
+ */
13
+ .qtip{
 
 
 
 
 
 
 
 
 
 
14
  position: absolute;
15
  left: -28000px;
16
  top: -28000px;
18
 
19
  max-width: 280px;
20
  min-width: 50px;
21
+
22
  font-size: 10.5px;
23
  line-height: 12px;
24
+
25
+ direction: ltr;
26
+
27
+ box-shadow: none;
28
+ padding: 0;
29
  }
30
 
31
+ .qtip-content{
32
  position: relative;
33
  padding: 5px 9px;
34
  overflow: hidden;
37
  word-wrap: break-word;
38
  }
39
 
40
+ .qtip-titlebar{
41
  position: relative;
 
42
  padding: 5px 35px 5px 10px;
43
  overflow: hidden;
44
 
46
  font-weight: bold;
47
  }
48
 
49
+ .qtip-titlebar + .qtip-content{ border-top-width: 0 !important; }
50
 
51
+ /* Default close button class */
52
+ .qtip-close{
53
+ position: absolute;
54
+ right: -9px; top: -9px;
55
+ z-index: 11; /* Overlap .qtip-tip */
 
56
 
57
+ cursor: pointer;
58
+ outline: medium none;
59
+
60
+ border: 1px solid transparent;
61
+ }
62
 
63
+ .qtip-titlebar .qtip-close{
64
+ right: 4px; top: 50%;
65
+ margin-top: -9px;
66
  }
 
 
67
 
68
+ * html .qtip-titlebar .qtip-close{ top: 16px; } /* IE fix */
69
+
70
+ .qtip-titlebar .ui-icon,
71
+ .qtip-icon .ui-icon{
72
  display: block;
73
  text-indent: -1000em;
74
  direction: ltr;
75
  }
76
 
77
+ .qtip-icon, .qtip-icon .ui-icon{
78
  -moz-border-radius: 3px;
79
  -webkit-border-radius: 3px;
80
  border-radius: 3px;
81
  text-decoration: none;
82
  }
83
 
84
+ .qtip-icon .ui-icon{
85
  width: 18px;
86
  height: 14px;
87
 
88
+ line-height: 14px;
89
  text-align: center;
90
  text-indent: 0;
91
  font: normal bold 10px/13px Tahoma,sans-serif;
94
  background: transparent none no-repeat -100em -100em;
95
  }
96
 
 
97
  /* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */
98
+ .qtip-focus{}
99
 
100
  /* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */
101
+ .qtip-hover{}
102
 
103
  /* Default tooltip style */
104
+ .qtip-default{
105
+ border: 1px solid #F1D031;
 
 
106
 
107
  background-color: #FFFFA3;
108
  color: #555;
109
  }
110
 
111
+ .qtip-default .qtip-titlebar{
112
  background-color: #FFEF93;
113
  }
114
 
115
+ .qtip-default .qtip-icon{
116
  border-color: #CCC;
117
  background: #F1F1F1;
118
  color: #777;
119
  }
120
+
121
+ .qtip-default .qtip-titlebar .qtip-close{
122
  border-color: #AAA;
123
  color: #111;
124
  }
125
 
126
 
127
  /*! Light tooltip style */
128
+ .qtip-light{
129
  background-color: white;
130
  border-color: #E2E2E2;
131
  color: #454545;
132
  }
133
 
134
+ .qtip-light .qtip-titlebar{
135
  background-color: #f1f1f1;
136
  }
137
 
138
 
139
  /*! Dark tooltip style */
140
+ .qtip-dark{
141
  background-color: #505050;
142
  border-color: #303030;
143
  color: #f3f3f3;
144
  }
145
 
146
+ .qtip-dark .qtip-titlebar{
147
  background-color: #404040;
148
  }
149
 
150
+ .qtip-dark .qtip-icon{
151
  border-color: #444;
152
  }
153
 
154
+ .qtip-dark .qtip-titlebar .ui-state-hover{
155
  border-color: #303030;
156
  }
157
 
158
 
159
  /*! Cream tooltip style */
160
+ .qtip-cream{
161
  background-color: #FBF7AA;
162
  border-color: #F9E98E;
163
  color: #A27D35;
164
  }
165
 
166
+ .qtip-cream .qtip-titlebar{
167
  background-color: #F0DE7D;
168
  }
169
 
170
+ .qtip-cream .qtip-close .qtip-icon{
171
  background-position: -82px 0;
172
  }
173
 
174
 
175
  /*! Red tooltip style */
176
+ .qtip-red{
177
  background-color: #F78B83;
178
  border-color: #D95252;
179
  color: #912323;
180
  }
181
 
182
+ .qtip-red .qtip-titlebar{
183
  background-color: #F06D65;
184
  }
185
 
186
+ .qtip-red .qtip-close .qtip-icon{
187
  background-position: -102px 0;
188
  }
189
 
190
+ .qtip-red .qtip-icon{
191
  border-color: #D95252;
192
  }
193
 
194
+ .qtip-red .qtip-titlebar .ui-state-hover{
195
  border-color: #D95252;
196
  }
197
 
198
 
199
  /*! Green tooltip style */
200
+ .qtip-green{
201
  background-color: #CAED9E;
202
  border-color: #90D93F;
203
  color: #3F6219;
204
  }
205
 
206
+ .qtip-green .qtip-titlebar{
207
  background-color: #B0DE78;
208
  }
209
 
210
+ .qtip-green .qtip-close .qtip-icon{
211
  background-position: -42px 0;
212
  }
213
 
214
 
215
  /*! Blue tooltip style */
216
+ .qtip-blue{
217
  background-color: #E5F6FE;
218
  border-color: #ADD9ED;
219
  color: #5E99BD;
220
  }
221
 
222
+ .qtip-blue .qtip-titlebar{
223
  background-color: #D0E9F5;
224
  }
225
 
226
+ .qtip-blue .qtip-close .qtip-icon{
227
  background-position: -2px 0;
228
  }
229
 
230
 
231
+ .qtip-shadow{
 
232
  -webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
233
  -moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
234
  box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
235
  }
236
 
237
  /* Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */
238
+ .qtip-rounded,
239
+ .qtip-tipsy,
240
+ .qtip-bootstrap{
241
  -moz-border-radius: 5px;
242
  -webkit-border-radius: 5px;
243
  border-radius: 5px;
244
  }
245
 
246
+ .qtip-rounded .qtip-titlebar{
247
+ -moz-border-radius: 4px 4px 0 0;
248
+ -webkit-border-radius: 4px 4px 0 0;
249
+ border-radius: 4px 4px 0 0;
250
+ }
251
+
252
  /* Youtube tooltip style */
253
+ .qtip-youtube{
254
  -moz-border-radius: 2px;
255
  -webkit-border-radius: 2px;
256
  border-radius: 2px;
257
+
258
  -webkit-box-shadow: 0 0 3px #333;
259
  -moz-box-shadow: 0 0 3px #333;
260
  box-shadow: 0 0 3px #333;
261
 
262
  color: white;
263
+ border: 0 solid transparent;
264
 
265
  background: #4A4A4A;
266
  background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,black));
270
  background-image: -o-linear-gradient(top,#4A4A4A 0,black 100%);
271
  }
272
 
273
+ .qtip-youtube .qtip-titlebar{
274
  background-color: #4A4A4A;
275
  background-color: rgba(0,0,0,0);
276
  }
277
+
278
+ .qtip-youtube .qtip-content{
279
  padding: .75em;
280
  font: 12px arial,sans-serif;
281
+
282
  filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);
283
  -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);";
284
  }
285
 
286
+ .qtip-youtube .qtip-icon{
287
  border-color: #222;
288
  }
289
 
290
+ .qtip-youtube .qtip-titlebar .ui-state-hover{
291
  border-color: #303030;
292
  }
293
 
294
 
295
  /* jQuery TOOLS Tooltip style */
296
+ .qtip-jtools{
297
  background: #232323;
298
  background: rgba(0, 0, 0, 0.7);
299
  background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323));
315
  }
316
 
317
  /* IE Specific */
318
+ .qtip-jtools .qtip-titlebar{
319
  background-color: transparent;
320
  filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);
321
  -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)";
322
  }
323
+ .qtip-jtools .qtip-content{
324
  filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);
325
  -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)";
326
  }
327
 
328
+ .qtip-jtools .qtip-titlebar,
329
+ .qtip-jtools .qtip-content{
330
  background: transparent;
331
  color: white;
332
  border: 0 dashed transparent;
333
  }
334
 
335
+ .qtip-jtools .qtip-icon{
336
  border-color: #555;
337
  }
338
 
339
+ .qtip-jtools .qtip-titlebar .ui-state-hover{
340
  border-color: #333;
341
  }
342
 
343
 
344
  /* Cluetip style */
345
+ .qtip-cluetip{
346
  -webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
347
  -moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
348
  box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
352
  border: 0 dashed transparent;
353
  }
354
 
355
+ .qtip-cluetip .qtip-titlebar{
356
  background-color: #87876A;
357
  color: white;
358
  border: 0 dashed transparent;
359
  }
360
+
361
+ .qtip-cluetip .qtip-icon{
362
  border-color: #808064;
363
  }
364
+
365
+ .qtip-cluetip .qtip-titlebar .ui-state-hover{
366
  border-color: #696952;
367
  color: #696952;
368
  }
369
 
370
 
371
  /* Tipsy style */
372
+ .qtip-tipsy{
373
  background: black;
374
  background: rgba(0, 0, 0, .87);
375
 
383
  text-shadow: 0 1px black;
384
  }
385
 
386
+ .qtip-tipsy .qtip-titlebar{
387
+ padding: 6px 35px 0 10px;
388
  background-color: transparent;
389
  }
390
 
391
+ .qtip-tipsy .qtip-content{
392
+ padding: 6px 10px;
393
  }
394
+
395
+ .qtip-tipsy .qtip-icon{
396
  border-color: #222;
397
  text-shadow: none;
398
  }
399
 
400
+ .qtip-tipsy .qtip-titlebar .ui-state-hover{
401
  border-color: #303030;
402
  }
403
 
404
 
405
  /* Tipped style */
406
+ .qtip-tipped{
407
  border: 3px solid #959FA9;
408
 
409
  -moz-border-radius: 3px;
417
  font-family: serif;
418
  }
419
 
420
+ .qtip-tipped .qtip-titlebar{
421
  border-bottom-width: 0;
422
 
423
  color: white;
431
  -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)";
432
  }
433
 
434
+ .qtip-tipped .qtip-icon{
435
  border: 2px solid #285589;
436
  background: #285589;
437
  }
438
 
439
+ .qtip-tipped .qtip-icon .ui-icon{
440
  background-color: #FBFBFB;
441
  color: #555;
442
  }
448
  * Tested with IE 8, IE 9, Chrome 18, Firefox 9, Opera 11.
449
  * Does not work with IE 7.
450
  */
451
+ .qtip-bootstrap{
452
+ /** Taken from Bootstrap body */
453
+ font-size: 14px;
454
+ line-height: 20px;
455
  color: #333333;
 
 
456
 
457
+ /** Taken from Bootstrap .popover */
458
+ padding: 1px;
459
+ background-color: #ffffff;
460
  border: 1px solid #ccc;
461
  border: 1px solid rgba(0, 0, 0, 0.2);
462
+ -webkit-border-radius: 6px;
463
+ -moz-border-radius: 6px;
464
+ border-radius: 6px;
 
 
 
 
 
465
  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
466
  -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
467
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
 
468
  -webkit-background-clip: padding-box;
469
  -moz-background-clip: padding;
470
  background-clip: padding-box;
471
  }
472
 
473
+ .qtip-bootstrap .qtip-titlebar{
474
+ /** Taken from Bootstrap .popover-title */
475
+ padding: 8px 14px;
476
+ margin: 0;
477
+ font-size: 14px;
478
+ font-weight: normal;
479
+ line-height: 18px;
480
+ background-color: #f7f7f7;
481
+ border-bottom: 1px solid #ebebeb;
482
+ -webkit-border-radius: 5px 5px 0 0;
483
+ -moz-border-radius: 5px 5px 0 0;
484
+ border-radius: 5px 5px 0 0;
485
+ }
486
+
487
+ .qtip-bootstrap .qtip-titlebar .qtip-close{
488
+ /**
489
+ * Overrides qTip2:
490
+ * .qtip-titlebar .qtip-close{
491
+ * [...]
492
+ * right: 4px;
493
+ * top: 50%;
494
+ * [...]
495
+ * border-style: solid;
496
+ * }
497
+ */
498
+ right: 11px;
499
+ top: 45%;
500
  border-style: none;
501
  }
502
 
503
+ .qtip-bootstrap .qtip-content{
504
+ /** Taken from Bootstrap .popover-content */
505
+ padding: 9px 14px;
506
+ }
507
+
508
+ .qtip-bootstrap .qtip-icon{
509
+ /**
510
+ * Overrides qTip2:
511
+ * .qtip-default .qtip-icon {
512
+ * border-color: #CCC;
513
+ * background: #F1F1F1;
514
+ * color: #777;
515
+ * }
516
+ */
517
+ background: transparent;
518
  }
519
 
520
+ .qtip-bootstrap .qtip-icon .ui-icon{
521
+ /**
522
+ * Overrides qTip2:
523
+ * .qtip-icon .ui-icon{
524
+ * width: 18px;
525
+ * height: 14px;
526
+ * }
527
+ */
528
  width: auto;
529
  height: auto;
530
+
531
+ /* Taken from Bootstrap .close */
532
  float: right;
533
  font-size: 20px;
534
  font-weight: bold;
539
  filter: alpha(opacity=20);
540
  }
541
 
542
+ .qtip-bootstrap .qtip-icon .ui-icon:hover{
543
+ /* Taken from Bootstrap .close:hover */
544
  color: #000000;
545
  text-decoration: none;
546
  cursor: pointer;
550
 
551
 
552
  /* IE9 fix - removes all filters */
553
+ .qtip:not(.ie9haxors) div.qtip-content,
554
+ .qtip:not(.ie9haxors) div.qtip-titlebar{
555
  filter: none;
556
  -ms-filter: none;
557
  }
558
 
559
 
560
+ .qtip .qtip-tip{
 
561
  margin: 0 auto;
562
  overflow: hidden;
563
  z-index: 10;
564
+
565
  }
566
 
567
+ /* Opera bug #357 - Incorrect tip position
568
+ https://github.com/Craga89/qTip2/issues/367 */
569
+ x:-o-prefocus, .qtip .qtip-tip{
570
+ visibility: hidden;
571
+ }
572
+
573
+ .qtip .qtip-tip,
574
+ .qtip .qtip-tip .qtip-vml,
575
+ .qtip .qtip-tip canvas{
576
  position: absolute;
 
 
 
 
577
 
578
+ color: #123456;
579
  background: transparent;
580
  border: 0 dashed transparent;
581
  }
 
 
582
 
583
+ .qtip .qtip-tip canvas{ top: 0; left: 0; }
584
+
585
+ .qtip .qtip-tip .qtip-vml{
586
  behavior: url(#default#VML);
587
  display: inline-block;
588
  visibility: visible;
589
  }
590
+
591
+
592
  #qtip-overlay{
593
  position: fixed;
594
+ left: 0; top: 0;
595
+ width: 100%; height: 100%;
596
  }
597
 
598
  /* Applied to modals with show.modal.blur set to true */
611
  -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
612
  }
613
 
614
+
615
+ .qtipmodal-ie6fix{
616
+ position: absolute !important;
617
+ }
css/jquery.qtip.min.css CHANGED
@@ -1 +1 @@
1
- /*! qTip2 v2.0.0 | http://craigsworks.com/projects/qtip2/ | Licensed MIT, GPL */#qtip-rcontainer{position:absolute;left:-28000px;top:-28000px;display:block;visibility:hidden}#qtip-rcontainer .ui-tooltip{display:block!important;visibility:hidden!important;position:static!important;float:left!important}.ui-tooltip,.qtip{position:absolute;left:-28000px;top:-28000px;display:none;max-width:280px;min-width:50px;font-size:10.5px;line-height:12px}.ui-tooltip-content{position:relative;padding:5px 9px;overflow:hidden;text-align:left;word-wrap:break-word}.ui-tooltip-titlebar{position:relative;min-height:14px;padding:5px 35px 5px 10px;overflow:hidden;border-width:0 0 1px;font-weight:700}.ui-tooltip-titlebar+.ui-tooltip-content{border-top-width:0!important}.ui-tooltip-titlebar .ui-state-default{position:absolute;right:4px;top:50%;margin-top:-9px;cursor:pointer;outline:medium none;border-width:1px;border-style:solid}* html .ui-tooltip-titlebar .ui-state-default{top:16px}.ui-tooltip-titlebar .ui-icon,.ui-tooltip-icon .ui-icon{display:block;text-indent:-1000em;direction:ltr}.ui-tooltip-icon,.ui-tooltip-icon .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;text-decoration:none}.ui-tooltip-icon .ui-icon{width:18px;height:14px;text-align:center;text-indent:0;font:normal bold 10px/13px Tahoma,sans-serif;color:inherit;background:transparent none no-repeat -100em -100em}.ui-tooltip-focus{}.ui-tooltip-hover{}.ui-tooltip-default{border-width:1px;border-style:solid;border-color:#F1D031;background-color:#FFFFA3;color:#555}.ui-tooltip-default .ui-tooltip-titlebar{background-color:#FFEF93}.ui-tooltip-default .ui-tooltip-icon{border-color:#CCC;background:#F1F1F1;color:#777}.ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{border-color:#AAA;color:#111}/*! Light tooltip style */.ui-tooltip-light{background-color:#fff;border-color:#E2E2E2;color:#454545}.ui-tooltip-light .ui-tooltip-titlebar{background-color:#f1f1f1}/*! Dark tooltip style */.ui-tooltip-dark{background-color:#505050;border-color:#303030;color:#f3f3f3}.ui-tooltip-dark .ui-tooltip-titlebar{background-color:#404040}.ui-tooltip-dark .ui-tooltip-icon{border-color:#444}.ui-tooltip-dark .ui-tooltip-titlebar .ui-state-hover{border-color:#303030}/*! Cream tooltip style */.ui-tooltip-cream{background-color:#FBF7AA;border-color:#F9E98E;color:#A27D35}.ui-tooltip-cream .ui-tooltip-titlebar{background-color:#F0DE7D}.ui-tooltip-cream .ui-state-default .ui-tooltip-icon{background-position:-82px 0}/*! Red tooltip style */.ui-tooltip-red{background-color:#F78B83;border-color:#D95252;color:#912323}.ui-tooltip-red .ui-tooltip-titlebar{background-color:#F06D65}.ui-tooltip-red .ui-state-default .ui-tooltip-icon{background-position:-102px 0}.ui-tooltip-red .ui-tooltip-icon{border-color:#D95252}.ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{border-color:#D95252}/*! Green tooltip style */.ui-tooltip-green{background-color:#CAED9E;border-color:#90D93F;color:#3F6219}.ui-tooltip-green .ui-tooltip-titlebar{background-color:#B0DE78}.ui-tooltip-green .ui-state-default .ui-tooltip-icon{background-position:-42px 0}/*! Blue tooltip style */.ui-tooltip-blue{background-color:#E5F6FE;border-color:#ADD9ED;color:#5E99BD}.ui-tooltip-blue .ui-tooltip-titlebar{background-color:#D0E9F5}.ui-tooltip-blue .ui-state-default .ui-tooltip-icon{background-position:-2px 0}.ui-tooltip-shadow{-webkit-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);-moz-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);box-shadow:1px 1px 3px 1px rgba(0,0,0,.15)}.ui-tooltip-rounded,.ui-tooltip-tipsy,.ui-tooltip-bootstrap{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.ui-tooltip-youtube{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 3px #333;-moz-box-shadow:0 0 3px #333;box-shadow:0 0 3px #333;color:#fff;border-width:0;background:#4A4A4A;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0, #4A4A4A),color-stop(100%,black));background-image:-webkit-linear-gradient(top, #4A4A4A 0,black 100%);background-image:-moz-linear-gradient(top, #4A4A4A 0,black 100%);background-image:-ms-linear-gradient(top, #4A4A4A 0,black 100%);background-image:-o-linear-gradient(top, #4A4A4A 0,black 100%)}.ui-tooltip-youtube .ui-tooltip-titlebar{background-color:#4A4A4A;background-color:rgba(0,0,0,0)}.ui-tooltip-youtube .ui-tooltip-content{padding:.75em;font:12px arial,sans-serif;filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#4a4a4a, EndColorStr=#000000);-ms-filter:"progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#4a4a4a, EndColorStr=#000000);"}.ui-tooltip-youtube .ui-tooltip-icon{border-color:#222}.ui-tooltip-youtube .ui-tooltip-titlebar .ui-state-hover{border-color:#303030}.ui-tooltip-jtools{background:#232323;background:rgba(0,0,0,.7);background-image:-webkit-gradient(linear,left top,left bottom,from( #717171),to( #232323));background-image:-moz-linear-gradient(top, #717171, #232323);background-image:-webkit-linear-gradient(top, #717171, #232323);background-image:-ms-linear-gradient(top, #717171, #232323);background-image:-o-linear-gradient(top, #717171, #232323);border:2px solid #ddd;border:2px solid rgba(241,241,241,1);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 12px #333;-moz-box-shadow:0 0 12px #333;box-shadow:0 0 12px #333}.ui-tooltip-jtools .ui-tooltip-titlebar{background-color:transparent;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171, endColorstr=#4A4A4A);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171, endColorstr=#4A4A4A)"}.ui-tooltip-jtools .ui-tooltip-content{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A, endColorstr=#232323);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A, endColorstr=#232323)"}.ui-tooltip-jtools .ui-tooltip-titlebar,.ui-tooltip-jtools .ui-tooltip-content{background:transparent;color:#fff;border:0 dashed transparent}.ui-tooltip-jtools .ui-tooltip-icon{border-color:#555}.ui-tooltip-jtools .ui-tooltip-titlebar .ui-state-hover{border-color:#333}.ui-tooltip-cluetip{-webkit-box-shadow:4px 4px 5px rgba(0,0,0,.4);-moz-box-shadow:4px 4px 5px rgba(0,0,0,.4);box-shadow:4px 4px 5px rgba(0,0,0,.4);background-color:#D9D9C2;color:#111;border:0 dashed transparent}.ui-tooltip-cluetip .ui-tooltip-titlebar{background-color:#87876A;color:#fff;border:0 dashed transparent}.ui-tooltip-cluetip .ui-tooltip-icon{border-color:#808064}.ui-tooltip-cluetip .ui-tooltip-titlebar .ui-state-hover{border-color:#696952;color:#696952}.ui-tooltip-tipsy{background:#000;background:rgba(0,0,0,.87);color:#fff;border:0 solid transparent;font-size:11px;font-family:'Lucida Grande',sans-serif;font-weight:700;line-height:16px;text-shadow:0 1px black}.ui-tooltip-tipsy .ui-tooltip-titlebar{padding:6px 35px 0 10;background-color:transparent}.ui-tooltip-tipsy .ui-tooltip-content{padding:6px 10}.ui-tooltip-tipsy .ui-tooltip-icon{border-color:#222;text-shadow:none}.ui-tooltip-tipsy .ui-tooltip-titlebar .ui-state-hover{border-color:#303030}.ui-tooltip-tipped{border:3px solid #959FA9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#F9F9F9;color:#454545;font-weight:400;font-family:serif}.ui-tooltip-tipped .ui-tooltip-titlebar{border-bottom-width:0;color:#fff;background:#3A79B8;background-image:-webkit-gradient(linear,left top,left bottom,from( #3A79B8),to( #2E629D));background-image:-webkit-linear-gradient(top, #3A79B8, #2E629D);background-image:-moz-linear-gradient(top, #3A79B8, #2E629D);background-image:-ms-linear-gradient(top, #3A79B8, #2E629D);background-image:-o-linear-gradient(top, #3A79B8, #2E629D);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8, endColorstr=#2E629D);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8, endColorstr=#2E629D)"}.ui-tooltip-tipped .ui-tooltip-icon{border:2px solid #285589;background:#285589}.ui-tooltip-tipped .ui-tooltip-icon .ui-icon{background-color:#FBFBFB;color:#555}.ui-tooltip-bootstrap{font-size:13px;line-height:18px;color:#333;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.ui-tooltip-bootstrap .ui-tooltip-titlebar{font-size:18px;line-height:22px;border-bottom:1px solid #ccc;background-color:transparent}.ui-tooltip-bootstrap .ui-tooltip-titlebar .ui-state-default{right:9px;top:49%;border-style:none}.ui-tooltip-bootstrap .ui-tooltip-icon{background:#fff}.ui-tooltip-bootstrap .ui-tooltip-icon .ui-icon{width:auto;height:auto;float:right;font-size:20px;font-weight:700;line-height:18px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.ui-tooltip-bootstrap .ui-tooltip-icon .ui-icon:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}.ui-tooltip:not(.ie9haxors) div.ui-tooltip-content,.ui-tooltip:not(.ie9haxors) div.ui-tooltip-titlebar{filter:none;-ms-filter:none}.ui-tooltip .ui-tooltip-tip{margin:0 auto;overflow:hidden;z-index:10}.ui-tooltip .ui-tooltip-tip,.ui-tooltip .ui-tooltip-tip .qtip-vml{position:absolute;line-height:.1px!important;font-size:.1px!important;color:#123456;background:transparent;border:0 dashed transparent}.ui-tooltip .ui-tooltip-tip canvas{top:0;left:0}.ui-tooltip .ui-tooltip-tip .qtip-vml{behavior:url(#default#VML);display:inline-block;visibility:visible}#qtip-overlay{position:fixed;left:-10000em;top:-10000em}#qtip-overlay.blurs{cursor:pointer}#qtip-overlay div{position:absolute;left:0;top:0;width:100%;height:100%;background-color:#000;opacity:.7;filter:alpha(opacity=70);-ms-filter:"alpha(Opacity=70)"}
1
+ #qtip-overlay.blurs,.qtip-close{cursor:pointer}.qtip{position:absolute;left:-28000px;top:-28000px;display:none;max-width:280px;min-width:50px;font-size:10.5px;line-height:12px;direction:ltr;box-shadow:none;padding:0}.qtip-content,.qtip-titlebar{position:relative;overflow:hidden}.qtip-content{padding:5px 9px;text-align:left;word-wrap:break-word}.qtip-titlebar{padding:5px 35px 5px 10px;border-width:0 0 1px;font-weight:700}.qtip-titlebar+.qtip-content{border-top-width:0!important}.qtip-close{position:absolute;right:-9px;top:-9px;z-index:11;outline:0;border:1px solid transparent}.qtip-titlebar .qtip-close{right:4px;top:50%;margin-top:-9px}* html .qtip-titlebar .qtip-close{top:16px}.qtip-icon .ui-icon,.qtip-titlebar .ui-icon{display:block;text-indent:-1000em;direction:ltr}.qtip-icon,.qtip-icon .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;text-decoration:none}.qtip-icon .ui-icon{width:18px;height:14px;line-height:14px;text-align:center;text-indent:0;font:normal 700 10px/13px Tahoma,sans-serif;color:inherit;background:-100em -100em no-repeat}.qtip-default{border:1px solid #F1D031;background-color:#FFFFA3;color:#555}.qtip-default .qtip-titlebar{background-color:#FFEF93}.qtip-default .qtip-icon{border-color:#CCC;background:#F1F1F1;color:#777}.qtip-default .qtip-titlebar .qtip-close{border-color:#AAA;color:#111}.qtip-light{background-color:#fff;border-color:#E2E2E2;color:#454545}.qtip-light .qtip-titlebar{background-color:#f1f1f1}.qtip-dark{background-color:#505050;border-color:#303030;color:#f3f3f3}.qtip-dark .qtip-titlebar{background-color:#404040}.qtip-dark .qtip-icon{border-color:#444}.qtip-dark .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-cream{background-color:#FBF7AA;border-color:#F9E98E;color:#A27D35}.qtip-red,.qtip-red .qtip-icon,.qtip-red .qtip-titlebar .ui-state-hover{border-color:#D95252}.qtip-cream .qtip-titlebar{background-color:#F0DE7D}.qtip-cream .qtip-close .qtip-icon{background-position:-82px 0}.qtip-red{background-color:#F78B83;color:#912323}.qtip-red .qtip-titlebar{background-color:#F06D65}.qtip-red .qtip-close .qtip-icon{background-position:-102px 0}.qtip-green{background-color:#CAED9E;border-color:#90D93F;color:#3F6219}.qtip-green .qtip-titlebar{background-color:#B0DE78}.qtip-green .qtip-close .qtip-icon{background-position:-42px 0}.qtip-blue{background-color:#E5F6FE;border-color:#ADD9ED;color:#5E99BD}.qtip-blue .qtip-titlebar{background-color:#D0E9F5}.qtip-blue .qtip-close .qtip-icon{background-position:-2px 0}.qtip-shadow{-webkit-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);-moz-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);box-shadow:1px 1px 3px 1px rgba(0,0,0,.15)}.qtip-bootstrap,.qtip-rounded,.qtip-tipsy{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.qtip-rounded .qtip-titlebar{-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.qtip-youtube{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 3px #333;-moz-box-shadow:0 0 3px #333;box-shadow:0 0 3px #333;color:#fff;border:0 solid transparent;background:#4A4A4A;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,#000));background-image:-webkit-linear-gradient(top,#4A4A4A 0,#000 100%);background-image:-moz-linear-gradient(top,#4A4A4A 0,#000 100%);background-image:-ms-linear-gradient(top,#4A4A4A 0,#000 100%);background-image:-o-linear-gradient(top,#4A4A4A 0,#000 100%)}.qtip-youtube .qtip-titlebar{background-color:#4A4A4A;background-color:rgba(0,0,0,0)}.qtip-youtube .qtip-content{padding:.75em;font:12px arial,sans-serif;filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#4a4a4a, EndColorStr=#000000);-ms-filter:"progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);"}.qtip-youtube .qtip-icon{border-color:#222}.qtip-youtube .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-jtools{background:#232323;background:rgba(0,0,0,.7);background-image:-webkit-gradient(linear,left top,left bottom,from(#717171),to(#232323));background-image:-moz-linear-gradient(top,#717171,#232323);background-image:-webkit-linear-gradient(top,#717171,#232323);background-image:-ms-linear-gradient(top,#717171,#232323);background-image:-o-linear-gradient(top,#717171,#232323);border:2px solid #ddd;border:2px solid rgba(241,241,241,1);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 12px #333;-moz-box-shadow:0 0 12px #333;box-shadow:0 0 12px #333}.qtip-jtools .qtip-titlebar{background-color:transparent;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171, endColorstr=#4A4A4A);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)"}.qtip-jtools .qtip-content{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A, endColorstr=#232323);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)"}.qtip-jtools .qtip-content,.qtip-jtools .qtip-titlebar{background:0 0;color:#fff;border:0 dashed transparent}.qtip-jtools .qtip-icon{border-color:#555}.qtip-jtools .qtip-titlebar .ui-state-hover{border-color:#333}.qtip-cluetip{-webkit-box-shadow:4px 4px 5px rgba(0,0,0,.4);-moz-box-shadow:4px 4px 5px rgba(0,0,0,.4);box-shadow:4px 4px 5px rgba(0,0,0,.4);background-color:#D9D9C2;color:#111;border:0 dashed transparent}.qtip-cluetip .qtip-titlebar{background-color:#87876A;color:#fff;border:0 dashed transparent}.qtip-cluetip .qtip-icon{border-color:#808064}.qtip-cluetip .qtip-titlebar .ui-state-hover{border-color:#696952;color:#696952}.qtip-tipsy{background:#000;background:rgba(0,0,0,.87);color:#fff;border:0 solid transparent;font-size:11px;font-family:'Lucida Grande',sans-serif;font-weight:700;line-height:16px;text-shadow:0 1px #000}.qtip-tipsy .qtip-titlebar{padding:6px 35px 0 10px;background-color:transparent}.qtip-tipsy .qtip-content{padding:6px 10px}.qtip-tipsy .qtip-icon{border-color:#222;text-shadow:none}.qtip-tipsy .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-tipped{border:3px solid #959FA9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#F9F9F9;color:#454545;font-weight:400;font-family:serif}.qtip-tipped .qtip-titlebar{border-bottom-width:0;color:#fff;background:#3A79B8;background-image:-webkit-gradient(linear,left top,left bottom,from(#3A79B8),to(#2E629D));background-image:-webkit-linear-gradient(top,#3A79B8,#2E629D);background-image:-moz-linear-gradient(top,#3A79B8,#2E629D);background-image:-ms-linear-gradient(top,#3A79B8,#2E629D);background-image:-o-linear-gradient(top,#3A79B8,#2E629D);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8, endColorstr=#2E629D);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)"}.qtip-tipped .qtip-icon{border:2px solid #285589;background:#285589}.qtip-tipped .qtip-icon .ui-icon{background-color:#FBFBFB;color:#555}.qtip-bootstrap{font-size:14px;line-height:20px;color:#333;padding:1px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.qtip-bootstrap .qtip-titlebar{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.qtip-bootstrap .qtip-titlebar .qtip-close{right:11px;top:45%;border-style:none}.qtip-bootstrap .qtip-content{padding:9px 14px}.qtip-bootstrap .qtip-icon{background:0 0}.qtip-bootstrap .qtip-icon .ui-icon{width:auto;height:auto;float:right;font-size:20px;font-weight:700;line-height:18px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}#qtip-overlay,#qtip-overlay div{left:0;top:0;width:100%;height:100%}.qtip-bootstrap .qtip-icon .ui-icon:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}.qtip:not(.ie9haxors) div.qtip-content,.qtip:not(.ie9haxors) div.qtip-titlebar{filter:none;-ms-filter:none}.qtip .qtip-tip{margin:0 auto;overflow:hidden;z-index:10}.qtip .qtip-tip,x:-o-prefocus{visibility:hidden}.qtip .qtip-tip,.qtip .qtip-tip .qtip-vml,.qtip .qtip-tip canvas{position:absolute;color:#123456;background:0 0;border:0 dashed transparent}.qtip .qtip-tip canvas{top:0;left:0}.qtip .qtip-tip .qtip-vml{behavior:url(#default#VML);display:inline-block;visibility:visible}#qtip-overlay{position:fixed}#qtip-overlay div{position:absolute;background-color:#000;opacity:.7;filter:alpha(opacity=70);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"}.qtipmodal-ie6fix{position:absolute!important}
css/menu-editor.css CHANGED
@@ -854,6 +854,8 @@ a#ws-ame-delete-color-preset:hover {
854
  position: fixed;
855
  left: 0;
856
  top: 0;
 
 
857
  opacity: 0.70;
858
  -moz-opacity: 0.70;
859
  filter: alpha(opacity=70);
854
  position: fixed;
855
  left: 0;
856
  top: 0;
857
+ right: 0;
858
+ bottom: 0;
859
  opacity: 0.70;
860
  -moz-opacity: 0.70;
861
  filter: alpha(opacity=70);
css/menu-editor.scss CHANGED
@@ -1160,6 +1160,8 @@ $colorFieldRightMargin: 5px;
1160
  position: fixed;
1161
  left: 0;
1162
  top: 0;
 
 
1163
  opacity: 0.70;
1164
  -moz-opacity: 0.70;
1165
  filter: alpha(opacity=70);
1160
  position: fixed;
1161
  left: 0;
1162
  top: 0;
1163
+ right: 0;
1164
+ bottom: 0;
1165
  opacity: 0.70;
1166
  -moz-opacity: 0.70;
1167
  filter: alpha(opacity=70);
includes/basic-dependencies.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !defined('AME_ROOT_DIR') ) {
3
+ define('AME_ROOT_DIR', dirname(dirname(__FILE__)));
4
+ }
5
+
6
+ $thisDirectory = dirname(__FILE__);
7
+ require_once $thisDirectory . '/shadow_plugin_framework.php';
8
+ require_once $thisDirectory . '/role-utils.php';
9
+ require_once $thisDirectory . '/ame-utils.php';
10
+ require_once $thisDirectory . '/menu-item.php';
11
+ require_once $thisDirectory . '/menu.php';
12
+ require_once $thisDirectory . '/auto-versioning.php';
13
+ require_once $thisDirectory . '/../ajax-wrapper/AjaxWrapper.php';
14
+ require_once $thisDirectory . '/module.php';
15
+ require_once $thisDirectory . '/persistent-module.php';
16
+
17
+ if ( !class_exists('WPMenuEditor', false) ) {
18
+ require_once $thisDirectory . '/menu-editor-core.php';
19
+ }
includes/menu-editor-core.php CHANGED
@@ -1,24 +1,5 @@
1
  <?php
2
 
3
- //Can't have two different versions of the plugin active at the same time. It would be incredibly buggy.
4
- if (class_exists('WPMenuEditor')){
5
- trigger_error(
6
- 'Another version of Admin Menu Editor is already active. Please deactivate it before activating this one.',
7
- E_USER_ERROR
8
- );
9
- }
10
-
11
- $thisDirectory = dirname(__FILE__);
12
- require $thisDirectory . '/shadow_plugin_framework.php';
13
- require $thisDirectory . '/role-utils.php';
14
- require $thisDirectory . '/ame-utils.php';
15
- require $thisDirectory . '/menu-item.php';
16
- require $thisDirectory . '/menu.php';
17
- require $thisDirectory . '/auto-versioning.php';
18
- require $thisDirectory . '/../ajax-wrapper/AjaxWrapper.php';
19
- require $thisDirectory . '/module.php';
20
- require $thisDirectory . '/persistent-module.php';
21
-
22
  class WPMenuEditor extends MenuEd_ShadowPluginFramework {
23
  const WPML_CONTEXT = 'admin-menu-editor menu texts';
24
 
@@ -115,6 +96,11 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
115
  */
116
  private $current_tab = '';
117
 
 
 
 
 
 
118
  /**
119
  * @var array List of capabilities that are used in the default admin menu. Used to detect meta capabilities.
120
  */
@@ -198,7 +184,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
198
  self::$admin_heading_tag = version_compare($GLOBALS['wp_version'], '4.3', '<') ? 'h2' : 'h1';
199
 
200
  $this->settings_link = (is_network_admin() ? 'settings.php' : 'options-general.php') . '?page=menu_editor';
201
-
202
  $this->magic_hooks = true;
203
  //Run our hooks last (almost). Priority is less than PHP_INT_MAX mostly for defensive programming purposes.
204
  //Old PHP versions have known bugs related to large array keys, and WP might have undiscovered edge cases.
@@ -255,7 +241,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
255
  'admin.php?page=WPCW_showPage_UserProgess' => true,
256
  'admin.php?page=WPCW_showPage_UserProgess_quizAnswers' => true,
257
  );
258
-
259
  //AJAXify screen options
260
  add_action('wp_ajax_ws_ame_save_screen_options', array($this,'ajax_save_screen_options'));
261
 
@@ -320,7 +306,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
320
  add_action('admin_menu_editor-display_footer', array($this, 'display_settings_page_footer'));
321
 
322
  }
323
-
324
  function init_finish() {
325
  parent::init_finish();
326
  $should_save_options = false;
@@ -375,7 +361,8 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
375
  /** @noinspection PhpIncludeInspection */
376
  include ($module['path']);
377
  if ( !empty($module['className']) ) {
378
- new $module['className']($this);
 
379
  }
380
  }
381
 
@@ -390,9 +377,16 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
390
  $this->tabs['settings'] = 'Settings';
391
  }
392
 
 
 
 
 
 
 
 
393
  /**
394
  * Import settings from a different version of the plugin.
395
- *
396
  * @return bool True if settings were imported successfully, False otherwise
397
  */
398
  function import_settings(){
@@ -431,9 +425,9 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
431
  if ( $reset_requested && $this->current_user_can_edit_menu() ){
432
  $this->set_custom_menu(null);
433
  }
434
-
435
  //The menu editor is only visible to users with the manage_options privilege.
436
- //Or, if the plugin is installed in mu-plugins, only to the site administrator(s).
437
  if ( $this->current_user_can_edit_menu() ){
438
  $this->log_security_note('Current user can edit the admin menu.');
439
 
@@ -450,9 +444,9 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
450
  $page = add_submenu_page(
451
  $parent_slug,
452
  apply_filters('admin_menu_editor-self_page_title', 'Menu Editor') . $tab_title,
453
- apply_filters('admin_menu_editor-self_menu_title', 'Menu Editor'),
454
  apply_filters('admin_menu_editor-capability', 'manage_options'),
455
- 'menu_editor',
456
  array($this, 'page_menu_editor')
457
  );
458
  //Output our JS & CSS on that page only
@@ -1216,6 +1210,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1216
  *
1217
  * @param array|null $custom_menu
1218
  * @param string|null $config_id Supported values: 'network-admin', 'global' or 'site'
 
1219
  */
1220
  function set_custom_menu($custom_menu, $config_id = null) {
1221
  if ( $config_id === null ) {
@@ -1343,7 +1338,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1343
 
1344
  /**
1345
  * Determine if the current user may use the menu editor.
1346
- *
1347
  * @return bool
1348
  */
1349
  public function current_user_can_edit_menu(){
@@ -1393,15 +1388,15 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1393
  $this->save_options();
1394
  }
1395
  }
1396
-
1397
  /**
1398
  * Apply the custom page title, if any.
1399
  *
1400
  * This is a callback for the "admin_title" filter. It will change the browser window/tab
1401
  * title (i.e. <title>), but not the title displayed on the admin page itself.
1402
- *
1403
  * @param string $admin_title The current admin title (full).
1404
- * @param string $title The current page title.
1405
  * @return string New admin title.
1406
  */
1407
  function hook_admin_title($admin_title, $title){
@@ -1745,7 +1740,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1745
 
1746
  /**
1747
  * Generate WP-compatible $menu and $submenu arrays from a custom menu tree.
1748
- *
1749
  * Side-effects: This function executes several filters that may modify global state.
1750
  * Specifically, IFrame-handling callbacks in 'extras.php' will add add new hooks
1751
  * and other menu-related structures.
@@ -1764,7 +1759,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1764
  $new_menu = array();
1765
  $new_submenu = array();
1766
  $this->title_lookups = array();
1767
-
1768
  //Prepare the top menu
1769
  $first_nonseparator_found = false;
1770
  foreach ($tree as $topmenu){
@@ -1782,7 +1777,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1782
  if ( empty($topmenu['separator']) ) {
1783
  $this->title_lookups[$topmenu['file']] = !empty($topmenu['page_title']) ? $topmenu['page_title'] : $topmenu['menu_title'];
1784
  }
1785
-
1786
  //Prepare the submenu of this menu
1787
  $new_items = array();
1788
  if( !empty($topmenu['items']) ){
@@ -2199,7 +2194,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
2199
  $item['access_level'] = $capability;
2200
  return $item;
2201
  }
2202
-
2203
  /**
2204
  * Output the menu editor page
2205
  *
@@ -2865,15 +2860,15 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
2865
  /**
2866
  * Create a virtual 'super_admin' capability that only super admins have.
2867
  * This function accomplishes that by by filtering 'user_has_cap' calls.
2868
- *
2869
  * @param array $allcaps All capabilities belonging to the current user, cap => true/false.
2870
  * @param array $required_caps The required capabilities.
2871
  * @param array $args The capability passed to current_user_can, the current user's ID, and other args.
2872
  * @return array Filtered version of $allcaps
2873
  */
2874
  function hook_user_has_cap($allcaps, /** @noinspection PhpUnusedParameterInspection */ $required_caps, $args){
2875
- //Be careful not to overwrite a super_admin cap added by other plugins
2876
- //For example, Advanced Access Manager also adds this capability.
2877
  if ( is_array($allcaps) && !isset($allcaps['super_admin']) ){
2878
  $user_id = intval($args[1]);
2879
  if ( $user_id != 0 ) {
@@ -2885,19 +2880,19 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
2885
 
2886
  /**
2887
  * AJAX callback for saving screen options (whether to show or to hide advanced menu options).
2888
- *
2889
- * Handles the 'ws_ame_save_screen_options' action. The new option value
2890
  * is read from $_POST['hide_advanced_settings'].
2891
- *
2892
  * @return void
2893
  */
2894
  function ajax_save_screen_options(){
2895
  if (!$this->current_user_can_edit_menu() || !check_ajax_referer('ws_ame_save_screen_options', false, false)){
2896
  die( $this->json_encode( array(
2897
- 'error' => "You're not allowed to do that!"
2898
  )));
2899
  }
2900
-
2901
  $this->options['hide_advanced_settings'] = !empty($this->post['hide_advanced_settings']);
2902
  $this->options['show_extra_icons'] = !empty($this->post['show_extra_icons']);
2903
  $this->save_options();
@@ -3362,7 +3357,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
3362
 
3363
  //Only display the notice on the Menu Editor (Pro) page.
3364
  $display_notice = $display_notice && isset($this->get['page']) && ($this->get['page'] == 'menu_editor');
3365
-
3366
  //Let the user override this completely (useful for client sites).
3367
  if ( $display_notice && file_exists(dirname($this->plugin_file) . '/never-display-surveys.txt') ) {
3368
  $display_notice = false;
@@ -3497,6 +3492,18 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
3497
  $this->save_options();
3498
  }
3499
 
 
 
 
 
 
 
 
 
 
 
 
 
3500
  /**
3501
  * Log a security-related message.
3502
  *
@@ -4236,27 +4243,36 @@ class ameMenuTemplateBuilder {
4236
  $this->templates = array();
4237
  $this->blacklist = $blacklist;
4238
 
4239
- //At this point, the menu might not be sorted yet, especially if other plugins have made changes to it.
4240
- //We need to know the relative order of menus to insert new items in the right place.
4241
- ksort($menu, SORT_NUMERIC);
 
4242
 
4243
- foreach($menu as $pos => $item){
4244
- $this->addItem($item, $pos);
 
4245
  }
4246
 
4247
- foreach($submenu as $parent => $items){
4248
- //Skip sub-menus attached to non-existent parents. This should theoretically never happen,
4249
- //but a buggy plugin can cause such a situation.
4250
- if ( !isset($this->parentNames[$parent]) ) {
4251
- continue;
4252
- }
4253
 
4254
- ksort($items, SORT_NUMERIC);
4255
- $this->previousItemId = '';
4256
- $this->wasPreviousItemSeparated = false;
 
 
4257
 
4258
- foreach($items as $pos => $item) {
4259
- $this->addItem($item, $pos, $parent);
 
 
 
 
 
4260
  }
4261
  }
4262
 
1
  <?php
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  class WPMenuEditor extends MenuEd_ShadowPluginFramework {
4
  const WPML_CONTEXT = 'admin-menu-editor menu texts';
5
 
96
  */
97
  private $current_tab = '';
98
 
99
+ /**
100
+ * @var ameModule[] List of modules that were loaded for the current request.
101
+ */
102
+ private $loaded_modules = array();
103
+
104
  /**
105
  * @var array List of capabilities that are used in the default admin menu. Used to detect meta capabilities.
106
  */
184
  self::$admin_heading_tag = version_compare($GLOBALS['wp_version'], '4.3', '<') ? 'h2' : 'h1';
185
 
186
  $this->settings_link = (is_network_admin() ? 'settings.php' : 'options-general.php') . '?page=menu_editor';
187
+
188
  $this->magic_hooks = true;
189
  //Run our hooks last (almost). Priority is less than PHP_INT_MAX mostly for defensive programming purposes.
190
  //Old PHP versions have known bugs related to large array keys, and WP might have undiscovered edge cases.
241
  'admin.php?page=WPCW_showPage_UserProgess' => true,
242
  'admin.php?page=WPCW_showPage_UserProgess_quizAnswers' => true,
243
  );
244
+
245
  //AJAXify screen options
246
  add_action('wp_ajax_ws_ame_save_screen_options', array($this,'ajax_save_screen_options'));
247
 
306
  add_action('admin_menu_editor-display_footer', array($this, 'display_settings_page_footer'));
307
 
308
  }
309
+
310
  function init_finish() {
311
  parent::init_finish();
312
  $should_save_options = false;
361
  /** @noinspection PhpIncludeInspection */
362
  include ($module['path']);
363
  if ( !empty($module['className']) ) {
364
+ $instance = new $module['className']($this);
365
+ $this->loaded_modules[] = $instance;
366
  }
367
  }
368
 
377
  $this->tabs['settings'] = 'Settings';
378
  }
379
 
380
+ /**
381
+ * @return ameModule[]
382
+ */
383
+ public function get_loaded_modules() {
384
+ return $this->loaded_modules;
385
+ }
386
+
387
  /**
388
  * Import settings from a different version of the plugin.
389
+ *
390
  * @return bool True if settings were imported successfully, False otherwise
391
  */
392
  function import_settings(){
425
  if ( $reset_requested && $this->current_user_can_edit_menu() ){
426
  $this->set_custom_menu(null);
427
  }
428
+
429
  //The menu editor is only visible to users with the manage_options privilege.
430
+ //Or, if the plugin is installed in mu-plugins, only to the site administrator(s).
431
  if ( $this->current_user_can_edit_menu() ){
432
  $this->log_security_note('Current user can edit the admin menu.');
433
 
444
  $page = add_submenu_page(
445
  $parent_slug,
446
  apply_filters('admin_menu_editor-self_page_title', 'Menu Editor') . $tab_title,
447
+ apply_filters('admin_menu_editor-self_menu_title', 'Menu Editor'),
448
  apply_filters('admin_menu_editor-capability', 'manage_options'),
449
+ 'menu_editor',
450
  array($this, 'page_menu_editor')
451
  );
452
  //Output our JS & CSS on that page only
1210
  *
1211
  * @param array|null $custom_menu
1212
  * @param string|null $config_id Supported values: 'network-admin', 'global' or 'site'
1213
+ * @throws InvalidMenuException
1214
  */
1215
  function set_custom_menu($custom_menu, $config_id = null) {
1216
  if ( $config_id === null ) {
1338
 
1339
  /**
1340
  * Determine if the current user may use the menu editor.
1341
+ *
1342
  * @return bool
1343
  */
1344
  public function current_user_can_edit_menu(){
1388
  $this->save_options();
1389
  }
1390
  }
1391
+
1392
  /**
1393
  * Apply the custom page title, if any.
1394
  *
1395
  * This is a callback for the "admin_title" filter. It will change the browser window/tab
1396
  * title (i.e. <title>), but not the title displayed on the admin page itself.
1397
+ *
1398
  * @param string $admin_title The current admin title (full).
1399
+ * @param string $title The current page title.
1400
  * @return string New admin title.
1401
  */
1402
  function hook_admin_title($admin_title, $title){
1740
 
1741
  /**
1742
  * Generate WP-compatible $menu and $submenu arrays from a custom menu tree.
1743
+ *
1744
  * Side-effects: This function executes several filters that may modify global state.
1745
  * Specifically, IFrame-handling callbacks in 'extras.php' will add add new hooks
1746
  * and other menu-related structures.
1759
  $new_menu = array();
1760
  $new_submenu = array();
1761
  $this->title_lookups = array();
1762
+
1763
  //Prepare the top menu
1764
  $first_nonseparator_found = false;
1765
  foreach ($tree as $topmenu){
1777
  if ( empty($topmenu['separator']) ) {
1778
  $this->title_lookups[$topmenu['file']] = !empty($topmenu['page_title']) ? $topmenu['page_title'] : $topmenu['menu_title'];
1779
  }
1780
+
1781
  //Prepare the submenu of this menu
1782
  $new_items = array();
1783
  if( !empty($topmenu['items']) ){
2194
  $item['access_level'] = $capability;
2195
  return $item;
2196
  }
2197
+
2198
  /**
2199
  * Output the menu editor page
2200
  *
2860
  /**
2861
  * Create a virtual 'super_admin' capability that only super admins have.
2862
  * This function accomplishes that by by filtering 'user_has_cap' calls.
2863
+ *
2864
  * @param array $allcaps All capabilities belonging to the current user, cap => true/false.
2865
  * @param array $required_caps The required capabilities.
2866
  * @param array $args The capability passed to current_user_can, the current user's ID, and other args.
2867
  * @return array Filtered version of $allcaps
2868
  */
2869
  function hook_user_has_cap($allcaps, /** @noinspection PhpUnusedParameterInspection */ $required_caps, $args){
2870
+ //Be careful not to overwrite a super_admin cap added by other plugins
2871
+ //For example, Advanced Access Manager also adds this capability.
2872
  if ( is_array($allcaps) && !isset($allcaps['super_admin']) ){
2873
  $user_id = intval($args[1]);
2874
  if ( $user_id != 0 ) {
2880
 
2881
  /**
2882
  * AJAX callback for saving screen options (whether to show or to hide advanced menu options).
2883
+ *
2884
+ * Handles the 'ws_ame_save_screen_options' action. The new option value
2885
  * is read from $_POST['hide_advanced_settings'].
2886
+ *
2887
  * @return void
2888
  */
2889
  function ajax_save_screen_options(){
2890
  if (!$this->current_user_can_edit_menu() || !check_ajax_referer('ws_ame_save_screen_options', false, false)){
2891
  die( $this->json_encode( array(
2892
+ 'error' => "You're not allowed to do that!"
2893
  )));
2894
  }
2895
+
2896
  $this->options['hide_advanced_settings'] = !empty($this->post['hide_advanced_settings']);
2897
  $this->options['show_extra_icons'] = !empty($this->post['show_extra_icons']);
2898
  $this->save_options();
3357
 
3358
  //Only display the notice on the Menu Editor (Pro) page.
3359
  $display_notice = $display_notice && isset($this->get['page']) && ($this->get['page'] == 'menu_editor');
3360
+
3361
  //Let the user override this completely (useful for client sites).
3362
  if ( $display_notice && file_exists(dirname($this->plugin_file) . '/never-display-surveys.txt') ) {
3363
  $display_notice = false;
3492
  $this->save_options();
3493
  }
3494
 
3495
+ /**
3496
+ * Update multiple plugin configuration values. Saves immediately.
3497
+ *
3498
+ * @param array $options An dictionary of key => value pairs.
3499
+ */
3500
+ public function set_many_plugin_options($options) {
3501
+ foreach($options as $key => $value) {
3502
+ $this->options[$key] = $value;
3503
+ }
3504
+ $this->save_options();
3505
+ }
3506
+
3507
  /**
3508
  * Log a security-related message.
3509
  *
4243
  $this->templates = array();
4244
  $this->blacklist = $blacklist;
4245
 
4246
+ if ( !empty($menu) ) {
4247
+ //At this point, the menu might not be sorted yet, especially if other plugins have made changes to it.
4248
+ //We need to know the relative order of menus to insert new items in the right place.
4249
+ ksort($menu, SORT_NUMERIC);
4250
 
4251
+ foreach($menu as $pos => $item){
4252
+ $this->addItem($item, $pos);
4253
+ }
4254
  }
4255
 
4256
+ if ( !empty($submenu) ) {
4257
+ foreach($submenu as $parent => $items){
4258
+ //Skip NULL's and empty arrays.
4259
+ if ( empty($items) ) {
4260
+ continue;
4261
+ }
4262
 
4263
+ //Skip sub-menus attached to non-existent parents. This should theoretically never happen,
4264
+ //but a buggy plugin can cause such a situation.
4265
+ if ( !isset($this->parentNames[$parent]) ) {
4266
+ continue;
4267
+ }
4268
 
4269
+ ksort($items, SORT_NUMERIC);
4270
+ $this->previousItemId = '';
4271
+ $this->wasPreviousItemSeparated = false;
4272
+
4273
+ foreach($items as $pos => $item) {
4274
+ $this->addItem($item, $pos, $parent);
4275
+ }
4276
  }
4277
  }
4278
 
includes/menu.php CHANGED
@@ -49,6 +49,12 @@ abstract class ameMenu {
49
  if ( ($compared === 0) && isset($arr['format']['is_normalized']) ) {
50
  $is_normalized = $arr['format']['is_normalized'];
51
  }
 
 
 
 
 
 
52
  } else {
53
  return self::load_menu_40($arr);
54
  }
@@ -169,6 +175,7 @@ abstract class ameMenu {
169
  * @static
170
  * @param array $arr
171
  * @return array
 
172
  */
173
  private static function load_menu_40($arr) {
174
  //This is *very* basic and might need to be improved.
@@ -176,7 +183,7 @@ abstract class ameMenu {
176
  return self::load_array($menu, true);
177
  }
178
 
179
- private static function add_format_header($menu) {
180
  if ( !isset($menu['format']) || !is_array($menu['format']) ) {
181
  $menu['format'] = array();
182
  }
49
  if ( ($compared === 0) && isset($arr['format']['is_normalized']) ) {
50
  $is_normalized = $arr['format']['is_normalized'];
51
  }
52
+ } else if ( isset($arr['format'], $arr['format']['name']) ) {
53
+ //This is not an admin menu configuration. It's something else with a "format" header.
54
+ throw new InvalidMenuException(sprintf(
55
+ 'Unknown menu configuration format: "%s".',
56
+ esc_html($arr['format']['name'])
57
+ ));
58
  } else {
59
  return self::load_menu_40($arr);
60
  }
175
  * @static
176
  * @param array $arr
177
  * @return array
178
+ * @throws InvalidMenuException
179
  */
180
  private static function load_menu_40($arr) {
181
  //This is *very* basic and might need to be improved.
183
  return self::load_array($menu, true);
184
  }
185
 
186
+ public static function add_format_header($menu) {
187
  if ( !isset($menu['format']) || !is_array($menu['format']) ) {
188
  $menu['format'] = array();
189
  }
includes/module.php CHANGED
@@ -18,6 +18,8 @@ abstract class ameModule {
18
  $this->menuEditor = $menuEditor;
19
 
20
  if ( class_exists('ReflectionClass', false) ) {
 
 
21
  $reflector = new ReflectionClass(get_class($this));
22
  $this->moduleDir = dirname($reflector->getFileName());
23
  $this->moduleId = basename($this->moduleDir);
@@ -147,4 +149,12 @@ abstract class ameModule {
147
  WPMenuEditor::atomic_update_site_option($name, $value);
148
  }
149
  }
 
 
 
 
 
 
 
 
150
  }
18
  $this->menuEditor = $menuEditor;
19
 
20
  if ( class_exists('ReflectionClass', false) ) {
21
+ //This should never throw an exception since the current class must exist for this constructor to be run.
22
+ /** @noinspection PhpUnhandledExceptionInspection */
23
  $reflector = new ReflectionClass(get_class($this));
24
  $this->moduleDir = dirname($reflector->getFileName());
25
  $this->moduleId = basename($this->moduleDir);
149
  WPMenuEditor::atomic_update_site_option($name, $value);
150
  }
151
  }
152
+
153
+ public function getModuleId() {
154
+ return $this->moduleId;
155
+ }
156
+
157
+ public function getTabTitle() {
158
+ return $this->tabTitle;
159
+ }
160
  }
includes/persistent-module.php CHANGED
@@ -47,6 +47,11 @@ abstract class amePersistentModule extends ameModule {
47
  $this->setScopedOption($this->optionName, $settings);
48
  }
49
 
 
 
 
 
 
50
  protected function getTemplateVariables($templateName) {
51
  $variables = parent::getTemplateVariables($templateName);
52
  if ( $templateName === $this->moduleId ) {
47
  $this->setScopedOption($this->optionName, $settings);
48
  }
49
 
50
+ public function mergeSettingsWith($newSettings) {
51
+ $this->settings = array_merge($this->loadSettings(), $newSettings);
52
+ return $this->settings;
53
+ }
54
+
55
  protected function getTemplateVariables($templateName) {
56
  $variables = parent::getTemplateVariables($templateName);
57
  if ( $templateName === $this->moduleId ) {
includes/reflection-callable.php CHANGED
@@ -16,6 +16,7 @@ class AmeReflectionCallable {
16
  * AmeReflectionCallable constructor.
17
  *
18
  * @param callable $callback
 
19
  */
20
  public function __construct($callback) {
21
  $this->callback = $callback;
@@ -25,6 +26,7 @@ class AmeReflectionCallable {
25
  /**
26
  * @param callable $callback
27
  * @return ReflectionFunctionAbstract
 
28
  */
29
  private function getReflectionFunction($callback) {
30
  //Closure or a simple function name.
16
  * AmeReflectionCallable constructor.
17
  *
18
  * @param callable $callback
19
+ * @throws ReflectionException
20
  */
21
  public function __construct($callback) {
22
  $this->callback = $callback;
26
  /**
27
  * @param callable $callback
28
  * @return ReflectionFunctionAbstract
29
+ * @throws ReflectionException
30
  */
31
  private function getReflectionFunction($callback) {
32
  //Closure or a simple function name.
includes/role-utils.php CHANGED
@@ -1,11 +1,12 @@
1
  <?php
2
  class ameRoleUtils {
3
  /**
4
- * Retrieve a list of all known, non-meta capabilities of all roles.
5
- *
6
- * @return array Associative array with capability names as keys
7
- */
8
- public static function get_all_capabilities(){
 
9
  //Cache the results.
10
  static $capabilities = null;
11
  if ( isset($capabilities) ) {
@@ -23,15 +24,17 @@ class ameRoleUtils {
23
  }
24
 
25
  //Add multisite-specific capabilities (not listed in any roles in WP 3.0)
26
- $multisite_caps = array(
27
- 'manage_sites' => 1,
28
- 'manage_network' => 1,
29
- 'manage_network_users' => 1,
30
- 'manage_network_themes' => 1,
31
- 'manage_network_options' => 1,
32
- 'manage_network_plugins' => 1,
33
- );
34
- $capabilities = array_merge($capabilities, $multisite_caps);
 
 
35
 
36
  return $capabilities;
37
  }
1
  <?php
2
  class ameRoleUtils {
3
  /**
4
+ * Retrieve a list of all known, non-meta capabilities of all roles.
5
+ *
6
+ * @param bool $include_multisite_caps
7
+ * @return array Associative array with capability names as keys
8
+ */
9
+ public static function get_all_capabilities($include_multisite_caps = true){
10
  //Cache the results.
11
  static $capabilities = null;
12
  if ( isset($capabilities) ) {
24
  }
25
 
26
  //Add multisite-specific capabilities (not listed in any roles in WP 3.0)
27
+ if ($include_multisite_caps) {
28
+ $multisite_caps = array(
29
+ 'manage_sites' => 1,
30
+ 'manage_network' => 1,
31
+ 'manage_network_users' => 1,
32
+ 'manage_network_themes' => 1,
33
+ 'manage_network_options' => 1,
34
+ 'manage_network_plugins' => 1,
35
+ );
36
+ $capabilities = array_merge($capabilities, $multisite_caps);
37
+ }
38
 
39
  return $capabilities;
40
  }
includes/shadow_plugin_framework.php CHANGED
@@ -306,13 +306,23 @@ class MenuEd_ShadowPluginFramework {
306
  * @return bool
307
  */
308
  function is_in_wpmu_plugin_dir( $filename = '' ){
309
- if ( !defined('WPMU_PLUGIN_DIR') ) return false;
 
 
310
 
311
  if ( empty($filename) ){
312
  $filename = $this->plugin_file;
313
  }
314
-
315
- return (strpos( realpath($filename), realpath(WPMU_PLUGIN_DIR) ) !== false);
 
 
 
 
 
 
 
 
316
  }
317
 
318
  /**
306
  * @return bool
307
  */
308
  function is_in_wpmu_plugin_dir( $filename = '' ){
309
+ if ( !defined('WPMU_PLUGIN_DIR') ) {
310
+ return false;
311
+ }
312
 
313
  if ( empty($filename) ){
314
  $filename = $this->plugin_file;
315
  }
316
+
317
+ $muPluginDir = realpath(WPMU_PLUGIN_DIR);
318
+ $filename = realpath($filename);
319
+
320
+ //If realpath() fails, just normalize the syntax instead.
321
+ if ( empty($muPluginDir) || empty($filename) ) {
322
+ $muPluginDir = wp_normalize_path($muPluginDir);
323
+ $filename = wp_normalize_path($filename);
324
+ }
325
+ return (strpos( $filename, $muPluginDir ) !== false);
326
  }
327
 
328
  /**
js/actor-manager.js CHANGED
@@ -1,9 +1,12 @@
1
  /// <reference path="lodash-3.10.d.ts" />
2
  /// <reference path="common.d.ts" />
3
  var __extends = (this && this.__extends) || (function () {
4
- var extendStatics = Object.setPrototypeOf ||
5
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
 
 
 
7
  return function (d, b) {
8
  extendStatics(d, b);
9
  function __() { this.constructor = d; }
@@ -58,6 +61,12 @@ var AmeBaseActor = /** @class */ (function () {
58
  AmeBaseActor.prototype.toString = function () {
59
  return this.displayName + ' [' + this.id + ']';
60
  };
 
 
 
 
 
 
61
  return AmeBaseActor;
62
  }());
63
  var AmeRole = /** @class */ (function (_super) {
@@ -162,6 +171,7 @@ var AmeActorManager = /** @class */ (function () {
162
  this.tagMetaCaps[tagMetaCaps[i]] = true;
163
  }
164
  }
 
165
  AmeActorManager.prototype.actorCanAccess = function (actorId, grantAccess, defaultCapability) {
166
  if (defaultCapability === void 0) { defaultCapability = null; }
167
  if (grantAccess.hasOwnProperty(actorId)) {
@@ -480,6 +490,9 @@ var AmeActorManager = /** @class */ (function () {
480
  AmeActorManager.prototype.getSuggestedCapabilities = function () {
481
  return this.suggestedCapabilities;
482
  };
 
 
 
483
  AmeActorManager._ = wsAmeLodash;
484
  return AmeActorManager;
485
  }());
1
  /// <reference path="lodash-3.10.d.ts" />
2
  /// <reference path="common.d.ts" />
3
  var __extends = (this && this.__extends) || (function () {
4
+ var extendStatics = function (d, b) {
5
+ extendStatics = Object.setPrototypeOf ||
6
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
7
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
8
+ return extendStatics(d, b);
9
+ }
10
  return function (d, b) {
11
  extendStatics(d, b);
12
  function __() { this.constructor = d; }
61
  AmeBaseActor.prototype.toString = function () {
62
  return this.displayName + ' [' + this.id + ']';
63
  };
64
+ AmeBaseActor.prototype.getId = function () {
65
+ return this.id;
66
+ };
67
+ AmeBaseActor.prototype.getDisplayName = function () {
68
+ return this.displayName;
69
+ };
70
  return AmeBaseActor;
71
  }());
72
  var AmeRole = /** @class */ (function (_super) {
171
  this.tagMetaCaps[tagMetaCaps[i]] = true;
172
  }
173
  }
174
+ // noinspection JSUnusedGlobalSymbols
175
  AmeActorManager.prototype.actorCanAccess = function (actorId, grantAccess, defaultCapability) {
176
  if (defaultCapability === void 0) { defaultCapability = null; }
177
  if (grantAccess.hasOwnProperty(actorId)) {
490
  AmeActorManager.prototype.getSuggestedCapabilities = function () {
491
  return this.suggestedCapabilities;
492
  };
493
+ AmeActorManager.prototype.createUserFromProperties = function (properties) {
494
+ return AmeUser.createFromProperties(properties);
495
+ };
496
  AmeActorManager._ = wsAmeLodash;
497
  return AmeActorManager;
498
  }());
js/actor-manager.ts CHANGED
@@ -12,7 +12,17 @@ interface CapabilityMap {
12
  [capabilityName: string] : boolean;
13
  }
14
 
15
- abstract class AmeBaseActor {
 
 
 
 
 
 
 
 
 
 
16
  public id: string;
17
  public displayName: string = '[Error: No displayName set]';
18
  public capabilities: CapabilityMap;
@@ -20,7 +30,7 @@ abstract class AmeBaseActor {
20
 
21
  groupActors: string[] = [];
22
 
23
- constructor(id: string, displayName: string, capabilities: CapabilityMap, metaCapabilities: CapabilityMap = {}) {
24
  this.id = id;
25
  this.displayName = displayName;
26
  this.capabilities = capabilities;
@@ -68,6 +78,14 @@ abstract class AmeBaseActor {
68
  toString(): string {
69
  return this.displayName + ' [' + this.id + ']';
70
  }
 
 
 
 
 
 
 
 
71
  }
72
 
73
  class AmeRole extends AmeBaseActor {
@@ -100,7 +118,7 @@ interface AmeUserPropertyMap {
100
  avatar_html?: string;
101
  }
102
 
103
- class AmeUser extends AmeBaseActor {
104
  userLogin: string;
105
  userId: number = 0;
106
  roles: string[];
@@ -175,7 +193,7 @@ interface AmeCapabilitySuggestion {
175
  capability: string;
176
  }
177
 
178
- class AmeActorManager {
179
  private static _ = wsAmeLodash;
180
 
181
  private roles: {[roleId: string] : AmeRole} = {};
@@ -183,7 +201,7 @@ class AmeActorManager {
183
  private grantedCapabilities: AmeGrantedCapabilityMap = {};
184
 
185
  public readonly isMultisite: boolean = false;
186
- private superAdmin: AmeSuperAdmin;
187
  private exclusiveSuperAdminCapabilities = {};
188
 
189
  private tagMetaCaps = {};
@@ -233,6 +251,7 @@ class AmeActorManager {
233
  }
234
  }
235
 
 
236
  actorCanAccess(
237
  actorId: string,
238
  grantAccess: {[actorId: string] : boolean},
@@ -619,6 +638,23 @@ class AmeActorManager {
619
  public getSuggestedCapabilities(): AmeCapabilitySuggestion[] {
620
  return this.suggestedCapabilities;
621
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
622
  }
623
 
624
  if (typeof wsAmeActorData !== 'undefined') {
12
  [capabilityName: string] : boolean;
13
  }
14
 
15
+ interface IAmeActor {
16
+ getId(): string;
17
+ getDisplayName(): string;
18
+ }
19
+
20
+ interface IAmeUser extends IAmeActor {
21
+ userLogin: string;
22
+ isSuperAdmin: boolean;
23
+ }
24
+
25
+ abstract class AmeBaseActor implements IAmeActor {
26
  public id: string;
27
  public displayName: string = '[Error: No displayName set]';
28
  public capabilities: CapabilityMap;
30
 
31
  groupActors: string[] = [];
32
 
33
+ protected constructor(id: string, displayName: string, capabilities: CapabilityMap, metaCapabilities: CapabilityMap = {}) {
34
  this.id = id;
35
  this.displayName = displayName;
36
  this.capabilities = capabilities;
78
  toString(): string {
79
  return this.displayName + ' [' + this.id + ']';
80
  }
81
+
82
+ getId(): string {
83
+ return this.id;
84
+ }
85
+
86
+ getDisplayName(): string {
87
+ return this.displayName;
88
+ }
89
  }
90
 
91
  class AmeRole extends AmeBaseActor {
118
  avatar_html?: string;
119
  }
120
 
121
+ class AmeUser extends AmeBaseActor implements IAmeUser {
122
  userLogin: string;
123
  userId: number = 0;
124
  roles: string[];
193
  capability: string;
194
  }
195
 
196
+ class AmeActorManager implements AmeActorManagerInterface {
197
  private static _ = wsAmeLodash;
198
 
199
  private roles: {[roleId: string] : AmeRole} = {};
201
  private grantedCapabilities: AmeGrantedCapabilityMap = {};
202
 
203
  public readonly isMultisite: boolean = false;
204
+ private readonly superAdmin: AmeSuperAdmin;
205
  private exclusiveSuperAdminCapabilities = {};
206
 
207
  private tagMetaCaps = {};
251
  }
252
  }
253
 
254
+ // noinspection JSUnusedGlobalSymbols
255
  actorCanAccess(
256
  actorId: string,
257
  grantAccess: {[actorId: string] : boolean},
638
  public getSuggestedCapabilities(): AmeCapabilitySuggestion[] {
639
  return this.suggestedCapabilities;
640
  }
641
+
642
+ createUserFromProperties(properties: AmeUserPropertyMap): IAmeUser {
643
+ return AmeUser.createFromProperties(properties);
644
+ }
645
+ }
646
+
647
+ interface AmeActorManagerInterface {
648
+ getUsers(): AmeDictionary<IAmeUser>;
649
+ getUser(login: string): IAmeUser;
650
+ addUsers(newUsers: IAmeUser[]);
651
+ createUserFromProperties(properties: AmeUserPropertyMap): IAmeUser;
652
+
653
+ getRoles(): AmeDictionary<IAmeActor>;
654
+ getSuperAdmin(): IAmeActor;
655
+
656
+ getActor(actorId): IAmeActor;
657
+ actorExists(actorId: string): boolean;
658
  }
659
 
660
  if (typeof wsAmeActorData !== 'undefined') {
js/jquery.qtip.js CHANGED
@@ -1,8 +1,15 @@
1
- /*! qTip2 - Pretty powerful tooltips - v2.0.0 - 2012-09-10
2
- * http://craigsworks.com/projects/qtip2/
3
- * Copyright (c) 2012 Craig Michael Thompson; Licensed MIT, GPL */
4
-
5
- /*jslint browser: true, onevar: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: true */
 
 
 
 
 
 
 
6
  /*global window: false, jQuery: false, console: false, define: false */
7
 
8
  /* Cache window, document, undefined */
@@ -19,2659 +26,2612 @@
19
  }
20
  }
21
  (function($) {
22
- /* This currently causes issues with Safari 6, so for it's disabled */
23
- //"use strict"; // (Dis)able ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
24
-
25
- // Munge the primitives - Paul Irish tip
26
- var TRUE = true,
27
- FALSE = false,
28
- NULL = null,
29
-
30
- // Side names and other stuff
31
- X = 'x', Y = 'y',
32
- WIDTH = 'width',
33
- HEIGHT = 'height',
34
- TOP = 'top',
35
- LEFT = 'left',
36
- BOTTOM = 'bottom',
37
- RIGHT = 'right',
38
- CENTER = 'center',
39
- FLIP = 'flip',
40
- FLIPINVERT = 'flipinvert',
41
- SHIFT = 'shift',
42
-
43
- // Shortcut vars
44
- QTIP, PLUGINS, MOUSE,
45
- usedIDs = {},
46
- uitooltip = 'ui-tooltip',
47
- widget = 'ui-widget',
48
- disabled = 'ui-state-disabled',
49
- selector = 'div.qtip.'+uitooltip,
50
- defaultClass = uitooltip + '-default',
51
- focusClass = uitooltip + '-focus',
52
- hoverClass = uitooltip + '-hover',
53
- replaceSuffix = '_replacedByqTip',
54
- oldtitle = 'oldtitle',
55
- trackingBound,
56
- redrawContainer;
57
-
 
 
 
 
 
 
 
 
 
58
  /*
59
- * redraw() container for width/height calculations
60
- */
61
- redrawContainer = $('<div/>', { id: 'qtip-rcontainer' });
62
- $(function() { redrawContainer.appendTo(document.body); });
63
-
64
-
65
-
66
- // Option object sanitizer
67
- function sanitizeOptions(opts)
68
- {
69
- var invalid = function(a) { return a === NULL || 'object' !== typeof a; },
70
- invalidContent = function(c) { return !$.isFunction(c) && ((!c && !c.attr) || c.length < 1 || ('object' === typeof c && !c.jquery)); };
71
-
72
- if(!opts || 'object' !== typeof opts) { return FALSE; }
73
-
74
- if(invalid(opts.metadata)) {
75
- opts.metadata = { type: opts.metadata };
76
- }
77
-
78
- if('content' in opts) {
79
- if(invalid(opts.content) || opts.content.jquery) {
80
- opts.content = { text: opts.content };
81
- }
82
-
83
- if(invalidContent(opts.content.text || FALSE)) {
84
- opts.content.text = FALSE;
85
- }
86
-
87
- if('title' in opts.content) {
88
- if(invalid(opts.content.title)) {
89
- opts.content.title = { text: opts.content.title };
90
- }
91
-
92
- if(invalidContent(opts.content.title.text || FALSE)) {
93
- opts.content.title.text = FALSE;
94
- }
95
- }
96
- }
97
-
98
- if('position' in opts && invalid(opts.position)) {
99
- opts.position = { my: opts.position, at: opts.position };
100
- }
101
-
102
- if('show' in opts && invalid(opts.show)) {
103
- opts.show = opts.show.jquery ? { target: opts.show } : { event: opts.show };
104
- }
105
-
106
- if('hide' in opts && invalid(opts.hide)) {
107
- opts.hide = opts.hide.jquery ? { target: opts.hide } : { event: opts.hide };
108
- }
109
-
110
- if('style' in opts && invalid(opts.style)) {
111
- opts.style = { classes: opts.style };
112
- }
113
-
114
- // Sanitize plugin options
115
- $.each(PLUGINS, function() {
116
- if(this.sanitize) { this.sanitize(opts); }
117
- });
118
-
119
- return opts;
120
- }
121
-
122
- /*
123
- * Core plugin implementation
124
- */
125
- function QTip(target, options, id, attr)
126
- {
127
- // Declare this reference
128
- var self = this,
129
- docBody = document.body,
130
- tooltipID = uitooltip + '-' + id,
131
- isPositioning = 0,
132
- isDrawing = 0,
133
- tooltip = $(),
134
- namespace = '.qtip-' + id,
135
- elements, cache;
136
-
137
- // Setup class attributes
138
- self.id = id;
139
- self.rendered = FALSE;
140
- self.destroyed = FALSE;
141
- self.elements = elements = { target: target };
142
- self.timers = { img: {} };
143
- self.options = options;
144
- self.checks = {};
145
- self.plugins = {};
146
- self.cache = cache = {
147
- event: {},
148
- target: $(),
149
- disabled: FALSE,
150
- attr: attr,
151
- onTarget: FALSE,
152
- lastClass: ''
153
- };
154
-
155
- /*
156
- * Private core functions
157
- */
158
- function convertNotation(notation)
159
- {
160
- var i = 0, obj, option = options,
161
-
162
- // Split notation into array
163
- levels = notation.split('.');
164
-
165
- // Loop through
166
- while( option = option[ levels[i++] ] ) {
167
- if(i < levels.length) { obj = option; }
168
- }
169
-
170
- return [obj || options, levels.pop()];
171
- }
172
-
173
- function triggerEvent(type, args, event) {
174
- var callback = $.Event('tooltip'+type);
175
- callback.originalEvent = (event ? $.extend({}, event) : NULL) || cache.event || NULL;
176
- tooltip.trigger(callback, [self].concat(args || []));
177
-
178
- return !callback.isDefaultPrevented();
179
- }
180
-
181
- function setWidget()
182
- {
183
- var on = options.style.widget;
184
-
185
- tooltip.toggleClass('ui-helper-reset '+widget, on).toggleClass(defaultClass, options.style.def && !on);
186
-
187
- if(elements.content) {
188
- elements.content.toggleClass(widget+'-content', on);
189
- }
190
-
191
- if(elements.titlebar) {
192
- elements.titlebar.toggleClass(widget+'-header', on);
193
- }
194
- if(elements.button) {
195
- elements.button.toggleClass(uitooltip+'-icon', !on);
196
- }
197
- }
198
-
199
- function removeTitle(reposition)
200
- {
201
- if(elements.title) {
202
- elements.titlebar.remove();
203
- elements.titlebar = elements.title = elements.button = NULL;
204
-
205
- // Reposition if enabled
206
- if(reposition !== FALSE) { self.reposition(); }
207
- }
208
- }
209
-
210
- function createButton()
211
- {
212
- var button = options.content.title.button,
213
- isString = typeof button === 'string',
214
- close = isString ? button : 'Close tooltip';
215
-
216
- if(elements.button) { elements.button.remove(); }
217
-
218
- // Use custom button if one was supplied by user, else use default
219
- if(button.jquery) {
220
- elements.button = button;
221
- }
222
- else {
223
- elements.button = $('<a />', {
224
- 'class': 'ui-state-default ui-tooltip-close ' + (options.style.widget ? '' : uitooltip+'-icon'),
225
- 'title': close,
226
- 'aria-label': close
227
- })
228
- .prepend(
229
- $('<span />', {
230
- 'class': 'ui-icon ui-icon-close',
231
- 'html': '&times;'
232
- })
233
- );
234
- }
235
-
236
- // Create button and setup attributes
237
- elements.button.appendTo(elements.titlebar)
238
- .attr('role', 'button')
239
- .click(function(event) {
240
- if(!tooltip.hasClass(disabled)) { self.hide(event); }
241
- return FALSE;
242
- });
243
-
244
- // Redraw the tooltip when we're done
245
- self.redraw();
246
- }
247
-
248
- function createTitle()
249
- {
250
- var id = tooltipID+'-title';
251
-
252
- // Destroy previous title element, if present
253
- if(elements.titlebar) { removeTitle(); }
254
-
255
- // Create title bar and title elements
256
- elements.titlebar = $('<div />', {
257
- 'class': uitooltip + '-titlebar ' + (options.style.widget ? 'ui-widget-header' : '')
258
- })
259
- .append(
260
- elements.title = $('<div />', {
261
- 'id': id,
262
- 'class': uitooltip + '-title',
263
- 'aria-atomic': TRUE
264
- })
265
- )
266
- .insertBefore(elements.content)
267
-
268
- // Button-specific events
269
- .delegate('.ui-tooltip-close', 'mousedown keydown mouseup keyup mouseout', function(event) {
270
- $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down');
271
- })
272
- .delegate('.ui-tooltip-close', 'mouseover mouseout', function(event){
273
- $(this).toggleClass('ui-state-hover', event.type === 'mouseover');
274
- });
275
-
276
- // Create button if enabled
277
- if(options.content.title.button) { createButton(); }
278
-
279
- // Redraw the tooltip dimensions if it's rendered
280
- else if(self.rendered){ self.redraw(); }
281
- }
282
-
283
- function updateButton(button)
284
- {
285
- var elem = elements.button,
286
- title = elements.title;
287
-
288
- // Make sure tooltip is rendered and if not, return
289
- if(!self.rendered) { return FALSE; }
290
-
291
- if(!button) {
292
- elem.remove();
293
- }
294
- else {
295
- if(!title) {
296
- createTitle();
297
- }
298
- createButton();
299
- }
300
- }
301
-
302
- function updateTitle(content, reposition)
303
- {
304
- var elem = elements.title;
305
-
306
- // Make sure tooltip is rendered and if not, return
307
- if(!self.rendered || !content) { return FALSE; }
308
-
309
- // Use function to parse content
310
- if($.isFunction(content)) {
311
- content = content.call(target, cache.event, self);
312
- }
313
-
314
- // Remove title if callback returns false or null/undefined (but not '')
315
- if(content === FALSE || (!content && content !== '')) { return removeTitle(FALSE); }
316
-
317
- // Append new content if its a DOM array and show it if hidden
318
- else if(content.jquery && content.length > 0) {
319
- elem.empty().append(content.css({ display: 'block' }));
320
- }
321
-
322
- // Content is a regular string, insert the new content
323
- else { elem.html(content); }
324
-
325
- // Redraw and reposition
326
- self.redraw();
327
- if(reposition !== FALSE && self.rendered && tooltip[0].offsetWidth > 0) {
328
- self.reposition(cache.event);
329
- }
330
- }
331
-
332
- function updateContent(content, reposition)
333
- {
334
- var elem = elements.content;
335
-
336
- // Make sure tooltip is rendered and content is defined. If not return
337
- if(!self.rendered || !content) { return FALSE; }
338
-
339
- // Use function to parse content
340
- if($.isFunction(content)) {
341
- content = content.call(target, cache.event, self) || '';
342
- }
343
-
344
- // Append new content if its a DOM array and show it if hidden
345
- if(content.jquery && content.length > 0) {
346
- elem.empty().append(content.css({ display: 'block' }));
347
- }
348
-
349
- // Content is a regular string, insert the new content
350
- else { elem.html(content); }
351
-
352
- // Image detection
353
- function detectImages(next) {
354
- var images, srcs = {};
355
-
356
- function imageLoad(image) {
357
- // Clear src from object and any timers and events associated with the image
358
- if(image) {
359
- delete srcs[image.src];
360
- clearTimeout(self.timers.img[image.src]);
361
- $(image).unbind(namespace);
362
- }
363
-
364
- // If queue is empty after image removal, update tooltip and continue the queue
365
- if($.isEmptyObject(srcs)) {
366
- self.redraw();
367
- if(reposition !== FALSE) {
368
- self.reposition(cache.event);
369
- }
370
-
371
- next();
372
- }
373
- }
374
-
375
- // Find all content images without dimensions, and if no images were found, continue
376
- if((images = elem.find('img[src]:not([height]):not([width])')).length === 0) { return imageLoad(); }
377
-
378
- // Apply timer to each image to poll for dimensions
379
- images.each(function(i, elem) {
380
- // Skip if the src is already present
381
- if(srcs[elem.src] !== undefined) { return; }
382
-
383
- // Keep track of how many times we poll for image dimensions.
384
- // If it doesn't return in a reasonable amount of time, it's better
385
- // to display the tooltip, rather than hold up the queue.
386
- var iterations = 0, maxIterations = 3;
387
-
388
- (function timer(){
389
- // When the dimensions are found, remove the image from the queue
390
- if(elem.height || elem.width || (iterations > maxIterations)) { return imageLoad(elem); }
391
-
392
- // Increase iterations and restart timer
393
- iterations += 1;
394
- self.timers.img[elem.src] = setTimeout(timer, 700);
395
- }());
396
-
397
- // Also apply regular load/error event handlers
398
- $(elem).bind('error'+namespace+' load'+namespace, function(){ imageLoad(this); });
399
-
400
- // Store the src and element in our object
401
- srcs[elem.src] = elem;
402
- });
403
- }
404
-
405
- /*
406
- * If we're still rendering... insert into 'fx' queue our image dimension
407
- * checker which will halt the showing of the tooltip until image dimensions
408
- * can be detected properly.
409
- */
410
- if(self.rendered < 0) { tooltip.queue('fx', detectImages); }
411
-
412
- // We're fully rendered, so reset isDrawing flag and proceed without queue delay
413
- else { isDrawing = 0; detectImages($.noop); }
414
-
415
- return self;
416
- }
417
-
418
- function assignEvents()
419
- {
420
- var posOptions = options.position,
421
- targets = {
422
- show: options.show.target,
423
- hide: options.hide.target,
424
- viewport: $(posOptions.viewport),
425
- document: $(document),
426
- body: $(document.body),
427
- window: $(window)
428
- },
429
- events = {
430
- show: $.trim('' + options.show.event).split(' '),
431
- hide: $.trim('' + options.hide.event).split(' ')
432
- },
433
- IE6 = $.browser.msie && parseInt($.browser.version, 10) === 6;
434
-
435
- // Define show event method
436
- function showMethod(event)
437
- {
438
- if(tooltip.hasClass(disabled)) { return FALSE; }
439
-
440
- // Clear hide timers
441
- clearTimeout(self.timers.show);
442
- clearTimeout(self.timers.hide);
443
-
444
- // Start show timer
445
- var callback = function(){ self.toggle(TRUE, event); };
446
- if(options.show.delay > 0) {
447
- self.timers.show = setTimeout(callback, options.show.delay);
448
- }
449
- else{ callback(); }
450
- }
451
-
452
- // Define hide method
453
- function hideMethod(event)
454
- {
455
- if(tooltip.hasClass(disabled) || isPositioning || isDrawing) { return FALSE; }
456
-
457
- // Check if new target was actually the tooltip element
458
- var relatedTarget = $(event.relatedTarget || event.target),
459
- ontoTooltip = relatedTarget.closest(selector)[0] === tooltip[0],
460
- ontoTarget = relatedTarget[0] === targets.show[0];
461
-
462
- // Clear timers and stop animation queue
463
- clearTimeout(self.timers.show);
464
- clearTimeout(self.timers.hide);
465
-
466
- // Prevent hiding if tooltip is fixed and event target is the tooltip. Or if mouse positioning is enabled and cursor momentarily overlaps
467
- if((posOptions.target === 'mouse' && ontoTooltip) || (options.hide.fixed && ((/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget)))) {
468
- try { event.preventDefault(); event.stopImmediatePropagation(); } catch(e) {} return;
469
- }
470
-
471
- // If tooltip has displayed, start hide timer
472
- if(options.hide.delay > 0) {
473
- self.timers.hide = setTimeout(function(){ self.hide(event); }, options.hide.delay);
474
- }
475
- else{ self.hide(event); }
476
- }
477
-
478
- // Define inactive method
479
- function inactiveMethod(event)
480
- {
481
- if(tooltip.hasClass(disabled)) { return FALSE; }
482
-
483
- // Clear timer
484
- clearTimeout(self.timers.inactive);
485
- self.timers.inactive = setTimeout(function(){ self.hide(event); }, options.hide.inactive);
486
- }
487
-
488
- function repositionMethod(event) {
489
- if(self.rendered && tooltip[0].offsetWidth > 0) { self.reposition(event); }
490
- }
491
-
492
- // On mouseenter/mouseleave...
493
- tooltip.bind('mouseenter'+namespace+' mouseleave'+namespace, function(event) {
494
- var state = event.type === 'mouseenter';
495
-
496
- // Focus the tooltip on mouseenter (z-index stacking)
497
- if(state) { self.focus(event); }
498
-
499
- // Add hover class
500
- tooltip.toggleClass(hoverClass, state);
501
- });
502
-
503
- // If using mouseout/mouseleave as a hide event...
504
- if(/mouse(out|leave)/i.test(options.hide.event)) {
505
- // Hide tooltips when leaving current window/frame (but not select/option elements)
506
- if(options.hide.leave === 'window') {
507
- targets.window.bind('mouseout'+namespace+' blur'+namespace, function(event) {
508
- if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) { self.hide(event); }
509
- });
510
- }
511
- }
512
-
513
- // Enable hide.fixed
514
- if(options.hide.fixed) {
515
- // Add tooltip as a hide target
516
- targets.hide = targets.hide.add(tooltip);
517
-
518
- // Clear hide timer on tooltip hover to prevent it from closing
519
- tooltip.bind('mouseover'+namespace, function() {
520
- if(!tooltip.hasClass(disabled)) { clearTimeout(self.timers.hide); }
521
- });
522
- }
523
-
524
- /*
525
- * Make sure hoverIntent functions properly by using mouseleave to clear show timer if
526
- * mouseenter/mouseout is used for show.event, even if it isn't in the users options.
527
- */
528
- else if(/mouse(over|enter)/i.test(options.show.event)) {
529
- targets.hide.bind('mouseleave'+namespace, function(event) {
530
- clearTimeout(self.timers.show);
531
- });
532
- }
533
-
534
- // Hide tooltip on document mousedown if unfocus events are enabled
535
- if(('' + options.hide.event).indexOf('unfocus') > -1) {
536
- posOptions.container.closest('html').bind('mousedown'+namespace, function(event) {
537
- var elem = $(event.target),
538
- enabled = self.rendered && !tooltip.hasClass(disabled) && tooltip[0].offsetWidth > 0,
539
- isAncestor = elem.parents(selector).filter(tooltip[0]).length > 0;
540
-
541
- if(elem[0] !== target[0] && elem[0] !== tooltip[0] && !isAncestor &&
542
- !target.has(elem[0]).length && !elem.attr('disabled')
543
- ) {
544
- self.hide(event);
545
- }
546
- });
547
- }
548
-
549
- // Check if the tooltip hides when inactive
550
- if('number' === typeof options.hide.inactive) {
551
- // Bind inactive method to target as a custom event
552
- targets.show.bind('qtip-'+id+'-inactive', inactiveMethod);
553
-
554
- // Define events which reset the 'inactive' event handler
555
- $.each(QTIP.inactiveEvents, function(index, type){
556
- targets.hide.add(elements.tooltip).bind(type+namespace+'-inactive', inactiveMethod);
557
- });
558
- }
559
-
560
- // Apply hide events
561
- $.each(events.hide, function(index, type) {
562
- var showIndex = $.inArray(type, events.show),
563
- targetHide = $(targets.hide);
564
-
565
- // Both events and targets are identical, apply events using a toggle
566
- if((showIndex > -1 && targetHide.add(targets.show).length === targetHide.length) || type === 'unfocus')
567
- {
568
- targets.show.bind(type+namespace, function(event) {
569
- if(tooltip[0].offsetWidth > 0) { hideMethod(event); }
570
- else { showMethod(event); }
571
- });
572
-
573
- // Don't bind the event again
574
- delete events.show[ showIndex ];
575
- }
576
-
577
- // Events are not identical, bind normally
578
- else { targets.hide.bind(type+namespace, hideMethod); }
579
- });
580
-
581
- // Apply show events
582
- $.each(events.show, function(index, type) {
583
- targets.show.bind(type+namespace, showMethod);
584
- });
585
-
586
- // Check if the tooltip hides when mouse is moved a certain distance
587
- if('number' === typeof options.hide.distance) {
588
- // Bind mousemove to target to detect distance difference
589
- targets.show.add(tooltip).bind('mousemove'+namespace, function(event) {
590
- var origin = cache.origin || {},
591
- limit = options.hide.distance,
592
- abs = Math.abs;
593
-
594
- // Check if the movement has gone beyond the limit, and hide it if so
595
- if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) {
596
- self.hide(event);
597
- }
598
- });
599
- }
600
-
601
- // Mouse positioning events
602
- if(posOptions.target === 'mouse') {
603
- // Cache mousemove coords on show targets
604
- targets.show.bind('mousemove'+namespace, function(event) {
605
- MOUSE = { pageX: event.pageX, pageY: event.pageY, type: 'mousemove' };
606
- });
607
-
608
- // If mouse adjustment is on...
609
- if(posOptions.adjust.mouse) {
610
- // Apply a mouseleave event so we don't get problems with overlapping
611
- if(options.hide.event) {
612
- // Hide when we leave the tooltip and not onto the show target
613
- tooltip.bind('mouseleave'+namespace, function(event) {
614
- if((event.relatedTarget || event.target) !== targets.show[0]) { self.hide(event); }
615
- });
616
-
617
- // Track if we're on the target or not
618
- elements.target.bind('mouseenter'+namespace+' mouseleave'+namespace, function(event) {
619
- cache.onTarget = event.type === 'mouseenter';
620
- });
621
- }
622
-
623
- // Update tooltip position on mousemove
624
- targets.document.bind('mousemove'+namespace, function(event) {
625
- // Update the tooltip position only if the tooltip is visible and adjustment is enabled
626
- if(self.rendered && cache.onTarget && !tooltip.hasClass(disabled) && tooltip[0].offsetWidth > 0) {
627
- self.reposition(event || MOUSE);
628
- }
629
- });
630
- }
631
- }
632
-
633
- // Adjust positions of the tooltip on window resize if enabled
634
- if(posOptions.adjust.resize || targets.viewport.length) {
635
- ($.event.special.resize ? targets.viewport : targets.window).bind('resize'+namespace, repositionMethod);
636
- }
637
-
638
- // Adjust tooltip position on scroll if screen adjustment is enabled
639
- if(targets.viewport.length || (IE6 && tooltip.css('position') === 'fixed')) {
640
- targets.viewport.bind('scroll'+namespace, repositionMethod);
641
- }
642
- }
643
-
644
- function unassignEvents()
645
- {
646
- var targets = [
647
- options.show.target[0],
648
- options.hide.target[0],
649
- self.rendered && elements.tooltip[0],
650
- options.position.container[0],
651
- options.position.viewport[0],
652
- options.position.container.closest('html')[0], // unfocus
653
- window,
654
- document
655
- ];
656
-
657
- // Check if tooltip is rendered
658
- if(self.rendered) {
659
- $([]).pushStack( $.grep(targets, function(i){ return typeof i === 'object'; }) ).unbind(namespace);
660
- }
661
-
662
- // Tooltip isn't yet rendered, remove render event
663
- else { options.show.target.unbind(namespace+'-create'); }
664
- }
665
-
666
- // Setup builtin .set() option checks
667
- self.checks.builtin = {
668
- // Core checks
669
- '^id$': function(obj, o, v) {
670
- var id = v === TRUE ? QTIP.nextid : v,
671
- tooltipID = uitooltip + '-' + id;
672
-
673
- if(id !== FALSE && id.length > 0 && !$('#'+tooltipID).length) {
674
- tooltip[0].id = tooltipID;
675
- elements.content[0].id = tooltipID + '-content';
676
- elements.title[0].id = tooltipID + '-title';
677
- }
678
- },
679
-
680
- // Content checks
681
- '^content.text$': function(obj, o, v){ updateContent(v); },
682
- '^content.title.text$': function(obj, o, v) {
683
- // Remove title if content is null
684
- if(!v) { return removeTitle(); }
685
-
686
- // If title isn't already created, create it now and update
687
- if(!elements.title && v) { createTitle(); }
688
- updateTitle(v);
689
- },
690
- '^content.title.button$': function(obj, o, v){ updateButton(v); },
691
-
692
- // Position checks
693
- '^position.(my|at)$': function(obj, o, v){
694
- // Parse new corner value into Corner objecct
695
- if('string' === typeof v) {
696
- obj[o] = new PLUGINS.Corner(v);
697
- }
698
- },
699
- '^position.container$': function(obj, o, v){
700
- if(self.rendered) { tooltip.appendTo(v); }
701
- },
702
-
703
- // Show checks
704
- '^show.ready$': function() {
705
- if(!self.rendered) { self.render(1); }
706
- else { self.toggle(TRUE); }
707
- },
708
-
709
- // Style checks
710
- '^style.classes$': function(obj, o, v) {
711
- tooltip.attr('class', uitooltip + ' qtip ' + v);
712
- },
713
- '^style.widget|content.title': setWidget,
714
-
715
- // Events check
716
- '^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) {
717
- tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v);
718
- },
719
-
720
- // Properties which require event reassignment
721
- '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() {
722
- var posOptions = options.position;
723
-
724
- // Set tracking flag
725
- tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse);
726
-
727
- // Reassign events
728
- unassignEvents(); assignEvents();
729
- }
730
- };
731
-
732
- /*
733
- * Public API methods
734
- */
735
- $.extend(self, {
736
- render: function(show)
737
- {
738
- if(self.rendered) { return self; } // If tooltip has already been rendered, exit
739
-
740
- var text = options.content.text,
741
- title = options.content.title.text,
742
- posOptions = options.position;
743
-
744
- // Add ARIA attributes to target
745
- $.attr(target[0], 'aria-describedby', tooltipID);
746
-
747
- // Create tooltip element
748
- tooltip = elements.tooltip = $('<div/>', {
749
- 'id': tooltipID,
750
- 'class': uitooltip + ' qtip ' + defaultClass + ' ' + options.style.classes + ' '+ uitooltip + '-pos-' + options.position.my.abbrev(),
751
- 'width': options.style.width || '',
752
- 'height': options.style.height || '',
753
- 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse,
754
-
755
- /* ARIA specific attributes */
756
- 'role': 'alert',
757
- 'aria-live': 'polite',
758
- 'aria-atomic': FALSE,
759
- 'aria-describedby': tooltipID + '-content',
760
- 'aria-hidden': TRUE
761
- })
762
- .toggleClass(disabled, cache.disabled)
763
- .data('qtip', self)
764
- .appendTo(options.position.container)
765
- .append(
766
- // Create content element
767
- elements.content = $('<div />', {
768
- 'class': uitooltip + '-content',
769
- 'id': tooltipID + '-content',
770
- 'aria-atomic': TRUE
771
- })
772
- );
773
-
774
- // Set rendered flag and prevent redundant redraw/reposition calls for now
775
- self.rendered = -1;
776
- isDrawing = 1; isPositioning = 1;
777
-
778
- // Create title...
779
- if(title) {
780
- createTitle();
781
-
782
- // Update title only if its not a callback (called in toggle if so)
783
- if(!$.isFunction(title)) { updateTitle(title, FALSE); }
784
- }
785
-
786
- // Set proper rendered flag and update content if not a callback function (called in toggle)
787
- if(!$.isFunction(text)) { updateContent(text, FALSE); }
788
- self.rendered = TRUE;
789
-
790
- // Setup widget classes
791
- setWidget();
792
-
793
- // Assign passed event callbacks (before plugins!)
794
- $.each(options.events, function(name, callback) {
795
- if($.isFunction(callback)) {
796
- tooltip.bind(name === 'toggle' ? 'tooltipshow tooltiphide' : 'tooltip'+name, callback);
797
- }
798
- });
799
-
800
- // Initialize 'render' plugins
801
- $.each(PLUGINS, function() {
802
- if(this.initialize === 'render') { this(self); }
803
- });
804
-
805
- // Assign events
806
- assignEvents();
807
-
808
- /* Queue this part of the render process in our fx queue so we can
809
- * load images before the tooltip renders fully.
810
- *
811
- * See: updateContent method
812
- */
813
- tooltip.queue('fx', function(next) {
814
- // tooltiprender event
815
- triggerEvent('render');
816
-
817
- // Reset flags
818
- isDrawing = 0; isPositioning = 0;
819
-
820
- // Redraw the tooltip manually now we're fully rendered
821
- self.redraw();
822
-
823
- // Show tooltip if needed
824
- if(options.show.ready || show) {
825
- self.toggle(TRUE, cache.event, FALSE);
826
- }
827
-
828
- next(); // Move on to next method in queue
829
- });
830
-
831
- return self;
832
- },
833
-
834
- get: function(notation)
835
- {
836
- var result, o;
837
-
838
- switch(notation.toLowerCase())
839
- {
840
- case 'dimensions':
841
- result = {
842
- height: tooltip.outerHeight(), width: tooltip.outerWidth()
843
- };
844
- break;
845
-
846
- case 'offset':
847
- result = PLUGINS.offset(tooltip, options.position.container);
848
- break;
849
-
850
- default:
851
- o = convertNotation(notation.toLowerCase());
852
- result = o[0][ o[1] ];
853
- result = result.precedance ? result.string() : result;
854
- break;
855
- }
856
-
857
- return result;
858
- },
859
-
860
- set: function(option, value)
861
- {
862
- var rmove = /^position\.(my|at|adjust|target|container)|style|content|show\.ready/i,
863
- rdraw = /^content\.(title|attr)|style/i,
864
- reposition = FALSE,
865
- redraw = FALSE,
866
- checks = self.checks,
867
- name;
868
-
869
- function callback(notation, args) {
870
- var category, rule, match;
871
-
872
- for(category in checks) {
873
- for(rule in checks[category]) {
874
- if(match = (new RegExp(rule, 'i')).exec(notation)) {
875
- args.push(match);
876
- checks[category][rule].apply(self, args);
877
- }
878
- }
879
- }
880
- }
881
-
882
- // Convert singular option/value pair into object form
883
- if('string' === typeof option) {
884
- name = option; option = {}; option[name] = value;
885
- }
886
- else { option = $.extend(TRUE, {}, option); }
887
-
888
- // Set all of the defined options to their new values
889
- $.each(option, function(notation, value) {
890
- var obj = convertNotation( notation.toLowerCase() ), previous;
891
-
892
- // Set new obj value
893
- previous = obj[0][ obj[1] ];
894
- obj[0][ obj[1] ] = 'object' === typeof value && value.nodeType ? $(value) : value;
895
-
896
- // Set the new params for the callback
897
- option[notation] = [obj[0], obj[1], value, previous];
898
-
899
- // Also check if we need to reposition / redraw
900
- reposition = rmove.test(notation) || reposition;
901
- redraw = rdraw.test(notation) || redraw;
902
- });
903
-
904
- // Re-sanitize options
905
- sanitizeOptions(options);
906
-
907
- /*
908
- * Execute any valid callbacks for the set options
909
- * Also set isPositioning/isDrawing so we don't get loads of redundant repositioning
910
- * and redraw calls.
911
- */
912
- isPositioning = isDrawing = 1; $.each(option, callback); isPositioning = isDrawing = 0;
913
-
914
- // Update position / redraw if needed
915
- if(self.rendered && tooltip[0].offsetWidth > 0) {
916
- if(reposition) {
917
- self.reposition( options.position.target === 'mouse' ? NULL : cache.event );
918
- }
919
- if(redraw) { self.redraw(); }
920
- }
921
-
922
- return self;
923
- },
924
-
925
- toggle: function(state, event)
926
- {
927
- // Render the tooltip if showing and it isn't already
928
- if(!self.rendered) { return state ? self.render(1) : self; }
929
-
930
- var type = state ? 'show' : 'hide',
931
- opts = options[type],
932
- otherOpts = options[ !state ? 'show' : 'hide' ],
933
- posOptions = options.position,
934
- contentOptions = options.content,
935
- visible = tooltip[0].offsetWidth > 0,
936
- animate = state || opts.target.length === 1,
937
- sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target,
938
- showEvent, delay;
939
-
940
- // Detect state if valid one isn't provided
941
- if((typeof state).search('boolean|number')) { state = !visible; }
942
-
943
- // Return if element is already in correct state
944
- if(!tooltip.is(':animated') && visible === state && sameTarget) { return self; }
945
-
946
- // Try to prevent flickering when tooltip overlaps show element
947
- if(event) {
948
- if((/over|enter/).test(event.type) && (/out|leave/).test(cache.event.type) &&
949
- options.show.target.add(event.target).length === options.show.target.length &&
950
- tooltip.has(event.relatedTarget).length) {
951
- return self;
952
- }
953
-
954
- // Cache event
955
- cache.event = $.extend({}, event);
956
- }
957
-
958
- // tooltipshow/tooltiphide events
959
- if(!triggerEvent(type, [90])) { return self; }
960
-
961
- // Set ARIA hidden status attribute
962
- $.attr(tooltip[0], 'aria-hidden', !!!state);
963
-
964
- // Execute state specific properties
965
- if(state) {
966
- // Store show origin coordinates
967
- cache.origin = $.extend({}, MOUSE);
968
-
969
- // Focus the tooltip
970
- self.focus(event);
971
-
972
- // Update tooltip content & title if it's a dynamic function
973
- if($.isFunction(contentOptions.text)) { updateContent(contentOptions.text, FALSE); }
974
- if($.isFunction(contentOptions.title.text)) { updateTitle(contentOptions.title.text, FALSE); }
975
-
976
- // Cache mousemove events for positioning purposes (if not already tracking)
977
- if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) {
978
- $(document).bind('mousemove.qtip', function(event) {
979
- MOUSE = { pageX: event.pageX, pageY: event.pageY, type: 'mousemove' };
980
- });
981
- trackingBound = TRUE;
982
- }
983
-
984
- // Update the tooltip position
985
- self.reposition(event, arguments[2]);
986
-
987
- // Hide other tooltips if tooltip is solo
988
- if(!!opts.solo) {
989
- $(selector, opts.solo).not(tooltip).qtip('hide', $.Event('tooltipsolo'));
990
- }
991
- }
992
- else {
993
- // Clear show timer if we're hiding
994
- clearTimeout(self.timers.show);
995
-
996
- // Remove cached origin on hide
997
- delete cache.origin;
998
-
999
- // Remove mouse tracking event if not needed (all tracking qTips are hidden)
1000
- if(trackingBound && !$(selector+'[tracking="true"]:visible', opts.solo).not(tooltip).length) {
1001
- $(document).unbind('mousemove.qtip');
1002
- trackingBound = FALSE;
1003
- }
1004
-
1005
- // Blur the tooltip
1006
- self.blur(event);
1007
- }
1008
-
1009
- // Define post-animation, state specific properties
1010
- function after() {
1011
- if(state) {
1012
- // Prevent antialias from disappearing in IE by removing filter
1013
- if($.browser.msie) { tooltip[0].style.removeAttribute('filter'); }
1014
-
1015
- // Remove overflow setting to prevent tip bugs
1016
- tooltip.css('overflow', '');
1017
-
1018
- // Autofocus elements if enabled
1019
- if('string' === typeof opts.autofocus) {
1020
- $(opts.autofocus, tooltip).focus();
1021
- }
1022
-
1023
- // If set, hide tooltip when inactive for delay period
1024
- opts.target.trigger('qtip-'+id+'-inactive');
1025
- }
1026
- else {
1027
- // Reset CSS states
1028
- tooltip.css({
1029
- display: '',
1030
- visibility: '',
1031
- opacity: '',
1032
- left: '',
1033
- top: ''
1034
- });
1035
- }
1036
-
1037
- // tooltipvisible/tooltiphidden events
1038
- triggerEvent(state ? 'visible' : 'hidden');
1039
- }
1040
-
1041
- // If no effect type is supplied, use a simple toggle
1042
- if(opts.effect === FALSE || animate === FALSE) {
1043
- tooltip[ type ]();
1044
- after.call(tooltip);
1045
- }
1046
-
1047
- // Use custom function if provided
1048
- else if($.isFunction(opts.effect)) {
1049
- tooltip.stop(1, 1);
1050
- opts.effect.call(tooltip, self);
1051
- tooltip.queue('fx', function(n){ after(); n(); });
1052
- }
1053
-
1054
- // Use basic fade function by default
1055
- else { tooltip.fadeTo(90, state ? 1 : 0, after); }
1056
-
1057
- // If inactive hide method is set, active it
1058
- if(state) { opts.target.trigger('qtip-'+id+'-inactive'); }
1059
-
1060
- return self;
1061
- },
1062
-
1063
- show: function(event){ return self.toggle(TRUE, event); },
1064
-
1065
- hide: function(event){ return self.toggle(FALSE, event); },
1066
-
1067
- focus: function(event)
1068
- {
1069
- if(!self.rendered) { return self; }
1070
-
1071
- var qtips = $(selector),
1072
- curIndex = parseInt(tooltip[0].style.zIndex, 10),
1073
- newIndex = QTIP.zindex + qtips.length,
1074
- cachedEvent = $.extend({}, event),
1075
- focusedElem;
1076
-
1077
- // Only update the z-index if it has changed and tooltip is not already focused
1078
- if(!tooltip.hasClass(focusClass))
1079
- {
1080
- // tooltipfocus event
1081
- if(triggerEvent('focus', [newIndex], cachedEvent)) {
1082
- // Only update z-index's if they've changed
1083
- if(curIndex !== newIndex) {
1084
- // Reduce our z-index's and keep them properly ordered
1085
- qtips.each(function() {
1086
- if(this.style.zIndex > curIndex) {
1087
- this.style.zIndex = this.style.zIndex - 1;
1088
- }
1089
- });
1090
-
1091
- // Fire blur event for focused tooltip
1092
- qtips.filter('.' + focusClass).qtip('blur', cachedEvent);
1093
- }
1094
-
1095
- // Set the new z-index
1096
- tooltip.addClass(focusClass)[0].style.zIndex = newIndex;
1097
- }
1098
- }
1099
-
1100
- return self;
1101
- },
1102
-
1103
- blur: function(event) {
1104
- // Set focused status to FALSE
1105
- tooltip.removeClass(focusClass);
1106
-
1107
- // tooltipblur event
1108
- triggerEvent('blur', [tooltip.css('zIndex')], event);
1109
-
1110
- return self;
1111
- },
1112
-
1113
- reposition: function(event, effect)
1114
- {
1115
- if(!self.rendered || isPositioning) { return self; }
1116
-
1117
- // Set positioning flag
1118
- isPositioning = 1;
1119
-
1120
- var target = options.position.target,
1121
- posOptions = options.position,
1122
- my = posOptions.my,
1123
- at = posOptions.at,
1124
- adjust = posOptions.adjust,
1125
- method = adjust.method.split(' '),
1126
- elemWidth = tooltip.outerWidth(),
1127
- elemHeight = tooltip.outerHeight(),
1128
- targetWidth = 0,
1129
- targetHeight = 0,
1130
- fixed = tooltip.css('position') === 'fixed',
1131
- viewport = posOptions.viewport,
1132
- position = { left: 0, top: 0 },
1133
- container = posOptions.container,
1134
- visible = tooltip[0].offsetWidth > 0,
1135
- adjusted, offset, win;
1136
-
1137
- // Check if absolute position was passed
1138
- if($.isArray(target) && target.length === 2) {
1139
- // Force left top and set position
1140
- at = { x: LEFT, y: TOP };
1141
- position = { left: target[0], top: target[1] };
1142
- }
1143
-
1144
- // Check if mouse was the target
1145
- else if(target === 'mouse' && ((event && event.pageX) || cache.event.pageX)) {
1146
- // Force left top to allow flipping
1147
- at = { x: LEFT, y: TOP };
1148
-
1149
- // Use cached event if one isn't available for positioning
1150
- event = (event && (event.type === 'resize' || event.type === 'scroll') ? cache.event :
1151
- event && event.pageX && event.type === 'mousemove' ? event :
1152
- MOUSE && MOUSE.pageX && (adjust.mouse || !event || !event.pageX) ? { pageX: MOUSE.pageX, pageY: MOUSE.pageY } :
1153
- !adjust.mouse && cache.origin && cache.origin.pageX && options.show.distance ? cache.origin :
1154
- event) || event || cache.event || MOUSE || {};
1155
-
1156
- // Use event coordinates for position
1157
- position = { top: event.pageY, left: event.pageX };
1158
- }
1159
-
1160
- // Target wasn't mouse or absolute...
1161
- else {
1162
- // Check if event targetting is being used
1163
- if(target === 'event' && event && event.target && event.type !== 'scroll' && event.type !== 'resize') {
1164
- cache.target = $(event.target);
1165
- }
1166
- else if(target !== 'event'){
1167
- cache.target = $(target.jquery ? target : elements.target);
1168
- }
1169
- target = cache.target;
1170
-
1171
- // Parse the target into a jQuery object and make sure there's an element present
1172
- target = $(target).eq(0);
1173
- if(target.length === 0) { return self; }
1174
-
1175
- // Check if window or document is the target
1176
- else if(target[0] === document || target[0] === window) {
1177
- targetWidth = PLUGINS.iOS ? window.innerWidth : target.width();
1178
- targetHeight = PLUGINS.iOS ? window.innerHeight : target.height();
1179
-
1180
- if(target[0] === window) {
1181
- position = {
1182
- top: (viewport || target).scrollTop(),
1183
- left: (viewport || target).scrollLeft()
1184
- };
1185
- }
1186
- }
1187
-
1188
- // Use Imagemap/SVG plugins if needed
1189
- else if(PLUGINS.imagemap && target.is('area')) {
1190
- adjusted = PLUGINS.imagemap(self, target, at, PLUGINS.viewport ? method : FALSE);
1191
- }
1192
- else if(PLUGINS.svg && typeof target[0].xmlbase === 'string') {
1193
- adjusted = PLUGINS.svg(self, target, at, PLUGINS.viewport ? method : FALSE);
1194
- }
1195
-
1196
- else {
1197
- targetWidth = target.outerWidth();
1198
- targetHeight = target.outerHeight();
1199
-
1200
- position = PLUGINS.offset(target, container);
1201
- }
1202
-
1203
- // Parse returned plugin values into proper variables
1204
- if(adjusted) {
1205
- targetWidth = adjusted.width;
1206
- targetHeight = adjusted.height;
1207
- offset = adjusted.offset;
1208
- position = adjusted.position;
1209
- }
1210
-
1211
- // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2)
1212
- if((PLUGINS.iOS > 3.1 && PLUGINS.iOS < 4.1) ||
1213
- (PLUGINS.iOS >= 4.3 && PLUGINS.iOS < 4.33) ||
1214
- (!PLUGINS.iOS && fixed)
1215
- ){
1216
- win = $(window);
1217
- position.left -= win.scrollLeft();
1218
- position.top -= win.scrollTop();
1219
- }
1220
-
1221
- // Adjust position relative to target
1222
- position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0;
1223
- position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0;
1224
- }
1225
-
1226
- // Adjust position relative to tooltip
1227
- position.left += adjust.x + (my.x === RIGHT ? -elemWidth : my.x === CENTER ? -elemWidth / 2 : 0);
1228
- position.top += adjust.y + (my.y === BOTTOM ? -elemHeight : my.y === CENTER ? -elemHeight / 2 : 0);
1229
-
1230
- // Use viewport adjustment plugin if enabled
1231
- if(PLUGINS.viewport) {
1232
- position.adjusted = PLUGINS.viewport(
1233
- self, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight
1234
- );
1235
-
1236
- // Apply offsets supplied by positioning plugin (if used)
1237
- if(offset && position.adjusted.left) { position.left += offset.left; }
1238
- if(offset && position.adjusted.top) { position.top += offset.top; }
1239
- }
1240
-
1241
- // Viewport adjustment is disabled, set values to zero
1242
- else { position.adjusted = { left: 0, top: 0 }; }
1243
-
1244
- // tooltipmove event
1245
- if(!triggerEvent('move', [position, viewport.elem || viewport], event)) { return self; }
1246
- delete position.adjusted;
1247
-
1248
- // If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly
1249
- if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) {
1250
- tooltip.css(position);
1251
- }
1252
-
1253
- // Use custom function if provided
1254
- else if($.isFunction(posOptions.effect)) {
1255
- posOptions.effect.call(tooltip, self, $.extend({}, position));
1256
- tooltip.queue(function(next) {
1257
- // Reset attributes to avoid cross-browser rendering bugs
1258
- $(this).css({ opacity: '', height: '' });
1259
- if($.browser.msie) { this.style.removeAttribute('filter'); }
1260
-
1261
- next();
1262
- });
1263
- }
1264
-
1265
- // Set positioning flag
1266
- isPositioning = 0;
1267
-
1268
- return self;
1269
- },
1270
-
1271
- // Max/min width simulator function for all browsers.. yeaaah!
1272
- redraw: function()
1273
- {
1274
- if(self.rendered < 1 || isDrawing) { return self; }
1275
-
1276
- var style = options.style,
1277
- container = options.position.container,
1278
- perc, width, max, min;
1279
-
1280
- // Set drawing flag
1281
- isDrawing = 1;
1282
-
1283
- // tooltipredraw event
1284
- triggerEvent('redraw');
1285
-
1286
- // If tooltip has a set height/width, just set it... like a boss!
1287
- if(style.height) { tooltip.css(HEIGHT, style.height); }
1288
- if(style.width) { tooltip.css(WIDTH, style.width); }
1289
-
1290
- // Simulate max/min width if not set width present...
1291
- else {
1292
- // Reset width and add fluid class
1293
- tooltip.css(WIDTH, '').appendTo(redrawContainer);
1294
-
1295
- // Grab our tooltip width (add 1 if odd so we don't get wrapping problems.. huzzah!)
1296
- width = tooltip.width();
1297
- if(width % 2 < 1) { width += 1; }
1298
-
1299
- // Grab our max/min properties
1300
- max = tooltip.css('max-width') || '';
1301
- min = tooltip.css('min-width') || '';
1302
-
1303
- // Parse into proper pixel values
1304
- perc = (max + min).indexOf('%') > -1 ? container.width() / 100 : 0;
1305
- max = ((max.indexOf('%') > -1 ? perc : 1) * parseInt(max, 10)) || width;
1306
- min = ((min.indexOf('%') > -1 ? perc : 1) * parseInt(min, 10)) || 0;
1307
-
1308
- // Determine new dimension size based on max/min/current values
1309
- width = max + min ? Math.min(Math.max(width, min), max) : width;
1310
-
1311
- // Set the newly calculated width and remvoe fluid class
1312
- tooltip.css(WIDTH, Math.round(width)).appendTo(container);
1313
- }
1314
-
1315
- // tooltipredrawn event
1316
- triggerEvent('redrawn');
1317
-
1318
- // Set drawing flag
1319
- isDrawing = 0;
1320
-
1321
- return self;
1322
- },
1323
-
1324
- disable: function(state)
1325
- {
1326
- if('boolean' !== typeof state) {
1327
- state = !(tooltip.hasClass(disabled) || cache.disabled);
1328
- }
1329
-
1330
- if(self.rendered) {
1331
- tooltip.toggleClass(disabled, state);
1332
- $.attr(tooltip[0], 'aria-disabled', state);
1333
- }
1334
- else {
1335
- cache.disabled = !!state;
1336
- }
1337
-
1338
- return self;
1339
- },
1340
-
1341
- enable: function() { return self.disable(FALSE); },
1342
-
1343
- destroy: function()
1344
- {
1345
- var t = target[0],
1346
- title = $.attr(t, oldtitle),
1347
- elemAPI = target.data('qtip');
1348
-
1349
- // Set flag the signify destroy is taking place to plugins
1350
- self.destroyed = TRUE;
1351
-
1352
- // Destroy tooltip and any associated plugins if rendered
1353
- if(self.rendered) {
1354
- tooltip.stop(1,0).remove();
1355
-
1356
- $.each(self.plugins, function() {
1357
- if(this.destroy) { this.destroy(); }
1358
- });
1359
- }
1360
-
1361
- // Clear timers and remove bound events
1362
- clearTimeout(self.timers.show);
1363
- clearTimeout(self.timers.hide);
1364
- unassignEvents();
1365
-
1366
- // If the API if actually this qTip API...
1367
- if(!elemAPI || self === elemAPI) {
1368
- // Remove api object
1369
- $.removeData(t, 'qtip');
1370
-
1371
- // Reset old title attribute if removed
1372
- if(options.suppress && title) {
1373
- $.attr(t, 'title', title);
1374
- target.removeAttr(oldtitle);
1375
- }
1376
-
1377
- // Remove ARIA attributes
1378
- target.removeAttr('aria-describedby');
1379
- }
1380
-
1381
- // Remove qTip events associated with this API
1382
- target.unbind('.qtip-'+id);
1383
-
1384
- // Remove ID from sued id object
1385
- delete usedIDs[self.id];
1386
-
1387
- return target;
1388
- }
1389
- });
1390
- }
1391
-
1392
- // Initialization method
1393
- function init(id, opts)
1394
- {
1395
- var obj, posOptions, attr, config, title,
1396
-
1397
- // Setup element references
1398
- elem = $(this),
1399
- docBody = $(document.body),
1400
-
1401
- // Use document body instead of document element if needed
1402
- newTarget = this === document ? docBody : elem,
1403
-
1404
- // Grab metadata from element if plugin is present
1405
- metadata = (elem.metadata) ? elem.metadata(opts.metadata) : NULL,
1406
-
1407
- // If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise
1408
- metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL,
1409
-
1410
- // Grab data from metadata.name (or data-qtipopts as fallback) using .data() method,
1411
- html5 = elem.data(opts.metadata.name || 'qtipopts');
1412
-
1413
- // If we don't get an object returned attempt to parse it manualyl without parseJSON
1414
- try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; } catch(e) {}
1415
-
1416
- // Merge in and sanitize metadata
1417
- config = $.extend(TRUE, {}, QTIP.defaults, opts,
1418
- typeof html5 === 'object' ? sanitizeOptions(html5) : NULL,
1419
- sanitizeOptions(metadata5 || metadata));
1420
-
1421
- // Re-grab our positioning options now we've merged our metadata and set id to passed value
1422
- posOptions = config.position;
1423
- config.id = id;
1424
-
1425
- // Setup missing content if none is detected
1426
- if('boolean' === typeof config.content.text) {
1427
- attr = elem.attr(config.content.attr);
1428
-
1429
- // Grab from supplied attribute if available
1430
- if(config.content.attr !== FALSE && attr) { config.content.text = attr; }
1431
-
1432
- // No valid content was found, abort render
1433
- else { return FALSE; }
1434
- }
1435
-
1436
- // Setup target options
1437
- if(!posOptions.container.length) { posOptions.container = docBody; }
1438
- if(posOptions.target === FALSE) { posOptions.target = newTarget; }
1439
- if(config.show.target === FALSE) { config.show.target = newTarget; }
1440
- if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); }
1441
- if(config.hide.target === FALSE) { config.hide.target = newTarget; }
1442
- if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; }
1443
-
1444
- // Ensure we only use a single container
1445
- posOptions.container = posOptions.container.eq(0);
1446
-
1447
- // Convert position corner values into x and y strings
1448
- posOptions.at = new PLUGINS.Corner(posOptions.at);
1449
- posOptions.my = new PLUGINS.Corner(posOptions.my);
1450
-
1451
- // Destroy previous tooltip if overwrite is enabled, or skip element if not
1452
- if($.data(this, 'qtip')) {
1453
- if(config.overwrite) {
1454
- elem.qtip('destroy');
1455
- }
1456
- else if(config.overwrite === FALSE) {
1457
- return FALSE;
1458
- }
1459
- }
1460
-
1461
- // Remove title attribute and store it if present
1462
- if(config.suppress && (title = $.attr(this, 'title'))) {
1463
- // Final attr call fixes event delegatiom and IE default tooltip showing problem
1464
- $(this).removeAttr('title').attr(oldtitle, title).attr('title', '');
1465
- }
1466
-
1467
- // Initialize the tooltip and add API reference
1468
- obj = new QTip(elem, config, id, !!attr);
1469
- $.data(this, 'qtip', obj);
1470
-
1471
- // Catch remove/removeqtip events on target element to destroy redundant tooltip
1472
- elem.bind('remove.qtip-'+id+' removeqtip.qtip-'+id, function(){ obj.destroy(); });
1473
-
1474
- return obj;
1475
- }
1476
-
1477
- // jQuery $.fn extension method
1478
- QTIP = $.fn.qtip = function(options, notation, newValue)
1479
- {
1480
- var command = ('' + options).toLowerCase(), // Parse command
1481
- returned = NULL,
1482
- args = $.makeArray(arguments).slice(1),
1483
- event = args[args.length - 1],
1484
- opts = this[0] ? $.data(this[0], 'qtip') : NULL;
1485
-
1486
- // Check for API request
1487
- if((!arguments.length && opts) || command === 'api') {
1488
- return opts;
1489
- }
1490
-
1491
- // Execute API command if present
1492
- else if('string' === typeof options)
1493
- {
1494
- this.each(function()
1495
- {
1496
- var api = $.data(this, 'qtip');
1497
- if(!api) { return TRUE; }
1498
-
1499
- // Cache the event if possible
1500
- if(event && event.timeStamp) { api.cache.event = event; }
1501
-
1502
- // Check for specific API commands
1503
- if((command === 'option' || command === 'options') && notation) {
1504
- if($.isPlainObject(notation) || newValue !== undefined) {
1505
- api.set(notation, newValue);
1506
- }
1507
- else {
1508
- returned = api.get(notation);
1509
- return FALSE;
1510
- }
1511
- }
1512
-
1513
- // Execute API command
1514
- else if(api[command]) {
1515
- api[command].apply(api[command], args);
1516
- }
1517
- });
1518
-
1519
- return returned !== NULL ? returned : this;
1520
- }
1521
-
1522
- // No API commands. validate provided options and setup qTips
1523
- else if('object' === typeof options || !arguments.length)
1524
- {
1525
- opts = sanitizeOptions($.extend(TRUE, {}, options));
1526
-
1527
- // Bind the qTips
1528
- return QTIP.bind.call(this, opts, event);
1529
- }
1530
- };
1531
-
1532
- // $.fn.qtip Bind method
1533
- QTIP.bind = function(opts, event)
1534
- {
1535
- return this.each(function(i) {
1536
- var options, targets, events, namespace, api, id;
1537
-
1538
- // Find next available ID, or use custom ID if provided
1539
- id = $.isArray(opts.id) ? opts.id[i] : opts.id;
1540
- id = !id || id === FALSE || id.length < 1 || usedIDs[id] ? QTIP.nextid++ : (usedIDs[id] = id);
1541
-
1542
- // Setup events namespace
1543
- namespace = '.qtip-'+id+'-create';
1544
-
1545
- // Initialize the qTip and re-grab newly sanitized options
1546
- api = init.call(this, id, opts);
1547
- if(api === FALSE) { return TRUE; }
1548
- options = api.options;
1549
-
1550
- // Initialize plugins
1551
- $.each(PLUGINS, function() {
1552
- if(this.initialize === 'initialize') { this(api); }
1553
- });
1554
-
1555
- // Determine hide and show targets
1556
- targets = { show: options.show.target, hide: options.hide.target };
1557
- events = {
1558
- show: $.trim('' + options.show.event).replace(/ /g, namespace+' ') + namespace,
1559
- hide: $.trim('' + options.hide.event).replace(/ /g, namespace+' ') + namespace
1560
- };
1561
-
1562
- /*
1563
- * Make sure hoverIntent functions properly by using mouseleave as a hide event if
1564
- * mouseenter/mouseout is used for show.event, even if it isn't in the users options.
1565
- */
1566
- if(/mouse(over|enter)/i.test(events.show) && !/mouse(out|leave)/i.test(events.hide)) {
1567
- events.hide += ' mouseleave' + namespace;
1568
- }
1569
-
1570
- /*
1571
- * Also make sure initial mouse targetting works correctly by caching mousemove coords
1572
- * on show targets before the tooltip has rendered.
1573
- *
1574
- * Also set onTarget when triggered to keep mouse tracking working
1575
- */
1576
- targets.show.bind('mousemove'+namespace, function(event) {
1577
- MOUSE = { pageX: event.pageX, pageY: event.pageY, type: 'mousemove' };
1578
- api.cache.onTarget = TRUE;
1579
- });
1580
-
1581
- // Define hoverIntent function
1582
- function hoverIntent(event) {
1583
- function render() {
1584
- // Cache mouse coords,render and render the tooltip
1585
- api.render(typeof event === 'object' || options.show.ready);
1586
-
1587
- // Unbind show and hide events
1588
- targets.show.add(targets.hide).unbind(namespace);
1589
- }
1590
-
1591
- // Only continue if tooltip isn't disabled
1592
- if(api.cache.disabled) { return FALSE; }
1593
-
1594
- // Cache the event data
1595
- api.cache.event = $.extend({}, event);
1596
- api.cache.target = event ? $(event.target) : [undefined];
1597
-
1598
- // Start the event sequence
1599
- if(options.show.delay > 0) {
1600
- clearTimeout(api.timers.show);
1601
- api.timers.show = setTimeout(render, options.show.delay);
1602
- if(events.show !== events.hide) {
1603
- targets.hide.bind(events.hide, function() { clearTimeout(api.timers.show); });
1604
- }
1605
- }
1606
- else { render(); }
1607
- }
1608
-
1609
- // Bind show events to target
1610
- targets.show.bind(events.show, hoverIntent);
1611
-
1612
- // Prerendering is enabled, create tooltip now
1613
- if(options.show.ready || options.prerender) { hoverIntent(event); }
1614
- });
1615
- };
1616
-
1617
- // Setup base plugins
1618
- PLUGINS = QTIP.plugins = {
1619
- // Corner object parser
1620
- Corner: function(corner) {
1621
- corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase();
1622
- this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase();
1623
- this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase();
1624
-
1625
- var f = corner.charAt(0); this.precedance = (f === 't' || f === 'b' ? Y : X);
1626
-
1627
- this.string = function() { return this.precedance === Y ? this.y+this.x : this.x+this.y; };
1628
- this.abbrev = function() {
1629
- var x = this.x.substr(0,1), y = this.y.substr(0,1);
1630
- return x === y ? x : this.precedance === Y ? y + x : x + y;
1631
- };
1632
-
1633
- this.invertx = function(center) { this.x = this.x === LEFT ? RIGHT : this.x === RIGHT ? LEFT : center || this.x; };
1634
- this.inverty = function(center) { this.y = this.y === TOP ? BOTTOM : this.y === BOTTOM ? TOP : center || this.y; };
1635
-
1636
- this.clone = function() {
1637
- return {
1638
- x: this.x, y: this.y, precedance: this.precedance,
1639
- string: this.string, abbrev: this.abbrev, clone: this.clone,
1640
- invertx: this.invertx, inverty: this.inverty
1641
- };
1642
- };
1643
- },
1644
-
1645
- // Custom (more correct for qTip!) offset calculator
1646
- offset: function(elem, container) {
1647
- var pos = elem.offset(),
1648
- docBody = elem.closest('body')[0],
1649
- parent = container, scrolled,
1650
- coffset, overflow;
1651
-
1652
- function scroll(e, i) {
1653
- pos.left += i * e.scrollLeft();
1654
- pos.top += i * e.scrollTop();
1655
- }
1656
-
1657
- if(parent) {
1658
- // Compensate for non-static containers offset
1659
- do {
1660
- if(parent.css('position') !== 'static') {
1661
- coffset = parent.position();
1662
-
1663
- // Account for element positioning, borders and margins
1664
- pos.left -= coffset.left + (parseInt(parent.css('borderLeftWidth'), 10) || 0) + (parseInt(parent.css('marginLeft'), 10) || 0);
1665
- pos.top -= coffset.top + (parseInt(parent.css('borderTopWidth'), 10) || 0) + (parseInt(parent.css('marginTop'), 10) || 0);
1666
-
1667
- // If this is the first parent element with an overflow of "scroll" or "auto", store it
1668
- if(!scrolled && (overflow = parent.css('overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = parent; }
1669
- }
1670
- }
1671
- while((parent = $(parent[0].offsetParent)).length);
1672
-
1673
- // Compensate for containers scroll if it also has an offsetParent
1674
- if(scrolled && scrolled[0] !== docBody) { scroll( scrolled, 1 ); }
1675
- }
1676
-
1677
- return pos;
1678
- },
1679
-
1680
- /*
1681
- * iOS version detection
1682
- */
1683
- iOS: parseFloat(
1684
- ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1])
1685
- .replace('undefined', '3_2').replace('_', '.').replace('_', '')
1686
- ) || FALSE,
1687
-
1688
- /*
1689
- * jQuery-specific $.fn overrides
1690
- */
1691
- fn: {
1692
- /* Allow other plugins to successfully retrieve the title of an element with a qTip applied */
1693
- attr: function(attr, val) {
1694
- if(this.length) {
1695
- var self = this[0],
1696
- title = 'title',
1697
- api = $.data(self, 'qtip');
1698
-
1699
- if(attr === title && api && 'object' === typeof api && api.options.suppress) {
1700
- if(arguments.length < 2) {
1701
- return $.attr(self, oldtitle);
1702
- }
1703
-
1704
- // If qTip is rendered and title was originally used as content, update it
1705
- if(api && api.options.content.attr === title && api.cache.attr) {
1706
- api.set('content.text', val);
1707
- }
1708
-
1709
- // Use the regular attr method to set, then cache the result
1710
- return this.attr(oldtitle, val);
1711
- }
1712
- }
1713
-
1714
- return $.fn['attr'+replaceSuffix].apply(this, arguments);
1715
- },
1716
-
1717
- /* Allow clone to correctly retrieve cached title attributes */
1718
- clone: function(keepData) {
1719
- var titles = $([]), title = 'title',
1720
-
1721
- // Clone our element using the real clone method
1722
- elems = $.fn['clone'+replaceSuffix].apply(this, arguments);
1723
-
1724
- // Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false
1725
- if(!keepData) {
1726
- elems.filter('['+oldtitle+']').attr('title', function() {
1727
- return $.attr(this, oldtitle);
1728
- })
1729
- .removeAttr(oldtitle);
1730
- }
1731
-
1732
- return elems;
1733
- }
1734
- }
1735
- };
1736
-
1737
- // Apply the fn overrides above
1738
- $.each(PLUGINS.fn, function(name, func) {
1739
- if(!func || $.fn[name+replaceSuffix]) { return TRUE; }
1740
-
1741
- var old = $.fn[name+replaceSuffix] = $.fn[name];
1742
- $.fn[name] = function() {
1743
- return func.apply(this, arguments) || old.apply(this, arguments);
1744
- };
1745
- });
1746
-
1747
- /* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar).
1748
- * This snippet is taken directly from jQuery UI source code found here:
1749
- * http://code.jquery.com/ui/jquery-ui-git.js
1750
- */
1751
- if(!$.ui) {
1752
- $['cleanData'+replaceSuffix] = $.cleanData;
1753
- $.cleanData = function( elems ) {
1754
- for(var i = 0, elem; (elem = elems[i]) !== undefined; i++) {
1755
- try { $( elem ).triggerHandler('removeqtip'); }
1756
- catch( e ) {}
1757
- }
1758
- $['cleanData'+replaceSuffix]( elems );
1759
- };
1760
- }
1761
-
1762
- // Set global qTip properties
1763
- QTIP.version = '@VERSION';
1764
- QTIP.nextid = 0;
1765
- QTIP.inactiveEvents = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' ');
1766
- QTIP.zindex = 15000;
1767
-
1768
- // Define configuration defaults
1769
- QTIP.defaults = {
1770
- prerender: FALSE,
1771
- id: FALSE,
1772
- overwrite: TRUE,
1773
- suppress: TRUE,
1774
- content: {
1775
- text: TRUE,
1776
- attr: 'title',
1777
- title: {
1778
- text: FALSE,
1779
- button: FALSE
1780
- }
1781
- },
1782
- position: {
1783
- my: 'top left',
1784
- at: 'bottom right',
1785
- target: FALSE,
1786
- container: FALSE,
1787
- viewport: FALSE,
1788
- adjust: {
1789
- x: 0, y: 0,
1790
- mouse: TRUE,
1791
- resize: TRUE,
1792
- method: 'flip flip'
1793
- },
1794
- effect: function(api, pos, viewport) {
1795
- $(this).animate(pos, {
1796
- duration: 200,
1797
- queue: FALSE
1798
- });
1799
- }
1800
- },
1801
- show: {
1802
- target: FALSE,
1803
- event: 'mouseenter',
1804
- effect: TRUE,
1805
- delay: 90,
1806
- solo: FALSE,
1807
- ready: FALSE,
1808
- autofocus: FALSE
1809
- },
1810
- hide: {
1811
- target: FALSE,
1812
- event: 'mouseleave',
1813
- effect: TRUE,
1814
- delay: 0,
1815
- fixed: FALSE,
1816
- inactive: FALSE,
1817
- leave: 'window',
1818
- distance: FALSE
1819
- },
1820
- style: {
1821
- classes: '',
1822
- widget: FALSE,
1823
- width: FALSE,
1824
- height: FALSE,
1825
- def: TRUE
1826
- },
1827
- events: {
1828
- render: NULL,
1829
- move: NULL,
1830
- show: NULL,
1831
- hide: NULL,
1832
- toggle: NULL,
1833
- visible: NULL,
1834
- hidden: NULL,
1835
- focus: NULL,
1836
- blur: NULL
1837
- }
1838
- };
1839
-
1840
-
1841
- PLUGINS.svg = function(api, svg, corner, adjustMethod)
1842
- {
1843
- var doc = $(document),
1844
- elem = svg[0],
1845
- result = {
1846
- width: 0, height: 0,
1847
- position: { top: 1e10, left: 1e10 }
1848
- },
1849
- box, mtx, root, point, tPoint;
1850
 
1851
- // Ascend the parentNode chain until we find an element with getBBox()
1852
- while(!elem.getBBox) { elem = elem.parentNode; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1853
 
1854
- // Check for a valid bounding box method
1855
- if (elem.getBBox && elem.parentNode) {
1856
- box = elem.getBBox();
1857
- mtx = elem.getScreenCTM();
1858
- root = elem.farthestViewportElement || elem;
1859
 
1860
- // Return if no method is found
1861
- if(!root.createSVGPoint) { return result; }
 
1862
 
1863
- // Create our point var
1864
- point = root.createSVGPoint();
1865
 
1866
- // Adjust top and left
1867
- point.x = box.x;
1868
- point.y = box.y;
1869
- tPoint = point.matrixTransform(mtx);
1870
- result.position.left = tPoint.x;
1871
- result.position.top = tPoint.y;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1872
 
1873
- // Adjust width and height
1874
- point.x += box.width;
1875
- point.y += box.height;
1876
- tPoint = point.matrixTransform(mtx);
1877
- result.width = tPoint.x - result.position.left;
1878
- result.height = tPoint.y - result.position.top;
1879
 
1880
- // Adjust by scroll offset
1881
- result.position.left += doc.scrollLeft();
1882
- result.position.top += doc.scrollTop();
1883
  }
 
1884
 
1885
- return result;
1886
- };
1887
-
1888
 
1889
- function Ajax(api)
1890
- {
1891
- var self = this,
1892
- tooltip = api.elements.tooltip,
1893
- opts = api.options.content.ajax,
1894
- defaults = QTIP.defaults.content.ajax,
1895
- namespace = '.qtip-ajax',
1896
- rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
1897
- first = TRUE,
1898
- stop = FALSE,
1899
- xhr;
1900
-
1901
- api.checks.ajax = {
1902
- '^content.ajax': function(obj, name, v) {
1903
- // If content.ajax object was reset, set our local var
1904
- if(name === 'ajax') { opts = v; }
1905
-
1906
- if(name === 'once') {
1907
- self.init();
1908
- }
1909
- else if(opts && opts.url) {
1910
- self.load();
1911
- }
1912
- else {
1913
- tooltip.unbind(namespace);
1914
- }
1915
  }
1916
- };
1917
 
1918
- $.extend(self, {
1919
- init: function() {
1920
- // Make sure ajax options are enabled and bind event
1921
- if(opts && opts.url) {
1922
- tooltip.unbind(namespace)[ opts.once ? 'one' : 'bind' ]('tooltipshow'+namespace, self.load);
1923
- }
1924
 
1925
- return self;
1926
- },
 
 
1927
 
1928
- load: function(event) {
1929
- if(stop) {stop = FALSE; return; }
1930
 
1931
- var hasSelector = opts.url.lastIndexOf(' '),
1932
- url = opts.url,
1933
- selector,
1934
- hideFirst = !opts.loading && first;
 
 
1935
 
1936
- // If loading option is disabled, prevent the tooltip showing until we've completed the request
1937
- if(hideFirst) { try{ event.preventDefault(); } catch(e) {} }
1938
 
1939
- // Make sure default event hasn't been prevented
1940
- else if(event && event.isDefaultPrevented()) { return self; }
1941
 
1942
- // Cancel old request
1943
- if(xhr && xhr.abort) { xhr.abort(); }
1944
-
1945
- // Check if user delcared a content selector like in .load()
1946
- if(hasSelector > -1) {
1947
- selector = url.substr(hasSelector);
1948
- url = url.substr(0, hasSelector);
1949
- }
1950
 
1951
- // Define common after callback for both success/error handlers
1952
- function after() {
1953
- var complete;
1954
 
1955
- // Don't proceed if tooltip is destroyed
1956
- if(api.destroyed) { return; }
 
1957
 
1958
- // Set first flag to false
1959
- first = FALSE;
 
 
1960
 
1961
- // Re-display tip if loading and first time, and reset first flag
1962
- if(hideFirst) { stop = TRUE; api.show(event.originalEvent); }
 
 
1963
 
1964
- // Call users complete method if it was defined
1965
- if((complete = defaults.complete || opts.complete) && $.isFunction(complete)) {
1966
- complete.apply(opts.context || api, arguments);
1967
- }
1968
  }
 
1969
 
1970
- // Define success handler
1971
- function successHandler(content, status, jqXHR) {
1972
- var success;
1973
-
1974
- // Don't proceed if tooltip is destroyed
1975
- if(api.destroyed) { return; }
1976
-
1977
- // If URL contains a selector
1978
- if(selector && 'string' === typeof content) {
1979
- // Create a dummy div to hold the results and grab the selector element
1980
- content = $('<div/>')
1981
- // inject the contents of the document in, removing the scripts
1982
- // to avoid any 'Permission Denied' errors in IE
1983
- .append(content.replace(rscript, ""))
1984
-
1985
- // Locate the specified elements
1986
- .find(selector);
1987
- }
1988
 
1989
- // Call the success function if one is defined
1990
- if((success = defaults.success || opts.success) && $.isFunction(success)) {
1991
- success.call(opts.context || api, content, status, jqXHR);
1992
- }
1993
 
1994
- // Otherwise set the content
1995
- else { api.set('content.text', content); }
1996
- }
1997
 
1998
- // Error handler
1999
- function errorHandler(xhr, status, error) {
2000
- if(api.destroyed || xhr.status === 0) { return; }
2001
- api.set('content.text', status + ': ' + error);
2002
- }
2003
 
2004
- // Setup $.ajax option object and process the request
2005
- xhr = $.ajax(
2006
- $.extend({
2007
- error: defaults.error || errorHandler,
2008
- context: api
2009
- },
2010
- opts, { url: url, success: successHandler, complete: after })
2011
- );
2012
- },
2013
 
2014
- destroy: function() {
2015
- // Cancel ajax request if possible
2016
- if(xhr && xhr.abort) { xhr.abort(); }
 
 
2017
 
2018
- // Set api.destroyed flag
2019
- api.destroyed = TRUE;
2020
- }
2021
- });
2022
 
2023
- self.init();
 
 
 
2024
  }
2025
 
 
 
 
 
 
 
2026
 
2027
- PLUGINS.ajax = function(api)
2028
- {
2029
- var self = api.plugins.ajax;
2030
-
2031
- return 'object' === typeof self ? self : (api.plugins.ajax = new Ajax(api));
2032
- };
2033
 
2034
- PLUGINS.ajax.initialize = 'render';
2035
 
2036
- // Setup plugin sanitization
2037
- PLUGINS.ajax.sanitize = function(options)
2038
- {
2039
- var content = options.content, opts;
2040
- if(content && 'ajax' in content) {
2041
- opts = content.ajax;
2042
- if(typeof opts !== 'object') { opts = options.content.ajax = { url: opts }; }
2043
- if('boolean' !== typeof opts.once && opts.once) { opts.once = !!opts.once; }
2044
  }
2045
- };
2046
 
2047
- // Extend original api defaults
2048
- $.extend(TRUE, QTIP.defaults, {
2049
- content: {
2050
- ajax: {
2051
- loading: TRUE,
2052
- once: TRUE
2053
- }
2054
- }
2055
- });
2056
 
 
 
 
 
 
 
 
2057
 
2058
- // Tip coordinates calculator
2059
- function calculateTip(corner, width, height)
2060
- {
2061
- var width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2),
2062
-
2063
- // Define tip coordinates in terms of height and width values
2064
- tips = {
2065
- bottomright: [[0,0], [width,height], [width,0]],
2066
- bottomleft: [[0,0], [width,0], [0,height]],
2067
- topright: [[0,height], [width,0], [width,height]],
2068
- topleft: [[0,0], [0,height], [width,height]],
2069
- topcenter: [[0,height], [width2,0], [width,height]],
2070
- bottomcenter: [[0,0], [width,0], [width2,height]],
2071
- rightcenter: [[0,0], [width,height2], [0,height]],
2072
- leftcenter: [[width,0], [width,height], [0,height2]]
2073
- };
2074
 
2075
- // Set common side shapes
2076
- tips.lefttop = tips.bottomright; tips.righttop = tips.bottomleft;
2077
- tips.leftbottom = tips.topright; tips.rightbottom = tips.topleft;
2078
 
2079
- return tips[ corner.string() ];
2080
- }
 
 
 
 
 
 
 
 
 
 
2081
 
 
 
 
2082
 
2083
- function Tip(qTip, command)
2084
- {
2085
- var self = this,
2086
- opts = qTip.options.style.tip,
2087
- elems = qTip.elements,
2088
- tooltip = elems.tooltip,
2089
- cache = { top: 0, left: 0 },
2090
- size = {
2091
- width: opts.width,
2092
- height: opts.height
2093
- },
2094
- color = { },
2095
- border = opts.border || 0,
2096
- namespace = '.qtip-tip',
2097
- hasCanvas = !!($('<canvas />')[0] || {}).getContext,
2098
- tiphtml;
2099
-
2100
- self.corner = NULL;
2101
- self.mimic = NULL;
2102
- self.border = border;
2103
- self.offset = opts.offset;
2104
- self.size = size;
2105
-
2106
- // Add new option checks for the plugin
2107
- qTip.checks.tip = {
2108
- '^position.my|style.tip.(corner|mimic|border)$': function() {
2109
- // Make sure a tip can be drawn
2110
- if(!self.init()) {
2111
- self.destroy();
2112
  }
2113
 
2114
- // Reposition the tooltip
2115
- qTip.reposition();
2116
- },
2117
- '^style.tip.(height|width)$': function() {
2118
- // Re-set dimensions and redraw the tip
2119
- size = {
2120
- width: opts.width,
2121
- height: opts.height
2122
- };
2123
- self.create();
2124
- self.update();
2125
-
2126
- // Reposition the tooltip
2127
- qTip.reposition();
2128
- },
2129
- '^content.title.text|style.(classes|widget)$': function() {
2130
- if(elems.tip && elems.tip.length) {
2131
- self.update();
2132
  }
2133
  }
2134
- };
2135
 
2136
- function whileVisible(callback) {
2137
- var visible = tooltip.is(':visible');
2138
- tooltip.show(); callback(); tooltip.toggle(visible);
2139
  }
2140
 
2141
- function swapDimensions() {
2142
- size.width = opts.height;
2143
- size.height = opts.width;
2144
  }
2145
 
2146
- function resetDimensions() {
2147
- size.width = opts.width;
2148
- size.height = opts.height;
2149
  }
2150
 
2151
- function reposition(event, api, pos, viewport) {
2152
- if(!elems.tip) { return; }
 
2153
 
2154
- var newCorner = self.corner.clone(),
2155
- adjust = pos.adjusted,
2156
- method = qTip.options.position.adjust.method.split(' '),
2157
- horizontal = method[0],
2158
- vertical = method[1] || method[0],
2159
- shift = { left: FALSE, top: FALSE, x: 0, y: 0 },
2160
- offset, css = {}, props;
2161
 
2162
- // If our tip position isn't fixed e.g. doesn't adjust with viewport...
2163
- if(self.corner.fixed !== TRUE) {
2164
- // Horizontal - Shift or flip method
2165
- if(horizontal === SHIFT && newCorner.precedance === X && adjust.left && newCorner.y !== CENTER) {
2166
- newCorner.precedance = newCorner.precedance === X ? Y : X;
2167
- }
2168
- else if(horizontal !== SHIFT && adjust.left){
2169
- newCorner.x = newCorner.x === CENTER ? (adjust.left > 0 ? LEFT : RIGHT) : (newCorner.x === LEFT ? RIGHT : LEFT);
2170
- }
2171
 
2172
- // Vertical - Shift or flip method
2173
- if(vertical === SHIFT && newCorner.precedance === Y && adjust.top && newCorner.x !== CENTER) {
2174
- newCorner.precedance = newCorner.precedance === Y ? X : Y;
 
 
 
 
 
 
 
 
 
 
 
 
 
2175
  }
2176
- else if(vertical !== SHIFT && adjust.top) {
2177
- newCorner.y = newCorner.y === CENTER ? (adjust.top > 0 ? TOP : BOTTOM) : (newCorner.y === TOP ? BOTTOM : TOP);
 
 
 
 
 
 
 
 
 
 
 
2178
  }
 
 
 
 
2179
 
2180
- // Update and redraw the tip if needed (check cached details of last drawn tip)
2181
- if(newCorner.string() !== cache.corner.string() && (cache.top !== adjust.top || cache.left !== adjust.left)) {
2182
- self.update(newCorner, FALSE);
 
 
 
 
 
 
 
 
 
 
 
 
2183
  }
2184
- }
 
 
 
2185
 
2186
- // Setup tip offset properties
2187
- offset = self.position(newCorner, adjust);
2188
- offset[ newCorner.x ] += parseWidth(newCorner, newCorner.x);
2189
- offset[ newCorner.y ] += parseWidth(newCorner, newCorner.y);
2190
 
2191
- // Readjust offset object to make it left/top
2192
- if(offset.right !== undefined) { offset.left = -offset.right; }
2193
- if(offset.bottom !== undefined) { offset.top = -offset.bottom; }
2194
- offset.user = Math.max(0, opts.offset);
 
 
 
 
 
 
 
 
 
2195
 
2196
- // Viewport "shift" specific adjustments
2197
- if(shift.left = (horizontal === SHIFT && !!adjust.left)) {
2198
- if(newCorner.x === CENTER) {
2199
- css['margin-left'] = shift.x = offset['margin-left'] - adjust.left;
2200
- }
2201
- else {
2202
- props = offset.right !== undefined ?
2203
- [ adjust.left, -offset.left ] : [ -adjust.left, offset.left ];
2204
 
2205
- if( (shift.x = Math.max(props[0], props[1])) > props[0] ) {
2206
- pos.left -= adjust.left;
2207
- shift.left = FALSE;
2208
- }
2209
-
2210
- css[ offset.right !== undefined ? RIGHT : LEFT ] = shift.x;
2211
- }
2212
- }
2213
- if(shift.top = (vertical === SHIFT && !!adjust.top)) {
2214
- if(newCorner.y === CENTER) {
2215
- css['margin-top'] = shift.y = offset['margin-top'] - adjust.top;
2216
- }
2217
- else {
2218
- props = offset.bottom !== undefined ?
2219
- [ adjust.top, -offset.top ] : [ -adjust.top, offset.top ];
2220
 
2221
- if( (shift.y = Math.max(props[0], props[1])) > props[0] ) {
2222
- pos.top -= adjust.top;
2223
- shift.top = FALSE;
2224
- }
2225
 
2226
- css[ offset.bottom !== undefined ? BOTTOM : TOP ] = shift.y;
2227
- }
 
2228
  }
 
 
2229
 
2230
- /*
2231
- * If the tip is adjusted in both dimensions, or in a
2232
- * direction that would cause it to be anywhere but the
2233
- * outer border, hide it!
2234
- */
2235
- elems.tip.css(css).toggle(
2236
- !((shift.x && shift.y) || (newCorner.x === CENTER && shift.y) || (newCorner.y === CENTER && shift.x))
2237
- );
2238
 
2239
- // Adjust position to accomodate tip dimensions
2240
- pos.left -= offset.left.charAt ? offset.user : horizontal !== SHIFT || shift.top || !shift.left && !shift.top ? offset.left : 0;
2241
- pos.top -= offset.top.charAt ? offset.user : vertical !== SHIFT || shift.left || !shift.left && !shift.top ? offset.top : 0;
2242
 
2243
- // Cache details
2244
- cache.left = adjust.left; cache.top = adjust.top;
2245
- cache.corner = newCorner.clone();
2246
  }
2247
 
2248
- function parseCorner() {
2249
- var corner = opts.corner,
2250
- posOptions = qTip.options.position,
2251
- at = posOptions.at,
2252
- my = posOptions.my.string ? posOptions.my.string() : posOptions.my;
2253
 
2254
- // Detect corner and mimic properties
2255
- if(corner === FALSE || (my === FALSE && at === FALSE)) {
2256
- return FALSE;
2257
- }
2258
- else {
2259
- if(corner === TRUE) {
2260
- self.corner = new PLUGINS.Corner(my);
2261
- }
2262
- else if(!corner.string) {
2263
- self.corner = new PLUGINS.Corner(corner);
2264
- self.corner.fixed = TRUE;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2265
  }
2266
  }
 
 
 
 
 
2267
 
2268
- // Cache it
2269
- cache.corner = new PLUGINS.Corner( self.corner.string() );
2270
 
2271
- return self.corner.string() !== 'centercenter';
 
 
 
 
 
 
 
2272
  }
 
 
 
 
 
 
 
2273
 
2274
- /* border width calculator */
2275
- function parseWidth(corner, side, use) {
2276
- side = !side ? corner[corner.precedance] : side;
2277
-
2278
- var isTitleTop = elems.titlebar && corner.y === TOP,
2279
- elem = isTitleTop ? elems.titlebar : tooltip,
2280
- borderSide = 'border-' + side + '-width',
2281
- css = function(elem) { return parseInt(elem.css(borderSide), 10); },
2282
- val;
2283
 
2284
- // Grab the border-width value (make tooltip visible first)
2285
- whileVisible(function() {
2286
- val = (use ? css(use) : (css(elems.content) || css(elem) || css(tooltip))) || 0;
2287
- });
2288
- return val;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2289
  }
2290
 
2291
- function parseRadius(corner) {
2292
- var isTitleTop = elems.titlebar && corner.y === TOP,
2293
- elem = isTitleTop ? elems.titlebar : elems.content,
2294
- moz = $.browser.mozilla,
2295
- prefix = moz ? '-moz-' : $.browser.webkit ? '-webkit-' : '',
2296
- nonStandard = 'border-radius-' + corner.y + corner.x,
2297
- standard = 'border-' + corner.y + '-' + corner.x + '-radius',
2298
- css = function(c) { return parseInt(elem.css(c), 10) || parseInt(tooltip.css(c), 10); },
2299
- val;
2300
 
2301
- whileVisible(function() {
2302
- val = css(standard) || css(prefix + standard) || css(prefix + nonStandard) || css(nonStandard) || 0;
 
 
 
 
 
 
 
 
 
 
 
2303
  });
2304
- return val;
2305
  }
2306
 
2307
- function parseColours(actual) {
2308
- var i, fill, border,
2309
- tip = elems.tip.css('cssText', ''),
2310
- corner = actual || self.corner,
2311
- invalid = /rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i,
2312
- borderSide = 'border-' + corner[ corner.precedance ] + '-color',
2313
- bgColor = 'background-color',
2314
- transparent = 'transparent',
2315
- important = ' !important',
2316
 
2317
- titlebar = elems.titlebar,
2318
- useTitle = titlebar && (corner.y === TOP || (corner.y === CENTER && tip.position().top + (size.height / 2) + opts.offset < titlebar.outerHeight(TRUE))),
2319
- colorElem = useTitle ? titlebar : elems.content;
2320
 
2321
- function css(elem, prop, compare) {
2322
- var val = elem.css(prop) || transparent;
2323
- if(compare && val === elem.css(compare)) { return FALSE; }
2324
- else { return invalid.test(val) ? FALSE : val; }
2325
  }
 
 
2326
 
2327
- // Ensure tooltip is visible then...
2328
- whileVisible(function() {
2329
- // Attempt to detect the background colour from various elements, left-to-right precedance
2330
- color.fill = css(tip, bgColor) || css(colorElem, bgColor) || css(elems.content, bgColor) ||
2331
- css(tooltip, bgColor) || tip.css(bgColor);
2332
 
2333
- // Attempt to detect the correct border side colour from various elements, left-to-right precedance
2334
- color.border = css(tip, borderSide, 'color') || css(colorElem, borderSide, 'color') ||
2335
- css(elems.content, borderSide, 'color') || css(tooltip, borderSide, 'color') || tooltip.css(borderSide);
2336
 
2337
- // Reset background and border colours
2338
- $('*', tip).add(tip).css('cssText', bgColor+':'+transparent+important+';border:0'+important+';');
2339
- });
 
 
 
 
 
 
 
 
 
 
2340
  }
 
2341
 
2342
- function calculateSize(corner) {
2343
- var y = corner.precedance === Y,
2344
- width = size [ y ? WIDTH : HEIGHT ],
2345
- height = size [ y ? HEIGHT : WIDTH ],
2346
- isCenter = corner.string().indexOf(CENTER) > -1,
2347
- base = width * (isCenter ? 0.5 : 1),
2348
- pow = Math.pow,
2349
- round = Math.round,
2350
- bigHyp, ratio, result,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2351
 
2352
- smallHyp = Math.sqrt( pow(base, 2) + pow(height, 2) ),
2353
-
2354
- hyp = [
2355
- (border / base) * smallHyp, (border / height) * smallHyp
2356
- ];
2357
- hyp[2] = Math.sqrt( pow(hyp[0], 2) - pow(border, 2) );
2358
- hyp[3] = Math.sqrt( pow(hyp[1], 2) - pow(border, 2) );
2359
 
2360
- bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]);
2361
- ratio = bigHyp / smallHyp;
 
2362
 
2363
- result = [ round(ratio * height), round(ratio * width) ];
2364
- return { height: result[ y ? 0 : 1 ], width: result[ y ? 1 : 0 ] };
2365
- }
2366
 
2367
- function createVML(tag, props, style) {
2368
- return '<qvml:'+tag+' xmlns="urn:schemas-microsoft.com:vml" class="qtip-vml" '+(props||'')+
2369
- ' style="behavior: url(#default#VML); '+(style||'')+ '" />';
2370
  }
 
 
 
 
2371
 
2372
- $.extend(self, {
2373
- init: function()
2374
- {
2375
- var enabled = parseCorner() && (hasCanvas || $.browser.msie);
2376
-
2377
- // Determine tip corner and type
2378
- if(enabled) {
2379
- // Create a new tip and draw it
2380
- self.create();
2381
- self.update();
2382
-
2383
- // Bind update events
2384
- tooltip.unbind(namespace).bind('tooltipmove'+namespace, reposition);
2385
-
2386
- // Fix for issue of tips not showing after redraw in IE (VML...)
2387
- if(!hasCanvas) {
2388
- tooltip.bind('tooltipredraw tooltipredrawn', function(event) {
2389
- if(event.type === 'tooltipredraw') {
2390
- tiphtml = elems.tip.html();
2391
- elems.tip.html('');
2392
- }
2393
- else { elems.tip.html(tiphtml); }
2394
- });
2395
- }
2396
- }
2397
-
2398
- return enabled;
2399
- },
2400
 
2401
- create: function()
2402
- {
2403
- var width = size.width,
2404
- height = size.height,
2405
- vml;
2406
 
2407
- // Remove previous tip element if present
2408
- if(elems.tip) { elems.tip.remove(); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2409
 
2410
- // Create tip element and prepend to the tooltip
2411
- elems.tip = $('<div />', { 'class': 'ui-tooltip-tip' }).css({ width: width, height: height }).prependTo(tooltip);
 
 
2412
 
2413
- // Create tip drawing element(s)
2414
- if(hasCanvas) {
2415
- // save() as soon as we create the canvas element so FF2 doesn't bork on our first restore()!
2416
- $('<canvas />').appendTo(elems.tip)[0].getContext('2d').save();
2417
- }
2418
- else {
2419
- vml = createVML('shape', 'coordorigin="0,0"', 'position:absolute;');
2420
- elems.tip.html(vml + vml);
2421
 
2422
- // Prevent mousing down on the tip since it causes problems with .live() handling in IE due to VML
2423
- $('*', elems.tip).bind('click mousedown', function(event) { event.stopPropagation(); });
2424
- }
2425
- },
2426
 
2427
- update: function(corner, position)
2428
- {
2429
- var tip = elems.tip,
2430
- inner = tip.children(),
2431
- width = size.width,
2432
- height = size.height,
2433
- mimic = opts.mimic,
2434
- round = Math.round,
2435
- precedance, context, coords, translate, newSize;
2436
 
2437
- // Re-determine tip if not already set
2438
- if(!corner) { corner = cache.corner || self.corner; }
 
 
 
2439
 
2440
- // Use corner property if we detect an invalid mimic value
2441
- if(mimic === FALSE) { mimic = corner; }
 
 
 
2442
 
2443
- // Otherwise inherit mimic properties from the corner object as necessary
2444
- else {
2445
- mimic = new PLUGINS.Corner(mimic);
2446
- mimic.precedance = corner.precedance;
 
 
2447
 
2448
- if(mimic.x === 'inherit') { mimic.x = corner.x; }
2449
- else if(mimic.y === 'inherit') { mimic.y = corner.y; }
2450
- else if(mimic.x === mimic.y) {
2451
- mimic[ corner.precedance ] = corner[ corner.precedance ];
2452
- }
 
2453
  }
2454
- precedance = mimic.precedance;
 
 
 
 
 
 
 
2455
 
2456
- // Ensure the tip width.height are relative to the tip position
2457
- if(corner.precedance === X) { swapDimensions(); }
2458
- else { resetDimensions(); }
2459
 
2460
- // Set the tip dimensions
2461
- elems.tip.css({
2462
- width: (width = size.width),
2463
- height: (height = size.height)
2464
- });
2465
 
2466
- // Update our colours
2467
- parseColours(corner);
 
 
 
 
 
2468
 
2469
- // Detect border width, taking into account colours
2470
- if(color.border !== 'transparent') {
2471
- // Grab border width
2472
- border = parseWidth(corner, NULL);
2473
 
2474
- // If border width isn't zero, use border color as fill (1.0 style tips)
2475
- if(opts.border === 0 && border > 0) { color.fill = color.border; }
 
 
2476
 
2477
- // Set border width (use detected border width if opts.border is true)
2478
- self.border = border = opts.border !== TRUE ? opts.border : border;
2479
- }
 
 
 
2480
 
2481
- // Border colour was invalid, set border to zero
2482
- else { self.border = border = 0; }
 
 
 
 
 
2483
 
2484
- // Calculate coordinates
2485
- coords = calculateTip(mimic, width , height);
2486
-
2487
- // Determine tip size
2488
- self.size = newSize = calculateSize(corner);
2489
- tip.css(newSize);
2490
-
2491
- // Calculate tip translation
2492
- if(corner.precedance === Y) {
2493
- translate = [
2494
- round(mimic.x === LEFT ? border : mimic.x === RIGHT ? newSize.width - width - border : (newSize.width - width) / 2),
2495
- round(mimic.y === TOP ? newSize.height - height : 0)
2496
- ];
2497
- }
2498
- else {
2499
- translate = [
2500
- round(mimic.x === LEFT ? newSize.width - width : 0),
2501
- round(mimic.y === TOP ? border : mimic.y === BOTTOM ? newSize.height - height - border : (newSize.height - height) / 2)
2502
- ];
2503
- }
2504
 
2505
- // Canvas drawing implementation
2506
- if(hasCanvas) {
2507
- // Set the canvas size using calculated size
2508
- inner.attr(newSize);
2509
-
2510
- // Grab canvas context and clear/save it
2511
- context = inner[0].getContext('2d');
2512
- context.restore(); context.save();
2513
- context.clearRect(0,0,3000,3000);
2514
-
2515
- // Set properties
2516
- context.fillStyle = color.fill;
2517
- context.strokeStyle = color.border;
2518
- context.lineWidth = border * 2;
2519
- context.lineJoin = 'miter';
2520
- context.miterLimit = 100;
2521
-
2522
- // Translate origin
2523
- context.translate(translate[0], translate[1]);
2524
-
2525
- // Draw the tip
2526
- context.beginPath();
2527
- context.moveTo(coords[0][0], coords[0][1]);
2528
- context.lineTo(coords[1][0], coords[1][1]);
2529
- context.lineTo(coords[2][0], coords[2][1]);
2530
- context.closePath();
2531
-
2532
- // Apply fill and border
2533
- if(border) {
2534
- // Make sure transparent borders are supported by doing a stroke
2535
- // of the background colour before the stroke colour
2536
- if(tooltip.css('background-clip') === 'border-box') {
2537
- context.strokeStyle = color.fill;
2538
- context.stroke();
2539
- }
2540
- context.strokeStyle = color.border;
2541
- context.stroke();
2542
- }
2543
- context.fill();
2544
- }
2545
 
2546
- // VML (IE Proprietary implementation)
2547
- else {
2548
- // Setup coordinates string
2549
- coords = 'm' + coords[0][0] + ',' + coords[0][1] + ' l' + coords[1][0] +
2550
- ',' + coords[1][1] + ' ' + coords[2][0] + ',' + coords[2][1] + ' xe';
2551
-
2552
- // Setup VML-specific offset for pixel-perfection
2553
- translate[2] = border && /^(r|b)/i.test(corner.string()) ?
2554
- parseFloat($.browser.version, 10) === 8 ? 2 : 1 : 0;
2555
-
2556
- // Set initial CSS
2557
- inner.css({
2558
- coordsize: (width+border) + ' ' + (height+border),
2559
- antialias: ''+(mimic.string().indexOf(CENTER) > -1),
2560
- left: translate[0],
2561
- top: translate[1],
2562
- width: width + border,
2563
- height: height + border
2564
- })
2565
- .each(function(i) {
2566
- var $this = $(this);
2567
-
2568
- // Set shape specific attributes
2569
- $this[ $this.prop ? 'prop' : 'attr' ]({
2570
- coordsize: (width+border) + ' ' + (height+border),
2571
- path: coords,
2572
- fillcolor: color.fill,
2573
- filled: !!i,
2574
- stroked: !i
2575
- })
2576
- .toggle(!!(border || i));
2577
-
2578
- // Check if border is enabled and add stroke element
2579
- if(!i && $this.html() === '') {
2580
- $this.html(
2581
- createVML('stroke', 'weight="'+(border*2)+'px" color="'+color.border+'" miterlimit="1000" joinstyle="miter"')
2582
- );
2583
- }
2584
- });
2585
- }
2586
 
2587
- // Position if needed
2588
- if(position !== FALSE) { self.position(corner); }
2589
- },
2590
 
2591
- // Tip positioning method
2592
- position: function(corner)
2593
- {
2594
- var tip = elems.tip,
2595
- position = {},
2596
- userOffset = Math.max(0, opts.offset),
2597
- precedance, dimensions, corners;
2598
 
2599
- // Return if tips are disabled or tip is not yet rendered
2600
- if(opts.corner === FALSE || !tip) { return FALSE; }
 
2601
 
2602
- // Inherit corner if not provided
2603
- corner = corner || self.corner;
2604
- precedance = corner.precedance;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2605
 
2606
- // Determine which tip dimension to use for adjustment
2607
- dimensions = calculateSize(corner);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2608
 
2609
- // Setup corners and offset array
2610
- corners = [ corner.x, corner.y ];
2611
- if(precedance === X) { corners.reverse(); }
 
2612
 
2613
- // Calculate tip position
2614
- $.each(corners, function(i, side) {
2615
- var b, bc, br;
 
 
 
 
 
 
2616
 
2617
- if(side === CENTER) {
2618
- b = precedance === Y ? LEFT : TOP;
2619
- position[ b ] = '50%';
2620
- position['margin-' + b] = -Math.round(dimensions[ precedance === Y ? WIDTH : HEIGHT ] / 2) + userOffset;
2621
- }
2622
- else {
2623
- b = parseWidth(corner, side);
2624
- bc = parseWidth(corner, side, elems.content);
2625
- br = parseRadius(corner);
2626
 
2627
- position[ side ] = i ? bc : (userOffset + (br > b ? br : -b));
2628
- }
2629
- });
 
 
2630
 
2631
- // Adjust for tip dimensions
2632
- position[ corner[precedance] ] -= dimensions[ precedance === X ? WIDTH : HEIGHT ];
 
 
2633
 
2634
- // Set and return new position
2635
- tip.css({ top: '', bottom: '', left: '', right: '', margin: '' }).css(position);
2636
- return position;
2637
- },
2638
-
2639
- destroy: function()
2640
- {
2641
- // Remove the tip element
2642
- if(elems.tip) { elems.tip.remove(); }
2643
- elems.tip = false;
2644
 
2645
- // Unbind events
2646
- tooltip.unbind(namespace);
 
 
2647
  }
2648
- });
2649
-
2650
- self.init();
2651
- }
2652
 
2653
- PLUGINS.tip = function(api)
2654
- {
2655
- var self = api.plugins.tip;
2656
-
2657
- return 'object' === typeof self ? self : (api.plugins.tip = new Tip(api));
2658
  };
2659
 
2660
  // Initialize tip on render
2661
- PLUGINS.tip.initialize = 'render';
2662
 
2663
  // Setup plugin sanitization options
2664
- PLUGINS.tip.sanitize = function(options)
2665
- {
2666
- var style = options.style, opts;
2667
- if(style && 'tip' in style) {
2668
- opts = options.style.tip;
2669
- if(typeof opts !== 'object'){ options.style.tip = { corner: opts }; }
2670
- if(!(/string|boolean/i).test(typeof opts['corner'])) { opts['corner'] = TRUE; }
2671
- if(typeof opts.width !== 'number'){ delete opts.width; }
2672
- if(typeof opts.height !== 'number'){ delete opts.height; }
2673
- if(typeof opts.border !== 'number' && opts.border !== TRUE){ delete opts.border; }
2674
- if(typeof opts.offset !== 'number'){ delete opts.offset; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2675
  }
2676
  };
2677
 
@@ -2688,42 +2648,47 @@ $.extend(TRUE, QTIP.defaults, {
2688
  }
2689
  }
2690
  });
 
 
 
2691
 
2692
-
2693
- function Modal(api)
2694
  {
2695
  var self = this,
2696
- options = api.options.show.modal,
2697
- elems = api.elements,
2698
- tooltip = elems.tooltip,
2699
- overlaySelector = '#qtip-overlay',
2700
- globalNamespace = '.qtipmodal',
2701
- namespace = globalNamespace + api.id,
2702
- attr = 'is-modal-qtip',
2703
- docBody = $(document.body),
2704
- focusableSelector = PLUGINS.modal.focusable.join(','),
2705
- focusableElems = {}, overlay;
2706
-
2707
- // Setup option set checks
2708
- api.checks.modal = {
2709
- '^show.modal.(on|blur)$': function() {
2710
- // Initialise
2711
- self.init();
2712
-
2713
- // Show the modal if not visible already and tooltip is visible
2714
- elems.overlay.toggle( tooltip.is(':visible') );
2715
- },
2716
- '^content.text$': function() {
2717
- updateFocusable();
 
2718
  }
2719
- };
2720
 
2721
- function updateFocusable() {
2722
- focusableElems = $(focusableSelector, tooltip).not('[disabled]').map(function() {
2723
- return typeof this.focus === 'function' ? this : null;
2724
- });
 
 
2725
  }
2726
 
 
2727
  function focusInputs(blurElems) {
2728
  // Blurring body element in IE causes window.open windows to unfocus!
2729
  if(focusableElems.length < 1 && blurElems.length) { blurElems.not('body').blur(); }
@@ -2732,273 +2697,282 @@ function Modal(api)
2732
  else { focusableElems.first().focus(); }
2733
  }
2734
 
 
2735
  function stealFocus(event) {
 
 
2736
  var target = $(event.target),
2737
- container = target.closest('.qtip'),
 
2738
  targetOnTop;
2739
 
2740
  // Determine if input container target is above this
2741
  targetOnTop = container.length < 1 ? FALSE :
2742
- (parseInt(container[0].style.zIndex, 10) > parseInt(tooltip[0].style.zIndex, 10));
2743
 
2744
  // If we're showing a modal, but focus has landed on an input below
2745
  // this modal, divert focus to the first visible input in this modal
2746
  // or if we can't find one... the tooltip itself
2747
- if(!targetOnTop && ($(event.target).closest(selector)[0] !== tooltip[0])) {
2748
  focusInputs(target);
2749
  }
2750
  }
2751
 
2752
  $.extend(self, {
2753
- init: function()
2754
- {
2755
- // If modal is disabled... return
2756
- if(!options.on) { return self; }
2757
-
2758
- // Create the overlay if needed
2759
- overlay = self.create();
2760
-
2761
- // Add unique attribute so we can grab modal tooltips easily via a selector
2762
- tooltip.attr(attr, TRUE)
2763
-
2764
- // Set z-index
2765
- .css('z-index', PLUGINS.modal.zindex + $(selector+'['+attr+']').length)
2766
-
2767
- // Remove previous bound events in globalNamespace
2768
- .unbind(globalNamespace).unbind(namespace)
2769
-
2770
- // Apply our show/hide/focus modal events
2771
- .bind('tooltipshow'+globalNamespace+' tooltiphide'+globalNamespace, function(event, api, duration) {
2772
- var oEvent = event.originalEvent;
2773
-
2774
- // Make sure mouseout doesn't trigger a hide when showing the modal and mousing onto backdrop
2775
- if(event.target === tooltip[0]) {
2776
- if(oEvent && event.type === 'tooltiphide' && /mouse(leave|enter)/.test(oEvent.type) && $(oEvent.relatedTarget).closest(overlay[0]).length) {
2777
- try { event.preventDefault(); } catch(e) {}
2778
- }
2779
- else if(!oEvent || (oEvent && !oEvent.solo)) {
2780
- self[ event.type.replace('tooltip', '') ](event, duration);
2781
- }
2782
- }
2783
  })
 
2784
 
2785
- // Adjust modal z-index on tooltip focus
2786
- .bind('tooltipfocus'+globalNamespace, function(event) {
2787
- // If focus was cancelled before it reearch us, don't do anything
2788
- if(event.isDefaultPrevented() || event.target !== tooltip[0]) { return; }
2789
-
2790
- var qtips = $(selector).filter('['+attr+']'),
2791
-
2792
- // Keep the modal's lower than other, regular qtips
2793
- newIndex = PLUGINS.modal.zindex + qtips.length,
2794
- curIndex = parseInt(tooltip[0].style.zIndex, 10);
2795
-
2796
- // Set overlay z-index
2797
- overlay[0].style.zIndex = newIndex - 2;
2798
-
2799
- // Reduce modal z-index's and keep them properly ordered
2800
- qtips.each(function() {
2801
- if(this.style.zIndex > curIndex) {
2802
- this.style.zIndex -= 1;
2803
- }
2804
- });
2805
-
2806
- // Fire blur event for focused tooltip
2807
- qtips.end().filter('.' + focusClass).qtip('blur', event.originalEvent);
2808
-
2809
- // Set the new z-index
2810
- tooltip.addClass(focusClass)[0].style.zIndex = newIndex;
2811
-
2812
- // Prevent default handling
2813
- try { event.preventDefault(); } catch(e) {}
2814
- })
2815
 
2816
- // Focus any other visible modals when this one hides
2817
- .bind('tooltiphide'+globalNamespace, function(event) {
2818
- if(event.target === tooltip[0]) {
2819
- $('[' + attr + ']').filter(':visible').not(tooltip).last().qtip('focus', event);
2820
  }
2821
  });
2822
 
2823
- // Apply keyboard "Escape key" close handler
2824
- if(options.escape) {
2825
- $(document).unbind(namespace).bind('keydown'+namespace, function(event) {
2826
- if(event.keyCode === 27 && tooltip.hasClass(focusClass)) {
2827
- api.hide(event);
2828
- }
2829
- });
2830
- }
2831
-
2832
  // Apply click handler for blur option
2833
- if(options.blur) {
2834
- elems.overlay.unbind(namespace).bind('click'+namespace, function(event) {
2835
- if(tooltip.hasClass(focusClass)) { api.hide(event); }
2836
- });
2837
- }
2838
-
2839
- // Update focusable elements
2840
- updateFocusable();
2841
 
2842
  return self;
2843
  },
2844
 
2845
- create: function()
2846
- {
2847
- var elem = $(overlaySelector);
2848
-
2849
- // Return if overlay is already rendered
2850
- if(elem.length) {
2851
- // Modal overlay should always be below all tooltips if possible
2852
- return (elems.overlay = elem.insertAfter( $(selector).last() ));
2853
- }
2854
 
2855
- // Create document overlay
2856
- overlay = elems.overlay = $('<div />', {
2857
- id: overlaySelector.substr(1),
2858
- html: '<div></div>',
2859
- mousedown: function() { return FALSE; }
2860
- })
2861
- .hide()
2862
- .insertAfter( $(selector).last() );
2863
-
2864
- // Update position on window resize or scroll
2865
- function resize() {
2866
- overlay.css({
2867
- height: $(window).height(),
2868
- width: $(window).width()
2869
  });
2870
  }
2871
- $(window).unbind(globalNamespace).bind('resize'+globalNamespace, resize);
2872
- resize(); // Fire it initially too
2873
-
2874
- return overlay;
2875
  },
2876
 
2877
- toggle: function(event, state, duration)
2878
- {
2879
- // Make sure default event hasn't been prevented
2880
- if(event && event.isDefaultPrevented()) { return self; }
2881
-
2882
- var effect = options.effect,
2883
  type = state ? 'show': 'hide',
2884
- visible = overlay.is(':visible'),
2885
- modals = $('[' + attr + ']').filter(':visible').not(tooltip),
2886
- zindex;
2887
-
2888
- // Create our overlay if it isn't present already
2889
- if(!overlay) { overlay = self.create(); }
2890
 
2891
- // Prevent modal from conflicting with show.solo, and don't hide backdrop is other modals are visible
2892
- if((overlay.is(':animated') && visible === state) || (!state && modals.length)) { return self; }
2893
-
2894
- // State specific...
2895
- if(state) {
2896
- // Set position
2897
- overlay.css({ left: 0, top: 0 });
2898
 
2899
- // Toggle backdrop cursor style on show
2900
- overlay.toggleClass('blurs', options.blur);
 
 
 
2901
 
2902
- // IF the modal can steal the focus
2903
- if(options.stealfocus !== FALSE) {
2904
- // Make sure we can't focus anything outside the tooltip
2905
- docBody.bind('focusin'+namespace, stealFocus);
2906
 
2907
- // Blur the current item and focus anything in the modal we an
2908
- focusInputs( $('body :focus') );
2909
- }
2910
  }
2911
- else {
2912
- // Undelegate focus handler
2913
- docBody.unbind('focusin'+namespace);
 
2914
  }
2915
 
2916
  // Stop all animations
2917
- overlay.stop(TRUE, FALSE);
2918
 
2919
  // Use custom function if provided
2920
  if($.isFunction(effect)) {
2921
- effect.call(overlay, state);
2922
  }
2923
 
2924
  // If no effect type is supplied, use a simple toggle
2925
  else if(effect === FALSE) {
2926
- overlay[ type ]();
2927
  }
2928
 
2929
  // Use basic fade function
2930
  else {
2931
- overlay.fadeTo( parseInt(duration, 10) || 90, state ? 1 : 0, function() {
2932
- if(!state) { $(this).hide(); }
2933
  });
2934
  }
2935
 
2936
- // Reset position on hide
2937
  if(!state) {
2938
- overlay.queue(function(next) {
2939
- overlay.css({ left: '', top: '' });
 
2940
  next();
2941
  });
2942
  }
2943
 
 
 
 
 
 
 
2944
  return self;
2945
- },
 
 
 
 
 
 
 
 
 
 
 
 
 
2946
 
2947
- show: function(event, duration) { return self.toggle(event, TRUE, duration); },
2948
- hide: function(event, duration) { return self.toggle(event, FALSE, duration); },
 
2949
 
2950
- destroy: function()
2951
- {
2952
- var delBlanket = overlay;
2953
 
2954
- if(delBlanket) {
2955
- // Check if any other modal tooltips are present
2956
- delBlanket = $('[' + attr + ']').not(tooltip).length < 1;
2957
 
2958
- // Remove overlay if needed
2959
- if(delBlanket) {
2960
- elems.overlay.remove();
2961
- $(document).unbind(globalNamespace);
 
 
 
 
 
 
 
 
 
 
2962
  }
2963
- else {
2964
- elems.overlay.unbind(globalNamespace+api.id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2965
  }
 
 
 
 
2966
 
2967
- // Undelegate focus handler
2968
- docBody.undelegate('*', 'focusin'+namespace);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2969
  }
 
 
2970
 
2971
- // Remove bound events
2972
- return tooltip.removeAttr(attr).unbind(globalNamespace);
2973
- }
2974
- });
2975
 
2976
- self.init();
2977
- }
 
2978
 
2979
- PLUGINS.modal = function(api) {
2980
- var self = api.plugins.modal;
 
2981
 
2982
- return 'object' === typeof self ? self : (api.plugins.modal = new Modal(api));
2983
- };
 
 
 
 
 
 
2984
 
2985
- // Plugin needs to be initialized on render
2986
- PLUGINS.modal.initialize = 'render';
 
 
2987
 
2988
  // Setup sanitiztion rules
2989
- PLUGINS.modal.sanitize = function(opts) {
2990
- if(opts.show) {
2991
  if(typeof opts.show.modal !== 'object') { opts.show.modal = { on: !!opts.show.modal }; }
2992
  else if(typeof opts.show.modal.on === 'undefined') { opts.show.modal.on = TRUE; }
2993
  }
2994
  };
2995
 
2996
  // Base z-index for all modal tooltips (use qTip core z-index as a base)
2997
- PLUGINS.modal.zindex = QTIP.zindex - 200;
 
 
2998
 
2999
- // Defines the selector used to select all 'focusable' elements within the modal when using the show.modal.stealfocus option.
3000
- // Selectors initially taken from http://stackoverflow.com/questions/7668525/is-there-a-jquery-selector-to-get-all-elements-that-can-get-focus
3001
- PLUGINS.modal.focusable = ['a[href]', 'area[href]', 'input', 'select', 'textarea', 'button', 'iframe', 'object', 'embed', '[tabindex]', '[contenteditable]'];
 
 
 
 
 
 
 
 
 
 
 
 
 
3002
 
3003
  // Extend original api defaults
3004
  $.extend(TRUE, QTIP.defaults, {
@@ -3012,9 +2986,7 @@ $.extend(TRUE, QTIP.defaults, {
3012
  }
3013
  }
3014
  });
3015
-
3016
-
3017
- PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight)
3018
  {
3019
  var target = posOptions.target,
3020
  tooltip = api.elements.tooltip,
@@ -3026,83 +2998,81 @@ PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight
3026
  methodY = method[1] || method[0],
3027
  viewport = posOptions.viewport,
3028
  container = posOptions.container,
3029
- cache = api.cache,
3030
- tip = api.plugins.tip,
3031
  adjusted = { left: 0, top: 0 },
3032
- fixed, newMy, newClass;
 
3033
 
3034
- // If viewport is not a jQuery element, or it's the window/document or no adjustment method is used... return
3035
  if(!viewport.jquery || target[0] === window || target[0] === document.body || adjust.method === 'none') {
3036
  return adjusted;
3037
  }
3038
 
 
 
 
 
3039
  // Cache our viewport details
3040
  fixed = tooltip.css('position') === 'fixed';
3041
- viewport = {
3042
- elem: viewport,
3043
- height: viewport[ (viewport[0] === window ? 'h' : 'outerH') + 'eight' ](),
3044
- width: viewport[ (viewport[0] === window ? 'w' : 'outerW') + 'idth' ](),
3045
- scrollleft: fixed ? 0 : viewport.scrollLeft(),
3046
- scrolltop: fixed ? 0 : viewport.scrollTop(),
3047
- offset: viewport.offset() || { left: 0, top: 0 }
3048
- };
3049
- container = {
3050
- elem: container,
3051
- scrollLeft: container.scrollLeft(),
3052
- scrollTop: container.scrollTop(),
3053
- offset: container.offset() || { left: 0, top: 0 }
3054
- };
3055
 
3056
  // Generic calculation method
3057
- function calculate(side, otherSide, type, adjust, side1, side2, lengthName, targetLength, elemLength) {
3058
  var initialPos = position[side1],
3059
- mySide = my[side], atSide = at[side],
 
3060
  isShift = type === SHIFT,
3061
- viewportScroll = -container.offset[side1] + viewport.offset[side1] + viewport['scroll'+side1],
3062
  myLength = mySide === side1 ? elemLength : mySide === side2 ? -elemLength : -elemLength / 2,
3063
  atLength = atSide === side1 ? targetLength : atSide === side2 ? -targetLength : -targetLength / 2,
3064
- tipLength = tip && tip.size ? tip.size[lengthName] || 0 : 0,
3065
- tipAdjust = tip && tip.corner && tip.corner.precedance === side && !isShift ? tipLength : 0,
3066
- overflow1 = viewportScroll - initialPos + tipAdjust,
3067
- overflow2 = initialPos + elemLength - viewport[lengthName] - viewportScroll + tipAdjust,
3068
  offset = myLength - (my.precedance === side || mySide === my[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0);
3069
 
3070
  // shift
3071
  if(isShift) {
3072
- tipAdjust = tip && tip.corner && tip.corner.precedance === otherSide ? tipLength : 0;
3073
- offset = (mySide === side1 ? 1 : -1) * myLength - tipAdjust;
3074
 
3075
  // Adjust position but keep it within viewport dimensions
3076
  position[side1] += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0;
3077
  position[side1] = Math.max(
3078
- -container.offset[side1] + viewport.offset[side1] + (tipAdjust && tip.corner[side] === CENTER ? tip.offset : 0),
3079
  initialPos - offset,
3080
  Math.min(
3081
- Math.max(-container.offset[side1] + viewport.offset[side1] + viewport[lengthName], initialPos + offset),
3082
- position[side1]
 
 
 
 
 
 
3083
  )
3084
  );
 
3085
  }
3086
 
3087
  // flip/flipinvert
3088
  else {
3089
  // Update adjustment amount depending on if using flipinvert or flip
3090
- adjust *= (type === FLIPINVERT ? 2 : 0);
3091
 
3092
  // Check for overflow on the left/top
3093
  if(overflow1 > 0 && (mySide !== side1 || overflow2 > 0)) {
3094
- position[side1] -= offset + adjust;
3095
- newMy['invert'+side](side1);
3096
  }
3097
 
3098
  // Check for overflow on the bottom/right
3099
  else if(overflow2 > 0 && (mySide !== side2 || overflow1 > 0) ) {
3100
- position[side1] -= (mySide === CENTER ? -offset : offset) + adjust;
3101
- newMy['invert'+side](side2);
3102
  }
3103
 
3104
  // Make sure we haven't made things worse with the adjustment and reset if so
3105
- if(position[side1] < viewportScroll && -position[side1] > overflow2) {
3106
  position[side1] = initialPos; newMy = my.clone();
3107
  }
3108
  }
@@ -3116,90 +3086,34 @@ PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight
3116
  // Adjust position based onviewport and adjustment options
3117
  adjusted = {
3118
  left: methodX !== 'none' ? calculate( X, Y, methodX, adjust.x, LEFT, RIGHT, WIDTH, targetWidth, elemWidth ) : 0,
3119
- top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0
 
3120
  };
3121
 
3122
- // Set tooltip position class if it's changed
3123
- if(newMy && cache.lastClass !== (newClass = uitooltip + '-pos-' + newMy.abbrev())) {
3124
- tooltip.removeClass(api.cache.lastClass).addClass( (api.cache.lastClass = newClass) );
3125
- }
3126
-
3127
  return adjusted;
3128
  };
3129
- PLUGINS.imagemap = function(api, area, corner, adjustMethod)
3130
- {
3131
- if(!area.jquery) { area = $(area); }
3132
-
3133
- var cache = (api.cache.areas = {}),
3134
- shape = (area[0].shape || area.attr('shape')).toLowerCase(),
3135
- coordsString = area[0].coords || area.attr('coords'),
3136
- baseCoords = coordsString.split(','),
3137
- coords = [],
3138
- image = $('img[usemap="#'+area.parent('map').attr('name')+'"]'),
3139
- imageOffset = image.offset(),
3140
- result = {
3141
  width: 0, height: 0,
3142
  position: {
3143
  top: 1e10, right: 0,
3144
  bottom: 0, left: 1e10
3145
- }
 
3146
  },
3147
- i = 0, next = 0, dimensions;
3148
-
3149
- // POLY area coordinate calculator
3150
- // Special thanks to Ed Cradock for helping out with this.
3151
- // Uses a binary search algorithm to find suitable coordinates.
3152
- function polyCoordinates(result, coords, corner)
3153
- {
3154
- var i = 0,
3155
- compareX = 1, compareY = 1,
3156
- realX = 0, realY = 0,
3157
- newWidth = result.width,
3158
- newHeight = result.height;
3159
-
3160
- // Use a binary search algorithm to locate most suitable coordinate (hopefully)
3161
- while(newWidth > 0 && newHeight > 0 && compareX > 0 && compareY > 0)
3162
- {
3163
- newWidth = Math.floor(newWidth / 2);
3164
- newHeight = Math.floor(newHeight / 2);
3165
-
3166
- if(corner.x === LEFT){ compareX = newWidth; }
3167
- else if(corner.x === RIGHT){ compareX = result.width - newWidth; }
3168
- else{ compareX += Math.floor(newWidth / 2); }
3169
-
3170
- if(corner.y === TOP){ compareY = newHeight; }
3171
- else if(corner.y === BOTTOM){ compareY = result.height - newHeight; }
3172
- else{ compareY += Math.floor(newHeight / 2); }
3173
-
3174
- i = coords.length; while(i--)
3175
- {
3176
- if(coords.length < 2){ break; }
3177
-
3178
- realX = coords[i][0] - result.position.left;
3179
- realY = coords[i][1] - result.position.top;
3180
-
3181
- if((corner.x === LEFT && realX >= compareX) ||
3182
- (corner.x === RIGHT && realX <= compareX) ||
3183
- (corner.x === CENTER && (realX < compareX || realX > (result.width - compareX))) ||
3184
- (corner.y === TOP && realY >= compareY) ||
3185
- (corner.y === BOTTOM && realY <= compareY) ||
3186
- (corner.y === CENTER && (realY < compareY || realY > (result.height - compareY)))) {
3187
- coords.splice(i, 1);
3188
- }
3189
- }
3190
- }
3191
-
3192
- return { left: coords[0][0], top: coords[0][1] };
3193
- }
3194
-
3195
- // Make sure we account for padding and borders on the image
3196
- imageOffset.left += Math.ceil((image.outerWidth() - image.width()) / 2);
3197
- imageOffset.top += Math.ceil((image.outerHeight() - image.height()) / 2);
3198
 
3199
- // Parse coordinates into proper array
3200
- if(shape === 'poly') {
3201
- i = baseCoords.length; while(i--)
3202
- {
3203
  next = [ parseInt(baseCoords[--i], 10), parseInt(baseCoords[i+1], 10) ];
3204
 
3205
  if(next[0] > result.position.right){ result.position.right = next[0]; }
@@ -3209,157 +3123,365 @@ PLUGINS.imagemap = function(api, area, corner, adjustMethod)
3209
 
3210
  coords.push(next);
3211
  }
3212
- }
3213
- else {
3214
- i = -1; while(i++ < baseCoords.length) {
3215
- coords.push( parseInt(baseCoords[i], 10) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3216
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3217
  }
 
 
 
 
 
 
 
 
 
 
3218
 
3219
- // Calculate details
3220
- switch(shape)
3221
- {
3222
- case 'rect':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3223
  result = {
3224
- width: Math.abs(coords[2] - coords[0]),
3225
- height: Math.abs(coords[3] - coords[1]),
3226
  position: {
3227
- left: Math.min(coords[0], coords[2]),
3228
- top: Math.min(coords[1], coords[3])
3229
  }
3230
  };
3231
  break;
 
3232
 
3233
- case 'circle':
3234
- result = {
3235
- width: coords[2] + 2,
3236
- height: coords[2] + 2,
3237
- position: { left: coords[0], top: coords[1] }
3238
- };
3239
- break;
3240
 
3241
- case 'poly':
3242
- result.width = Math.abs(result.position.right - result.position.left);
3243
- result.height = Math.abs(result.position.bottom - result.position.top);
 
3244
 
3245
- if(corner.abbrev() === 'c') {
3246
- result.position = {
3247
- left: result.position.left + (result.width / 2),
3248
- top: result.position.top + (result.height / 2)
3249
- };
3250
- }
3251
- else {
3252
- // Calculate if we can't find a cached value
3253
- if(!cache[corner+coordsString]) {
3254
- result.position = polyCoordinates(result, coords.slice(), corner);
3255
-
3256
- // If flip adjustment is enabled, also calculate the closest opposite point
3257
- if(adjustMethod && (adjustMethod[0] === 'flip' || adjustMethod[1] === 'flip')) {
3258
- result.offset = polyCoordinates(result, coords.slice(), {
3259
- x: corner.x === LEFT ? RIGHT : corner.x === RIGHT ? LEFT : CENTER,
3260
- y: corner.y === TOP ? BOTTOM : corner.y === BOTTOM ? TOP : CENTER
3261
- });
3262
-
3263
- result.offset.left -= result.position.left;
3264
- result.offset.top -= result.position.top;
3265
- }
3266
 
3267
- // Store the result
3268
- cache[corner+coordsString] = result;
3269
- }
 
 
 
 
 
3270
 
3271
- // Grab the cached result
3272
- result = cache[corner+coordsString];
3273
- }
 
3274
 
3275
- result.width = result.height = 0;
3276
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3277
  }
3278
 
 
 
 
 
 
 
 
 
3279
  // Add image position to offset coordinates
3280
  result.position.left += imageOffset.left;
3281
  result.position.top += imageOffset.top;
3282
 
3283
  return result;
3284
  };
 
3285
 
3286
-
3287
- /*
3288
  * BGIFrame adaption (http://plugins.jquery.com/project/bgiframe)
3289
  * Special thanks to Brandon Aaron
3290
  */
3291
- function BGIFrame(api)
3292
- {
3293
- var self = this,
3294
- elems = api.elements,
3295
- tooltip = elems.tooltip,
3296
- namespace = '.bgiframe-' + api.id;
3297
 
3298
- $.extend(self, {
3299
- init: function()
3300
- {
3301
- // Create the BGIFrame element
3302
- elems.bgiframe = $('<iframe class="ui-tooltip-bgiframe" frameborder="0" tabindex="-1" src="javascript:\'\';" ' +
3303
- ' style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=0); ' +
3304
- '-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";"></iframe>');
3305
 
3306
- // Append the new element to the tooltip
3307
- elems.bgiframe.appendTo(tooltip);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3308
 
3309
  // Update BGIFrame on tooltip move
3310
- tooltip.bind('tooltipmove'+namespace, self.adjust);
3311
- },
3312
 
3313
- adjust: function()
3314
- {
3315
- var dimensions = api.get('dimensions'), // Determine current tooltip dimensions
3316
- plugin = api.plugins.tip,
3317
- tip = elems.tip,
3318
- tipAdjust, offset;
3319
-
3320
- // Adjust border offset
3321
- offset = parseInt(tooltip.css('border-left-width'), 10) || 0;
3322
- offset = { left: -offset, top: -offset };
3323
-
3324
- // Adjust for tips plugin
3325
- if(plugin && tip) {
3326
- tipAdjust = (plugin.corner.precedance === 'x') ? ['width', 'left'] : ['height', 'top'];
3327
- offset[ tipAdjust[1] ] -= tip[ tipAdjust[0] ]();
3328
- }
3329
 
3330
- // Update bgiframe
3331
- elems.bgiframe.css(offset).css(dimensions);
3332
- },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3333
 
3334
- destroy: function()
3335
- {
3336
- // Remove iframe
3337
- elems.bgiframe.remove();
 
 
 
 
 
 
 
 
 
 
 
 
 
3338
 
3339
- // Remove bound events
3340
- tooltip.unbind(namespace);
 
 
 
3341
  }
3342
- });
3343
 
3344
- self.init();
3345
- }
3346
 
3347
- PLUGINS.bgiframe = function(api)
3348
- {
3349
- var browser = $.browser,
3350
- self = api.plugins.bgiframe;
3351
-
3352
- // Proceed only if the browser is IE6 and offending elements are present
3353
- if($('select, object').length < 1 || !(browser.msie && (''+browser.version).charAt(0) === '6')) {
3354
- return FALSE;
 
3355
  }
 
3356
 
3357
- return 'object' === typeof self ? self : (api.plugins.bgiframe = new BGIFrame(api));
 
 
3358
  };
3359
 
3360
- // Plugin needs to be initialized on render
3361
- PLUGINS.bgiframe.initialize = 'render';
3362
-
3363
 
3364
- }));
3365
- }( window, document ));
 
 
 
 
 
1
+ /*
2
+ * qTip2 - Pretty powerful tooltips - v3.0.3
3
+ * http://qtip2.com
4
+ *
5
+ * Copyright (c) 2016
6
+ * Released under the MIT licenses
7
+ * http://jquery.org/license
8
+ *
9
+ * Date: Wed May 11 2016 10:31 GMT+0100+0100
10
+ * Plugins: tips modal viewport svg imagemap ie6
11
+ * Styles: core basic css3
12
+ */
13
  /*global window: false, jQuery: false, console: false, define: false */
14
 
15
  /* Cache window, document, undefined */
26
  }
27
  }
28
  (function($) {
29
+ "use strict"; // Enable ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
30
+ ;// Munge the primitives - Paul Irish tip
31
+ var TRUE = true,
32
+ FALSE = false,
33
+ NULL = null,
34
+
35
+ // Common variables
36
+ X = 'x', Y = 'y',
37
+ WIDTH = 'width',
38
+ HEIGHT = 'height',
39
+
40
+ // Positioning sides
41
+ TOP = 'top',
42
+ LEFT = 'left',
43
+ BOTTOM = 'bottom',
44
+ RIGHT = 'right',
45
+ CENTER = 'center',
46
+
47
+ // Position adjustment types
48
+ FLIP = 'flip',
49
+ FLIPINVERT = 'flipinvert',
50
+ SHIFT = 'shift',
51
+
52
+ // Shortcut vars
53
+ QTIP, PROTOTYPE, CORNER, CHECKS,
54
+ PLUGINS = {},
55
+ NAMESPACE = 'qtip',
56
+ ATTR_HAS = 'data-hasqtip',
57
+ ATTR_ID = 'data-qtip-id',
58
+ WIDGET = ['ui-widget', 'ui-tooltip'],
59
+ SELECTOR = '.'+NAMESPACE,
60
+ INACTIVE_EVENTS = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' '),
61
+
62
+ CLASS_FIXED = NAMESPACE+'-fixed',
63
+ CLASS_DEFAULT = NAMESPACE + '-default',
64
+ CLASS_FOCUS = NAMESPACE + '-focus',
65
+ CLASS_HOVER = NAMESPACE + '-hover',
66
+ CLASS_DISABLED = NAMESPACE+'-disabled',
67
+
68
+ replaceSuffix = '_replacedByqTip',
69
+ oldtitle = 'oldtitle',
70
+ trackingBound,
71
+
72
+ // Browser detection
73
+ BROWSER = {
74
  /*
75
+ * IE version detection
76
+ *
77
+ * Adapted from: http://ajaxian.com/archives/attack-of-the-ie-conditional-comment
78
+ * Credit to James Padolsey for the original implemntation!
79
+ */
80
+ ie: (function() {
81
+ /* eslint-disable no-empty */
82
+ var v, i;
83
+ for (
84
+ v = 4, i = document.createElement('div');
85
+ (i.innerHTML = '<!--[if gt IE ' + v + ']><i></i><![endif]-->') && i.getElementsByTagName('i')[0];
86
+ v+=1
87
+ ) {}
88
+ return v > 4 ? v : NaN;
89
+ /* eslint-enable no-empty */
90
+ })(),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
+ /*
93
+ * iOS version detection
94
+ */
95
+ iOS: parseFloat(
96
+ ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1])
97
+ .replace('undefined', '3_2').replace('_', '.').replace('_', '')
98
+ ) || FALSE
99
+ };
100
+ ;function QTip(target, options, id, attr) {
101
+ // Elements and ID
102
+ this.id = id;
103
+ this.target = target;
104
+ this.tooltip = NULL;
105
+ this.elements = { target: target };
106
+
107
+ // Internal constructs
108
+ this._id = NAMESPACE + '-' + id;
109
+ this.timers = { img: {} };
110
+ this.options = options;
111
+ this.plugins = {};
112
+
113
+ // Cache object
114
+ this.cache = {
115
+ event: {},
116
+ target: $(),
117
+ disabled: FALSE,
118
+ attr: attr,
119
+ onTooltip: FALSE,
120
+ lastClass: ''
121
+ };
122
 
123
+ // Set the initial flags
124
+ this.rendered = this.destroyed = this.disabled = this.waiting =
125
+ this.hiddenDuringWait = this.positioning = this.triggering = FALSE;
126
+ }
127
+ PROTOTYPE = QTip.prototype;
128
 
129
+ PROTOTYPE._when = function(deferreds) {
130
+ return $.when.apply($, deferreds);
131
+ };
132
 
133
+ PROTOTYPE.render = function(show) {
134
+ if(this.rendered || this.destroyed) { return this; } // If tooltip has already been rendered, exit
135
 
136
+ var self = this,
137
+ options = this.options,
138
+ cache = this.cache,
139
+ elements = this.elements,
140
+ text = options.content.text,
141
+ title = options.content.title,
142
+ button = options.content.button,
143
+ posOptions = options.position,
144
+ deferreds = [];
145
+
146
+ // Add ARIA attributes to target
147
+ $.attr(this.target[0], 'aria-describedby', this._id);
148
+
149
+ // Create public position object that tracks current position corners
150
+ cache.posClass = this._createPosClass(
151
+ (this.position = { my: posOptions.my, at: posOptions.at }).my
152
+ );
153
+
154
+ // Create tooltip element
155
+ this.tooltip = elements.tooltip = $('<div/>', {
156
+ 'id': this._id,
157
+ 'class': [ NAMESPACE, CLASS_DEFAULT, options.style.classes, cache.posClass ].join(' '),
158
+ 'width': options.style.width || '',
159
+ 'height': options.style.height || '',
160
+ 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse,
161
+
162
+ /* ARIA specific attributes */
163
+ 'role': 'alert',
164
+ 'aria-live': 'polite',
165
+ 'aria-atomic': FALSE,
166
+ 'aria-describedby': this._id + '-content',
167
+ 'aria-hidden': TRUE
168
+ })
169
+ .toggleClass(CLASS_DISABLED, this.disabled)
170
+ .attr(ATTR_ID, this.id)
171
+ .data(NAMESPACE, this)
172
+ .appendTo(posOptions.container)
173
+ .append(
174
+ // Create content element
175
+ elements.content = $('<div />', {
176
+ 'class': NAMESPACE + '-content',
177
+ 'id': this._id + '-content',
178
+ 'aria-atomic': TRUE
179
+ })
180
+ );
181
+
182
+ // Set rendered flag and prevent redundant reposition calls for now
183
+ this.rendered = -1;
184
+ this.positioning = TRUE;
185
+
186
+ // Create title...
187
+ if(title) {
188
+ this._createTitle();
189
+
190
+ // Update title only if its not a callback (called in toggle if so)
191
+ if(!$.isFunction(title)) {
192
+ deferreds.push( this._updateTitle(title, FALSE) );
193
+ }
194
+ }
195
 
196
+ // Create button
197
+ if(button) { this._createButton(); }
 
 
 
 
198
 
199
+ // Set proper rendered flag and update content if not a callback function (called in toggle)
200
+ if(!$.isFunction(text)) {
201
+ deferreds.push( this._updateContent(text, FALSE) );
202
  }
203
+ this.rendered = TRUE;
204
 
205
+ // Setup widget classes
206
+ this._setWidget();
 
207
 
208
+ // Initialize 'render' plugins
209
+ $.each(PLUGINS, function(name) {
210
+ var instance;
211
+ if(this.initialize === 'render' && (instance = this(self))) {
212
+ self.plugins[name] = instance;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  }
214
+ });
215
 
216
+ // Unassign initial events and assign proper events
217
+ this._unassignEvents();
218
+ this._assignEvents();
 
 
 
219
 
220
+ // When deferreds have completed
221
+ this._when(deferreds).then(function() {
222
+ // tooltiprender event
223
+ self._trigger('render');
224
 
225
+ // Reset flags
226
+ self.positioning = FALSE;
227
 
228
+ // Show tooltip if not hidden during wait period
229
+ if(!self.hiddenDuringWait && (options.show.ready || show)) {
230
+ self.toggle(TRUE, cache.event, FALSE);
231
+ }
232
+ self.hiddenDuringWait = FALSE;
233
+ });
234
 
235
+ // Expose API
236
+ QTIP.api[this.id] = this;
237
 
238
+ return this;
239
+ };
240
 
241
+ PROTOTYPE.destroy = function(immediate) {
242
+ // Set flag the signify destroy is taking place to plugins
243
+ // and ensure it only gets destroyed once!
244
+ if(this.destroyed) { return this.target; }
 
 
 
 
245
 
246
+ function process() {
247
+ if(this.destroyed) { return; }
248
+ this.destroyed = TRUE;
249
 
250
+ var target = this.target,
251
+ title = target.attr(oldtitle),
252
+ timer;
253
 
254
+ // Destroy tooltip if rendered
255
+ if(this.rendered) {
256
+ this.tooltip.stop(1,0).find('*').remove().end().remove();
257
+ }
258
 
259
+ // Destroy all plugins
260
+ $.each(this.plugins, function() {
261
+ this.destroy && this.destroy();
262
+ });
263
 
264
+ // Clear timers
265
+ for (timer in this.timers) {
266
+ if (this.timers.hasOwnProperty(timer)) {
267
+ clearTimeout(this.timers[timer]);
268
  }
269
+ }
270
 
271
+ // Remove api object and ARIA attributes
272
+ target.removeData(NAMESPACE)
273
+ .removeAttr(ATTR_ID)
274
+ .removeAttr(ATTR_HAS)
275
+ .removeAttr('aria-describedby');
 
 
 
 
 
 
 
 
 
 
 
 
 
276
 
277
+ // Reset old title attribute if removed
278
+ if(this.options.suppress && title) {
279
+ target.attr('title', title).removeAttr(oldtitle);
280
+ }
281
 
282
+ // Remove qTip events associated with this API
283
+ this._unassignEvents();
 
284
 
285
+ // Remove ID from used id objects, and delete object references
286
+ // for better garbage collection and leak protection
287
+ this.options = this.elements = this.cache = this.timers =
288
+ this.plugins = this.mouse = NULL;
 
289
 
290
+ // Delete epoxsed API object
291
+ delete QTIP.api[this.id];
292
+ }
 
 
 
 
 
 
293
 
294
+ // If an immediate destroy is needed
295
+ if((immediate !== TRUE || this.triggering === 'hide') && this.rendered) {
296
+ this.tooltip.one('tooltiphidden', $.proxy(process, this));
297
+ !this.triggering && this.hide();
298
+ }
299
 
300
+ // If we're not in the process of hiding... process
301
+ else { process.call(this); }
 
 
302
 
303
+ return this.target;
304
+ };
305
+ ;function invalidOpt(a) {
306
+ return a === NULL || $.type(a) !== 'object';
307
  }
308
 
309
+ function invalidContent(c) {
310
+ return !($.isFunction(c) ||
311
+ c && c.attr ||
312
+ c.length ||
313
+ $.type(c) === 'object' && (c.jquery || c.then));
314
+ }
315
 
316
+ // Option object sanitizer
317
+ function sanitizeOptions(opts) {
318
+ var content, text, ajax, once;
 
 
 
319
 
320
+ if(invalidOpt(opts)) { return FALSE; }
321
 
322
+ if(invalidOpt(opts.metadata)) {
323
+ opts.metadata = { type: opts.metadata };
 
 
 
 
 
 
324
  }
 
325
 
326
+ if('content' in opts) {
327
+ content = opts.content;
 
 
 
 
 
 
 
328
 
329
+ if(invalidOpt(content) || content.jquery || content.done) {
330
+ text = invalidContent(content) ? FALSE : content;
331
+ content = opts.content = {
332
+ text: text
333
+ };
334
+ }
335
+ else { text = content.text; }
336
 
337
+ // DEPRECATED - Old content.ajax plugin functionality
338
+ // Converts it into the proper Deferred syntax
339
+ if('ajax' in content) {
340
+ ajax = content.ajax;
341
+ once = ajax && ajax.once !== FALSE;
342
+ delete content.ajax;
 
 
 
 
 
 
 
 
 
 
343
 
344
+ content.text = function(event, api) {
345
+ var loading = text || $(this).attr(api.options.content.attr) || 'Loading...',
 
346
 
347
+ deferred = $.ajax(
348
+ $.extend({}, ajax, { context: api })
349
+ )
350
+ .then(ajax.success, NULL, ajax.error)
351
+ .then(function(newContent) {
352
+ if(newContent && once) { api.set('content.text', newContent); }
353
+ return newContent;
354
+ },
355
+ function(xhr, status, error) {
356
+ if(api.destroyed || xhr.status === 0) { return; }
357
+ api.set('content.text', status + ': ' + error);
358
+ });
359
 
360
+ return !once ? (api.set('content.text', loading), deferred) : loading;
361
+ };
362
+ }
363
 
364
+ if('title' in content) {
365
+ if($.isPlainObject(content.title)) {
366
+ content.button = content.title.button;
367
+ content.title = content.title.text;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
  }
369
 
370
+ if(invalidContent(content.title || FALSE)) {
371
+ content.title = FALSE;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
  }
373
  }
374
+ }
375
 
376
+ if('position' in opts && invalidOpt(opts.position)) {
377
+ opts.position = { my: opts.position, at: opts.position };
 
378
  }
379
 
380
+ if('show' in opts && invalidOpt(opts.show)) {
381
+ opts.show = opts.show.jquery ? { target: opts.show } :
382
+ opts.show === TRUE ? { ready: TRUE } : { event: opts.show };
383
  }
384
 
385
+ if('hide' in opts && invalidOpt(opts.hide)) {
386
+ opts.hide = opts.hide.jquery ? { target: opts.hide } : { event: opts.hide };
 
387
  }
388
 
389
+ if('style' in opts && invalidOpt(opts.style)) {
390
+ opts.style = { classes: opts.style };
391
+ }
392
 
393
+ // Sanitize plugin options
394
+ $.each(PLUGINS, function() {
395
+ this.sanitize && this.sanitize(opts);
396
+ });
 
 
 
397
 
398
+ return opts;
399
+ }
 
 
 
 
 
 
 
400
 
401
+ // Setup builtin .set() option checks
402
+ CHECKS = PROTOTYPE.checks = {
403
+ builtin: {
404
+ // Core checks
405
+ '^id$': function(obj, o, v, prev) {
406
+ var id = v === TRUE ? QTIP.nextid : v,
407
+ newId = NAMESPACE + '-' + id;
408
+
409
+ if(id !== FALSE && id.length > 0 && !$('#'+newId).length) {
410
+ this._id = newId;
411
+
412
+ if(this.rendered) {
413
+ this.tooltip[0].id = this._id;
414
+ this.elements.content[0].id = this._id + '-content';
415
+ this.elements.title[0].id = this._id + '-title';
416
+ }
417
  }
418
+ else { obj[o] = prev; }
419
+ },
420
+ '^prerender': function(obj, o, v) {
421
+ v && !this.rendered && this.render(this.options.show.ready);
422
+ },
423
+
424
+ // Content checks
425
+ '^content.text$': function(obj, o, v) {
426
+ this._updateContent(v);
427
+ },
428
+ '^content.attr$': function(obj, o, v, prev) {
429
+ if(this.options.content.text === this.target.attr(prev)) {
430
+ this._updateContent( this.target.attr(v) );
431
  }
432
+ },
433
+ '^content.title$': function(obj, o, v) {
434
+ // Remove title if content is null
435
+ if(!v) { return this._removeTitle(); }
436
 
437
+ // If title isn't already created, create it now and update
438
+ v && !this.elements.title && this._createTitle();
439
+ this._updateTitle(v);
440
+ },
441
+ '^content.button$': function(obj, o, v) {
442
+ this._updateButton(v);
443
+ },
444
+ '^content.title.(text|button)$': function(obj, o, v) {
445
+ this.set('content.'+o, v); // Backwards title.text/button compat
446
+ },
447
+
448
+ // Position checks
449
+ '^position.(my|at)$': function(obj, o, v){
450
+ if('string' === typeof v) {
451
+ this.position[o] = obj[o] = new CORNER(v, o === 'at');
452
  }
453
+ },
454
+ '^position.container$': function(obj, o, v){
455
+ this.rendered && this.tooltip.appendTo(v);
456
+ },
457
 
458
+ // Show checks
459
+ '^show.ready$': function(obj, o, v) {
460
+ v && (!this.rendered && this.render(TRUE) || this.toggle(TRUE));
461
+ },
462
 
463
+ // Style checks
464
+ '^style.classes$': function(obj, o, v, p) {
465
+ this.rendered && this.tooltip.removeClass(p).addClass(v);
466
+ },
467
+ '^style.(width|height)': function(obj, o, v) {
468
+ this.rendered && this.tooltip.css(o, v);
469
+ },
470
+ '^style.widget|content.title': function() {
471
+ this.rendered && this._setWidget();
472
+ },
473
+ '^style.def': function(obj, o, v) {
474
+ this.rendered && this.tooltip.toggleClass(CLASS_DEFAULT, !!v);
475
+ },
476
 
477
+ // Events check
478
+ '^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) {
479
+ this.rendered && this.tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v);
480
+ },
 
 
 
 
481
 
482
+ // Properties which require event reassignment
483
+ '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() {
484
+ if(!this.rendered) { return; }
 
 
 
 
 
 
 
 
 
 
 
 
485
 
486
+ // Set tracking flag
487
+ var posOptions = this.options.position;
488
+ this.tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse);
 
489
 
490
+ // Reassign events
491
+ this._unassignEvents();
492
+ this._assignEvents();
493
  }
494
+ }
495
+ };
496
 
497
+ // Dot notation converter
498
+ function convertNotation(options, notation) {
499
+ var i = 0, obj, option = options,
 
 
 
 
 
500
 
501
+ // Split notation into array
502
+ levels = notation.split('.');
 
503
 
504
+ // Loop through
505
+ while(option = option[ levels[i++] ]) {
506
+ if(i < levels.length) { obj = option; }
507
  }
508
 
509
+ return [obj || options, levels.pop()];
510
+ }
 
 
 
511
 
512
+ PROTOTYPE.get = function(notation) {
513
+ if(this.destroyed) { return this; }
514
+
515
+ var o = convertNotation(this.options, notation.toLowerCase()),
516
+ result = o[0][ o[1] ];
517
+
518
+ return result.precedance ? result.string() : result;
519
+ };
520
+
521
+ function setCallback(notation, args) {
522
+ var category, rule, match;
523
+
524
+ for(category in this.checks) {
525
+ if (!this.checks.hasOwnProperty(category)) { continue; }
526
+
527
+ for(rule in this.checks[category]) {
528
+ if (!this.checks[category].hasOwnProperty(rule)) { continue; }
529
+
530
+ if(match = (new RegExp(rule, 'i')).exec(notation)) {
531
+ args.push(match);
532
+
533
+ if(category === 'builtin' || this.plugins[category]) {
534
+ this.checks[category][rule].apply(
535
+ this.plugins[category] || this, args
536
+ );
537
+ }
538
  }
539
  }
540
+ }
541
+ }
542
+
543
+ var rmove = /^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i,
544
+ rrender = /^prerender|show\.ready/i;
545
 
546
+ PROTOTYPE.set = function(option, value) {
547
+ if(this.destroyed) { return this; }
548
 
549
+ var rendered = this.rendered,
550
+ reposition = FALSE,
551
+ options = this.options,
552
+ name;
553
+
554
+ // Convert singular option/value pair into object form
555
+ if('string' === typeof option) {
556
+ name = option; option = {}; option[name] = value;
557
  }
558
+ else { option = $.extend({}, option); }
559
+
560
+ // Set all of the defined options to their new values
561
+ $.each(option, function(notation, val) {
562
+ if(rendered && rrender.test(notation)) {
563
+ delete option[notation]; return;
564
+ }
565
 
566
+ // Set new obj value
567
+ var obj = convertNotation(options, notation.toLowerCase()), previous;
568
+ previous = obj[0][ obj[1] ];
569
+ obj[0][ obj[1] ] = val && val.nodeType ? $(val) : val;
 
 
 
 
 
570
 
571
+ // Also check if we need to reposition
572
+ reposition = rmove.test(notation) || reposition;
573
+
574
+ // Set the new params for the callback
575
+ option[notation] = [obj[0], obj[1], val, previous];
576
+ });
577
+
578
+ // Re-sanitize options
579
+ sanitizeOptions(options);
580
+
581
+ /*
582
+ * Execute any valid callbacks for the set options
583
+ * Also set positioning flag so we don't get loads of redundant repositioning calls.
584
+ */
585
+ this.positioning = TRUE;
586
+ $.each(option, $.proxy(setCallback, this));
587
+ this.positioning = FALSE;
588
+
589
+ // Update position if needed
590
+ if(this.rendered && this.tooltip[0].offsetWidth > 0 && reposition) {
591
+ this.reposition( options.position.target === 'mouse' ? NULL : this.cache.event );
592
  }
593
 
594
+ return this;
595
+ };
596
+ ;PROTOTYPE._update = function(content, element) {
597
+ var self = this,
598
+ cache = this.cache;
599
+
600
+ // Make sure tooltip is rendered and content is defined. If not return
601
+ if(!this.rendered || !content) { return FALSE; }
 
602
 
603
+ // Use function to parse content
604
+ if($.isFunction(content)) {
605
+ content = content.call(this.elements.target, cache.event, this) || '';
606
+ }
607
+
608
+ // Handle deferred content
609
+ if($.isFunction(content.then)) {
610
+ cache.waiting = TRUE;
611
+ return content.then(function(c) {
612
+ cache.waiting = FALSE;
613
+ return self._update(c, element);
614
+ }, NULL, function(e) {
615
+ return self._update(e, element);
616
  });
 
617
  }
618
 
619
+ // If content is null... return false
620
+ if(content === FALSE || !content && content !== '') { return FALSE; }
621
+
622
+ // Append new content if its a DOM array and show it if hidden
623
+ if(content.jquery && content.length > 0) {
624
+ element.empty().append(
625
+ content.css({ display: 'block', visibility: 'visible' })
626
+ );
627
+ }
628
 
629
+ // Content is a regular string, insert the new content
630
+ else { element.html(content); }
 
631
 
632
+ // Wait for content to be loaded, and reposition
633
+ return this._waitForContent(element).then(function(images) {
634
+ if(self.rendered && self.tooltip[0].offsetWidth > 0) {
635
+ self.reposition(cache.event, !images.length);
636
  }
637
+ });
638
+ };
639
 
640
+ PROTOTYPE._waitForContent = function(element) {
641
+ var cache = this.cache;
 
 
 
642
 
643
+ // Set flag
644
+ cache.waiting = TRUE;
 
645
 
646
+ // If imagesLoaded is included, ensure images have loaded and return promise
647
+ return ( $.fn.imagesLoaded ? element.imagesLoaded() : new $.Deferred().resolve([]) )
648
+ .done(function() { cache.waiting = FALSE; })
649
+ .promise();
650
+ };
651
+
652
+ PROTOTYPE._updateContent = function(content, reposition) {
653
+ this._update(content, this.elements.content, reposition);
654
+ };
655
+
656
+ PROTOTYPE._updateTitle = function(content, reposition) {
657
+ if(this._update(content, this.elements.title, reposition) === FALSE) {
658
+ this._removeTitle(FALSE);
659
  }
660
+ };
661
 
662
+ PROTOTYPE._createTitle = function()
663
+ {
664
+ var elements = this.elements,
665
+ id = this._id+'-title';
666
+
667
+ // Destroy previous title element, if present
668
+ if(elements.titlebar) { this._removeTitle(); }
669
+
670
+ // Create title bar and title elements
671
+ elements.titlebar = $('<div />', {
672
+ 'class': NAMESPACE + '-titlebar ' + (this.options.style.widget ? createWidgetClass('header') : '')
673
+ })
674
+ .append(
675
+ elements.title = $('<div />', {
676
+ 'id': id,
677
+ 'class': NAMESPACE + '-title',
678
+ 'aria-atomic': TRUE
679
+ })
680
+ )
681
+ .insertBefore(elements.content)
682
+
683
+ // Button-specific events
684
+ .delegate('.qtip-close', 'mousedown keydown mouseup keyup mouseout', function(event) {
685
+ $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down');
686
+ })
687
+ .delegate('.qtip-close', 'mouseover mouseout', function(event){
688
+ $(this).toggleClass('ui-state-hover', event.type === 'mouseover');
689
+ });
690
 
691
+ // Create button if enabled
692
+ if(this.options.content.button) { this._createButton(); }
693
+ };
 
 
 
 
694
 
695
+ PROTOTYPE._removeTitle = function(reposition)
696
+ {
697
+ var elements = this.elements;
698
 
699
+ if(elements.title) {
700
+ elements.titlebar.remove();
701
+ elements.titlebar = elements.title = elements.button = NULL;
702
 
703
+ // Reposition if enabled
704
+ if(reposition !== FALSE) { this.reposition(); }
 
705
  }
706
+ };
707
+ ;PROTOTYPE._createPosClass = function(my) {
708
+ return NAMESPACE + '-pos-' + (my || this.options.position.my).abbrev();
709
+ };
710
 
711
+ PROTOTYPE.reposition = function(event, effect) {
712
+ if(!this.rendered || this.positioning || this.destroyed) { return this; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
713
 
714
+ // Set positioning flag
715
+ this.positioning = TRUE;
 
 
 
716
 
717
+ var cache = this.cache,
718
+ tooltip = this.tooltip,
719
+ posOptions = this.options.position,
720
+ target = posOptions.target,
721
+ my = posOptions.my,
722
+ at = posOptions.at,
723
+ viewport = posOptions.viewport,
724
+ container = posOptions.container,
725
+ adjust = posOptions.adjust,
726
+ method = adjust.method.split(' '),
727
+ tooltipWidth = tooltip.outerWidth(FALSE),
728
+ tooltipHeight = tooltip.outerHeight(FALSE),
729
+ targetWidth = 0,
730
+ targetHeight = 0,
731
+ type = tooltip.css('position'),
732
+ position = { left: 0, top: 0 },
733
+ visible = tooltip[0].offsetWidth > 0,
734
+ isScroll = event && event.type === 'scroll',
735
+ win = $(window),
736
+ doc = container[0].ownerDocument,
737
+ mouse = this.mouse,
738
+ pluginCalculations, offset, adjusted, newClass;
739
+
740
+ // Check if absolute position was passed
741
+ if($.isArray(target) && target.length === 2) {
742
+ // Force left top and set position
743
+ at = { x: LEFT, y: TOP };
744
+ position = { left: target[0], top: target[1] };
745
+ }
746
 
747
+ // Check if mouse was the target
748
+ else if(target === 'mouse') {
749
+ // Force left top to allow flipping
750
+ at = { x: LEFT, y: TOP };
751
 
752
+ // Use the mouse origin that caused the show event, if distance hiding is enabled
753
+ if((!adjust.mouse || this.options.hide.distance) && cache.origin && cache.origin.pageX) {
754
+ event = cache.origin;
755
+ }
 
 
 
 
756
 
757
+ // Use cached event for resize/scroll events
758
+ else if(!event || event && (event.type === 'resize' || event.type === 'scroll')) {
759
+ event = cache.event;
760
+ }
761
 
762
+ // Otherwise, use the cached mouse coordinates if available
763
+ else if(mouse && mouse.pageX) {
764
+ event = mouse;
765
+ }
 
 
 
 
 
766
 
767
+ // Calculate body and container offset and take them into account below
768
+ if(type !== 'static') { position = container.offset(); }
769
+ if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) {
770
+ offset = $(document.body).offset();
771
+ }
772
 
773
+ // Use event coordinates for position
774
+ position = {
775
+ left: event.pageX - position.left + (offset && offset.left || 0),
776
+ top: event.pageY - position.top + (offset && offset.top || 0)
777
+ };
778
 
779
+ // Scroll events are a pain, some browsers
780
+ if(adjust.mouse && isScroll && mouse) {
781
+ position.left -= (mouse.scrollX || 0) - win.scrollLeft();
782
+ position.top -= (mouse.scrollY || 0) - win.scrollTop();
783
+ }
784
+ }
785
 
786
+ // Target wasn't mouse or absolute...
787
+ else {
788
+ // Check if event targetting is being used
789
+ if(target === 'event') {
790
+ if(event && event.target && event.type !== 'scroll' && event.type !== 'resize') {
791
+ cache.target = $(event.target);
792
  }
793
+ else if(!event.target) {
794
+ cache.target = this.elements.target;
795
+ }
796
+ }
797
+ else if(target !== 'event'){
798
+ cache.target = $(target.jquery ? target : this.elements.target);
799
+ }
800
+ target = cache.target;
801
 
802
+ // Parse the target into a jQuery object and make sure there's an element present
803
+ target = $(target).eq(0);
804
+ if(target.length === 0) { return this; }
805
 
806
+ // Check if window or document is the target
807
+ else if(target[0] === document || target[0] === window) {
808
+ targetWidth = BROWSER.iOS ? window.innerWidth : target.width();
809
+ targetHeight = BROWSER.iOS ? window.innerHeight : target.height();
 
810
 
811
+ if(target[0] === window) {
812
+ position = {
813
+ top: (viewport || target).scrollTop(),
814
+ left: (viewport || target).scrollLeft()
815
+ };
816
+ }
817
+ }
818
 
819
+ // Check if the target is an <AREA> element
820
+ else if(PLUGINS.imagemap && target.is('area')) {
821
+ pluginCalculations = PLUGINS.imagemap(this, target, at, PLUGINS.viewport ? method : FALSE);
822
+ }
823
 
824
+ // Check if the target is an SVG element
825
+ else if(PLUGINS.svg && target && target[0].ownerSVGElement) {
826
+ pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.viewport ? method : FALSE);
827
+ }
828
 
829
+ // Otherwise use regular jQuery methods
830
+ else {
831
+ targetWidth = target.outerWidth(FALSE);
832
+ targetHeight = target.outerHeight(FALSE);
833
+ position = target.offset();
834
+ }
835
 
836
+ // Parse returned plugin values into proper variables
837
+ if(pluginCalculations) {
838
+ targetWidth = pluginCalculations.width;
839
+ targetHeight = pluginCalculations.height;
840
+ offset = pluginCalculations.offset;
841
+ position = pluginCalculations.position;
842
+ }
843
 
844
+ // Adjust position to take into account offset parents
845
+ position = this.reposition.offset(target, position, container);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
846
 
847
+ // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2)
848
+ if(BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1 ||
849
+ BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33 ||
850
+ !BROWSER.iOS && type === 'fixed'
851
+ ){
852
+ position.left -= win.scrollLeft();
853
+ position.top -= win.scrollTop();
854
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
855
 
856
+ // Adjust position relative to target
857
+ if(!pluginCalculations || pluginCalculations && pluginCalculations.adjustable !== FALSE) {
858
+ position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0;
859
+ position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0;
860
+ }
861
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
862
 
863
+ // Adjust position relative to tooltip
864
+ position.left += adjust.x + (my.x === RIGHT ? -tooltipWidth : my.x === CENTER ? -tooltipWidth / 2 : 0);
865
+ position.top += adjust.y + (my.y === BOTTOM ? -tooltipHeight : my.y === CENTER ? -tooltipHeight / 2 : 0);
866
 
867
+ // Use viewport adjustment plugin if enabled
868
+ if(PLUGINS.viewport) {
869
+ adjusted = position.adjusted = PLUGINS.viewport(
870
+ this, position, posOptions, targetWidth, targetHeight, tooltipWidth, tooltipHeight
871
+ );
 
 
872
 
873
+ // Apply offsets supplied by positioning plugin (if used)
874
+ if(offset && adjusted.left) { position.left += offset.left; }
875
+ if(offset && adjusted.top) { position.top += offset.top; }
876
 
877
+ // Apply any new 'my' position
878
+ if(adjusted.my) { this.position.my = adjusted.my; }
879
+ }
880
+
881
+ // Viewport adjustment is disabled, set values to zero
882
+ else { position.adjusted = { left: 0, top: 0 }; }
883
+
884
+ // Set tooltip position class if it's changed
885
+ if(cache.posClass !== (newClass = this._createPosClass(this.position.my))) {
886
+ cache.posClass = newClass;
887
+ tooltip.removeClass(cache.posClass).addClass(newClass);
888
+ }
889
+
890
+ // tooltipmove event
891
+ if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; }
892
+ delete position.adjusted;
893
+
894
+ // If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly
895
+ if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) {
896
+ tooltip.css(position);
897
+ }
898
+
899
+ // Use custom function if provided
900
+ else if($.isFunction(posOptions.effect)) {
901
+ posOptions.effect.call(tooltip, this, $.extend({}, position));
902
+ tooltip.queue(function(next) {
903
+ // Reset attributes to avoid cross-browser rendering bugs
904
+ $(this).css({ opacity: '', height: '' });
905
+ if(BROWSER.ie) { this.style.removeAttribute('filter'); }
906
+
907
+ next();
908
+ });
909
+ }
910
+
911
+ // Set positioning flag
912
+ this.positioning = FALSE;
913
+
914
+ return this;
915
+ };
916
+
917
+ // Custom (more correct for qTip!) offset calculator
918
+ PROTOTYPE.reposition.offset = function(elem, pos, container) {
919
+ if(!container[0]) { return pos; }
920
+
921
+ var ownerDocument = $(elem[0].ownerDocument),
922
+ quirks = !!BROWSER.ie && document.compatMode !== 'CSS1Compat',
923
+ parent = container[0],
924
+ scrolled, position, parentOffset, overflow;
925
+
926
+ function scroll(e, i) {
927
+ pos.left += i * e.scrollLeft();
928
+ pos.top += i * e.scrollTop();
929
+ }
930
+
931
+ // Compensate for non-static containers offset
932
+ do {
933
+ if((position = $.css(parent, 'position')) !== 'static') {
934
+ if(position === 'fixed') {
935
+ parentOffset = parent.getBoundingClientRect();
936
+ scroll(ownerDocument, -1);
937
+ }
938
+ else {
939
+ parentOffset = $(parent).position();
940
+ parentOffset.left += parseFloat($.css(parent, 'borderLeftWidth')) || 0;
941
+ parentOffset.top += parseFloat($.css(parent, 'borderTopWidth')) || 0;
942
+ }
943
+
944
+ pos.left -= parentOffset.left + (parseFloat($.css(parent, 'marginLeft')) || 0);
945
+ pos.top -= parentOffset.top + (parseFloat($.css(parent, 'marginTop')) || 0);
946
+
947
+ // If this is the first parent element with an overflow of "scroll" or "auto", store it
948
+ if(!scrolled && (overflow = $.css(parent, 'overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = $(parent); }
949
+ }
950
+ }
951
+ while(parent = parent.offsetParent);
952
+
953
+ // Compensate for containers scroll if it also has an offsetParent (or in IE quirks mode)
954
+ if(scrolled && (scrolled[0] !== ownerDocument[0] || quirks)) {
955
+ scroll(scrolled, 1);
956
+ }
957
+
958
+ return pos;
959
+ };
960
+
961
+ // Corner class
962
+ var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) {
963
+ corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase();
964
+ this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase();
965
+ this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase();
966
+ this.forceY = !!forceY;
967
+
968
+ var f = corner.charAt(0);
969
+ this.precedance = f === 't' || f === 'b' ? Y : X;
970
+ }).prototype;
971
+
972
+ C.invert = function(z, center) {
973
+ this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z];
974
+ };
975
+
976
+ C.string = function(join) {
977
+ var x = this.x, y = this.y;
978
+
979
+ var result = x !== y ?
980
+ x === 'center' || y !== 'center' && (this.precedance === Y || this.forceY) ?
981
+ [y,x] :
982
+ [x,y] :
983
+ [x];
984
+
985
+ return join !== false ? result.join(' ') : result;
986
+ };
987
+
988
+ C.abbrev = function() {
989
+ var result = this.string(false);
990
+ return result[0].charAt(0) + (result[1] && result[1].charAt(0) || '');
991
+ };
992
+
993
+ C.clone = function() {
994
+ return new CORNER( this.string(), this.forceY );
995
+ };
996
+
997
+ ;
998
+ PROTOTYPE.toggle = function(state, event) {
999
+ var cache = this.cache,
1000
+ options = this.options,
1001
+ tooltip = this.tooltip;
1002
+
1003
+ // Try to prevent flickering when tooltip overlaps show element
1004
+ if(event) {
1005
+ if((/over|enter/).test(event.type) && cache.event && (/out|leave/).test(cache.event.type) &&
1006
+ options.show.target.add(event.target).length === options.show.target.length &&
1007
+ tooltip.has(event.relatedTarget).length) {
1008
+ return this;
1009
+ }
1010
+
1011
+ // Cache event
1012
+ cache.event = $.event.fix(event);
1013
+ }
1014
+
1015
+ // If we're currently waiting and we've just hidden... stop it
1016
+ this.waiting && !state && (this.hiddenDuringWait = TRUE);
1017
+
1018
+ // Render the tooltip if showing and it isn't already
1019
+ if(!this.rendered) { return state ? this.render(1) : this; }
1020
+ else if(this.destroyed || this.disabled) { return this; }
1021
+
1022
+ var type = state ? 'show' : 'hide',
1023
+ opts = this.options[type],
1024
+ posOptions = this.options.position,
1025
+ contentOptions = this.options.content,
1026
+ width = this.tooltip.css('width'),
1027
+ visible = this.tooltip.is(':visible'),
1028
+ animate = state || opts.target.length === 1,
1029
+ sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target,
1030
+ identicalState, allow, after;
1031
+
1032
+ // Detect state if valid one isn't provided
1033
+ if((typeof state).search('boolean|number')) { state = !visible; }
1034
+
1035
+ // Check if the tooltip is in an identical state to the new would-be state
1036
+ identicalState = !tooltip.is(':animated') && visible === state && sameTarget;
1037
+
1038
+ // Fire tooltip(show/hide) event and check if destroyed
1039
+ allow = !identicalState ? !!this._trigger(type, [90]) : NULL;
1040
+
1041
+ // Check to make sure the tooltip wasn't destroyed in the callback
1042
+ if(this.destroyed) { return this; }
1043
+
1044
+ // If the user didn't stop the method prematurely and we're showing the tooltip, focus it
1045
+ if(allow !== FALSE && state) { this.focus(event); }
1046
+
1047
+ // If the state hasn't changed or the user stopped it, return early
1048
+ if(!allow || identicalState) { return this; }
1049
+
1050
+ // Set ARIA hidden attribute
1051
+ $.attr(tooltip[0], 'aria-hidden', !!!state);
1052
+
1053
+ // Execute state specific properties
1054
+ if(state) {
1055
+ // Store show origin coordinates
1056
+ this.mouse && (cache.origin = $.event.fix(this.mouse));
1057
+
1058
+ // Update tooltip content & title if it's a dynamic function
1059
+ if($.isFunction(contentOptions.text)) { this._updateContent(contentOptions.text, FALSE); }
1060
+ if($.isFunction(contentOptions.title)) { this._updateTitle(contentOptions.title, FALSE); }
1061
+
1062
+ // Cache mousemove events for positioning purposes (if not already tracking)
1063
+ if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) {
1064
+ $(document).bind('mousemove.'+NAMESPACE, this._storeMouse);
1065
+ trackingBound = TRUE;
1066
+ }
1067
+
1068
+ // Update the tooltip position (set width first to prevent viewport/max-width issues)
1069
+ if(!width) { tooltip.css('width', tooltip.outerWidth(FALSE)); }
1070
+ this.reposition(event, arguments[2]);
1071
+ if(!width) { tooltip.css('width', ''); }
1072
+
1073
+ // Hide other tooltips if tooltip is solo
1074
+ if(!!opts.solo) {
1075
+ (typeof opts.solo === 'string' ? $(opts.solo) : $(SELECTOR, opts.solo))
1076
+ .not(tooltip).not(opts.target).qtip('hide', new $.Event('tooltipsolo'));
1077
+ }
1078
+ }
1079
+ else {
1080
+ // Clear show timer if we're hiding
1081
+ clearTimeout(this.timers.show);
1082
+
1083
+ // Remove cached origin on hide
1084
+ delete cache.origin;
1085
+
1086
+ // Remove mouse tracking event if not needed (all tracking qTips are hidden)
1087
+ if(trackingBound && !$(SELECTOR+'[tracking="true"]:visible', opts.solo).not(tooltip).length) {
1088
+ $(document).unbind('mousemove.'+NAMESPACE);
1089
+ trackingBound = FALSE;
1090
+ }
1091
+
1092
+ // Blur the tooltip
1093
+ this.blur(event);
1094
+ }
1095
+
1096
+ // Define post-animation, state specific properties
1097
+ after = $.proxy(function() {
1098
+ if(state) {
1099
+ // Prevent antialias from disappearing in IE by removing filter
1100
+ if(BROWSER.ie) { tooltip[0].style.removeAttribute('filter'); }
1101
+
1102
+ // Remove overflow setting to prevent tip bugs
1103
+ tooltip.css('overflow', '');
1104
+
1105
+ // Autofocus elements if enabled
1106
+ if('string' === typeof opts.autofocus) {
1107
+ $(this.options.show.autofocus, tooltip).focus();
1108
+ }
1109
+
1110
+ // If set, hide tooltip when inactive for delay period
1111
+ this.options.show.target.trigger('qtip-'+this.id+'-inactive');
1112
+ }
1113
+ else {
1114
+ // Reset CSS states
1115
+ tooltip.css({
1116
+ display: '',
1117
+ visibility: '',
1118
+ opacity: '',
1119
+ left: '',
1120
+ top: ''
1121
+ });
1122
+ }
1123
+
1124
+ // tooltipvisible/tooltiphidden events
1125
+ this._trigger(state ? 'visible' : 'hidden');
1126
+ }, this);
1127
+
1128
+ // If no effect type is supplied, use a simple toggle
1129
+ if(opts.effect === FALSE || animate === FALSE) {
1130
+ tooltip[ type ]();
1131
+ after();
1132
+ }
1133
+
1134
+ // Use custom function if provided
1135
+ else if($.isFunction(opts.effect)) {
1136
+ tooltip.stop(1, 1);
1137
+ opts.effect.call(tooltip, this);
1138
+ tooltip.queue('fx', function(n) {
1139
+ after(); n();
1140
+ });
1141
+ }
1142
+
1143
+ // Use basic fade function by default
1144
+ else { tooltip.fadeTo(90, state ? 1 : 0, after); }
1145
+
1146
+ // If inactive hide method is set, active it
1147
+ if(state) { opts.target.trigger('qtip-'+this.id+'-inactive'); }
1148
+
1149
+ return this;
1150
+ };
1151
+
1152
+ PROTOTYPE.show = function(event) { return this.toggle(TRUE, event); };
1153
+
1154
+ PROTOTYPE.hide = function(event) { return this.toggle(FALSE, event); };
1155
+ ;PROTOTYPE.focus = function(event) {
1156
+ if(!this.rendered || this.destroyed) { return this; }
1157
+
1158
+ var qtips = $(SELECTOR),
1159
+ tooltip = this.tooltip,
1160
+ curIndex = parseInt(tooltip[0].style.zIndex, 10),
1161
+ newIndex = QTIP.zindex + qtips.length;
1162
+
1163
+ // Only update the z-index if it has changed and tooltip is not already focused
1164
+ if(!tooltip.hasClass(CLASS_FOCUS)) {
1165
+ // tooltipfocus event
1166
+ if(this._trigger('focus', [newIndex], event)) {
1167
+ // Only update z-index's if they've changed
1168
+ if(curIndex !== newIndex) {
1169
+ // Reduce our z-index's and keep them properly ordered
1170
+ qtips.each(function() {
1171
+ if(this.style.zIndex > curIndex) {
1172
+ this.style.zIndex = this.style.zIndex - 1;
1173
+ }
1174
+ });
1175
+
1176
+ // Fire blur event for focused tooltip
1177
+ qtips.filter('.' + CLASS_FOCUS).qtip('blur', event);
1178
+ }
1179
+
1180
+ // Set the new z-index
1181
+ tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex;
1182
+ }
1183
+ }
1184
+
1185
+ return this;
1186
+ };
1187
+
1188
+ PROTOTYPE.blur = function(event) {
1189
+ if(!this.rendered || this.destroyed) { return this; }
1190
+
1191
+ // Set focused status to FALSE
1192
+ this.tooltip.removeClass(CLASS_FOCUS);
1193
+
1194
+ // tooltipblur event
1195
+ this._trigger('blur', [ this.tooltip.css('zIndex') ], event);
1196
+
1197
+ return this;
1198
+ };
1199
+ ;PROTOTYPE.disable = function(state) {
1200
+ if(this.destroyed) { return this; }
1201
+
1202
+ // If 'toggle' is passed, toggle the current state
1203
+ if(state === 'toggle') {
1204
+ state = !(this.rendered ? this.tooltip.hasClass(CLASS_DISABLED) : this.disabled);
1205
+ }
1206
+
1207
+ // Disable if no state passed
1208
+ else if('boolean' !== typeof state) {
1209
+ state = TRUE;
1210
+ }
1211
+
1212
+ if(this.rendered) {
1213
+ this.tooltip.toggleClass(CLASS_DISABLED, state)
1214
+ .attr('aria-disabled', state);
1215
+ }
1216
+
1217
+ this.disabled = !!state;
1218
+
1219
+ return this;
1220
+ };
1221
+
1222
+ PROTOTYPE.enable = function() { return this.disable(FALSE); };
1223
+ ;PROTOTYPE._createButton = function()
1224
+ {
1225
+ var self = this,
1226
+ elements = this.elements,
1227
+ tooltip = elements.tooltip,
1228
+ button = this.options.content.button,
1229
+ isString = typeof button === 'string',
1230
+ close = isString ? button : 'Close tooltip';
1231
 
1232
+ if(elements.button) { elements.button.remove(); }
1233
+
1234
+ // Use custom button if one was supplied by user, else use default
1235
+ if(button.jquery) {
1236
+ elements.button = button;
1237
+ }
1238
+ else {
1239
+ elements.button = $('<a />', {
1240
+ 'class': 'qtip-close ' + (this.options.style.widget ? '' : NAMESPACE+'-icon'),
1241
+ 'title': close,
1242
+ 'aria-label': close
1243
+ })
1244
+ .prepend(
1245
+ $('<span />', {
1246
+ 'class': 'ui-icon ui-icon-close',
1247
+ 'html': '&times;'
1248
+ })
1249
+ );
1250
+ }
1251
+
1252
+ // Create button and setup attributes
1253
+ elements.button.appendTo(elements.titlebar || tooltip)
1254
+ .attr('role', 'button')
1255
+ .click(function(event) {
1256
+ if(!tooltip.hasClass(CLASS_DISABLED)) { self.hide(event); }
1257
+ return FALSE;
1258
+ });
1259
+ };
1260
+
1261
+ PROTOTYPE._updateButton = function(button)
1262
+ {
1263
+ // Make sure tooltip is rendered and if not, return
1264
+ if(!this.rendered) { return FALSE; }
1265
+
1266
+ var elem = this.elements.button;
1267
+ if(button) { this._createButton(); }
1268
+ else { elem.remove(); }
1269
+ };
1270
+ ;// Widget class creator
1271
+ function createWidgetClass(cls) {
1272
+ return WIDGET.concat('').join(cls ? '-'+cls+' ' : ' ');
1273
+ }
1274
+
1275
+ // Widget class setter method
1276
+ PROTOTYPE._setWidget = function()
1277
+ {
1278
+ var on = this.options.style.widget,
1279
+ elements = this.elements,
1280
+ tooltip = elements.tooltip,
1281
+ disabled = tooltip.hasClass(CLASS_DISABLED);
1282
+
1283
+ tooltip.removeClass(CLASS_DISABLED);
1284
+ CLASS_DISABLED = on ? 'ui-state-disabled' : 'qtip-disabled';
1285
+ tooltip.toggleClass(CLASS_DISABLED, disabled);
1286
+
1287
+ tooltip.toggleClass('ui-helper-reset '+createWidgetClass(), on).toggleClass(CLASS_DEFAULT, this.options.style.def && !on);
1288
+
1289
+ if(elements.content) {
1290
+ elements.content.toggleClass( createWidgetClass('content'), on);
1291
+ }
1292
+ if(elements.titlebar) {
1293
+ elements.titlebar.toggleClass( createWidgetClass('header'), on);
1294
+ }
1295
+ if(elements.button) {
1296
+ elements.button.toggleClass(NAMESPACE+'-icon', !on);
1297
+ }
1298
+ };
1299
+ ;function delay(callback, duration) {
1300
+ // If tooltip has displayed, start hide timer
1301
+ if(duration > 0) {
1302
+ return setTimeout(
1303
+ $.proxy(callback, this), duration
1304
+ );
1305
+ }
1306
+ else{ callback.call(this); }
1307
+ }
1308
+
1309
+ function showMethod(event) {
1310
+ if(this.tooltip.hasClass(CLASS_DISABLED)) { return; }
1311
+
1312
+ // Clear hide timers
1313
+ clearTimeout(this.timers.show);
1314
+ clearTimeout(this.timers.hide);
1315
+
1316
+ // Start show timer
1317
+ this.timers.show = delay.call(this,
1318
+ function() { this.toggle(TRUE, event); },
1319
+ this.options.show.delay
1320
+ );
1321
+ }
1322
+
1323
+ function hideMethod(event) {
1324
+ if(this.tooltip.hasClass(CLASS_DISABLED) || this.destroyed) { return; }
1325
+
1326
+ // Check if new target was actually the tooltip element
1327
+ var relatedTarget = $(event.relatedTarget),
1328
+ ontoTooltip = relatedTarget.closest(SELECTOR)[0] === this.tooltip[0],
1329
+ ontoTarget = relatedTarget[0] === this.options.show.target[0];
1330
+
1331
+ // Clear timers and stop animation queue
1332
+ clearTimeout(this.timers.show);
1333
+ clearTimeout(this.timers.hide);
1334
+
1335
+ // Prevent hiding if tooltip is fixed and event target is the tooltip.
1336
+ // Or if mouse positioning is enabled and cursor momentarily overlaps
1337
+ if(this !== relatedTarget[0] &&
1338
+ (this.options.position.target === 'mouse' && ontoTooltip) ||
1339
+ this.options.hide.fixed && (
1340
+ (/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget))
1341
+ )
1342
+ {
1343
+ /* eslint-disable no-empty */
1344
+ try {
1345
+ event.preventDefault();
1346
+ event.stopImmediatePropagation();
1347
+ } catch(e) {}
1348
+ /* eslint-enable no-empty */
1349
+
1350
+ return;
1351
+ }
1352
+
1353
+ // If tooltip has displayed, start hide timer
1354
+ this.timers.hide = delay.call(this,
1355
+ function() { this.toggle(FALSE, event); },
1356
+ this.options.hide.delay,
1357
+ this
1358
+ );
1359
+ }
1360
+
1361
+ function inactiveMethod(event) {
1362
+ if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return; }
1363
+
1364
+ // Clear timer
1365
+ clearTimeout(this.timers.inactive);
1366
+
1367
+ this.timers.inactive = delay.call(this,
1368
+ function(){ this.hide(event); },
1369
+ this.options.hide.inactive
1370
+ );
1371
+ }
1372
+
1373
+ function repositionMethod(event) {
1374
+ if(this.rendered && this.tooltip[0].offsetWidth > 0) { this.reposition(event); }
1375
+ }
1376
+
1377
+ // Store mouse coordinates
1378
+ PROTOTYPE._storeMouse = function(event) {
1379
+ (this.mouse = $.event.fix(event)).type = 'mousemove';
1380
+ return this;
1381
+ };
1382
+
1383
+ // Bind events
1384
+ PROTOTYPE._bind = function(targets, events, method, suffix, context) {
1385
+ if(!targets || !method || !events.length) { return; }
1386
+ var ns = '.' + this._id + (suffix ? '-'+suffix : '');
1387
+ $(targets).bind(
1388
+ (events.split ? events : events.join(ns + ' ')) + ns,
1389
+ $.proxy(method, context || this)
1390
+ );
1391
+ return this;
1392
+ };
1393
+ PROTOTYPE._unbind = function(targets, suffix) {
1394
+ targets && $(targets).unbind('.' + this._id + (suffix ? '-'+suffix : ''));
1395
+ return this;
1396
+ };
1397
+
1398
+ // Global delegation helper
1399
+ function delegate(selector, events, method) {
1400
+ $(document.body).delegate(selector,
1401
+ (events.split ? events : events.join('.'+NAMESPACE + ' ')) + '.'+NAMESPACE,
1402
+ function() {
1403
+ var api = QTIP.api[ $.attr(this, ATTR_ID) ];
1404
+ api && !api.disabled && method.apply(api, arguments);
1405
+ }
1406
+ );
1407
+ }
1408
+ // Event trigger
1409
+ PROTOTYPE._trigger = function(type, args, event) {
1410
+ var callback = new $.Event('tooltip'+type);
1411
+ callback.originalEvent = event && $.extend({}, event) || this.cache.event || NULL;
1412
+
1413
+ this.triggering = type;
1414
+ this.tooltip.trigger(callback, [this].concat(args || []));
1415
+ this.triggering = FALSE;
1416
+
1417
+ return !callback.isDefaultPrevented();
1418
+ };
1419
+
1420
+ PROTOTYPE._bindEvents = function(showEvents, hideEvents, showTargets, hideTargets, showCallback, hideCallback) {
1421
+ // Get tasrgets that lye within both
1422
+ var similarTargets = showTargets.filter( hideTargets ).add( hideTargets.filter(showTargets) ),
1423
+ toggleEvents = [];
1424
+
1425
+ // If hide and show targets are the same...
1426
+ if(similarTargets.length) {
1427
+
1428
+ // Filter identical show/hide events
1429
+ $.each(hideEvents, function(i, type) {
1430
+ var showIndex = $.inArray(type, showEvents);
1431
+
1432
+ // Both events are identical, remove from both hide and show events
1433
+ // and append to toggleEvents
1434
+ showIndex > -1 && toggleEvents.push( showEvents.splice( showIndex, 1 )[0] );
1435
+ });
1436
+
1437
+ // Toggle events are special case of identical show/hide events, which happen in sequence
1438
+ if(toggleEvents.length) {
1439
+ // Bind toggle events to the similar targets
1440
+ this._bind(similarTargets, toggleEvents, function(event) {
1441
+ var state = this.rendered ? this.tooltip[0].offsetWidth > 0 : false;
1442
+ (state ? hideCallback : showCallback).call(this, event);
1443
+ });
1444
+
1445
+ // Remove the similar targets from the regular show/hide bindings
1446
+ showTargets = showTargets.not(similarTargets);
1447
+ hideTargets = hideTargets.not(similarTargets);
1448
+ }
1449
+ }
1450
+
1451
+ // Apply show/hide/toggle events
1452
+ this._bind(showTargets, showEvents, showCallback);
1453
+ this._bind(hideTargets, hideEvents, hideCallback);
1454
+ };
1455
+
1456
+ PROTOTYPE._assignInitialEvents = function(event) {
1457
+ var options = this.options,
1458
+ showTarget = options.show.target,
1459
+ hideTarget = options.hide.target,
1460
+ showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [],
1461
+ hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : [];
1462
+
1463
+ // Catch remove/removeqtip events on target element to destroy redundant tooltips
1464
+ this._bind(this.elements.target, ['remove', 'removeqtip'], function() {
1465
+ this.destroy(true);
1466
+ }, 'destroy');
1467
+
1468
+ /*
1469
+ * Make sure hoverIntent functions properly by using mouseleave as a hide event if
1470
+ * mouseenter/mouseout is used for show.event, even if it isn't in the users options.
1471
+ */
1472
+ if(/mouse(over|enter)/i.test(options.show.event) && !/mouse(out|leave)/i.test(options.hide.event)) {
1473
+ hideEvents.push('mouseleave');
1474
+ }
1475
+
1476
+ /*
1477
+ * Also make sure initial mouse targetting works correctly by caching mousemove coords
1478
+ * on show targets before the tooltip has rendered. Also set onTarget when triggered to
1479
+ * keep mouse tracking working.
1480
+ */
1481
+ this._bind(showTarget, 'mousemove', function(moveEvent) {
1482
+ this._storeMouse(moveEvent);
1483
+ this.cache.onTarget = TRUE;
1484
+ });
1485
+
1486
+ // Define hoverIntent function
1487
+ function hoverIntent(hoverEvent) {
1488
+ // Only continue if tooltip isn't disabled
1489
+ if(this.disabled || this.destroyed) { return FALSE; }
1490
+
1491
+ // Cache the event data
1492
+ this.cache.event = hoverEvent && $.event.fix(hoverEvent);
1493
+ this.cache.target = hoverEvent && $(hoverEvent.target);
1494
+
1495
+ // Start the event sequence
1496
+ clearTimeout(this.timers.show);
1497
+ this.timers.show = delay.call(this,
1498
+ function() { this.render(typeof hoverEvent === 'object' || options.show.ready); },
1499
+ options.prerender ? 0 : options.show.delay
1500
+ );
1501
+ }
1502
+
1503
+ // Filter and bind events
1504
+ this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, hoverIntent, function() {
1505
+ if(!this.timers) { return FALSE; }
1506
+ clearTimeout(this.timers.show);
1507
+ });
1508
+
1509
+ // Prerendering is enabled, create tooltip now
1510
+ if(options.show.ready || options.prerender) { hoverIntent.call(this, event); }
1511
+ };
1512
+
1513
+ // Event assignment method
1514
+ PROTOTYPE._assignEvents = function() {
1515
+ var self = this,
1516
+ options = this.options,
1517
+ posOptions = options.position,
1518
+
1519
+ tooltip = this.tooltip,
1520
+ showTarget = options.show.target,
1521
+ hideTarget = options.hide.target,
1522
+ containerTarget = posOptions.container,
1523
+ viewportTarget = posOptions.viewport,
1524
+ documentTarget = $(document),
1525
+ windowTarget = $(window),
1526
+
1527
+ showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [],
1528
+ hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : [];
1529
+
1530
+
1531
+ // Assign passed event callbacks
1532
+ $.each(options.events, function(name, callback) {
1533
+ self._bind(tooltip, name === 'toggle' ? ['tooltipshow','tooltiphide'] : ['tooltip'+name], callback, null, tooltip);
1534
+ });
1535
+
1536
+ // Hide tooltips when leaving current window/frame (but not select/option elements)
1537
+ if(/mouse(out|leave)/i.test(options.hide.event) && options.hide.leave === 'window') {
1538
+ this._bind(documentTarget, ['mouseout', 'blur'], function(event) {
1539
+ if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) {
1540
+ this.hide(event);
1541
+ }
1542
+ });
1543
+ }
1544
+
1545
+ // Enable hide.fixed by adding appropriate class
1546
+ if(options.hide.fixed) {
1547
+ hideTarget = hideTarget.add( tooltip.addClass(CLASS_FIXED) );
1548
+ }
1549
+
1550
+ /*
1551
+ * Make sure hoverIntent functions properly by using mouseleave to clear show timer if
1552
+ * mouseenter/mouseout is used for show.event, even if it isn't in the users options.
1553
+ */
1554
+ else if(/mouse(over|enter)/i.test(options.show.event)) {
1555
+ this._bind(hideTarget, 'mouseleave', function() {
1556
+ clearTimeout(this.timers.show);
1557
+ });
1558
+ }
1559
+
1560
+ // Hide tooltip on document mousedown if unfocus events are enabled
1561
+ if(('' + options.hide.event).indexOf('unfocus') > -1) {
1562
+ this._bind(containerTarget.closest('html'), ['mousedown', 'touchstart'], function(event) {
1563
+ var elem = $(event.target),
1564
+ enabled = this.rendered && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0,
1565
+ isAncestor = elem.parents(SELECTOR).filter(this.tooltip[0]).length > 0;
1566
+
1567
+ if(elem[0] !== this.target[0] && elem[0] !== this.tooltip[0] && !isAncestor &&
1568
+ !this.target.has(elem[0]).length && enabled
1569
+ ) {
1570
+ this.hide(event);
1571
+ }
1572
+ });
1573
+ }
1574
+
1575
+ // Check if the tooltip hides when inactive
1576
+ if('number' === typeof options.hide.inactive) {
1577
+ // Bind inactive method to show target(s) as a custom event
1578
+ this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod, 'inactive');
1579
+
1580
+ // Define events which reset the 'inactive' event handler
1581
+ this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod);
1582
+ }
1583
+
1584
+ // Filter and bind events
1585
+ this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, showMethod, hideMethod);
1586
+
1587
+ // Mouse movement bindings
1588
+ this._bind(showTarget.add(tooltip), 'mousemove', function(event) {
1589
+ // Check if the tooltip hides when mouse is moved a certain distance
1590
+ if('number' === typeof options.hide.distance) {
1591
+ var origin = this.cache.origin || {},
1592
+ limit = this.options.hide.distance,
1593
+ abs = Math.abs;
1594
+
1595
+ // Check if the movement has gone beyond the limit, and hide it if so
1596
+ if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) {
1597
+ this.hide(event);
1598
+ }
1599
+ }
1600
+
1601
+ // Cache mousemove coords on show targets
1602
+ this._storeMouse(event);
1603
+ });
1604
+
1605
+ // Mouse positioning events
1606
+ if(posOptions.target === 'mouse') {
1607
+ // If mouse adjustment is on...
1608
+ if(posOptions.adjust.mouse) {
1609
+ // Apply a mouseleave event so we don't get problems with overlapping
1610
+ if(options.hide.event) {
1611
+ // Track if we're on the target or not
1612
+ this._bind(showTarget, ['mouseenter', 'mouseleave'], function(event) {
1613
+ if(!this.cache) {return FALSE; }
1614
+ this.cache.onTarget = event.type === 'mouseenter';
1615
+ });
1616
+ }
1617
+
1618
+ // Update tooltip position on mousemove
1619
+ this._bind(documentTarget, 'mousemove', function(event) {
1620
+ // Update the tooltip position only if the tooltip is visible and adjustment is enabled
1621
+ if(this.rendered && this.cache.onTarget && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0) {
1622
+ this.reposition(event);
1623
+ }
1624
+ });
1625
+ }
1626
+ }
1627
+
1628
+ // Adjust positions of the tooltip on window resize if enabled
1629
+ if(posOptions.adjust.resize || viewportTarget.length) {
1630
+ this._bind( $.event.special.resize ? viewportTarget : windowTarget, 'resize', repositionMethod );
1631
+ }
1632
+
1633
+ // Adjust tooltip position on scroll of the window or viewport element if present
1634
+ if(posOptions.adjust.scroll) {
1635
+ this._bind( windowTarget.add(posOptions.container), 'scroll', repositionMethod );
1636
+ }
1637
+ };
1638
+
1639
+ // Un-assignment method
1640
+ PROTOTYPE._unassignEvents = function() {
1641
+ var options = this.options,
1642
+ showTargets = options.show.target,
1643
+ hideTargets = options.hide.target,
1644
+ targets = $.grep([
1645
+ this.elements.target[0],
1646
+ this.rendered && this.tooltip[0],
1647
+ options.position.container[0],
1648
+ options.position.viewport[0],
1649
+ options.position.container.closest('html')[0], // unfocus
1650
+ window,
1651
+ document
1652
+ ], function(i) {
1653
+ return typeof i === 'object';
1654
+ });
1655
+
1656
+ // Add show and hide targets if they're valid
1657
+ if(showTargets && showTargets.toArray) {
1658
+ targets = targets.concat(showTargets.toArray());
1659
+ }
1660
+ if(hideTargets && hideTargets.toArray) {
1661
+ targets = targets.concat(hideTargets.toArray());
1662
+ }
1663
+
1664
+ // Unbind the events
1665
+ this._unbind(targets)
1666
+ ._unbind(targets, 'destroy')
1667
+ ._unbind(targets, 'inactive');
1668
+ };
1669
+
1670
+ // Apply common event handlers using delegate (avoids excessive .bind calls!)
1671
+ $(function() {
1672
+ delegate(SELECTOR, ['mouseenter', 'mouseleave'], function(event) {
1673
+ var state = event.type === 'mouseenter',
1674
+ tooltip = $(event.currentTarget),
1675
+ target = $(event.relatedTarget || event.target),
1676
+ options = this.options;
1677
+
1678
+ // On mouseenter...
1679
+ if(state) {
1680
+ // Focus the tooltip on mouseenter (z-index stacking)
1681
+ this.focus(event);
1682
+
1683
+ // Clear hide timer on tooltip hover to prevent it from closing
1684
+ tooltip.hasClass(CLASS_FIXED) && !tooltip.hasClass(CLASS_DISABLED) && clearTimeout(this.timers.hide);
1685
+ }
1686
+
1687
+ // On mouseleave...
1688
+ else {
1689
+ // When mouse tracking is enabled, hide when we leave the tooltip and not onto the show target (if a hide event is set)
1690
+ if(options.position.target === 'mouse' && options.position.adjust.mouse &&
1691
+ options.hide.event && options.show.target && !target.closest(options.show.target[0]).length) {
1692
+ this.hide(event);
1693
+ }
1694
+ }
1695
+
1696
+ // Add hover class
1697
+ tooltip.toggleClass(CLASS_HOVER, state);
1698
+ });
1699
+
1700
+ // Define events which reset the 'inactive' event handler
1701
+ delegate('['+ATTR_ID+']', INACTIVE_EVENTS, inactiveMethod);
1702
+ });
1703
+ ;// Initialization method
1704
+ function init(elem, id, opts) {
1705
+ var obj, posOptions, attr, config, title,
1706
+
1707
+ // Setup element references
1708
+ docBody = $(document.body),
1709
+
1710
+ // Use document body instead of document element if needed
1711
+ newTarget = elem[0] === document ? docBody : elem,
1712
+
1713
+ // Grab metadata from element if plugin is present
1714
+ metadata = elem.metadata ? elem.metadata(opts.metadata) : NULL,
1715
+
1716
+ // If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise
1717
+ metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL,
1718
+
1719
+ // Grab data from metadata.name (or data-qtipopts as fallback) using .data() method,
1720
+ html5 = elem.data(opts.metadata.name || 'qtipopts');
1721
+
1722
+ // If we don't get an object returned attempt to parse it manualyl without parseJSON
1723
+ /* eslint-disable no-empty */
1724
+ try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; }
1725
+ catch(e) {}
1726
+ /* eslint-enable no-empty */
1727
+
1728
+ // Merge in and sanitize metadata
1729
+ config = $.extend(TRUE, {}, QTIP.defaults, opts,
1730
+ typeof html5 === 'object' ? sanitizeOptions(html5) : NULL,
1731
+ sanitizeOptions(metadata5 || metadata));
1732
+
1733
+ // Re-grab our positioning options now we've merged our metadata and set id to passed value
1734
+ posOptions = config.position;
1735
+ config.id = id;
1736
+
1737
+ // Setup missing content if none is detected
1738
+ if('boolean' === typeof config.content.text) {
1739
+ attr = elem.attr(config.content.attr);
1740
+
1741
+ // Grab from supplied attribute if available
1742
+ if(config.content.attr !== FALSE && attr) { config.content.text = attr; }
1743
+
1744
+ // No valid content was found, abort render
1745
+ else { return FALSE; }
1746
+ }
1747
+
1748
+ // Setup target options
1749
+ if(!posOptions.container.length) { posOptions.container = docBody; }
1750
+ if(posOptions.target === FALSE) { posOptions.target = newTarget; }
1751
+ if(config.show.target === FALSE) { config.show.target = newTarget; }
1752
+ if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); }
1753
+ if(config.hide.target === FALSE) { config.hide.target = newTarget; }
1754
+ if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; }
1755
+
1756
+ // Ensure we only use a single container
1757
+ posOptions.container = posOptions.container.eq(0);
1758
+
1759
+ // Convert position corner values into x and y strings
1760
+ posOptions.at = new CORNER(posOptions.at, TRUE);
1761
+ posOptions.my = new CORNER(posOptions.my);
1762
+
1763
+ // Destroy previous tooltip if overwrite is enabled, or skip element if not
1764
+ if(elem.data(NAMESPACE)) {
1765
+ if(config.overwrite) {
1766
+ elem.qtip('destroy', true);
1767
+ }
1768
+ else if(config.overwrite === FALSE) {
1769
+ return FALSE;
1770
+ }
1771
+ }
1772
+
1773
+ // Add has-qtip attribute
1774
+ elem.attr(ATTR_HAS, id);
1775
+
1776
+ // Remove title attribute and store it if present
1777
+ if(config.suppress && (title = elem.attr('title'))) {
1778
+ // Final attr call fixes event delegatiom and IE default tooltip showing problem
1779
+ elem.removeAttr('title').attr(oldtitle, title).attr('title', '');
1780
+ }
1781
+
1782
+ // Initialize the tooltip and add API reference
1783
+ obj = new QTip(elem, config, id, !!attr);
1784
+ elem.data(NAMESPACE, obj);
1785
+
1786
+ return obj;
1787
+ }
1788
+
1789
+ // jQuery $.fn extension method
1790
+ QTIP = $.fn.qtip = function(options, notation, newValue)
1791
+ {
1792
+ var command = ('' + options).toLowerCase(), // Parse command
1793
+ returned = NULL,
1794
+ args = $.makeArray(arguments).slice(1),
1795
+ event = args[args.length - 1],
1796
+ opts = this[0] ? $.data(this[0], NAMESPACE) : NULL;
1797
+
1798
+ // Check for API request
1799
+ if(!arguments.length && opts || command === 'api') {
1800
+ return opts;
1801
+ }
1802
+
1803
+ // Execute API command if present
1804
+ else if('string' === typeof options) {
1805
+ this.each(function() {
1806
+ var api = $.data(this, NAMESPACE);
1807
+ if(!api) { return TRUE; }
1808
+
1809
+ // Cache the event if possible
1810
+ if(event && event.timeStamp) { api.cache.event = event; }
1811
+
1812
+ // Check for specific API commands
1813
+ if(notation && (command === 'option' || command === 'options')) {
1814
+ if(newValue !== undefined || $.isPlainObject(notation)) {
1815
+ api.set(notation, newValue);
1816
+ }
1817
+ else {
1818
+ returned = api.get(notation);
1819
+ return FALSE;
1820
+ }
1821
+ }
1822
+
1823
+ // Execute API command
1824
+ else if(api[command]) {
1825
+ api[command].apply(api, args);
1826
+ }
1827
+ });
1828
+
1829
+ return returned !== NULL ? returned : this;
1830
+ }
1831
+
1832
+ // No API commands. validate provided options and setup qTips
1833
+ else if('object' === typeof options || !arguments.length) {
1834
+ // Sanitize options first
1835
+ opts = sanitizeOptions($.extend(TRUE, {}, options));
1836
+
1837
+ return this.each(function(i) {
1838
+ var api, id;
1839
+
1840
+ // Find next available ID, or use custom ID if provided
1841
+ id = $.isArray(opts.id) ? opts.id[i] : opts.id;
1842
+ id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ? QTIP.nextid++ : id;
1843
+
1844
+ // Initialize the qTip and re-grab newly sanitized options
1845
+ api = init($(this), id, opts);
1846
+ if(api === FALSE) { return TRUE; }
1847
+ else { QTIP.api[id] = api; }
1848
+
1849
+ // Initialize plugins
1850
+ $.each(PLUGINS, function() {
1851
+ if(this.initialize === 'initialize') { this(api); }
1852
+ });
1853
+
1854
+ // Assign initial pre-render events
1855
+ api._assignInitialEvents(event);
1856
+ });
1857
+ }
1858
+ };
1859
+
1860
+ // Expose class
1861
+ $.qtip = QTip;
1862
+
1863
+ // Populated in render method
1864
+ QTIP.api = {};
1865
+ ;$.each({
1866
+ /* Allow other plugins to successfully retrieve the title of an element with a qTip applied */
1867
+ attr: function(attr, val) {
1868
+ if(this.length) {
1869
+ var self = this[0],
1870
+ title = 'title',
1871
+ api = $.data(self, 'qtip');
1872
+
1873
+ if(attr === title && api && api.options && 'object' === typeof api && 'object' === typeof api.options && api.options.suppress) {
1874
+ if(arguments.length < 2) {
1875
+ return $.attr(self, oldtitle);
1876
+ }
1877
+
1878
+ // If qTip is rendered and title was originally used as content, update it
1879
+ if(api && api.options.content.attr === title && api.cache.attr) {
1880
+ api.set('content.text', val);
1881
+ }
1882
+
1883
+ // Use the regular attr method to set, then cache the result
1884
+ return this.attr(oldtitle, val);
1885
+ }
1886
+ }
1887
+
1888
+ return $.fn['attr'+replaceSuffix].apply(this, arguments);
1889
+ },
1890
+
1891
+ /* Allow clone to correctly retrieve cached title attributes */
1892
+ clone: function(keepData) {
1893
+ // Clone our element using the real clone method
1894
+ var elems = $.fn['clone'+replaceSuffix].apply(this, arguments);
1895
+
1896
+ // Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false
1897
+ if(!keepData) {
1898
+ elems.filter('['+oldtitle+']').attr('title', function() {
1899
+ return $.attr(this, oldtitle);
1900
+ })
1901
+ .removeAttr(oldtitle);
1902
+ }
1903
+
1904
+ return elems;
1905
+ }
1906
+ }, function(name, func) {
1907
+ if(!func || $.fn[name+replaceSuffix]) { return TRUE; }
1908
+
1909
+ var old = $.fn[name+replaceSuffix] = $.fn[name];
1910
+ $.fn[name] = function() {
1911
+ return func.apply(this, arguments) || old.apply(this, arguments);
1912
+ };
1913
+ });
1914
+
1915
+ /* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar).
1916
+ * This snippet is taken directly from jQuery UI source code found here:
1917
+ * http://code.jquery.com/ui/jquery-ui-git.js
1918
+ */
1919
+ if(!$.ui) {
1920
+ $['cleanData'+replaceSuffix] = $.cleanData;
1921
+ $.cleanData = function( elems ) {
1922
+ for(var i = 0, elem; (elem = $( elems[i] )).length; i++) {
1923
+ if(elem.attr(ATTR_HAS)) {
1924
+ /* eslint-disable no-empty */
1925
+ try { elem.triggerHandler('removeqtip'); }
1926
+ catch( e ) {}
1927
+ /* eslint-enable no-empty */
1928
+ }
1929
+ }
1930
+ $['cleanData'+replaceSuffix].apply(this, arguments);
1931
+ };
1932
+ }
1933
+ ;// qTip version
1934
+ QTIP.version = '3.0.3';
1935
+
1936
+ // Base ID for all qTips
1937
+ QTIP.nextid = 0;
1938
+
1939
+ // Inactive events array
1940
+ QTIP.inactiveEvents = INACTIVE_EVENTS;
1941
+
1942
+ // Base z-index for all qTips
1943
+ QTIP.zindex = 15000;
1944
+
1945
+ // Define configuration defaults
1946
+ QTIP.defaults = {
1947
+ prerender: FALSE,
1948
+ id: FALSE,
1949
+ overwrite: TRUE,
1950
+ suppress: TRUE,
1951
+ content: {
1952
+ text: TRUE,
1953
+ attr: 'title',
1954
+ title: FALSE,
1955
+ button: FALSE
1956
+ },
1957
+ position: {
1958
+ my: 'top left',
1959
+ at: 'bottom right',
1960
+ target: FALSE,
1961
+ container: FALSE,
1962
+ viewport: FALSE,
1963
+ adjust: {
1964
+ x: 0, y: 0,
1965
+ mouse: TRUE,
1966
+ scroll: TRUE,
1967
+ resize: TRUE,
1968
+ method: 'flipinvert flipinvert'
1969
+ },
1970
+ effect: function(api, pos) {
1971
+ $(this).animate(pos, {
1972
+ duration: 200,
1973
+ queue: FALSE
1974
+ });
1975
+ }
1976
+ },
1977
+ show: {
1978
+ target: FALSE,
1979
+ event: 'mouseenter',
1980
+ effect: TRUE,
1981
+ delay: 90,
1982
+ solo: FALSE,
1983
+ ready: FALSE,
1984
+ autofocus: FALSE
1985
+ },
1986
+ hide: {
1987
+ target: FALSE,
1988
+ event: 'mouseleave',
1989
+ effect: TRUE,
1990
+ delay: 0,
1991
+ fixed: FALSE,
1992
+ inactive: FALSE,
1993
+ leave: 'window',
1994
+ distance: FALSE
1995
+ },
1996
+ style: {
1997
+ classes: '',
1998
+ widget: FALSE,
1999
+ width: FALSE,
2000
+ height: FALSE,
2001
+ def: TRUE
2002
+ },
2003
+ events: {
2004
+ render: NULL,
2005
+ move: NULL,
2006
+ show: NULL,
2007
+ hide: NULL,
2008
+ toggle: NULL,
2009
+ visible: NULL,
2010
+ hidden: NULL,
2011
+ focus: NULL,
2012
+ blur: NULL
2013
+ }
2014
+ };
2015
+ ;var TIP,
2016
+ createVML,
2017
+ SCALE,
2018
+ PIXEL_RATIO,
2019
+ BACKING_STORE_RATIO,
2020
+
2021
+ // Common CSS strings
2022
+ MARGIN = 'margin',
2023
+ BORDER = 'border',
2024
+ COLOR = 'color',
2025
+ BG_COLOR = 'background-color',
2026
+ TRANSPARENT = 'transparent',
2027
+ IMPORTANT = ' !important',
2028
+
2029
+ // Check if the browser supports <canvas/> elements
2030
+ HASCANVAS = !!document.createElement('canvas').getContext,
2031
+
2032
+ // Invalid colour values used in parseColours()
2033
+ INVALID = /rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i;
2034
+
2035
+ // Camel-case method, taken from jQuery source
2036
+ // http://code.jquery.com/jquery-1.8.0.js
2037
+ function camel(s) { return s.charAt(0).toUpperCase() + s.slice(1); }
2038
+
2039
+ /*
2040
+ * Modified from Modernizr's testPropsAll()
2041
+ * http://modernizr.com/downloads/modernizr-latest.js
2042
+ */
2043
+ var cssProps = {}, cssPrefixes = ['Webkit', 'O', 'Moz', 'ms'];
2044
+ function vendorCss(elem, prop) {
2045
+ var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
2046
+ props = (prop + ' ' + cssPrefixes.join(ucProp + ' ') + ucProp).split(' '),
2047
+ cur, val, i = 0;
2048
+
2049
+ // If the property has already been mapped...
2050
+ if(cssProps[prop]) { return elem.css(cssProps[prop]); }
2051
+
2052
+ while(cur = props[i++]) {
2053
+ if((val = elem.css(cur)) !== undefined) {
2054
+ cssProps[prop] = cur;
2055
+ return val;
2056
+ }
2057
+ }
2058
+ }
2059
+
2060
+ // Parse a given elements CSS property into an int
2061
+ function intCss(elem, prop) {
2062
+ return Math.ceil(parseFloat(vendorCss(elem, prop)));
2063
+ }
2064
+
2065
+
2066
+ // VML creation (for IE only)
2067
+ if(!HASCANVAS) {
2068
+ createVML = function(tag, props, style) {
2069
+ return '<qtipvml:'+tag+' xmlns="urn:schemas-microsoft.com:vml" class="qtip-vml" '+(props||'')+
2070
+ ' style="behavior: url(#default#VML); '+(style||'')+ '" />';
2071
+ };
2072
+ }
2073
+
2074
+ // Canvas only definitions
2075
+ else {
2076
+ PIXEL_RATIO = window.devicePixelRatio || 1;
2077
+ BACKING_STORE_RATIO = (function() {
2078
+ var context = document.createElement('canvas').getContext('2d');
2079
+ return context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio ||
2080
+ context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || 1;
2081
+ })();
2082
+ SCALE = PIXEL_RATIO / BACKING_STORE_RATIO;
2083
+ }
2084
+
2085
+
2086
+ function Tip(qtip, options) {
2087
+ this._ns = 'tip';
2088
+ this.options = options;
2089
+ this.offset = options.offset;
2090
+ this.size = [ options.width, options.height ];
2091
+
2092
+ // Initialize
2093
+ this.qtip = qtip;
2094
+ this.init(qtip);
2095
+ }
2096
+
2097
+ $.extend(Tip.prototype, {
2098
+ init: function(qtip) {
2099
+ var context, tip;
2100
+
2101
+ // Create tip element and prepend to the tooltip
2102
+ tip = this.element = qtip.elements.tip = $('<div />', { 'class': NAMESPACE+'-tip' }).prependTo(qtip.tooltip);
2103
+
2104
+ // Create tip drawing element(s)
2105
+ if(HASCANVAS) {
2106
+ // save() as soon as we create the canvas element so FF2 doesn't bork on our first restore()!
2107
+ context = $('<canvas />').appendTo(this.element)[0].getContext('2d');
2108
+
2109
+ // Setup constant parameters
2110
+ context.lineJoin = 'miter';
2111
+ context.miterLimit = 100000;
2112
+ context.save();
2113
+ }
2114
+ else {
2115
+ context = createVML('shape', 'coordorigin="0,0"', 'position:absolute;');
2116
+ this.element.html(context + context);
2117
+
2118
+ // Prevent mousing down on the tip since it causes problems with .live() handling in IE due to VML
2119
+ qtip._bind( $('*', tip).add(tip), ['click', 'mousedown'], function(event) { event.stopPropagation(); }, this._ns);
2120
+ }
2121
+
2122
+ // Bind update events
2123
+ qtip._bind(qtip.tooltip, 'tooltipmove', this.reposition, this._ns, this);
2124
+
2125
+ // Create it
2126
+ this.create();
2127
+ },
2128
+
2129
+ _swapDimensions: function() {
2130
+ this.size[0] = this.options.height;
2131
+ this.size[1] = this.options.width;
2132
+ },
2133
+ _resetDimensions: function() {
2134
+ this.size[0] = this.options.width;
2135
+ this.size[1] = this.options.height;
2136
+ },
2137
+
2138
+ _useTitle: function(corner) {
2139
+ var titlebar = this.qtip.elements.titlebar;
2140
+ return titlebar && (
2141
+ corner.y === TOP || corner.y === CENTER && this.element.position().top + this.size[1] / 2 + this.options.offset < titlebar.outerHeight(TRUE)
2142
+ );
2143
+ },
2144
+
2145
+ _parseCorner: function(corner) {
2146
+ var my = this.qtip.options.position.my;
2147
+
2148
+ // Detect corner and mimic properties
2149
+ if(corner === FALSE || my === FALSE) {
2150
+ corner = FALSE;
2151
+ }
2152
+ else if(corner === TRUE) {
2153
+ corner = new CORNER( my.string() );
2154
+ }
2155
+ else if(!corner.string) {
2156
+ corner = new CORNER(corner);
2157
+ corner.fixed = TRUE;
2158
+ }
2159
+
2160
+ return corner;
2161
+ },
2162
+
2163
+ _parseWidth: function(corner, side, use) {
2164
+ var elements = this.qtip.elements,
2165
+ prop = BORDER + camel(side) + 'Width';
2166
+
2167
+ return (use ? intCss(use, prop) :
2168
+ intCss(elements.content, prop) ||
2169
+ intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) ||
2170
+ intCss(elements.tooltip, prop)
2171
+ ) || 0;
2172
+ },
2173
+
2174
+ _parseRadius: function(corner) {
2175
+ var elements = this.qtip.elements,
2176
+ prop = BORDER + camel(corner.y) + camel(corner.x) + 'Radius';
2177
+
2178
+ return BROWSER.ie < 9 ? 0 :
2179
+ intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) ||
2180
+ intCss(elements.tooltip, prop) || 0;
2181
+ },
2182
+
2183
+ _invalidColour: function(elem, prop, compare) {
2184
+ var val = elem.css(prop);
2185
+ return !val || compare && val === elem.css(compare) || INVALID.test(val) ? FALSE : val;
2186
+ },
2187
+
2188
+ _parseColours: function(corner) {
2189
+ var elements = this.qtip.elements,
2190
+ tip = this.element.css('cssText', ''),
2191
+ borderSide = BORDER + camel(corner[ corner.precedance ]) + camel(COLOR),
2192
+ colorElem = this._useTitle(corner) && elements.titlebar || elements.content,
2193
+ css = this._invalidColour, color = [];
2194
+
2195
+ // Attempt to detect the background colour from various elements, left-to-right precedance
2196
+ color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css(elements.content, BG_COLOR) ||
2197
+ css(elements.tooltip, BG_COLOR) || tip.css(BG_COLOR);
2198
+
2199
+ // Attempt to detect the correct border side colour from various elements, left-to-right precedance
2200
+ color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderSide, COLOR) ||
2201
+ css(elements.content, borderSide, COLOR) || css(elements.tooltip, borderSide, COLOR) || elements.tooltip.css(borderSide);
2202
+
2203
+ // Reset background and border colours
2204
+ $('*', tip).add(tip).css('cssText', BG_COLOR+':'+TRANSPARENT+IMPORTANT+';'+BORDER+':0'+IMPORTANT+';');
2205
+
2206
+ return color;
2207
+ },
2208
+
2209
+ _calculateSize: function(corner) {
2210
+ var y = corner.precedance === Y,
2211
+ width = this.options.width,
2212
+ height = this.options.height,
2213
+ isCenter = corner.abbrev() === 'c',
2214
+ base = (y ? width: height) * (isCenter ? 0.5 : 1),
2215
+ pow = Math.pow,
2216
+ round = Math.round,
2217
+ bigHyp, ratio, result,
2218
+
2219
+ smallHyp = Math.sqrt( pow(base, 2) + pow(height, 2) ),
2220
+ hyp = [
2221
+ this.border / base * smallHyp,
2222
+ this.border / height * smallHyp
2223
+ ];
2224
+
2225
+ hyp[2] = Math.sqrt( pow(hyp[0], 2) - pow(this.border, 2) );
2226
+ hyp[3] = Math.sqrt( pow(hyp[1], 2) - pow(this.border, 2) );
2227
+
2228
+ bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]);
2229
+ ratio = bigHyp / smallHyp;
2230
+
2231
+ result = [ round(ratio * width), round(ratio * height) ];
2232
+ return y ? result : result.reverse();
2233
+ },
2234
+
2235
+ // Tip coordinates calculator
2236
+ _calculateTip: function(corner, size, scale) {
2237
+ scale = scale || 1;
2238
+ size = size || this.size;
2239
+
2240
+ var width = size[0] * scale,
2241
+ height = size[1] * scale,
2242
+ width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2),
2243
+
2244
+ // Define tip coordinates in terms of height and width values
2245
+ tips = {
2246
+ br: [0,0, width,height, width,0],
2247
+ bl: [0,0, width,0, 0,height],
2248
+ tr: [0,height, width,0, width,height],
2249
+ tl: [0,0, 0,height, width,height],
2250
+ tc: [0,height, width2,0, width,height],
2251
+ bc: [0,0, width,0, width2,height],
2252
+ rc: [0,0, width,height2, 0,height],
2253
+ lc: [width,0, width,height, 0,height2]
2254
+ };
2255
+
2256
+ // Set common side shapes
2257
+ tips.lt = tips.br; tips.rt = tips.bl;
2258
+ tips.lb = tips.tr; tips.rb = tips.tl;
2259
+
2260
+ return tips[ corner.abbrev() ];
2261
+ },
2262
+
2263
+ // Tip coordinates drawer (canvas)
2264
+ _drawCoords: function(context, coords) {
2265
+ context.beginPath();
2266
+ context.moveTo(coords[0], coords[1]);
2267
+ context.lineTo(coords[2], coords[3]);
2268
+ context.lineTo(coords[4], coords[5]);
2269
+ context.closePath();
2270
+ },
2271
+
2272
+ create: function() {
2273
+ // Determine tip corner
2274
+ var c = this.corner = (HASCANVAS || BROWSER.ie) && this._parseCorner(this.options.corner);
2275
+
2276
+ // If we have a tip corner...
2277
+ this.enabled = !!this.corner && this.corner.abbrev() !== 'c';
2278
+ if(this.enabled) {
2279
+ // Cache it
2280
+ this.qtip.cache.corner = c.clone();
2281
+
2282
+ // Create it
2283
+ this.update();
2284
+ }
2285
+
2286
+ // Toggle tip element
2287
+ this.element.toggle(this.enabled);
2288
+
2289
+ return this.corner;
2290
+ },
2291
+
2292
+ update: function(corner, position) {
2293
+ if(!this.enabled) { return this; }
2294
+
2295
+ var elements = this.qtip.elements,
2296
+ tip = this.element,
2297
+ inner = tip.children(),
2298
+ options = this.options,
2299
+ curSize = this.size,
2300
+ mimic = options.mimic,
2301
+ round = Math.round,
2302
+ color, precedance, context,
2303
+ coords, bigCoords, translate, newSize, border;
2304
+
2305
+ // Re-determine tip if not already set
2306
+ if(!corner) { corner = this.qtip.cache.corner || this.corner; }
2307
+
2308
+ // Use corner property if we detect an invalid mimic value
2309
+ if(mimic === FALSE) { mimic = corner; }
2310
+
2311
+ // Otherwise inherit mimic properties from the corner object as necessary
2312
+ else {
2313
+ mimic = new CORNER(mimic);
2314
+ mimic.precedance = corner.precedance;
2315
+
2316
+ if(mimic.x === 'inherit') { mimic.x = corner.x; }
2317
+ else if(mimic.y === 'inherit') { mimic.y = corner.y; }
2318
+ else if(mimic.x === mimic.y) {
2319
+ mimic[ corner.precedance ] = corner[ corner.precedance ];
2320
+ }
2321
+ }
2322
+ precedance = mimic.precedance;
2323
+
2324
+ // Ensure the tip width.height are relative to the tip position
2325
+ if(corner.precedance === X) { this._swapDimensions(); }
2326
+ else { this._resetDimensions(); }
2327
+
2328
+ // Update our colours
2329
+ color = this.color = this._parseColours(corner);
2330
+
2331
+ // Detect border width, taking into account colours
2332
+ if(color[1] !== TRANSPARENT) {
2333
+ // Grab border width
2334
+ border = this.border = this._parseWidth(corner, corner[corner.precedance]);
2335
+
2336
+ // If border width isn't zero, use border color as fill if it's not invalid (1.0 style tips)
2337
+ if(options.border && border < 1 && !INVALID.test(color[1])) { color[0] = color[1]; }
2338
+
2339
+ // Set border width (use detected border width if options.border is true)
2340
+ this.border = border = options.border !== TRUE ? options.border : border;
2341
+ }
2342
+
2343
+ // Border colour was invalid, set border to zero
2344
+ else { this.border = border = 0; }
2345
+
2346
+ // Determine tip size
2347
+ newSize = this.size = this._calculateSize(corner);
2348
+ tip.css({
2349
+ width: newSize[0],
2350
+ height: newSize[1],
2351
+ lineHeight: newSize[1]+'px'
2352
+ });
2353
+
2354
+ // Calculate tip translation
2355
+ if(corner.precedance === Y) {
2356
+ translate = [
2357
+ round(mimic.x === LEFT ? border : mimic.x === RIGHT ? newSize[0] - curSize[0] - border : (newSize[0] - curSize[0]) / 2),
2358
+ round(mimic.y === TOP ? newSize[1] - curSize[1] : 0)
2359
+ ];
2360
+ }
2361
+ else {
2362
+ translate = [
2363
+ round(mimic.x === LEFT ? newSize[0] - curSize[0] : 0),
2364
+ round(mimic.y === TOP ? border : mimic.y === BOTTOM ? newSize[1] - curSize[1] - border : (newSize[1] - curSize[1]) / 2)
2365
+ ];
2366
+ }
2367
+
2368
+ // Canvas drawing implementation
2369
+ if(HASCANVAS) {
2370
+ // Grab canvas context and clear/save it
2371
+ context = inner[0].getContext('2d');
2372
+ context.restore(); context.save();
2373
+ context.clearRect(0,0,6000,6000);
2374
+
2375
+ // Calculate coordinates
2376
+ coords = this._calculateTip(mimic, curSize, SCALE);
2377
+ bigCoords = this._calculateTip(mimic, this.size, SCALE);
2378
+
2379
+ // Set the canvas size using calculated size
2380
+ inner.attr(WIDTH, newSize[0] * SCALE).attr(HEIGHT, newSize[1] * SCALE);
2381
+ inner.css(WIDTH, newSize[0]).css(HEIGHT, newSize[1]);
2382
+
2383
+ // Draw the outer-stroke tip
2384
+ this._drawCoords(context, bigCoords);
2385
+ context.fillStyle = color[1];
2386
+ context.fill();
2387
+
2388
+ // Draw the actual tip
2389
+ context.translate(translate[0] * SCALE, translate[1] * SCALE);
2390
+ this._drawCoords(context, coords);
2391
+ context.fillStyle = color[0];
2392
+ context.fill();
2393
+ }
2394
+
2395
+ // VML (IE Proprietary implementation)
2396
+ else {
2397
+ // Calculate coordinates
2398
+ coords = this._calculateTip(mimic);
2399
+
2400
+ // Setup coordinates string
2401
+ coords = 'm' + coords[0] + ',' + coords[1] + ' l' + coords[2] +
2402
+ ',' + coords[3] + ' ' + coords[4] + ',' + coords[5] + ' xe';
2403
+
2404
+ // Setup VML-specific offset for pixel-perfection
2405
+ translate[2] = border && /^(r|b)/i.test(corner.string()) ?
2406
+ BROWSER.ie === 8 ? 2 : 1 : 0;
2407
+
2408
+ // Set initial CSS
2409
+ inner.css({
2410
+ coordsize: newSize[0]+border + ' ' + newSize[1]+border,
2411
+ antialias: ''+(mimic.string().indexOf(CENTER) > -1),
2412
+ left: translate[0] - translate[2] * Number(precedance === X),
2413
+ top: translate[1] - translate[2] * Number(precedance === Y),
2414
+ width: newSize[0] + border,
2415
+ height: newSize[1] + border
2416
+ })
2417
+ .each(function(i) {
2418
+ var $this = $(this);
2419
+
2420
+ // Set shape specific attributes
2421
+ $this[ $this.prop ? 'prop' : 'attr' ]({
2422
+ coordsize: newSize[0]+border + ' ' + newSize[1]+border,
2423
+ path: coords,
2424
+ fillcolor: color[0],
2425
+ filled: !!i,
2426
+ stroked: !i
2427
+ })
2428
+ .toggle(!!(border || i));
2429
+
2430
+ // Check if border is enabled and add stroke element
2431
+ !i && $this.html( createVML(
2432
+ 'stroke', 'weight="'+border*2+'px" color="'+color[1]+'" miterlimit="1000" joinstyle="miter"'
2433
+ ) );
2434
+ });
2435
+ }
2436
+
2437
+ // Opera bug #357 - Incorrect tip position
2438
+ // https://github.com/Craga89/qTip2/issues/367
2439
+ window.opera && setTimeout(function() {
2440
+ elements.tip.css({
2441
+ display: 'inline-block',
2442
+ visibility: 'visible'
2443
+ });
2444
+ }, 1);
2445
+
2446
+ // Position if needed
2447
+ if(position !== FALSE) { this.calculate(corner, newSize); }
2448
+ },
2449
+
2450
+ calculate: function(corner, size) {
2451
+ if(!this.enabled) { return FALSE; }
2452
+
2453
+ var self = this,
2454
+ elements = this.qtip.elements,
2455
+ tip = this.element,
2456
+ userOffset = this.options.offset,
2457
+ position = {},
2458
+ precedance, corners;
2459
+
2460
+ // Inherit corner if not provided
2461
+ corner = corner || this.corner;
2462
+ precedance = corner.precedance;
2463
+
2464
+ // Determine which tip dimension to use for adjustment
2465
+ size = size || this._calculateSize(corner);
2466
+
2467
+ // Setup corners and offset array
2468
+ corners = [ corner.x, corner.y ];
2469
+ if(precedance === X) { corners.reverse(); }
2470
+
2471
+ // Calculate tip position
2472
+ $.each(corners, function(i, side) {
2473
+ var b, bc, br;
2474
+
2475
+ if(side === CENTER) {
2476
+ b = precedance === Y ? LEFT : TOP;
2477
+ position[ b ] = '50%';
2478
+ position[MARGIN+'-' + b] = -Math.round(size[ precedance === Y ? 0 : 1 ] / 2) + userOffset;
2479
+ }
2480
+ else {
2481
+ b = self._parseWidth(corner, side, elements.tooltip);
2482
+ bc = self._parseWidth(corner, side, elements.content);
2483
+ br = self._parseRadius(corner);
2484
+
2485
+ position[ side ] = Math.max(-self.border, i ? bc : userOffset + (br > b ? br : -b));
2486
+ }
2487
+ });
2488
+
2489
+ // Adjust for tip size
2490
+ position[ corner[precedance] ] -= size[ precedance === X ? 0 : 1 ];
2491
+
2492
+ // Set and return new position
2493
+ tip.css({ margin: '', top: '', bottom: '', left: '', right: '' }).css(position);
2494
+ return position;
2495
+ },
2496
+
2497
+ reposition: function(event, api, pos) {
2498
+ if(!this.enabled) { return; }
2499
+
2500
+ var cache = api.cache,
2501
+ newCorner = this.corner.clone(),
2502
+ adjust = pos.adjusted,
2503
+ method = api.options.position.adjust.method.split(' '),
2504
+ horizontal = method[0],
2505
+ vertical = method[1] || method[0],
2506
+ shift = { left: FALSE, top: FALSE, x: 0, y: 0 },
2507
+ offset, css = {}, props;
2508
+
2509
+ function shiftflip(direction, precedance, popposite, side, opposite) {
2510
+ // Horizontal - Shift or flip method
2511
+ if(direction === SHIFT && newCorner.precedance === precedance && adjust[side] && newCorner[popposite] !== CENTER) {
2512
+ newCorner.precedance = newCorner.precedance === X ? Y : X;
2513
+ }
2514
+ else if(direction !== SHIFT && adjust[side]){
2515
+ newCorner[precedance] = newCorner[precedance] === CENTER ?
2516
+ adjust[side] > 0 ? side : opposite :
2517
+ newCorner[precedance] === side ? opposite : side;
2518
+ }
2519
+ }
2520
+
2521
+ function shiftonly(xy, side, opposite) {
2522
+ if(newCorner[xy] === CENTER) {
2523
+ css[MARGIN+'-'+side] = shift[xy] = offset[MARGIN+'-'+side] - adjust[side];
2524
+ }
2525
+ else {
2526
+ props = offset[opposite] !== undefined ?
2527
+ [ adjust[side], -offset[side] ] : [ -adjust[side], offset[side] ];
2528
+
2529
+ if( (shift[xy] = Math.max(props[0], props[1])) > props[0] ) {
2530
+ pos[side] -= adjust[side];
2531
+ shift[side] = FALSE;
2532
+ }
2533
+
2534
+ css[ offset[opposite] !== undefined ? opposite : side ] = shift[xy];
2535
+ }
2536
+ }
2537
+
2538
+ // If our tip position isn't fixed e.g. doesn't adjust with viewport...
2539
+ if(this.corner.fixed !== TRUE) {
2540
+ // Perform shift/flip adjustments
2541
+ shiftflip(horizontal, X, Y, LEFT, RIGHT);
2542
+ shiftflip(vertical, Y, X, TOP, BOTTOM);
2543
+
2544
+ // Update and redraw the tip if needed (check cached details of last drawn tip)
2545
+ if(newCorner.string() !== cache.corner.string() || cache.cornerTop !== adjust.top || cache.cornerLeft !== adjust.left) {
2546
+ this.update(newCorner, FALSE);
2547
+ }
2548
+ }
2549
+
2550
+ // Setup tip offset properties
2551
+ offset = this.calculate(newCorner);
2552
 
2553
+ // Readjust offset object to make it left/top
2554
+ if(offset.right !== undefined) { offset.left = -offset.right; }
2555
+ if(offset.bottom !== undefined) { offset.top = -offset.bottom; }
2556
+ offset.user = this.offset;
2557
 
2558
+ // Perform shift adjustments
2559
+ shift.left = horizontal === SHIFT && !!adjust.left;
2560
+ if(shift.left) {
2561
+ shiftonly(X, LEFT, RIGHT);
2562
+ }
2563
+ shift.top = vertical === SHIFT && !!adjust.top;
2564
+ if(shift.top) {
2565
+ shiftonly(Y, TOP, BOTTOM);
2566
+ }
2567
 
2568
+ /*
2569
+ * If the tip is adjusted in both dimensions, or in a
2570
+ * direction that would cause it to be anywhere but the
2571
+ * outer border, hide it!
2572
+ */
2573
+ this.element.css(css).toggle(
2574
+ !(shift.x && shift.y || newCorner.x === CENTER && shift.y || newCorner.y === CENTER && shift.x)
2575
+ );
 
2576
 
2577
+ // Adjust position to accomodate tip dimensions
2578
+ pos.left -= offset.left.charAt ? offset.user :
2579
+ horizontal !== SHIFT || shift.top || !shift.left && !shift.top ? offset.left + this.border : 0;
2580
+ pos.top -= offset.top.charAt ? offset.user :
2581
+ vertical !== SHIFT || shift.left || !shift.left && !shift.top ? offset.top + this.border : 0;
2582
 
2583
+ // Cache details
2584
+ cache.cornerLeft = adjust.left; cache.cornerTop = adjust.top;
2585
+ cache.corner = newCorner.clone();
2586
+ },
2587
 
2588
+ destroy: function() {
2589
+ // Unbind events
2590
+ this.qtip._unbind(this.qtip.tooltip, this._ns);
 
 
 
 
 
 
 
2591
 
2592
+ // Remove the tip element(s)
2593
+ if(this.qtip.elements.tip) {
2594
+ this.qtip.elements.tip.find('*')
2595
+ .remove().end().remove();
2596
  }
2597
+ }
2598
+ });
 
 
2599
 
2600
+ TIP = PLUGINS.tip = function(api) {
2601
+ return new Tip(api, api.options.style.tip);
 
 
 
2602
  };
2603
 
2604
  // Initialize tip on render
2605
+ TIP.initialize = 'render';
2606
 
2607
  // Setup plugin sanitization options
2608
+ TIP.sanitize = function(options) {
2609
+ if(options.style && 'tip' in options.style) {
2610
+ var opts = options.style.tip;
2611
+ if(typeof opts !== 'object') { opts = options.style.tip = { corner: opts }; }
2612
+ if(!(/string|boolean/i).test(typeof opts.corner)) { opts.corner = TRUE; }
2613
+ }
2614
+ };
2615
+
2616
+ // Add new option checks for the plugin
2617
+ CHECKS.tip = {
2618
+ '^position.my|style.tip.(corner|mimic|border)$': function() {
2619
+ // Make sure a tip can be drawn
2620
+ this.create();
2621
+
2622
+ // Reposition the tooltip
2623
+ this.qtip.reposition();
2624
+ },
2625
+ '^style.tip.(height|width)$': function(obj) {
2626
+ // Re-set dimensions and redraw the tip
2627
+ this.size = [ obj.width, obj.height ];
2628
+ this.update();
2629
+
2630
+ // Reposition the tooltip
2631
+ this.qtip.reposition();
2632
+ },
2633
+ '^content.title|style.(classes|widget)$': function() {
2634
+ this.update();
2635
  }
2636
  };
2637
 
2648
  }
2649
  }
2650
  });
2651
+ ;var MODAL, OVERLAY,
2652
+ MODALCLASS = 'qtip-modal',
2653
+ MODALSELECTOR = '.'+MODALCLASS;
2654
 
2655
+ OVERLAY = function()
 
2656
  {
2657
  var self = this,
2658
+ focusableElems = {},
2659
+ current,
2660
+ prevState,
2661
+ elem;
2662
+
2663
+ // Modified code from jQuery UI 1.10.0 source
2664
+ // http://code.jquery.com/ui/1.10.0/jquery-ui.js
2665
+ function focusable(element) {
2666
+ // Use the defined focusable checker when possible
2667
+ if($.expr[':'].focusable) { return $.expr[':'].focusable; }
2668
+
2669
+ var isTabIndexNotNaN = !isNaN($.attr(element, 'tabindex')),
2670
+ nodeName = element.nodeName && element.nodeName.toLowerCase(),
2671
+ map, mapName, img;
2672
+
2673
+ if('area' === nodeName) {
2674
+ map = element.parentNode;
2675
+ mapName = map.name;
2676
+ if(!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') {
2677
+ return false;
2678
+ }
2679
+ img = $('img[usemap=#' + mapName + ']')[0];
2680
+ return !!img && img.is(':visible');
2681
  }
 
2682
 
2683
+ return /input|select|textarea|button|object/.test( nodeName ) ?
2684
+ !element.disabled :
2685
+ 'a' === nodeName ?
2686
+ element.href || isTabIndexNotNaN :
2687
+ isTabIndexNotNaN
2688
+ ;
2689
  }
2690
 
2691
+ // Focus inputs using cached focusable elements (see update())
2692
  function focusInputs(blurElems) {
2693
  // Blurring body element in IE causes window.open windows to unfocus!
2694
  if(focusableElems.length < 1 && blurElems.length) { blurElems.not('body').blur(); }
2697
  else { focusableElems.first().focus(); }
2698
  }
2699
 
2700
+ // Steal focus from elements outside tooltip
2701
  function stealFocus(event) {
2702
+ if(!elem.is(':visible')) { return; }
2703
+
2704
  var target = $(event.target),
2705
+ tooltip = current.tooltip,
2706
+ container = target.closest(SELECTOR),
2707
  targetOnTop;
2708
 
2709
  // Determine if input container target is above this
2710
  targetOnTop = container.length < 1 ? FALSE :
2711
+ parseInt(container[0].style.zIndex, 10) > parseInt(tooltip[0].style.zIndex, 10);
2712
 
2713
  // If we're showing a modal, but focus has landed on an input below
2714
  // this modal, divert focus to the first visible input in this modal
2715
  // or if we can't find one... the tooltip itself
2716
+ if(!targetOnTop && target.closest(SELECTOR)[0] !== tooltip[0]) {
2717
  focusInputs(target);
2718
  }
2719
  }
2720
 
2721
  $.extend(self, {
2722
+ init: function() {
2723
+ // Create document overlay
2724
+ elem = self.elem = $('<div />', {
2725
+ id: 'qtip-overlay',
2726
+ html: '<div></div>',
2727
+ mousedown: function() { return FALSE; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2728
  })
2729
+ .hide();
2730
 
2731
+ // Make sure we can't focus anything outside the tooltip
2732
+ $(document.body).bind('focusin'+MODALSELECTOR, stealFocus);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2733
 
2734
+ // Apply keyboard "Escape key" close handler
2735
+ $(document).bind('keydown'+MODALSELECTOR, function(event) {
2736
+ if(current && current.options.show.modal.escape && event.keyCode === 27) {
2737
+ current.hide(event);
2738
  }
2739
  });
2740
 
 
 
 
 
 
 
 
 
 
2741
  // Apply click handler for blur option
2742
+ elem.bind('click'+MODALSELECTOR, function(event) {
2743
+ if(current && current.options.show.modal.blur) {
2744
+ current.hide(event);
2745
+ }
2746
+ });
 
 
 
2747
 
2748
  return self;
2749
  },
2750
 
2751
+ update: function(api) {
2752
+ // Update current API reference
2753
+ current = api;
 
 
 
 
 
 
2754
 
2755
+ // Update focusable elements if enabled
2756
+ if(api.options.show.modal.stealfocus !== FALSE) {
2757
+ focusableElems = api.tooltip.find('*').filter(function() {
2758
+ return focusable(this);
 
 
 
 
 
 
 
 
 
 
2759
  });
2760
  }
2761
+ else { focusableElems = []; }
 
 
 
2762
  },
2763
 
2764
+ toggle: function(api, state, duration) {
2765
+ var tooltip = api.tooltip,
2766
+ options = api.options.show.modal,
2767
+ effect = options.effect,
 
 
2768
  type = state ? 'show': 'hide',
2769
+ visible = elem.is(':visible'),
2770
+ visibleModals = $(MODALSELECTOR).filter(':visible:not(:animated)').not(tooltip);
 
 
 
 
2771
 
2772
+ // Set active tooltip API reference
2773
+ self.update(api);
 
 
 
 
 
2774
 
2775
+ // If the modal can steal the focus...
2776
+ // Blur the current item and focus anything in the modal we an
2777
+ if(state && options.stealfocus !== FALSE) {
2778
+ focusInputs( $(':focus') );
2779
+ }
2780
 
2781
+ // Toggle backdrop cursor style on show
2782
+ elem.toggleClass('blurs', options.blur);
 
 
2783
 
2784
+ // Append to body on show
2785
+ if(state) {
2786
+ elem.appendTo(document.body);
2787
  }
2788
+
2789
+ // Prevent modal from conflicting with show.solo, and don't hide backdrop is other modals are visible
2790
+ if(elem.is(':animated') && visible === state && prevState !== FALSE || !state && visibleModals.length) {
2791
+ return self;
2792
  }
2793
 
2794
  // Stop all animations
2795
+ elem.stop(TRUE, FALSE);
2796
 
2797
  // Use custom function if provided
2798
  if($.isFunction(effect)) {
2799
+ effect.call(elem, state);
2800
  }
2801
 
2802
  // If no effect type is supplied, use a simple toggle
2803
  else if(effect === FALSE) {
2804
+ elem[ type ]();
2805
  }
2806
 
2807
  // Use basic fade function
2808
  else {
2809
+ elem.fadeTo( parseInt(duration, 10) || 90, state ? 1 : 0, function() {
2810
+ if(!state) { elem.hide(); }
2811
  });
2812
  }
2813
 
2814
+ // Reset position and detach from body on hide
2815
  if(!state) {
2816
+ elem.queue(function(next) {
2817
+ elem.css({ left: '', top: '' });
2818
+ if(!$(MODALSELECTOR).length) { elem.detach(); }
2819
  next();
2820
  });
2821
  }
2822
 
2823
+ // Cache the state
2824
+ prevState = state;
2825
+
2826
+ // If the tooltip is destroyed, set reference to null
2827
+ if(current.destroyed) { current = NULL; }
2828
+
2829
  return self;
2830
+ }
2831
+ });
2832
+
2833
+ self.init();
2834
+ };
2835
+ OVERLAY = new OVERLAY();
2836
+
2837
+ function Modal(api, options) {
2838
+ this.options = options;
2839
+ this._ns = '-modal';
2840
+
2841
+ this.qtip = api;
2842
+ this.init(api);
2843
+ }
2844
 
2845
+ $.extend(Modal.prototype, {
2846
+ init: function(qtip) {
2847
+ var tooltip = qtip.tooltip;
2848
 
2849
+ // If modal is disabled... return
2850
+ if(!this.options.on) { return this; }
 
2851
 
2852
+ // Set overlay reference
2853
+ qtip.elements.overlay = OVERLAY.elem;
 
2854
 
2855
+ // Add unique attribute so we can grab modal tooltips easily via a SELECTOR, and set z-index
2856
+ tooltip.addClass(MODALCLASS).css('z-index', QTIP.modal_zindex + $(MODALSELECTOR).length);
2857
+
2858
+ // Apply our show/hide/focus modal events
2859
+ qtip._bind(tooltip, ['tooltipshow', 'tooltiphide'], function(event, api, duration) {
2860
+ var oEvent = event.originalEvent;
2861
+
2862
+ // Make sure mouseout doesn't trigger a hide when showing the modal and mousing onto backdrop
2863
+ if(event.target === tooltip[0]) {
2864
+ if(oEvent && event.type === 'tooltiphide' && /mouse(leave|enter)/.test(oEvent.type) && $(oEvent.relatedTarget).closest(OVERLAY.elem[0]).length) {
2865
+ /* eslint-disable no-empty */
2866
+ try { event.preventDefault(); }
2867
+ catch(e) {}
2868
+ /* eslint-enable no-empty */
2869
  }
2870
+ else if(!oEvent || oEvent && oEvent.type !== 'tooltipsolo') {
2871
+ this.toggle(event, event.type === 'tooltipshow', duration);
2872
+ }
2873
+ }
2874
+ }, this._ns, this);
2875
+
2876
+ // Adjust modal z-index on tooltip focus
2877
+ qtip._bind(tooltip, 'tooltipfocus', function(event, api) {
2878
+ // If focus was cancelled before it reached us, don't do anything
2879
+ if(event.isDefaultPrevented() || event.target !== tooltip[0]) { return; }
2880
+
2881
+ var qtips = $(MODALSELECTOR),
2882
+
2883
+ // Keep the modal's lower than other, regular qtips
2884
+ newIndex = QTIP.modal_zindex + qtips.length,
2885
+ curIndex = parseInt(tooltip[0].style.zIndex, 10);
2886
+
2887
+ // Set overlay z-index
2888
+ OVERLAY.elem[0].style.zIndex = newIndex - 1;
2889
+
2890
+ // Reduce modal z-index's and keep them properly ordered
2891
+ qtips.each(function() {
2892
+ if(this.style.zIndex > curIndex) {
2893
+ this.style.zIndex -= 1;
2894
  }
2895
+ });
2896
+
2897
+ // Fire blur event for focused tooltip
2898
+ qtips.filter('.' + CLASS_FOCUS).qtip('blur', event.originalEvent);
2899
 
2900
+ // Set the new z-index
2901
+ tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex;
2902
+
2903
+ // Set current
2904
+ OVERLAY.update(api);
2905
+
2906
+ // Prevent default handling
2907
+ /* eslint-disable no-empty */
2908
+ try { event.preventDefault(); }
2909
+ catch(e) {}
2910
+ /* eslint-enable no-empty */
2911
+ }, this._ns, this);
2912
+
2913
+ // Focus any other visible modals when this one hides
2914
+ qtip._bind(tooltip, 'tooltiphide', function(event) {
2915
+ if(event.target === tooltip[0]) {
2916
+ $(MODALSELECTOR).filter(':visible').not(tooltip).last().qtip('focus', event);
2917
  }
2918
+ }, this._ns, this);
2919
+ },
2920
 
2921
+ toggle: function(event, state, duration) {
2922
+ // Make sure default event hasn't been prevented
2923
+ if(event && event.isDefaultPrevented()) { return this; }
 
2924
 
2925
+ // Toggle it
2926
+ OVERLAY.toggle(this.qtip, !!state, duration);
2927
+ },
2928
 
2929
+ destroy: function() {
2930
+ // Remove modal class
2931
+ this.qtip.tooltip.removeClass(MODALCLASS);
2932
 
2933
+ // Remove bound events
2934
+ this.qtip._unbind(this.qtip.tooltip, this._ns);
2935
+
2936
+ // Delete element reference
2937
+ OVERLAY.toggle(this.qtip, FALSE);
2938
+ delete this.qtip.elements.overlay;
2939
+ }
2940
+ });
2941
 
2942
+
2943
+ MODAL = PLUGINS.modal = function(api) {
2944
+ return new Modal(api, api.options.show.modal);
2945
+ };
2946
 
2947
  // Setup sanitiztion rules
2948
+ MODAL.sanitize = function(opts) {
2949
+ if(opts.show) {
2950
  if(typeof opts.show.modal !== 'object') { opts.show.modal = { on: !!opts.show.modal }; }
2951
  else if(typeof opts.show.modal.on === 'undefined') { opts.show.modal.on = TRUE; }
2952
  }
2953
  };
2954
 
2955
  // Base z-index for all modal tooltips (use qTip core z-index as a base)
2956
+ /* eslint-disable camelcase */
2957
+ QTIP.modal_zindex = QTIP.zindex - 200;
2958
+ /* eslint-enable camelcase */
2959
 
2960
+ // Plugin needs to be initialized on render
2961
+ MODAL.initialize = 'render';
2962
+
2963
+ // Setup option set checks
2964
+ CHECKS.modal = {
2965
+ '^show.modal.(on|blur)$': function() {
2966
+ // Initialise
2967
+ this.destroy();
2968
+ this.init();
2969
+
2970
+ // Show the modal if not visible already and tooltip is visible
2971
+ this.qtip.elems.overlay.toggle(
2972
+ this.qtip.tooltip[0].offsetWidth > 0
2973
+ );
2974
+ }
2975
+ };
2976
 
2977
  // Extend original api defaults
2978
  $.extend(TRUE, QTIP.defaults, {
2986
  }
2987
  }
2988
  });
2989
+ ;PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight)
 
 
2990
  {
2991
  var target = posOptions.target,
2992
  tooltip = api.elements.tooltip,
2998
  methodY = method[1] || method[0],
2999
  viewport = posOptions.viewport,
3000
  container = posOptions.container,
 
 
3001
  adjusted = { left: 0, top: 0 },
3002
+ fixed, newMy, containerOffset, containerStatic,
3003
+ viewportWidth, viewportHeight, viewportScroll, viewportOffset;
3004
 
3005
+ // If viewport is not a jQuery element, or it's the window/document, or no adjustment method is used... return
3006
  if(!viewport.jquery || target[0] === window || target[0] === document.body || adjust.method === 'none') {
3007
  return adjusted;
3008
  }
3009
 
3010
+ // Cach container details
3011
+ containerOffset = container.offset() || adjusted;
3012
+ containerStatic = container.css('position') === 'static';
3013
+
3014
  // Cache our viewport details
3015
  fixed = tooltip.css('position') === 'fixed';
3016
+ viewportWidth = viewport[0] === window ? viewport.width() : viewport.outerWidth(FALSE);
3017
+ viewportHeight = viewport[0] === window ? viewport.height() : viewport.outerHeight(FALSE);
3018
+ viewportScroll = { left: fixed ? 0 : viewport.scrollLeft(), top: fixed ? 0 : viewport.scrollTop() };
3019
+ viewportOffset = viewport.offset() || adjusted;
 
 
 
 
 
 
 
 
 
 
3020
 
3021
  // Generic calculation method
3022
+ function calculate(side, otherSide, type, adjustment, side1, side2, lengthName, targetLength, elemLength) {
3023
  var initialPos = position[side1],
3024
+ mySide = my[side],
3025
+ atSide = at[side],
3026
  isShift = type === SHIFT,
 
3027
  myLength = mySide === side1 ? elemLength : mySide === side2 ? -elemLength : -elemLength / 2,
3028
  atLength = atSide === side1 ? targetLength : atSide === side2 ? -targetLength : -targetLength / 2,
3029
+ sideOffset = viewportScroll[side1] + viewportOffset[side1] - (containerStatic ? 0 : containerOffset[side1]),
3030
+ overflow1 = sideOffset - initialPos,
3031
+ overflow2 = initialPos + elemLength - (lengthName === WIDTH ? viewportWidth : viewportHeight) - sideOffset,
 
3032
  offset = myLength - (my.precedance === side || mySide === my[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0);
3033
 
3034
  // shift
3035
  if(isShift) {
3036
+ offset = (mySide === side1 ? 1 : -1) * myLength;
 
3037
 
3038
  // Adjust position but keep it within viewport dimensions
3039
  position[side1] += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0;
3040
  position[side1] = Math.max(
3041
+ -containerOffset[side1] + viewportOffset[side1],
3042
  initialPos - offset,
3043
  Math.min(
3044
+ Math.max(
3045
+ -containerOffset[side1] + viewportOffset[side1] + (lengthName === WIDTH ? viewportWidth : viewportHeight),
3046
+ initialPos + offset
3047
+ ),
3048
+ position[side1],
3049
+
3050
+ // Make sure we don't adjust complete off the element when using 'center'
3051
+ mySide === 'center' ? initialPos - myLength : 1E9
3052
  )
3053
  );
3054
+
3055
  }
3056
 
3057
  // flip/flipinvert
3058
  else {
3059
  // Update adjustment amount depending on if using flipinvert or flip
3060
+ adjustment *= type === FLIPINVERT ? 2 : 0;
3061
 
3062
  // Check for overflow on the left/top
3063
  if(overflow1 > 0 && (mySide !== side1 || overflow2 > 0)) {
3064
+ position[side1] -= offset + adjustment;
3065
+ newMy.invert(side, side1);
3066
  }
3067
 
3068
  // Check for overflow on the bottom/right
3069
  else if(overflow2 > 0 && (mySide !== side2 || overflow1 > 0) ) {
3070
+ position[side1] -= (mySide === CENTER ? -offset : offset) + adjustment;
3071
+ newMy.invert(side, side2);
3072
  }
3073
 
3074
  // Make sure we haven't made things worse with the adjustment and reset if so
3075
+ if(position[side1] < viewportScroll[side1] && -position[side1] > overflow2) {
3076
  position[side1] = initialPos; newMy = my.clone();
3077
  }
3078
  }
3086
  // Adjust position based onviewport and adjustment options
3087
  adjusted = {
3088
  left: methodX !== 'none' ? calculate( X, Y, methodX, adjust.x, LEFT, RIGHT, WIDTH, targetWidth, elemWidth ) : 0,
3089
+ top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0,
3090
+ my: newMy
3091
  };
3092
 
 
 
 
 
 
3093
  return adjusted;
3094
  };
3095
+ ;PLUGINS.polys = {
3096
+ // POLY area coordinate calculator
3097
+ // Special thanks to Ed Cradock for helping out with this.
3098
+ // Uses a binary search algorithm to find suitable coordinates.
3099
+ polygon: function(baseCoords, corner) {
3100
+ var result = {
 
 
 
 
 
 
3101
  width: 0, height: 0,
3102
  position: {
3103
  top: 1e10, right: 0,
3104
  bottom: 0, left: 1e10
3105
+ },
3106
+ adjustable: FALSE
3107
  },
3108
+ i = 0, next,
3109
+ coords = [],
3110
+ compareX = 1, compareY = 1,
3111
+ realX = 0, realY = 0,
3112
+ newWidth, newHeight;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3113
 
3114
+ // First pass, sanitize coords and determine outer edges
3115
+ i = baseCoords.length;
3116
+ while(i--) {
 
3117
  next = [ parseInt(baseCoords[--i], 10), parseInt(baseCoords[i+1], 10) ];
3118
 
3119
  if(next[0] > result.position.right){ result.position.right = next[0]; }
3123
 
3124
  coords.push(next);
3125
  }
3126
+
3127
+ // Calculate height and width from outer edges
3128
+ newWidth = result.width = Math.abs(result.position.right - result.position.left);
3129
+ newHeight = result.height = Math.abs(result.position.bottom - result.position.top);
3130
+
3131
+ // If it's the center corner...
3132
+ if(corner.abbrev() === 'c') {
3133
+ result.position = {
3134
+ left: result.position.left + result.width / 2,
3135
+ top: result.position.top + result.height / 2
3136
+ };
3137
+ }
3138
+ else {
3139
+ // Second pass, use a binary search algorithm to locate most suitable coordinate
3140
+ while(newWidth > 0 && newHeight > 0 && compareX > 0 && compareY > 0)
3141
+ {
3142
+ newWidth = Math.floor(newWidth / 2);
3143
+ newHeight = Math.floor(newHeight / 2);
3144
+
3145
+ if(corner.x === LEFT){ compareX = newWidth; }
3146
+ else if(corner.x === RIGHT){ compareX = result.width - newWidth; }
3147
+ else{ compareX += Math.floor(newWidth / 2); }
3148
+
3149
+ if(corner.y === TOP){ compareY = newHeight; }
3150
+ else if(corner.y === BOTTOM){ compareY = result.height - newHeight; }
3151
+ else{ compareY += Math.floor(newHeight / 2); }
3152
+
3153
+ i = coords.length;
3154
+ while(i--)
3155
+ {
3156
+ if(coords.length < 2){ break; }
3157
+
3158
+ realX = coords[i][0] - result.position.left;
3159
+ realY = coords[i][1] - result.position.top;
3160
+
3161
+ if(
3162
+ corner.x === LEFT && realX >= compareX ||
3163
+ corner.x === RIGHT && realX <= compareX ||
3164
+ corner.x === CENTER && (realX < compareX || realX > result.width - compareX) ||
3165
+ corner.y === TOP && realY >= compareY ||
3166
+ corner.y === BOTTOM && realY <= compareY ||
3167
+ corner.y === CENTER && (realY < compareY || realY > result.height - compareY)) {
3168
+ coords.splice(i, 1);
3169
+ }
3170
+ }
3171
+ }
3172
+ result.position = { left: coords[0][0], top: coords[0][1] };
3173
  }
3174
+
3175
+ return result;
3176
+ },
3177
+
3178
+ rect: function(ax, ay, bx, by) {
3179
+ return {
3180
+ width: Math.abs(bx - ax),
3181
+ height: Math.abs(by - ay),
3182
+ position: {
3183
+ left: Math.min(ax, bx),
3184
+ top: Math.min(ay, by)
3185
+ }
3186
+ };
3187
+ },
3188
+
3189
+ _angles: {
3190
+ tc: 3 / 2, tr: 7 / 4, tl: 5 / 4,
3191
+ bc: 1 / 2, br: 1 / 4, bl: 3 / 4,
3192
+ rc: 2, lc: 1, c: 0
3193
+ },
3194
+ ellipse: function(cx, cy, rx, ry, corner) {
3195
+ var c = PLUGINS.polys._angles[ corner.abbrev() ],
3196
+ rxc = c === 0 ? 0 : rx * Math.cos( c * Math.PI ),
3197
+ rys = ry * Math.sin( c * Math.PI );
3198
+
3199
+ return {
3200
+ width: rx * 2 - Math.abs(rxc),
3201
+ height: ry * 2 - Math.abs(rys),
3202
+ position: {
3203
+ left: cx + rxc,
3204
+ top: cy + rys
3205
+ },
3206
+ adjustable: FALSE
3207
+ };
3208
+ },
3209
+ circle: function(cx, cy, r, corner) {
3210
+ return PLUGINS.polys.ellipse(cx, cy, r, r, corner);
3211
  }
3212
+ };
3213
+ ;PLUGINS.svg = function(api, svg, corner)
3214
+ {
3215
+ var elem = svg[0],
3216
+ root = $(elem.ownerSVGElement),
3217
+ ownerDocument = elem.ownerDocument,
3218
+ strokeWidth2 = (parseInt(svg.css('stroke-width'), 10) || 0) / 2,
3219
+ frameOffset, mtx, transformed,
3220
+ len, next, i, points,
3221
+ result, position;
3222
 
3223
+ // Ascend the parentNode chain until we find an element with getBBox()
3224
+ while(!elem.getBBox) { elem = elem.parentNode; }
3225
+ if(!elem.getBBox || !elem.parentNode) { return FALSE; }
3226
+
3227
+ // Determine which shape calculation to use
3228
+ switch(elem.nodeName) {
3229
+ case 'ellipse':
3230
+ case 'circle':
3231
+ result = PLUGINS.polys.ellipse(
3232
+ elem.cx.baseVal.value,
3233
+ elem.cy.baseVal.value,
3234
+ (elem.rx || elem.r).baseVal.value + strokeWidth2,
3235
+ (elem.ry || elem.r).baseVal.value + strokeWidth2,
3236
+ corner
3237
+ );
3238
+ break;
3239
+
3240
+ case 'line':
3241
+ case 'polygon':
3242
+ case 'polyline':
3243
+ // Determine points object (line has none, so mimic using array)
3244
+ points = elem.points || [
3245
+ { x: elem.x1.baseVal.value, y: elem.y1.baseVal.value },
3246
+ { x: elem.x2.baseVal.value, y: elem.y2.baseVal.value }
3247
+ ];
3248
+
3249
+ for(result = [], i = -1, len = points.numberOfItems || points.length; ++i < len;) {
3250
+ next = points.getItem ? points.getItem(i) : points[i];
3251
+ result.push.apply(result, [next.x, next.y]);
3252
+ }
3253
+
3254
+ result = PLUGINS.polys.polygon(result, corner);
3255
+ break;
3256
+
3257
+ // Unknown shape or rectangle? Use bounding box
3258
+ default:
3259
+ result = elem.getBBox();
3260
  result = {
3261
+ width: result.width,
3262
+ height: result.height,
3263
  position: {
3264
+ left: result.x,
3265
+ top: result.y
3266
  }
3267
  };
3268
  break;
3269
+ }
3270
 
3271
+ // Shortcut assignments
3272
+ position = result.position;
3273
+ root = root[0];
 
 
 
 
3274
 
3275
+ // Convert position into a pixel value
3276
+ if(root.createSVGPoint) {
3277
+ mtx = elem.getScreenCTM();
3278
+ points = root.createSVGPoint();
3279
 
3280
+ points.x = position.left;
3281
+ points.y = position.top;
3282
+ transformed = points.matrixTransform( mtx );
3283
+ position.left = transformed.x;
3284
+ position.top = transformed.y;
3285
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3286
 
3287
+ // Check the element is not in a child document, and if so, adjust for frame elements offset
3288
+ if(ownerDocument !== document && api.position.target !== 'mouse') {
3289
+ frameOffset = $((ownerDocument.defaultView || ownerDocument.parentWindow).frameElement).offset();
3290
+ if(frameOffset) {
3291
+ position.left += frameOffset.left;
3292
+ position.top += frameOffset.top;
3293
+ }
3294
+ }
3295
 
3296
+ // Adjust by scroll offset of owner document
3297
+ ownerDocument = $(ownerDocument);
3298
+ position.left += ownerDocument.scrollLeft();
3299
+ position.top += ownerDocument.scrollTop();
3300
 
3301
+ return result;
3302
+ };
3303
+ ;PLUGINS.imagemap = function(api, area, corner)
3304
+ {
3305
+ if(!area.jquery) { area = $(area); }
3306
+
3307
+ var shape = (area.attr('shape') || 'rect').toLowerCase().replace('poly', 'polygon'),
3308
+ image = $('img[usemap="#'+area.parent('map').attr('name')+'"]'),
3309
+ coordsString = $.trim(area.attr('coords')),
3310
+ coordsArray = coordsString.replace(/,$/, '').split(','),
3311
+ imageOffset, coords, i, result, len;
3312
+
3313
+ // If we can't find the image using the map...
3314
+ if(!image.length) { return FALSE; }
3315
+
3316
+ // Pass coordinates string if polygon
3317
+ if(shape === 'polygon') {
3318
+ result = PLUGINS.polys.polygon(coordsArray, corner);
3319
+ }
3320
+
3321
+ // Otherwise parse the coordinates and pass them as arguments
3322
+ else if(PLUGINS.polys[shape]) {
3323
+ for(i = -1, len = coordsArray.length, coords = []; ++i < len;) {
3324
+ coords.push( parseInt(coordsArray[i], 10) );
3325
+ }
3326
+
3327
+ result = PLUGINS.polys[shape].apply(
3328
+ this, coords.concat(corner)
3329
+ );
3330
  }
3331
 
3332
+ // If no shapre calculation method was found, return false
3333
+ else { return FALSE; }
3334
+
3335
+ // Make sure we account for padding and borders on the image
3336
+ imageOffset = image.offset();
3337
+ imageOffset.left += Math.ceil((image.outerWidth(FALSE) - image.width()) / 2);
3338
+ imageOffset.top += Math.ceil((image.outerHeight(FALSE) - image.height()) / 2);
3339
+
3340
  // Add image position to offset coordinates
3341
  result.position.left += imageOffset.left;
3342
  result.position.top += imageOffset.top;
3343
 
3344
  return result;
3345
  };
3346
+ ;var IE6,
3347
 
3348
+ /*
 
3349
  * BGIFrame adaption (http://plugins.jquery.com/project/bgiframe)
3350
  * Special thanks to Brandon Aaron
3351
  */
3352
+ BGIFRAME = '<iframe class="qtip-bgiframe" frameborder="0" tabindex="-1" src="javascript:\'\';" ' +
3353
+ ' style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=0); ' +
3354
+ '-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";"></iframe>';
 
 
 
3355
 
3356
+ function Ie6(api) {
3357
+ this._ns = 'ie6';
 
 
 
 
 
3358
 
3359
+ this.qtip = api;
3360
+ this.init(api);
3361
+ }
3362
+
3363
+ $.extend(Ie6.prototype, {
3364
+ _scroll : function() {
3365
+ var overlay = this.qtip.elements.overlay;
3366
+ overlay && (overlay[0].style.top = $(window).scrollTop() + 'px');
3367
+ },
3368
+
3369
+ init: function(qtip) {
3370
+ var tooltip = qtip.tooltip;
3371
+
3372
+ // Create the BGIFrame element if needed
3373
+ if($('select, object').length < 1) {
3374
+ this.bgiframe = qtip.elements.bgiframe = $(BGIFRAME).appendTo(tooltip);
3375
 
3376
  // Update BGIFrame on tooltip move
3377
+ qtip._bind(tooltip, 'tooltipmove', this.adjustBGIFrame, this._ns, this);
3378
+ }
3379
 
3380
+ // redraw() container for width/height calculations
3381
+ this.redrawContainer = $('<div/>', { id: NAMESPACE+'-rcontainer' })
3382
+ .appendTo(document.body);
 
 
 
 
 
 
 
 
 
 
 
 
 
3383
 
3384
+ // Fixup modal plugin if present too
3385
+ if( qtip.elements.overlay && qtip.elements.overlay.addClass('qtipmodal-ie6fix') ) {
3386
+ qtip._bind(window, ['scroll', 'resize'], this._scroll, this._ns, this);
3387
+ qtip._bind(tooltip, ['tooltipshow'], this._scroll, this._ns, this);
3388
+ }
3389
+
3390
+ // Set dimensions
3391
+ this.redraw();
3392
+ },
3393
+
3394
+ adjustBGIFrame: function() {
3395
+ var tooltip = this.qtip.tooltip,
3396
+ dimensions = {
3397
+ height: tooltip.outerHeight(FALSE),
3398
+ width: tooltip.outerWidth(FALSE)
3399
+ },
3400
+ plugin = this.qtip.plugins.tip,
3401
+ tip = this.qtip.elements.tip,
3402
+ tipAdjust, offset;
3403
+
3404
+ // Adjust border offset
3405
+ offset = parseInt(tooltip.css('borderLeftWidth'), 10) || 0;
3406
+ offset = { left: -offset, top: -offset };
3407
+
3408
+ // Adjust for tips plugin
3409
+ if(plugin && tip) {
3410
+ tipAdjust = plugin.corner.precedance === 'x' ? [WIDTH, LEFT] : [HEIGHT, TOP];
3411
+ offset[ tipAdjust[1] ] -= tip[ tipAdjust[0] ]();
3412
+ }
3413
+
3414
+ // Update bgiframe
3415
+ this.bgiframe.css(offset).css(dimensions);
3416
+ },
3417
+
3418
+ // Max/min width simulator function
3419
+ redraw: function() {
3420
+ if(this.qtip.rendered < 1 || this.drawing) { return this; }
3421
+
3422
+ var tooltip = this.qtip.tooltip,
3423
+ style = this.qtip.options.style,
3424
+ container = this.qtip.options.position.container,
3425
+ perc, width, max, min;
3426
+
3427
+ // Set drawing flag
3428
+ this.qtip.drawing = 1;
3429
+
3430
+ // If tooltip has a set height/width, just set it... like a boss!
3431
+ if(style.height) { tooltip.css(HEIGHT, style.height); }
3432
+ if(style.width) { tooltip.css(WIDTH, style.width); }
3433
 
3434
+ // Simulate max/min width if not set width present...
3435
+ else {
3436
+ // Reset width and add fluid class
3437
+ tooltip.css(WIDTH, '').appendTo(this.redrawContainer);
3438
+
3439
+ // Grab our tooltip width (add 1 if odd so we don't get wrapping problems.. huzzah!)
3440
+ width = tooltip.width();
3441
+ if(width % 2 < 1) { width += 1; }
3442
+
3443
+ // Grab our max/min properties
3444
+ max = tooltip.css('maxWidth') || '';
3445
+ min = tooltip.css('minWidth') || '';
3446
+
3447
+ // Parse into proper pixel values
3448
+ perc = (max + min).indexOf('%') > -1 ? container.width() / 100 : 0;
3449
+ max = (max.indexOf('%') > -1 ? perc : 1 * parseInt(max, 10)) || width;
3450
+ min = (min.indexOf('%') > -1 ? perc : 1 * parseInt(min, 10)) || 0;
3451
 
3452
+ // Determine new dimension size based on max/min/current values
3453
+ width = max + min ? Math.min(Math.max(width, min), max) : width;
3454
+
3455
+ // Set the newly calculated width and remvoe fluid class
3456
+ tooltip.css(WIDTH, Math.round(width)).appendTo(container);
3457
  }
 
3458
 
3459
+ // Set drawing flag
3460
+ this.drawing = 0;
3461
 
3462
+ return this;
3463
+ },
3464
+
3465
+ destroy: function() {
3466
+ // Remove iframe
3467
+ this.bgiframe && this.bgiframe.remove();
3468
+
3469
+ // Remove bound events
3470
+ this.qtip._unbind([window, this.qtip.tooltip], this._ns);
3471
  }
3472
+ });
3473
 
3474
+ IE6 = PLUGINS.ie6 = function(api) {
3475
+ // Proceed only if the browser is IE6
3476
+ return BROWSER.ie === 6 ? new Ie6(api) : FALSE;
3477
  };
3478
 
3479
+ IE6.initialize = 'render';
 
 
3480
 
3481
+ CHECKS.ie6 = {
3482
+ '^content|style$': function() {
3483
+ this.redraw();
3484
+ }
3485
+ };
3486
+ ;}));
3487
+ }( window, document ));
js/jquery.qtip.min.js CHANGED
@@ -1,2 +1,5 @@
1
- /*! qTip2 v2.0.0 | http://craigsworks.com/projects/qtip2/ | Licensed MIT, GPL */
2
- (function(a,b,c){(function(a){"use strict",typeof define=="function"&&define.amd?define(["jquery"],a):jQuery&&!jQuery.fn.qtip&&a(jQuery)})(function(d){function I(a){var b=function(a){return a===g||"object"!=typeof a},c=function(a){return!d.isFunction(a)&&(!a&&!a.attr||a.length<1||"object"==typeof a&&!a.jquery)};if(!a||"object"!=typeof a)return f;b(a.metadata)&&(a.metadata={type:a.metadata});if("content"in a){if(b(a.content)||a.content.jquery)a.content={text:a.content};c(a.content.text||f)&&(a.content.text=f),"title"in a.content&&(b(a.content.title)&&(a.content.title={text:a.content.title}),c(a.content.title.text||f)&&(a.content.title.text=f))}return"position"in a&&b(a.position)&&(a.position={my:a.position,at:a.position}),"show"in a&&b(a.show)&&(a.show=a.show.jquery?{target:a.show}:{event:a.show}),"hide"in a&&b(a.hide)&&(a.hide=a.hide.jquery?{target:a.hide}:{event:a.hide}),"style"in a&&b(a.style)&&(a.style={classes:a.style}),d.each(u,function(){this.sanitize&&this.sanitize(a)}),a}function J(h,i,q,r){function Q(a){var b=0,c,d=i,e=a.split(".");while(d=d[e[b++]])b<e.length&&(c=d);return[c||i,e.pop()]}function R(a,b,c){var e=d.Event("tooltip"+a);return e.originalEvent=(c?d.extend({},c):g)||P.event||g,M.trigger(e,[s].concat(b||[])),!e.isDefaultPrevented()}function S(){var a=i.style.widget;M.toggleClass("ui-helper-reset "+y,a).toggleClass(B,i.style.def&&!a),O.content&&O.content.toggleClass(y+"-content",a),O.titlebar&&O.titlebar.toggleClass(y+"-header",a),O.button&&O.button.toggleClass(x+"-icon",!a)}function T(a){O.title&&(O.titlebar.remove(),O.titlebar=O.title=O.button=g,a!==f&&s.reposition())}function U(){var a=i.content.title.button,b=typeof a=="string",c=b?a:"Close tooltip";O.button&&O.button.remove(),a.jquery?O.button=a:O.button=d("<a />",{"class":"ui-state-default ui-tooltip-close "+(i.style.widget?"":x+"-icon"),title:c,"aria-label":c}).prepend(d("<span />",{"class":"ui-icon ui-icon-close",html:"&times;"})),O.button.appendTo(O.titlebar).attr("role","button").click(function(a){return M.hasClass(z)||s.hide(a),f}),s.redraw()}function V(){var a=J+"-title";O.titlebar&&T(),O.titlebar=d("<div />",{"class":x+"-titlebar "+(i.style.widget?"ui-widget-header":"")}).append(O.title=d("<div />",{id:a,"class":x+"-title","aria-atomic":e})).insertBefore(O.content).delegate(".ui-tooltip-close","mousedown keydown mouseup keyup mouseout",function(a){d(this).toggleClass("ui-state-active ui-state-focus",a.type.substr(-4)==="down")}).delegate(".ui-tooltip-close","mouseover mouseout",function(a){d(this).toggleClass("ui-state-hover",a.type==="mouseover")}),i.content.title.button?U():s.rendered&&s.redraw()}function W(a){var b=O.button,c=O.title;if(!s.rendered)return f;a?(c||V(),U()):b.remove()}function X(a,b){var c=O.title;if(!s.rendered||!a)return f;d.isFunction(a)&&(a=a.call(h,P.event,s));if(a===f||!a&&a!=="")return T(f);a.jquery&&a.length>0?c.empty().append(a.css({display:"block"})):c.html(a),s.redraw(),b!==f&&s.rendered&&M[0].offsetWidth>0&&s.reposition(P.event)}function Y(a,b){function g(a){function i(c){c&&(delete h[c.src],clearTimeout(s.timers.img[c.src]),d(c).unbind(N)),d.isEmptyObject(h)&&(s.redraw(),b!==f&&s.reposition(P.event),a())}var g,h={};if((g=e.find("img[src]:not([height]):not([width])")).length===0)return i();g.each(function(a,b){if(h[b.src]!==c)return;var e=0,f=3;(function g(){if(b.height||b.width||e>f)return i(b);e+=1,s.timers.img[b.src]=setTimeout(g,700)})(),d(b).bind("error"+N+" load"+N,function(){i(this)}),h[b.src]=b})}var e=O.content;return!s.rendered||!a?f:(d.isFunction(a)&&(a=a.call(h,P.event,s)||""),a.jquery&&a.length>0?e.empty().append(a.css({display:"block"})):e.html(a),s.rendered<0?M.queue("fx",g):(L=0,g(d.noop)),s)}function Z(){function l(a){if(M.hasClass(z))return f;clearTimeout(s.timers.show),clearTimeout(s.timers.hide);var b=function(){s.toggle(e,a)};i.show.delay>0?s.timers.show=setTimeout(b,i.show.delay):b()}function m(a){if(M.hasClass(z)||K||L)return f;var b=d(a.relatedTarget||a.target),e=b.closest(A)[0]===M[0],h=b[0]===g.show[0];clearTimeout(s.timers.show),clearTimeout(s.timers.hide);if(c.target==="mouse"&&e||i.hide.fixed&&/mouse(out|leave|move)/.test(a.type)&&(e||h)){try{a.preventDefault(),a.stopImmediatePropagation()}catch(j){}return}i.hide.delay>0?s.timers.hide=setTimeout(function(){s.hide(a)},i.hide.delay):s.hide(a)}function n(a){if(M.hasClass(z))return f;clearTimeout(s.timers.inactive),s.timers.inactive=setTimeout(function(){s.hide(a)},i.hide.inactive)}function o(a){s.rendered&&M[0].offsetWidth>0&&s.reposition(a)}var c=i.position,g={show:i.show.target,hide:i.hide.target,viewport:d(c.viewport),document:d(b),body:d(b.body),window:d(a)},j={show:d.trim(""+i.show.event).split(" "),hide:d.trim(""+i.hide.event).split(" ")},k=d.browser.msie&&parseInt(d.browser.version,10)===6;M.bind("mouseenter"+N+" mouseleave"+N,function(a){var b=a.type==="mouseenter";b&&s.focus(a),M.toggleClass(D,b)}),/mouse(out|leave)/i.test(i.hide.event)&&i.hide.leave==="window"&&g.window.bind("mouseout"+N+" blur"+N,function(a){!/select|option/.test(a.target.nodeName)&&!a.relatedTarget&&s.hide(a)}),i.hide.fixed?(g.hide=g.hide.add(M),M.bind("mouseover"+N,function(){M.hasClass(z)||clearTimeout(s.timers.hide)})):/mouse(over|enter)/i.test(i.show.event)&&g.hide.bind("mouseleave"+N,function(a){clearTimeout(s.timers.show)}),(""+i.hide.event).indexOf("unfocus")>-1&&c.container.closest("html").bind("mousedown"+N,function(a){var b=d(a.target),c=s.rendered&&!M.hasClass(z)&&M[0].offsetWidth>0,e=b.parents(A).filter(M[0]).length>0;b[0]!==h[0]&&b[0]!==M[0]&&!e&&!h.has(b[0]).length&&!b.attr("disabled")&&s.hide(a)}),"number"==typeof i.hide.inactive&&(g.show.bind("qtip-"+q+"-inactive",n),d.each(t.inactiveEvents,function(a,b){g.hide.add(O.tooltip).bind(b+N+"-inactive",n)})),d.each(j.hide,function(a,b){var c=d.inArray(b,j.show),e=d(g.hide);c>-1&&e.add(g.show).length===e.length||b==="unfocus"?(g.show.bind(b+N,function(a){M[0].offsetWidth>0?m(a):l(a)}),delete j.show[c]):g.hide.bind(b+N,m)}),d.each(j.show,function(a,b){g.show.bind(b+N,l)}),"number"==typeof i.hide.distance&&g.show.add(M).bind("mousemove"+N,function(a){var b=P.origin||{},c=i.hide.distance,d=Math.abs;(d(a.pageX-b.pageX)>=c||d(a.pageY-b.pageY)>=c)&&s.hide(a)}),c.target==="mouse"&&(g.show.bind("mousemove"+N,function(a){v={pageX:a.pageX,pageY:a.pageY,type:"mousemove"}}),c.adjust.mouse&&(i.hide.event&&(M.bind("mouseleave"+N,function(a){(a.relatedTarget||a.target)!==g.show[0]&&s.hide(a)}),O.target.bind("mouseenter"+N+" mouseleave"+N,function(a){P.onTarget=a.type==="mouseenter"})),g.document.bind("mousemove"+N,function(a){s.rendered&&P.onTarget&&!M.hasClass(z)&&M[0].offsetWidth>0&&s.reposition(a||v)}))),(c.adjust.resize||g.viewport.length)&&(d.event.special.resize?g.viewport:g.window).bind("resize"+N,o),(g.viewport.length||k&&M.css("position")==="fixed")&&g.viewport.bind("scroll"+N,o)}function _(){var c=[i.show.target[0],i.hide.target[0],s.rendered&&O.tooltip[0],i.position.container[0],i.position.viewport[0],i.position.container.closest("html")[0],a,b];s.rendered?d([]).pushStack(d.grep(c,function(a){return typeof a=="object"})).unbind(N):i.show.target.unbind(N+"-create")}var s=this,E=b.body,J=x+"-"+q,K=0,L=0,M=d(),N=".qtip-"+q,O,P;s.id=q,s.rendered=f,s.destroyed=f,s.elements=O={target:h},s.timers={img:{}},s.options=i,s.checks={},s.plugins={},s.cache=P={event:{},target:d(),disabled:f,attr:r,onTarget:f,lastClass:""},s.checks.builtin={"^id$":function(a,b,c){var g=c===e?t.nextid:c,h=x+"-"+g;g!==f&&g.length>0&&!d("#"+h).length&&(M[0].id=h,O.content[0].id=h+"-content",O.title[0].id=h+"-title")},"^content.text$":function(a,b,c){Y(c)},"^content.title.text$":function(a,b,c){if(!c)return T();!O.title&&c&&V(),X(c)},"^content.title.button$":function(a,b,c){W(c)},"^position.(my|at)$":function(a,b,c){"string"==typeof c&&(a[b]=new u.Corner(c))},"^position.container$":function(a,b,c){s.rendered&&M.appendTo(c)},"^show.ready$":function(){s.rendered?s.toggle(e):s.render(1)},"^style.classes$":function(a,b,c){M.attr("class",x+" qtip "+c)},"^style.widget|content.title":S,"^events.(render|show|move|hide|focus|blur)$":function(a,b,c){M[(d.isFunction(c)?"":"un")+"bind"]("tooltip"+b,c)},"^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)":function(){var a=i.position;M.attr("tracking",a.target==="mouse"&&a.adjust.mouse),_(),Z()}},d.extend(s,{render:function(a){if(s.rendered)return s;var b=i.content.text,c=i.content.title.text,g=i.position;return d.attr(h[0],"aria-describedby",J),M=O.tooltip=d("<div/>",{id:J,"class":x+" qtip "+B+" "+i.style.classes+" "+x+"-pos-"+i.position.my.abbrev(),width:i.style.width||"",height:i.style.height||"",tracking:g.target==="mouse"&&g.adjust.mouse,role:"alert","aria-live":"polite","aria-atomic":f,"aria-describedby":J+"-content","aria-hidden":e}).toggleClass(z,P.disabled).data("qtip",s).appendTo(i.position.container).append(O.content=d("<div />",{"class":x+"-content",id:J+"-content","aria-atomic":e})),s.rendered=-1,L=1,K=1,c&&(V(),d.isFunction(c)||X(c,f)),d.isFunction(b)||Y(b,f),s.rendered=e,S(),d.each(i.events,function(a,b){d.isFunction(b)&&M.bind(a==="toggle"?"tooltipshow tooltiphide":"tooltip"+a,b)}),d.each(u,function(){this.initialize==="render"&&this(s)}),Z(),M.queue("fx",function(b){R("render"),L=0,K=0,s.redraw(),(i.show.ready||a)&&s.toggle(e,P.event,f),b()}),s},get:function(a){var b,c;switch(a.toLowerCase()){case"dimensions":b={height:M.outerHeight(),width:M.outerWidth()};break;case"offset":b=u.offset(M,i.position.container);break;default:c=Q(a.toLowerCase()),b=c[0][c[1]],b=b.precedance?b.string():b}return b},set:function(a,b){function n(a,b){var c,d,e;for(c in l)for(d in l[c])if(e=(new RegExp(d,"i")).exec(a))b.push(e),l[c][d].apply(s,b)}var c=/^position\.(my|at|adjust|target|container)|style|content|show\.ready/i,h=/^content\.(title|attr)|style/i,j=f,k=f,l=s.checks,m;return"string"==typeof a?(m=a,a={},a[m]=b):a=d.extend(e,{},a),d.each(a,function(b,e){var f=Q(b.toLowerCase()),g;g=f[0][f[1]],f[0][f[1]]="object"==typeof e&&e.nodeType?d(e):e,a[b]=[f[0],f[1],e,g],j=c.test(b)||j,k=h.test(b)||k}),I(i),K=L=1,d.each(a,n),K=L=0,s.rendered&&M[0].offsetWidth>0&&(j&&s.reposition(i.position.target==="mouse"?g:P.event),k&&s.redraw()),s},toggle:function(a,c){function t(){a?(d.browser.msie&&M[0].style.removeAttribute("filter"),M.css("overflow",""),"string"==typeof h.autofocus&&d(h.autofocus,M).focus(),h.target.trigger("qtip-"+q+"-inactive")):M.css({display:"",visibility:"",opacity:"",left:"",top:""}),R(a?"visible":"hidden")}if(!s.rendered)return a?s.render(1):s;var g=a?"show":"hide",h=i[g],j=i[a?"hide":"show"],k=i.position,l=i.content,m=M[0].offsetWidth>0,n=a||h.target.length===1,o=!c||h.target.length<2||P.target[0]===c.target,p,r;(typeof a).search("boolean|number")&&(a=!m);if(!M.is(":animated")&&m===a&&o)return s;if(c){if(/over|enter/.test(c.type)&&/out|leave/.test(P.event.type)&&i.show.target.add(c.target).length===i.show.target.length&&M.has(c.relatedTarget).length)return s;P.event=d.extend({},c)}return R(g,[90])?(d.attr(M[0],"aria-hidden",!a),a?(P.origin=d.extend({},v),s.focus(c),d.isFunction(l.text)&&Y(l.text,f),d.isFunction(l.title.text)&&X(l.title.text,f),!G&&k.target==="mouse"&&k.adjust.mouse&&(d(b).bind("mousemove.qtip",function(a){v={pageX:a.pageX,pageY:a.pageY,type:"mousemove"}}),G=e),s.reposition(c,arguments[2]),!h.solo||d(A,h.solo).not(M).qtip("hide",d.Event("tooltipsolo"))):(clearTimeout(s.timers.show),delete P.origin,G&&!d(A+'[tracking="true"]:visible',h.solo).not(M).length&&(d(b).unbind("mousemove.qtip"),G=f),s.blur(c)),h.effect===f||n===f?(M[g](),t.call(M)):d.isFunction(h.effect)?(M.stop(1,1),h.effect.call(M,s),M.queue("fx",function(a){t(),a()})):M.fadeTo(90,a?1:0,t),a&&h.target.trigger("qtip-"+q+"-inactive"),s):s},show:function(a){return s.toggle(e,a)},hide:function(a){return s.toggle(f,a)},focus:function(a){if(!s.rendered)return s;var b=d(A),c=parseInt(M[0].style.zIndex,10),e=t.zindex+b.length,f=d.extend({},a),g;return M.hasClass(C)||R("focus",[e],f)&&(c!==e&&(b.each(function(){this.style.zIndex>c&&(this.style.zIndex=this.style.zIndex-1)}),b.filter("."+C).qtip("blur",f)),M.addClass(C)[0].style.zIndex=e),s},blur:function(a){return M.removeClass(C),R("blur",[M.css("zIndex")],a),s},reposition:function(c,e){if(!s.rendered||K)return s;K=1;var g=i.position.target,h=i.position,j=h.my,k=h.at,q=h.adjust,r=q.method.split(" "),t=M.outerWidth(),w=M.outerHeight(),x=0,y=0,z=M.css("position")==="fixed",A=h.viewport,B={left:0,top:0},C=h.container,D=M[0].offsetWidth>0,E,F,G;if(d.isArray(g)&&g.length===2)k={x:m,y:l},B={left:g[0],top:g[1]};else if(g==="mouse"&&(c&&c.pageX||P.event.pageX))k={x:m,y:l},c=(c&&(c.type==="resize"||c.type==="scroll")?P.event:c&&c.pageX&&c.type==="mousemove"?c:v&&v.pageX&&(q.mouse||!c||!c.pageX)?{pageX:v.pageX,pageY:v.pageY}:!q.mouse&&P.origin&&P.origin.pageX&&i.show.distance?P.origin:c)||c||P.event||v||{},B={top:c.pageY,left:c.pageX};else{g==="event"&&c&&c.target&&c.type!=="scroll"&&c.type!=="resize"?P.target=d(c.target):g!=="event"&&(P.target=d(g.jquery?g:O.target)),g=P.target,g=d(g).eq(0);if(g.length===0)return s;g[0]===b||g[0]===a?(x=u.iOS?a.innerWidth:g.width(),y=u.iOS?a.innerHeight:g.height(),g[0]===a&&(B={top:(A||g).scrollTop(),left:(A||g).scrollLeft()})):u.imagemap&&g.is("area")?E=u.imagemap(s,g,k,u.viewport?r:f):u.svg&&typeof g[0].xmlbase=="string"?E=u.svg(s,g,k,u.viewport?r:f):(x=g.outerWidth(),y=g.outerHeight(),B=u.offset(g,C)),E&&(x=E.width,y=E.height,F=E.offset,B=E.position);if(u.iOS>3.1&&u.iOS<4.1||u.iOS>=4.3&&u.iOS<4.33||!u.iOS&&z)G=d(a),B.left-=G.scrollLeft(),B.top-=G.scrollTop();B.left+=k.x===o?x:k.x===p?x/2:0,B.top+=k.y===n?y:k.y===p?y/2:0}return B.left+=q.x+(j.x===o?-t:j.x===p?-t/2:0),B.top+=q.y+(j.y===n?-w:j.y===p?-w/2:0),u.viewport?(B.adjusted=u.viewport(s,B,h,x,y,t,w),F&&B.adjusted.left&&(B.left+=F.left),F&&B.adjusted.top&&(B.top+=F.top)):B.adjusted={left:0,top:0},R("move",[B,A.elem||A],c)?(delete B.adjusted,e===f||!D||isNaN(B.left)||isNaN(B.top)||g==="mouse"||!d.isFunction(h.effect)?M.css(B):d.isFunction(h.effect)&&(h.effect.call(M,s,d.extend({},B)),M.queue(function(a){d(this).css({opacity:"",height:""}),d.browser.msie&&this.style.removeAttribute("filter"),a()})),K=0,s):s},redraw:function(){if(s.rendered<1||L)return s;var a=i.style,b=i.position.container,c,d,e,f;return L=1,R("redraw"),a.height&&M.css(k,a.height),a.width?M.css(j,a.width):(M.css(j,"").appendTo(H),d=M.width(),d%2<1&&(d+=1),e=M.css("max-width")||"",f=M.css("min-width")||"",c=(e+f).indexOf("%")>-1?b.width()/100:0,e=(e.indexOf("%")>-1?c:1)*parseInt(e,10)||d,f=(f.indexOf("%")>-1?c:1)*parseInt(f,10)||0,d=e+f?Math.min(Math.max(d,f),e):d,M.css(j,Math.round(d)).appendTo(b)),R("redrawn"),L=0,s},disable:function(a){return"boolean"!=typeof a&&(a=!M.hasClass(z)&&!P.disabled),s.rendered?(M.toggleClass(z,a),d.attr(M[0],"aria-disabled",a)):P.disabled=!!a,s},enable:function(){return s.disable(f)},destroy:function(){var a=h[0],b=d.attr(a,F),c=h.data("qtip");s.destroyed=e,s.rendered&&(M.stop(1,0).remove(),d.each(s.plugins,function(){this.destroy&&this.destroy()})),clearTimeout(s.timers.show),clearTimeout(s.timers.hide),_();if(!c||s===c)d.removeData(a,"qtip"),i.suppress&&b&&(d.attr(a,"title",b),h.removeAttr(F)),h.removeAttr("aria-describedby");return h.unbind(".qtip-"+q),delete w[s.id],h}})}function K(a,c){var h,i,j,k,l,m=d(this),n=d(b.body),o=this===b?n:m,p=m.metadata?m.metadata(c.metadata):g,q=c.metadata.type==="html5"&&p?p[c.metadata.name]:g,r=m.data(c.metadata.name||"qtipopts");try{r=typeof r=="string"?d.parseJSON(r):r}catch(s){}k=d.extend(e,{},t.defaults,c,typeof r=="object"?I(r):g,I(q||p)),i=k.position,k.id=a;if("boolean"==typeof k.content.text){j=m.attr(k.content.attr);if(k.content.attr!==f&&j)k.content.text=j;else return f}i.container.length||(i.container=n),i.target===f&&(i.target=o),k.show.target===f&&(k.show.target=o),k.show.solo===e&&(k.show.solo=i.container.closest("body")),k.hide.target===f&&(k.hide.target=o),k.position.viewport===e&&(k.position.viewport=i.container),i.container=i.container.eq(0),i.at=new u.Corner(i.at),i.my=new u.Corner(i.my);if(d.data(this,"qtip"))if(k.overwrite)m.qtip("destroy");else if(k.overwrite===f)return f;return k.suppress&&(l=d.attr(this,"title"))&&d(this).removeAttr("title").attr(F,l).attr("title",""),h=new J(m,k,a,!!j),d.data(this,"qtip",h),m.bind("remove.qtip-"+a+" removeqtip.qtip-"+a,function(){h.destroy()}),h}function L(a){var b=this,c=a.elements.tooltip,g=a.options.content.ajax,h=t.defaults.content.ajax,i=".qtip-ajax",j=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,k=e,l=f,m;a.checks.ajax={"^content.ajax":function(a,d,e){d==="ajax"&&(g=e),d==="once"?b.init():g&&g.url?b.load():c.unbind(i)}},d.extend(b,{init:function(){return g&&g.url&&c.unbind(i)[g.once?"one":"bind"]("tooltipshow"+i,b.load),b},load:function(c){function r(){var b;if(a.destroyed)return;k=f,p&&(l=e,a.show(c.originalEvent)),(b=h.complete||g.complete)&&d.isFunction(b)&&b.apply(g.context||a,arguments)}function s(b,c,e){var f;if(a.destroyed)return;o&&"string"==typeof b&&(b=d("<div/>").append(b.replace(j,"")).find(o)),(f=h.success||g.success)&&d.isFunction(f)?f.call(g.context||a,b,c,e):a.set("content.text",b)}function t(b,c,d){if(a.destroyed||b.status===0)return;a.set("content.text",c+": "+d)}if(l){l=f;return}var i=g.url.lastIndexOf(" "),n=g.url,o,p=!g.loading&&k;if(p)try{c.preventDefault()}catch(q){}else if(c&&c.isDefaultPrevented())return b;m&&m.abort&&m.abort(),i>-1&&(o=n.substr(i),n=n.substr(0,i)),m=d.ajax(d.extend({error:h.error||t,context:a},g,{url:n,success:s,complete:r}))},destroy:function(){m&&m.abort&&m.abort(),a.destroyed=e}}),b.init()}function M(a,b,c){var d=Math.ceil(b/2),e=Math.ceil(c/2),f={bottomright:[[0,0],[b,c],[b,0]],bottomleft:[[0,0],[b,0],[0,c]],topright:[[0,c],[b,0],[b,c]],topleft:[[0,0],[0,c],[b,c]],topcenter:[[0,c],[d,0],[b,c]],bottomcenter:[[0,0],[b,0],[d,c]],rightcenter:[[0,0],[b,e],[0,c]],leftcenter:[[b,0],[b,c],[0,e]]};return f.lefttop=f.bottomright,f.righttop=f.bottomleft,f.leftbottom=f.topright,f.rightbottom=f.topleft,f[a.string()]}function N(a,b){function D(a){var b=v.is(":visible");v.show(),a(),v.toggle(b)}function E(){x.width=r.height,x.height=r.width}function F(){x.width=r.width,x.height=r.height}function G(b,d,g,j){if(!t.tip)return;var k=q.corner.clone(),u=g.adjusted,v=a.options.position.adjust.method.split(" "),x=v[0],y=v[1]||v[0],z={left:f,top:f,x:0,y:0},A,B={},C;q.corner.fixed!==e&&(x===s&&k.precedance===h&&u.left&&k.y!==p?k.precedance=k.precedance===h?i:h:x!==s&&u.left&&(k.x=k.x===p?u.left>0?m:o:k.x===m?o:m),y===s&&k.precedance===i&&u.top&&k.x!==p?k.precedance=k.precedance===i?h:i:y!==s&&u.top&&(k.y=k.y===p?u.top>0?l:n:k.y===l?n:l),k.string()!==w.corner.string()&&(w.top!==u.top||w.left!==u.left)&&q.update(k,f)),A=q.position(k,u),A[k.x]+=I(k,k.x),A[k.y]+=I(k,k.y),A.right!==c&&(A.left=-A.right),A.bottom!==c&&(A.top=-A.bottom),A.user=Math.max(0,r.offset);if(z.left=x===s&&!!u.left)k.x===p?B["margin-left"]=z.x=A["margin-left"]-u.left:(C=A.right!==c?[u.left,-A.left]:[-u.left,A.left],(z.x=Math.max(C[0],C[1]))>C[0]&&(g.left-=u.left,z.left=f),B[A.right!==c?o:m]=z.x);if(z.top=y===s&&!!u.top)k.y===p?B["margin-top"]=z.y=A["margin-top"]-u.top:(C=A.bottom!==c?[u.top,-A.top]:[-u.top,A.top],(z.y=Math.max(C[0],C[1]))>C[0]&&(g.top-=u.top,z.top=f),B[A.bottom!==c?n:l]=z.y);t.tip.css(B).toggle(!(z.x&&z.y||k.x===p&&z.y||k.y===p&&z.x)),g.left-=A.left.charAt?A.user:x!==s||z.top||!z.left&&!z.top?A.left:0,g.top-=A.top.charAt?A.user:y!==s||z.left||!z.left&&!z.top?A.top:0,w.left=u.left,w.top=u.top,w.corner=k.clone()}function H(){var b=r.corner,c=a.options.position,d=c.at,g=c.my.string?c.my.string():c.my;return b===f||g===f&&d===f?f:(b===e?q.corner=new u.Corner(g):b.string||(q.corner=new u.Corner(b),q.corner.fixed=e),w.corner=new u.Corner(q.corner.string()),q.corner.string()!=="centercenter")}function I(a,b,c){b=b?b:a[a.precedance];var d=t.titlebar&&a.y===l,e=d?t.titlebar:v,f="border-"+b+"-width",g=function(a){return parseInt(a.css(f),10)},h;return D(function(){h=(c?g(c):g(t.content)||g(e)||g(v))||0}),h}function J(a){var b=t.titlebar&&a.y===l,c=b?t.titlebar:t.content,e=d.browser.mozilla,f=e?"-moz-":d.browser.webkit?"-webkit-":"",g="border-radius-"+a.y+a.x,h="border-"+a.y+"-"+a.x+"-radius",i=function(a){return parseInt(c.css(a),10)||parseInt(v.css(a),10)},j;return D(function(){j=i(h)||i(f+h)||i(f+g)||i(g)||0}),j}function K(a){function z(a,b,c){var d=a.css(b)||n;return c&&d===a.css(c)?f:j.test(d)?f:d}var b,c,g,h=t.tip.css("cssText",""),i=a||q.corner,j=/rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i,k="border-"+i[i.precedance]+"-color",m="background-color",n="transparent",o=" !important",s=t.titlebar,u=s&&(i.y===l||i.y===p&&h.position().top+x.height/2+r.offset<s.outerHeight(e)),w=u?s:t.content;D(function(){y.fill=z(h,m)||z(w,m)||z(t.content,m)||z(v,m)||h.css(m),y.border=z(h,k,"color")||z(w,k,"color")||z(t.content,k,"color")||z(v,k,"color")||v.css(k),d("*",h).add(h).css("cssText",m+":"+n+o+";border:0"+o+";")})}function L(a){var b=a.precedance===i,c=x[b?j:k],d=x[b?k:j],e=a.string().indexOf(p)>-1,f=c*(e?.5:1),g=Math.pow,h=Math.round,l,m,n,o=Math.sqrt(g(f,2)+g(d,2)),q=[z/f*o,z/d*o];return q[2]=Math.sqrt(g(q[0],2)-g(z,2)),q[3]=Math.sqrt(g(q[1],2)-g(z,2)),l=o+q[2]+q[3]+(e?0:q[0]),m=l/o,n=[h(m*d),h(m*c)],{height:n[b?0:1],width:n[b?1:0]}}function N(a,b,c){return"<qvml:"+a+' xmlns="urn:schemas-microsoft.com:vml" class="qtip-vml" '+(b||"")+' style="behavior: url(#default#VML); '+(c||"")+'" />'}var q=this,r=a.options.style.tip,t=a.elements,v=t.tooltip,w={top:0,left:0},x={width:r.width,height:r.height},y={},z=r.border||0,A=".qtip-tip",B=!!(d("<canvas />")[0]||{}).getContext,C;q.corner=g,q.mimic=g,q.border=z,q.offset=r.offset,q.size=x,a.checks.tip={"^position.my|style.tip.(corner|mimic|border)$":function(){q.init()||q.destroy(),a.reposition()},"^style.tip.(height|width)$":function(){x={width:r.width,height:r.height},q.create(),q.update(),a.reposition()},"^content.title.text|style.(classes|widget)$":function(){t.tip&&t.tip.length&&q.update()}},d.extend(q,{init:function(){var a=H()&&(B||d.browser.msie);return a&&(q.create(),q.update(),v.unbind(A).bind("tooltipmove"+A,G),B||v.bind("tooltipredraw tooltipredrawn",function(a){a.type==="tooltipredraw"?(C=t.tip.html(),t.tip.html("")):t.tip.html(C)})),a},create:function(){var a=x.width,b=x.height,c;t.tip&&t.tip.remove(),t.tip=d("<div />",{"class":"ui-tooltip-tip"}).css({width:a,height:b}).prependTo(v),B?d("<canvas />").appendTo(t.tip)[0].getContext("2d").save():(c=N("shape",'coordorigin="0,0"',"position:absolute;"),t.tip.html(c+c),d("*",t.tip).bind("click mousedown",function(a){a.stopPropagation()}))},update:function(a,b){var c=t.tip,j=c.children(),k=x.width,s=x.height,A=r.mimic,C=Math.round,D,G,H,J,O;a||(a=w.corner||q.corner),A===f?A=a:(A=new u.Corner(A),A.precedance=a.precedance,A.x==="inherit"?A.x=a.x:A.y==="inherit"?A.y=a.y:A.x===A.y&&(A[a.precedance]=a[a.precedance])),D=A.precedance,a.precedance===h?E():F(),t.tip.css({width:k=x.width,height:s=x.height}),K(a),y.border!=="transparent"?(z=I(a,g),r.border===0&&z>0&&(y.fill=y.border),q.border=z=r.border!==e?r.border:z):q.border=z=0,H=M(A,k,s),q.size=O=L(a),c.css(O),a.precedance===i?J=[C(A.x===m?z:A.x===o?O.width-k-z:(O.width-k)/2),C(A.y===l?O.height-s:0)]:J=[C(A.x===m?O.width-k:0),C(A.y===l?z:A.y===n?O.height-s-z:(O.height-s)/2)],B?(j.attr(O),G=j[0].getContext("2d"),G.restore(),G.save(),G.clearRect(0,0,3e3,3e3),G.fillStyle=y.fill,G.strokeStyle=y.border,G.lineWidth=z*2,G.lineJoin="miter",G.miterLimit=100,G.translate(J[0],J[1]),G.beginPath(),G.moveTo(H[0][0],H[0][1]),G.lineTo(H[1][0],H[1][1]),G.lineTo(H[2][0],H[2][1]),G.closePath(),z&&(v.css("background-clip")==="border-box"&&(G.strokeStyle=y.fill,G.stroke()),G.strokeStyle=y.border,G.stroke()),G.fill()):(H="m"+H[0][0]+","+H[0][1]+" l"+H[1][0]+","+H[1][1]+" "+H[2][0]+","+H[2][1]+" xe",J[2]=z&&/^(r|b)/i.test(a.string())?parseFloat(d.browser.version,10)===8?2:1:0,j.css({coordsize:k+z+" "+(s+z),antialias:""+(A.string().indexOf(p)>-1),left:J[0],top:J[1],width:k+z,height:s+z}).each(function(a){var b=d(this);b[b.prop?"prop":"attr"]({coordsize:k+z+" "+(s+z),path:H,fillcolor:y.fill,filled:!!a,stroked:!a}).toggle(!!z||!!a),!a&&b.html()===""&&b.html(N("stroke",'weight="'+z*2+'px" color="'+y.border+'" miterlimit="1000" joinstyle="miter"'))})),b!==f&&q.position(a)},position:function(a){var b=t.tip,c={},e=Math.max(0,r.offset),g,n,o;return r.corner===f||!b?f:(a=a||q.corner,g=a.precedance,n=L(a),o=[a.x,a.y],g===h&&o.reverse(),d.each(o,function(b,d){var f,h,o;d===p?(f=g===i?m:l,c[f]="50%",c["margin-"+f]=-Math.round(n[g===i?j:k]/2)+e):(f=I(a,d),h=I(a,d,t.content),o=J(a),c[d]=b?h:e+(o>f?o:-f))}),c[a[g]]-=n[g===h?j:k],b.css({top:"",bottom:"",left:"",right:"",margin:""}).css(c),c)},destroy:function(){t.tip&&t.tip.remove(),t.tip=!1,v.unbind(A)}}),q.init()}function O(c){function s(){q=d(p,j).not("[disabled]").map(function(){return typeof this.focus=="function"?this:null})}function t(a){q.length<1&&a.length?a.not("body").blur():q.first().focus()}function v(a){var b=d(a.target),c=b.closest(".qtip"),e;e=c.length<1?f:parseInt(c[0].style.zIndex,10)>parseInt(j[0].style.zIndex,10),!e&&d(a.target).closest(A)[0]!==j[0]&&t(b)}var g=this,h=c.options.show.modal,i=c.elements,j=i.tooltip,k="#qtip-overlay",l=".qtipmodal",m=l+c.id,n="is-modal-qtip",o=d(b.body),p=u.modal.focusable.join(","),q={},r;c.checks.modal={"^show.modal.(on|blur)$":function(){g.init(),i.overlay.toggle(j.is(":visible"))},"^content.text$":function(){s()}},d.extend(g,{init:function(){return h.on?(r=g.create(),j.attr(n,e).css("z-index",u.modal.zindex+d(A+"["+n+"]").length).unbind(l).unbind(m).bind("tooltipshow"+l+" tooltiphide"+l,function(a,b,c){var e=a.originalEvent;if(a.target===j[0])if(e&&a.type==="tooltiphide"&&/mouse(leave|enter)/.test(e.type)&&d(e.relatedTarget).closest(r[0]).length)try{a.preventDefault()}catch(f){}else(!e||e&&!e.solo)&&g[a.type.replace("tooltip","")](a,c)}).bind("tooltipfocus"+l,function(a){if(a.isDefaultPrevented()||a.target!==j[0])return;var b=d(A).filter("["+n+"]"),c=u.modal.zindex+b.length,e=parseInt(j[0].style.zIndex,10);r[0].style.zIndex=c-2,b.each(function(){this.style.zIndex>e&&(this.style.zIndex-=1)}),b.end().filter("."+C).qtip("blur",a.originalEvent),j.addClass(C)[0].style.zIndex=c;try{a.preventDefault()}catch(f){}}).bind("tooltiphide"+l,function(a){a.target===j[0]&&d("["+n+"]").filter(":visible").not(j).last().qtip("focus",a)}),h.escape&&d(b).unbind(m).bind("keydown"+m,function(a){a.keyCode===27&&j.hasClass(C)&&c.hide(a)}),h.blur&&i.overlay.unbind(m).bind("click"+m,function(a){j.hasClass(C)&&c.hide(a)}),s(),g):g},create:function(){function c(){r.css({height:d(a).height(),width:d(a).width()})}var b=d(k);return b.length?i.overlay=b.insertAfter(d(A).last()):(r=i.overlay=d("<div />",{id:k.substr(1),html:"<div></div>",mousedown:function(){return f}}).hide().insertAfter(d(A).last()),d(a).unbind(l).bind("resize"+l,c),c(),r)},toggle:function(a,b,c){if(a&&a.isDefaultPrevented())return g;var i=h.effect,k=b?"show":"hide",l=r.is(":visible"),p=d("["+n+"]").filter(":visible").not(j),q;return r||(r=g.create()),r.is(":animated")&&l===b||!b&&p.length?g:(b?(r.css({left:0,top:0}),r.toggleClass("blurs",h.blur),h.stealfocus!==f&&(o.bind("focusin"+m,v),t(d("body :focus")))):o.unbind("focusin"+m),r.stop(e,f),d.isFunction(i)?i.call(r,b):i===f?r[k]():r.fadeTo(parseInt(c,10)||90,b?1:0,function(){b||d(this).hide()}),b||r.queue(function(a){r.css({left:"",top:""}),a()}),g)},show:function(a,b){return g.toggle(a,e,b)},hide:function(a,b){return g.toggle(a,f,b)},destroy:function(){var a=r;return a&&(a=d("["+n+"]").not(j).length<1,a?(i.overlay.remove(),d(b).unbind(l)):i.overlay.unbind(l+c.id),o.undelegate("*","focusin"+m)),j.removeAttr(n).unbind(l)}}),g.init()}function P(a){var b=this,c=a.elements,e=c.tooltip,f=".bgiframe-"+a.id;d.extend(b,{init:function(){c.bgiframe=d('<iframe class="ui-tooltip-bgiframe" frameborder="0" tabindex="-1" src="javascript:\'\';" style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=0); -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";"></iframe>'),c.bgiframe.appendTo(e),e.bind("tooltipmove"+f,b.adjust)},adjust:function(){var b=a.get("dimensions"),d=a.plugins.tip,f=c.tip,g,h;h=parseInt(e.css("border-left-width"),10)||0,h={left:-h,top:-h},d&&f&&(g=d.corner.precedance==="x"?["width","left"]:["height","top"],h[g[1]]-=f[g[0]]()),c.bgiframe.css(h).css(b)},destroy:function(){c.bgiframe.remove(),e.unbind(f)}}),b.init()}var e=!0,f=!1,g=null,h="x",i="y",j="width",k="height",l="top",m="left",n="bottom",o="right",p="center",q="flip",r="flipinvert",s="shift",t,u,v,w={},x="ui-tooltip",y="ui-widget",z="ui-state-disabled",A="div.qtip."+x,B=x+"-default",C=x+"-focus",D=x+"-hover",E="_replacedByqTip",F="oldtitle",G,H;H=d("<div/>",{id:"qtip-rcontainer"}),d(function(){H.appendTo(b.body)}),t=d.fn.qtip=function(a,b,h){var i=(""+a).toLowerCase(),j=g,k=d.makeArray(arguments).slice(1),l=k[k.length-1],m=this[0]?d.data(this[0],"qtip"):g;if(!arguments.length&&m||i==="api")return m;if("string"==typeof a)return this.each(function(){var a=d.data(this,"qtip");if(!a)return e;l&&l.timeStamp&&(a.cache.event=l);if(i!=="option"&&i!=="options"||!b)a[i]&&a[i].apply(a[i],k);else if(d.isPlainObject(b)||h!==c)a.set(b,h);else return j=a.get(b),f}),j!==g?j:this;if("object"==typeof a||!arguments.length)return m=I(d.extend(e,{},a)),t.bind.call(this,m,l)},t.bind=function(a,b){return this.each(function(g){function n(a){function b(){l.render(typeof a=="object"||h.show.ready),i.show.add(i.hide).unbind(k)}if(l.cache.disabled)return f;l.cache.event=d.extend({},a),l.cache.target=a?d(a.target):[c],h.show.delay>0?(clearTimeout(l.timers.show),l.timers.show=setTimeout(b,h.show.delay),j.show!==j.hide&&i.hide.bind(j.hide,function(){clearTimeout(l.timers.show)})):b()}var h,i,j,k,l,m;m=d.isArray(a.id)?a.id[g]:a.id,m=!m||m===f||m.length<1||w[m]?t.nextid++:w[m]=m,k=".qtip-"+m+"-create",l=K.call(this,m,a);if(l===f)return e;h=l.options,d.each(u,function(){this.initialize==="initialize"&&this(l)}),i={show:h.show.target,hide:h.hide.target},j={show:d.trim(""+h.show.event).replace(/ /g,k+" ")+k,hide:d.trim(""+h.hide.event).replace(/ /g,k+" ")+k},/mouse(over|enter)/i.test(j.show)&&!/mouse(out|leave)/i.test(j.hide)&&(j.hide+=" mouseleave"+k),i.show.bind("mousemove"+k,function(a){v={pageX:a.pageX,pageY:a.pageY,type:"mousemove"},l.cache.onTarget=e}),i.show.bind(j.show,n),(h.show.ready||h.prerender)&&n(b)})},u=t.plugins={Corner:function(a){a=(""+a).replace(/([A-Z])/," $1").replace(/middle/gi,p).toLowerCase(),this.x=(a.match(/left|right/i)||a.match(/center/)||["inherit"])[0].toLowerCase(),this.y=(a.match(/top|bottom|center/i)||["inherit"])[0].toLowerCase();var b=a.charAt(0);this.precedance=b==="t"||b==="b"?i:h,this.string=function(){return this.precedance===i?this.y+this.x:this.x+this.y},this.abbrev=function(){var a=this.x.substr(0,1),b=this.y.substr(0,1);return a===b?a:this.precedance===i?b+a:a+b},this.invertx=function(a){this.x=this.x===m?o:this.x===o?m:a||this.x},this.inverty=function(a){this.y=this.y===l?n:this.y===n?l:a||this.y},this.clone=function(){return{x:this.x,y:this.y,precedance:this.precedance,string:this.string,abbrev:this.abbrev,clone:this.clone,invertx:this.invertx,inverty:this.inverty}}},offset:function(a,b){function j(a,b){c.left+=b*a.scrollLeft(),c.top+=b*a.scrollTop()}var c=a.offset(),e=a.closest("body")[0],f=b,g,h,i;if(f){do f.css("position")!=="static"&&(h=f.position(),c.left-=h.left+(parseInt(f.css("borderLeftWidth"),10)||0)+(parseInt(f.css("marginLeft"),10)||0),c.top-=h.top+(parseInt(f.css("borderTopWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0),!g&&(i=f.css("overflow"))!=="hidden"&&i!=="visible"&&(g=f));while((f=d(f[0].offsetParent)).length);g&&g[0]!==e&&j(g,1)}return c},iOS:parseFloat((""+(/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))||f,fn:{attr:function(a,b){if(this.length){var c=this[0],e="title",f=d.data(c,"qtip");if(a===e&&f&&"object"==typeof f&&f.options.suppress)return arguments.length<2?d.attr(c,F):(f&&f.options.content.attr===e&&f.cache.attr&&f.set("content.text",b),this.attr(F,b))}return d.fn["attr"+E].apply(this,arguments)},clone:function(a){var b=d([]),c="title",e=d.fn["clone"+E].apply(this,arguments);return a||e.filter("["+F+"]").attr("title",function(){return d.attr(this,F)}).removeAttr(F),e}}},d.each(u.fn,function(a,b){if(!b||d.fn[a+E])return e;var c=d.fn[a+E]=d.fn[a];d.fn[a]=function(){return b.apply(this,arguments)||c.apply(this,arguments)}}),d.ui||(d["cleanData"+E]=d.cleanData,d.cleanData=function(a){for(var b=0,e;(e=a[b])!==c;b++)try{d(e).triggerHandler("removeqtip")}catch(f){}d["cleanData"+E](a)}),t.version="@VERSION",t.nextid=0,t.inactiveEvents="click dblclick mousedown mouseup mousemove mouseleave mouseenter".split(" "),t.zindex=15e3,t.defaults={prerender:f,id:f,overwrite:e,suppress:e,content:{text:e,attr:"title",title:{text:f,button:f}},position:{my:"top left",at:"bottom right",target:f,container:f,viewport:f,adjust:{x:0,y:0,mouse:e,resize:e,method:"flip flip"},effect:function(a,b,c){d(this).animate(b,{duration:200,queue:f})}},show:{target:f,event:"mouseenter",effect:e,delay:90,solo:f,ready:f,autofocus:f},hide:{target:f,event:"mouseleave",effect:e,delay:0,fixed:f,inactive:f,leave:"window",distance:f},style:{classes:"",widget:f,width:f,height:f,def:e},events:{render:g,move:g,show:g,hide:g,toggle:g,visible:g,hidden:g,focus:g,blur:g}},u.svg=function(a,c,e,f){var g=d(b),h=c[0],i={width:0,height:0,position:{top:1e10,left:1e10}},j,k,l,m,n;while(!h.getBBox)h=h.parentNode;if(h.getBBox&&h.parentNode){j=h.getBBox(),k=h.getScreenCTM(),l=h.farthestViewportElement||h;if(!l.createSVGPoint)return i;m=l.createSVGPoint(),m.x=j.x,m.y=j.y,n=m.matrixTransform(k),i.position.left=n.x,i.position.top=n.y,m.x+=j.width,m.y+=j.height,n=m.matrixTransform(k),i.width=n.x-i.position.left,i.height=n.y-i.position.top,i.position.left+=g.scrollLeft(),i.position.top+=g.scrollTop()}return i},u.ajax=function(a){var b=a.plugins.ajax;return"object"==typeof b?b:a.plugins.ajax=new L(a)},u.ajax.initialize="render",u.ajax.sanitize=function(a){var b=a.content,c;b&&"ajax"in b&&(c=b.ajax,typeof c!="object"&&(c=a.content.ajax={url:c}),"boolean"!=typeof c.once&&c.once&&(c.once=!!c.once))},d.extend(e,t.defaults,{content:{ajax:{loading:e,once:e}}}),u.tip=function(a){var b=a.plugins.tip;return"object"==typeof b?b:a.plugins.tip=new N(a)},u.tip.initialize="render",u.tip.sanitize=function(a){var b=a.style,c;b&&"tip"in b&&(c=a.style.tip,typeof c!="object"&&(a.style.tip={corner:c}),/string|boolean/i.test(typeof c.corner)||(c.corner=e),typeof c.width!="number"&&delete c.width,typeof c.height!="number"&&delete c.height,typeof c.border!="number"&&c.border!==e&&delete c.border,typeof c.offset!="number"&&delete c.offset)},d.extend(e,t.defaults,{style:{tip:{corner:e,mimic:f,width:6,height:6,border:e,offset:0}}}),u.modal=function(a){var b=a.plugins.modal;return"object"==typeof b?b:a.plugins.modal=new O(a)},u.modal.initialize="render",u.modal.sanitize=function(a){a.show&&(typeof a.show.modal!="object"?a.show.modal={on:!!a.show.modal}:typeof a.show.modal.on=="undefined"&&(a.show.modal.on=e))},u.modal.zindex=t.zindex-200,u.modal.focusable=["a[href]","area[href]","input","select","textarea","button","iframe","object","embed","[tabindex]","[contenteditable]"],d.extend(e,t.defaults,{show:{modal:{on:f,effect:e,blur:e,stealfocus:e,escape:e}}}),u.viewport=function(c,d,e,f,g,q,t){function L(a,b,c,e,f,g,h,i,j){var k=d[f],l=w[a],m=y[a],n=c===s,o=-E.offset[f]+D.offset[f]+D["scroll"+f],q=l===f?j:l===g?-j:-j/2,t=m===f?i:m===g?-i:-i/2,u=G&&G.size?G.size[h]||0:0,v=G&&G.corner&&G.corner.precedance===a&&!n?u:0,x=o-k+v,z=k+j-D[h]-o+v,A=q-(w.precedance===a||l===w[b]?t:0)-(m===p?i/2:0);return n?(v=G&&G.corner&&G.corner.precedance===b?u:0,A=(l===f?1:-1)*q-v,d[f]+=x>0?x:z>0?-z:0,d[f]=Math.max(-E.offset[f]+D.offset[f]+(v&&G.corner[a]===p?G.offset:0),k-A,Math.min(Math.max(-E.offset[f]+D.offset[f]+D[h],k+A),d[f]))):(e*=c===r?2:0,x>0&&(l!==f||z>0)?(d[f]-=A+e,J["invert"+a](f)):z>0&&(l!==g||x>0)&&(d[f]-=(l===p?-A:A)+e,J["invert"+a](g)),d[f]<o&&-d[f]>z&&(d[f]=k,J=w.clone())),d[f]-k}var u=e.target,v=c.elements.tooltip,w=e.my,y=e.at,z=e.adjust,A=z.method.split(" "),B=A[0],C=A[1]||A[0],D=e.viewport,E=e.container,F=c.cache,G=c.plugins.tip,H={left:0,top:0},I,J,K;if(!D.jquery||u[0]===a||u[0]===b.body||z.method==="none")return H;I=v.css("position")==="fixed",D={elem:D,height:D[(D[0]===a?"h":"outerH")+"eight"](),width:D[(D[0]===a?"w":"outerW")+"idth"](),scrollleft:I?0:D.scrollLeft(),scrolltop:I?0:D.scrollTop(),offset:D.offset()||{left:0,top:0}},E={elem:E,scrollLeft:E.scrollLeft(),scrollTop:E.scrollTop(),offset:E.offset()||{left:0,top:0}};if(B!=="shift"||C!=="shift")J=w.clone();return H={left:B!=="none"?L(h,i,B,z.x,m,o,j,f,q):0,top:C!=="none"?L(i,h,C,z.y,l,n,k,g,t):0},J&&F.lastClass!==(K=x+"-pos-"+J.abbrev())&&v.removeClass(c.cache.lastClass).addClass(c.cache.lastClass=K),H},u.imagemap=function(a,b,c,e){function v(a,b,c){var d=0,e=1,f=1,g=0,h=0,i=a.width,j=a.height;while(i>0&&j>0&&e>0&&f>0){i=Math.floor(i/2),j=Math.floor(j/2),c.x===m?e=i:c.x===o?e=a.width-i:e+=Math.floor(i/2),c.y===l?f=j:c.y===n?f=a.height-j:f+=Math.floor(j/2),d=b.length;while(d--){if(b.length<2)break;g=b[d][0]-a.position.left,h=b[d][1]-a.position.top,(c.x===m&&g>=e||c.x===o&&g<=e||c.x===p&&(g<e||g>a.width-e)||c.y===l&&h>=f||c.y===n&&h<=f||c.y===p&&(h<f||h>a.height-f))&&b.splice(d,1)}}return{left:b[0][0],top:b[0][1]}}b.jquery||(b=d(b));var f=a.cache.areas={},g=(b[0].shape||b.attr("shape")).toLowerCase(),h=b[0].coords||b.attr("coords"),i=h.split(","),j=[],k=d('img[usemap="#'+b.parent("map").attr("name")+'"]'),q=k.offset(),r={width:0,height:0,position:{top:1e10,right:0,bottom:0,left:1e10}},s=0,t=0,u;q.left+=Math.ceil((k.outerWidth()-k.width())/2),q.top+=Math.ceil((k.outerHeight()-k.height())/2);if(g==="poly"){s=i.length;while(s--)t=[parseInt(i[--s],10),parseInt(i[s+1],10)],t[0]>r.position.right&&(r.position.right=t[0]),t[0]<r.position.left&&(r.position.left=t[0]),t[1]>r.position.bottom&&(r.position.bottom=t[1]),t[1]<r.position.top&&(r.position.top=t[1]),j.push(t)}else{s=-1;while(s++<i.length)j.push(parseInt(i[s],10))}switch(g){case"rect":r={width:Math.abs(j[2]-j[0]),height:Math.abs(j[3]-j[1]),position:{left:Math.min(j[0],j[2]),top:Math.min(j[1],j[3])}};break;case"circle":r={width:j[2]+2,height:j[2]+2,position:{left:j[0],top:j[1]}};break;case"poly":r.width=Math.abs(r.position.right-r.position.left),r.height=Math.abs(r.position.bottom-r.position.top),c.abbrev()==="c"?r.position={left:r.position.left+r.width/2,top:r.position.top+r.height/2}:(f[c+h]||(r.position=v(r,j.slice(),c),e&&(e[0]==="flip"||e[1]==="flip")&&(r.offset=v(r,j.slice(),{x:c.x===m?o:c.x===o?m:p,y:c.y===l?n:c.y===n?l:p}),r.offset.left-=r.position.left,r.offset.top-=r.position.top),f[c+h]=r),r=f[c+h]),r.width=r.height=0}return r.position.left+=q.left,r.position.top+=q.top,r},u.bgiframe=function(a){var b=d.browser,c=a.plugins.bgiframe;return d("select, object").length<1||!b.msie||(""+b.version).charAt(0)!=="6"?f:"object"==typeof c?c:a.plugins.bgiframe=new P(a)},u.bgiframe.initialize="render"})})(window,document);
 
 
 
1
+ /* qtip2 v3.0.3 | Plugins: tips modal viewport svg imagemap ie6 | Styles: core basic css3 | qtip2.com | Licensed MIT | Wed May 11 2016 22:31:31 */
2
+
3
+ !function(a,b,c){!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):jQuery&&!jQuery.fn.qtip&&a(jQuery)}(function(d){"use strict";function e(a,b,c,e){this.id=c,this.target=a,this.tooltip=F,this.elements={target:a},this._id=S+"-"+c,this.timers={img:{}},this.options=b,this.plugins={},this.cache={event:{},target:d(),disabled:E,attr:e,onTooltip:E,lastClass:""},this.rendered=this.destroyed=this.disabled=this.waiting=this.hiddenDuringWait=this.positioning=this.triggering=E}function f(a){return a===F||"object"!==d.type(a)}function g(a){return!(d.isFunction(a)||a&&a.attr||a.length||"object"===d.type(a)&&(a.jquery||a.then))}function h(a){var b,c,e,h;return f(a)?E:(f(a.metadata)&&(a.metadata={type:a.metadata}),"content"in a&&(b=a.content,f(b)||b.jquery||b.done?(c=g(b)?E:b,b=a.content={text:c}):c=b.text,"ajax"in b&&(e=b.ajax,h=e&&e.once!==E,delete b.ajax,b.text=function(a,b){var f=c||d(this).attr(b.options.content.attr)||"Loading...",g=d.ajax(d.extend({},e,{context:b})).then(e.success,F,e.error).then(function(a){return a&&h&&b.set("content.text",a),a},function(a,c,d){b.destroyed||0===a.status||b.set("content.text",c+": "+d)});return h?f:(b.set("content.text",f),g)}),"title"in b&&(d.isPlainObject(b.title)&&(b.button=b.title.button,b.title=b.title.text),g(b.title||E)&&(b.title=E))),"position"in a&&f(a.position)&&(a.position={my:a.position,at:a.position}),"show"in a&&f(a.show)&&(a.show=a.show.jquery?{target:a.show}:a.show===D?{ready:D}:{event:a.show}),"hide"in a&&f(a.hide)&&(a.hide=a.hide.jquery?{target:a.hide}:{event:a.hide}),"style"in a&&f(a.style)&&(a.style={classes:a.style}),d.each(R,function(){this.sanitize&&this.sanitize(a)}),a)}function i(a,b){for(var c,d=0,e=a,f=b.split(".");e=e[f[d++]];)d<f.length&&(c=e);return[c||a,f.pop()]}function j(a,b){var c,d,e;for(c in this.checks)if(this.checks.hasOwnProperty(c))for(d in this.checks[c])this.checks[c].hasOwnProperty(d)&&(e=new RegExp(d,"i").exec(a))&&(b.push(e),("builtin"===c||this.plugins[c])&&this.checks[c][d].apply(this.plugins[c]||this,b))}function k(a){return V.concat("").join(a?"-"+a+" ":" ")}function l(a,b){return b>0?setTimeout(d.proxy(a,this),b):void a.call(this)}function m(a){this.tooltip.hasClass(aa)||(clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this.timers.show=l.call(this,function(){this.toggle(D,a)},this.options.show.delay))}function n(a){if(!this.tooltip.hasClass(aa)&&!this.destroyed){var b=d(a.relatedTarget),c=b.closest(W)[0]===this.tooltip[0],e=b[0]===this.options.show.target[0];if(clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this!==b[0]&&"mouse"===this.options.position.target&&c||this.options.hide.fixed&&/mouse(out|leave|move)/.test(a.type)&&(c||e))try{a.preventDefault(),a.stopImmediatePropagation()}catch(f){}else this.timers.hide=l.call(this,function(){this.toggle(E,a)},this.options.hide.delay,this)}}function o(a){!this.tooltip.hasClass(aa)&&this.options.hide.inactive&&(clearTimeout(this.timers.inactive),this.timers.inactive=l.call(this,function(){this.hide(a)},this.options.hide.inactive))}function p(a){this.rendered&&this.tooltip[0].offsetWidth>0&&this.reposition(a)}function q(a,c,e){d(b.body).delegate(a,(c.split?c:c.join("."+S+" "))+"."+S,function(){var a=y.api[d.attr(this,U)];a&&!a.disabled&&e.apply(a,arguments)})}function r(a,c,f){var g,i,j,k,l,m=d(b.body),n=a[0]===b?m:a,o=a.metadata?a.metadata(f.metadata):F,p="html5"===f.metadata.type&&o?o[f.metadata.name]:F,q=a.data(f.metadata.name||"qtipopts");try{q="string"==typeof q?d.parseJSON(q):q}catch(r){}if(k=d.extend(D,{},y.defaults,f,"object"==typeof q?h(q):F,h(p||o)),i=k.position,k.id=c,"boolean"==typeof k.content.text){if(j=a.attr(k.content.attr),k.content.attr===E||!j)return E;k.content.text=j}if(i.container.length||(i.container=m),i.target===E&&(i.target=n),k.show.target===E&&(k.show.target=n),k.show.solo===D&&(k.show.solo=i.container.closest("body")),k.hide.target===E&&(k.hide.target=n),k.position.viewport===D&&(k.position.viewport=i.container),i.container=i.container.eq(0),i.at=new A(i.at,D),i.my=new A(i.my),a.data(S))if(k.overwrite)a.qtip("destroy",!0);else if(k.overwrite===E)return E;return a.attr(T,c),k.suppress&&(l=a.attr("title"))&&a.removeAttr("title").attr(ca,l).attr("title",""),g=new e(a,k,c,!!j),a.data(S,g),g}function s(a){return a.charAt(0).toUpperCase()+a.slice(1)}function t(a,b){var d,e,f=b.charAt(0).toUpperCase()+b.slice(1),g=(b+" "+va.join(f+" ")+f).split(" "),h=0;if(ua[b])return a.css(ua[b]);for(;d=g[h++];)if((e=a.css(d))!==c)return ua[b]=d,e}function u(a,b){return Math.ceil(parseFloat(t(a,b)))}function v(a,b){this._ns="tip",this.options=b,this.offset=b.offset,this.size=[b.width,b.height],this.qtip=a,this.init(a)}function w(a,b){this.options=b,this._ns="-modal",this.qtip=a,this.init(a)}function x(a){this._ns="ie6",this.qtip=a,this.init(a)}var y,z,A,B,C,D=!0,E=!1,F=null,G="x",H="y",I="width",J="height",K="top",L="left",M="bottom",N="right",O="center",P="flipinvert",Q="shift",R={},S="qtip",T="data-hasqtip",U="data-qtip-id",V=["ui-widget","ui-tooltip"],W="."+S,X="click dblclick mousedown mouseup mousemove mouseleave mouseenter".split(" "),Y=S+"-fixed",Z=S+"-default",$=S+"-focus",_=S+"-hover",aa=S+"-disabled",ba="_replacedByqTip",ca="oldtitle",da={ie:function(){var a,c;for(a=4,c=b.createElement("div");(c.innerHTML="<!--[if gt IE "+a+"]><i></i><![endif]-->")&&c.getElementsByTagName("i")[0];a+=1);return a>4?a:NaN}(),iOS:parseFloat((""+(/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))||E};z=e.prototype,z._when=function(a){return d.when.apply(d,a)},z.render=function(a){if(this.rendered||this.destroyed)return this;var b=this,c=this.options,e=this.cache,f=this.elements,g=c.content.text,h=c.content.title,i=c.content.button,j=c.position,k=[];return d.attr(this.target[0],"aria-describedby",this._id),e.posClass=this._createPosClass((this.position={my:j.my,at:j.at}).my),this.tooltip=f.tooltip=d("<div/>",{id:this._id,"class":[S,Z,c.style.classes,e.posClass].join(" "),width:c.style.width||"",height:c.style.height||"",tracking:"mouse"===j.target&&j.adjust.mouse,role:"alert","aria-live":"polite","aria-atomic":E,"aria-describedby":this._id+"-content","aria-hidden":D}).toggleClass(aa,this.disabled).attr(U,this.id).data(S,this).appendTo(j.container).append(f.content=d("<div />",{"class":S+"-content",id:this._id+"-content","aria-atomic":D})),this.rendered=-1,this.positioning=D,h&&(this._createTitle(),d.isFunction(h)||k.push(this._updateTitle(h,E))),i&&this._createButton(),d.isFunction(g)||k.push(this._updateContent(g,E)),this.rendered=D,this._setWidget(),d.each(R,function(a){var c;"render"===this.initialize&&(c=this(b))&&(b.plugins[a]=c)}),this._unassignEvents(),this._assignEvents(),this._when(k).then(function(){b._trigger("render"),b.positioning=E,b.hiddenDuringWait||!c.show.ready&&!a||b.toggle(D,e.event,E),b.hiddenDuringWait=E}),y.api[this.id]=this,this},z.destroy=function(a){function b(){if(!this.destroyed){this.destroyed=D;var a,b=this.target,c=b.attr(ca);this.rendered&&this.tooltip.stop(1,0).find("*").remove().end().remove(),d.each(this.plugins,function(){this.destroy&&this.destroy()});for(a in this.timers)this.timers.hasOwnProperty(a)&&clearTimeout(this.timers[a]);b.removeData(S).removeAttr(U).removeAttr(T).removeAttr("aria-describedby"),this.options.suppress&&c&&b.attr("title",c).removeAttr(ca),this._unassignEvents(),this.options=this.elements=this.cache=this.timers=this.plugins=this.mouse=F,delete y.api[this.id]}}return this.destroyed?this.target:(a===D&&"hide"!==this.triggering||!this.rendered?b.call(this):(this.tooltip.one("tooltiphidden",d.proxy(b,this)),!this.triggering&&this.hide()),this.target)},B=z.checks={builtin:{"^id$":function(a,b,c,e){var f=c===D?y.nextid:c,g=S+"-"+f;f!==E&&f.length>0&&!d("#"+g).length?(this._id=g,this.rendered&&(this.tooltip[0].id=this._id,this.elements.content[0].id=this._id+"-content",this.elements.title[0].id=this._id+"-title")):a[b]=e},"^prerender":function(a,b,c){c&&!this.rendered&&this.render(this.options.show.ready)},"^content.text$":function(a,b,c){this._updateContent(c)},"^content.attr$":function(a,b,c,d){this.options.content.text===this.target.attr(d)&&this._updateContent(this.target.attr(c))},"^content.title$":function(a,b,c){return c?(c&&!this.elements.title&&this._createTitle(),void this._updateTitle(c)):this._removeTitle()},"^content.button$":function(a,b,c){this._updateButton(c)},"^content.title.(text|button)$":function(a,b,c){this.set("content."+b,c)},"^position.(my|at)$":function(a,b,c){"string"==typeof c&&(this.position[b]=a[b]=new A(c,"at"===b))},"^position.container$":function(a,b,c){this.rendered&&this.tooltip.appendTo(c)},"^show.ready$":function(a,b,c){c&&(!this.rendered&&this.render(D)||this.toggle(D))},"^style.classes$":function(a,b,c,d){this.rendered&&this.tooltip.removeClass(d).addClass(c)},"^style.(width|height)":function(a,b,c){this.rendered&&this.tooltip.css(b,c)},"^style.widget|content.title":function(){this.rendered&&this._setWidget()},"^style.def":function(a,b,c){this.rendered&&this.tooltip.toggleClass(Z,!!c)},"^events.(render|show|move|hide|focus|blur)$":function(a,b,c){this.rendered&&this.tooltip[(d.isFunction(c)?"":"un")+"bind"]("tooltip"+b,c)},"^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)":function(){if(this.rendered){var a=this.options.position;this.tooltip.attr("tracking","mouse"===a.target&&a.adjust.mouse),this._unassignEvents(),this._assignEvents()}}}},z.get=function(a){if(this.destroyed)return this;var b=i(this.options,a.toLowerCase()),c=b[0][b[1]];return c.precedance?c.string():c};var ea=/^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i,fa=/^prerender|show\.ready/i;z.set=function(a,b){if(this.destroyed)return this;var c,e=this.rendered,f=E,g=this.options;return"string"==typeof a?(c=a,a={},a[c]=b):a=d.extend({},a),d.each(a,function(b,c){if(e&&fa.test(b))return void delete a[b];var h,j=i(g,b.toLowerCase());h=j[0][j[1]],j[0][j[1]]=c&&c.nodeType?d(c):c,f=ea.test(b)||f,a[b]=[j[0],j[1],c,h]}),h(g),this.positioning=D,d.each(a,d.proxy(j,this)),this.positioning=E,this.rendered&&this.tooltip[0].offsetWidth>0&&f&&this.reposition("mouse"===g.position.target?F:this.cache.event),this},z._update=function(a,b){var c=this,e=this.cache;return this.rendered&&a?(d.isFunction(a)&&(a=a.call(this.elements.target,e.event,this)||""),d.isFunction(a.then)?(e.waiting=D,a.then(function(a){return e.waiting=E,c._update(a,b)},F,function(a){return c._update(a,b)})):a===E||!a&&""!==a?E:(a.jquery&&a.length>0?b.empty().append(a.css({display:"block",visibility:"visible"})):b.html(a),this._waitForContent(b).then(function(a){c.rendered&&c.tooltip[0].offsetWidth>0&&c.reposition(e.event,!a.length)}))):E},z._waitForContent=function(a){var b=this.cache;return b.waiting=D,(d.fn.imagesLoaded?a.imagesLoaded():(new d.Deferred).resolve([])).done(function(){b.waiting=E}).promise()},z._updateContent=function(a,b){this._update(a,this.elements.content,b)},z._updateTitle=function(a,b){this._update(a,this.elements.title,b)===E&&this._removeTitle(E)},z._createTitle=function(){var a=this.elements,b=this._id+"-title";a.titlebar&&this._removeTitle(),a.titlebar=d("<div />",{"class":S+"-titlebar "+(this.options.style.widget?k("header"):"")}).append(a.title=d("<div />",{id:b,"class":S+"-title","aria-atomic":D})).insertBefore(a.content).delegate(".qtip-close","mousedown keydown mouseup keyup mouseout",function(a){d(this).toggleClass("ui-state-active ui-state-focus","down"===a.type.substr(-4))}).delegate(".qtip-close","mouseover mouseout",function(a){d(this).toggleClass("ui-state-hover","mouseover"===a.type)}),this.options.content.button&&this._createButton()},z._removeTitle=function(a){var b=this.elements;b.title&&(b.titlebar.remove(),b.titlebar=b.title=b.button=F,a!==E&&this.reposition())},z._createPosClass=function(a){return S+"-pos-"+(a||this.options.position.my).abbrev()},z.reposition=function(c,e){if(!this.rendered||this.positioning||this.destroyed)return this;this.positioning=D;var f,g,h,i,j=this.cache,k=this.tooltip,l=this.options.position,m=l.target,n=l.my,o=l.at,p=l.viewport,q=l.container,r=l.adjust,s=r.method.split(" "),t=k.outerWidth(E),u=k.outerHeight(E),v=0,w=0,x=k.css("position"),y={left:0,top:0},z=k[0].offsetWidth>0,A=c&&"scroll"===c.type,B=d(a),C=q[0].ownerDocument,F=this.mouse;if(d.isArray(m)&&2===m.length)o={x:L,y:K},y={left:m[0],top:m[1]};else if("mouse"===m)o={x:L,y:K},(!r.mouse||this.options.hide.distance)&&j.origin&&j.origin.pageX?c=j.origin:!c||c&&("resize"===c.type||"scroll"===c.type)?c=j.event:F&&F.pageX&&(c=F),"static"!==x&&(y=q.offset()),C.body.offsetWidth!==(a.innerWidth||C.documentElement.clientWidth)&&(g=d(b.body).offset()),y={left:c.pageX-y.left+(g&&g.left||0),top:c.pageY-y.top+(g&&g.top||0)},r.mouse&&A&&F&&(y.left-=(F.scrollX||0)-B.scrollLeft(),y.top-=(F.scrollY||0)-B.scrollTop());else{if("event"===m?c&&c.target&&"scroll"!==c.type&&"resize"!==c.type?j.target=d(c.target):c.target||(j.target=this.elements.target):"event"!==m&&(j.target=d(m.jquery?m:this.elements.target)),m=j.target,m=d(m).eq(0),0===m.length)return this;m[0]===b||m[0]===a?(v=da.iOS?a.innerWidth:m.width(),w=da.iOS?a.innerHeight:m.height(),m[0]===a&&(y={top:(p||m).scrollTop(),left:(p||m).scrollLeft()})):R.imagemap&&m.is("area")?f=R.imagemap(this,m,o,R.viewport?s:E):R.svg&&m&&m[0].ownerSVGElement?f=R.svg(this,m,o,R.viewport?s:E):(v=m.outerWidth(E),w=m.outerHeight(E),y=m.offset()),f&&(v=f.width,w=f.height,g=f.offset,y=f.position),y=this.reposition.offset(m,y,q),(da.iOS>3.1&&da.iOS<4.1||da.iOS>=4.3&&da.iOS<4.33||!da.iOS&&"fixed"===x)&&(y.left-=B.scrollLeft(),y.top-=B.scrollTop()),(!f||f&&f.adjustable!==E)&&(y.left+=o.x===N?v:o.x===O?v/2:0,y.top+=o.y===M?w:o.y===O?w/2:0)}return y.left+=r.x+(n.x===N?-t:n.x===O?-t/2:0),y.top+=r.y+(n.y===M?-u:n.y===O?-u/2:0),R.viewport?(h=y.adjusted=R.viewport(this,y,l,v,w,t,u),g&&h.left&&(y.left+=g.left),g&&h.top&&(y.top+=g.top),h.my&&(this.position.my=h.my)):y.adjusted={left:0,top:0},j.posClass!==(i=this._createPosClass(this.position.my))&&(j.posClass=i,k.removeClass(j.posClass).addClass(i)),this._trigger("move",[y,p.elem||p],c)?(delete y.adjusted,e===E||!z||isNaN(y.left)||isNaN(y.top)||"mouse"===m||!d.isFunction(l.effect)?k.css(y):d.isFunction(l.effect)&&(l.effect.call(k,this,d.extend({},y)),k.queue(function(a){d(this).css({opacity:"",height:""}),da.ie&&this.style.removeAttribute("filter"),a()})),this.positioning=E,this):this},z.reposition.offset=function(a,c,e){function f(a,b){c.left+=b*a.scrollLeft(),c.top+=b*a.scrollTop()}if(!e[0])return c;var g,h,i,j,k=d(a[0].ownerDocument),l=!!da.ie&&"CSS1Compat"!==b.compatMode,m=e[0];do"static"!==(h=d.css(m,"position"))&&("fixed"===h?(i=m.getBoundingClientRect(),f(k,-1)):(i=d(m).position(),i.left+=parseFloat(d.css(m,"borderLeftWidth"))||0,i.top+=parseFloat(d.css(m,"borderTopWidth"))||0),c.left-=i.left+(parseFloat(d.css(m,"marginLeft"))||0),c.top-=i.top+(parseFloat(d.css(m,"marginTop"))||0),g||"hidden"===(j=d.css(m,"overflow"))||"visible"===j||(g=d(m)));while(m=m.offsetParent);return g&&(g[0]!==k[0]||l)&&f(g,1),c};var ga=(A=z.reposition.Corner=function(a,b){a=(""+a).replace(/([A-Z])/," $1").replace(/middle/gi,O).toLowerCase(),this.x=(a.match(/left|right/i)||a.match(/center/)||["inherit"])[0].toLowerCase(),this.y=(a.match(/top|bottom|center/i)||["inherit"])[0].toLowerCase(),this.forceY=!!b;var c=a.charAt(0);this.precedance="t"===c||"b"===c?H:G}).prototype;ga.invert=function(a,b){this[a]=this[a]===L?N:this[a]===N?L:b||this[a]},ga.string=function(a){var b=this.x,c=this.y,d=b!==c?"center"===b||"center"!==c&&(this.precedance===H||this.forceY)?[c,b]:[b,c]:[b];return a!==!1?d.join(" "):d},ga.abbrev=function(){var a=this.string(!1);return a[0].charAt(0)+(a[1]&&a[1].charAt(0)||"")},ga.clone=function(){return new A(this.string(),this.forceY)},z.toggle=function(a,c){var e=this.cache,f=this.options,g=this.tooltip;if(c){if(/over|enter/.test(c.type)&&e.event&&/out|leave/.test(e.event.type)&&f.show.target.add(c.target).length===f.show.target.length&&g.has(c.relatedTarget).length)return this;e.event=d.event.fix(c)}if(this.waiting&&!a&&(this.hiddenDuringWait=D),!this.rendered)return a?this.render(1):this;if(this.destroyed||this.disabled)return this;var h,i,j,k=a?"show":"hide",l=this.options[k],m=this.options.position,n=this.options.content,o=this.tooltip.css("width"),p=this.tooltip.is(":visible"),q=a||1===l.target.length,r=!c||l.target.length<2||e.target[0]===c.target;return(typeof a).search("boolean|number")&&(a=!p),h=!g.is(":animated")&&p===a&&r,i=h?F:!!this._trigger(k,[90]),this.destroyed?this:(i!==E&&a&&this.focus(c),!i||h?this:(d.attr(g[0],"aria-hidden",!a),a?(this.mouse&&(e.origin=d.event.fix(this.mouse)),d.isFunction(n.text)&&this._updateContent(n.text,E),d.isFunction(n.title)&&this._updateTitle(n.title,E),!C&&"mouse"===m.target&&m.adjust.mouse&&(d(b).bind("mousemove."+S,this._storeMouse),C=D),o||g.css("width",g.outerWidth(E)),this.reposition(c,arguments[2]),o||g.css("width",""),l.solo&&("string"==typeof l.solo?d(l.solo):d(W,l.solo)).not(g).not(l.target).qtip("hide",new d.Event("tooltipsolo"))):(clearTimeout(this.timers.show),delete e.origin,C&&!d(W+'[tracking="true"]:visible',l.solo).not(g).length&&(d(b).unbind("mousemove."+S),C=E),this.blur(c)),j=d.proxy(function(){a?(da.ie&&g[0].style.removeAttribute("filter"),g.css("overflow",""),"string"==typeof l.autofocus&&d(this.options.show.autofocus,g).focus(),this.options.show.target.trigger("qtip-"+this.id+"-inactive")):g.css({display:"",visibility:"",opacity:"",left:"",top:""}),this._trigger(a?"visible":"hidden")},this),l.effect===E||q===E?(g[k](),j()):d.isFunction(l.effect)?(g.stop(1,1),l.effect.call(g,this),g.queue("fx",function(a){j(),a()})):g.fadeTo(90,a?1:0,j),a&&l.target.trigger("qtip-"+this.id+"-inactive"),this))},z.show=function(a){return this.toggle(D,a)},z.hide=function(a){return this.toggle(E,a)},z.focus=function(a){if(!this.rendered||this.destroyed)return this;var b=d(W),c=this.tooltip,e=parseInt(c[0].style.zIndex,10),f=y.zindex+b.length;return c.hasClass($)||this._trigger("focus",[f],a)&&(e!==f&&(b.each(function(){this.style.zIndex>e&&(this.style.zIndex=this.style.zIndex-1)}),b.filter("."+$).qtip("blur",a)),c.addClass($)[0].style.zIndex=f),this},z.blur=function(a){return!this.rendered||this.destroyed?this:(this.tooltip.removeClass($),this._trigger("blur",[this.tooltip.css("zIndex")],a),this)},z.disable=function(a){return this.destroyed?this:("toggle"===a?a=!(this.rendered?this.tooltip.hasClass(aa):this.disabled):"boolean"!=typeof a&&(a=D),this.rendered&&this.tooltip.toggleClass(aa,a).attr("aria-disabled",a),this.disabled=!!a,this)},z.enable=function(){return this.disable(E)},z._createButton=function(){var a=this,b=this.elements,c=b.tooltip,e=this.options.content.button,f="string"==typeof e,g=f?e:"Close tooltip";b.button&&b.button.remove(),e.jquery?b.button=e:b.button=d("<a />",{"class":"qtip-close "+(this.options.style.widget?"":S+"-icon"),title:g,"aria-label":g}).prepend(d("<span />",{"class":"ui-icon ui-icon-close",html:"&times;"})),b.button.appendTo(b.titlebar||c).attr("role","button").click(function(b){return c.hasClass(aa)||a.hide(b),E})},z._updateButton=function(a){if(!this.rendered)return E;var b=this.elements.button;a?this._createButton():b.remove()},z._setWidget=function(){var a=this.options.style.widget,b=this.elements,c=b.tooltip,d=c.hasClass(aa);c.removeClass(aa),aa=a?"ui-state-disabled":"qtip-disabled",c.toggleClass(aa,d),c.toggleClass("ui-helper-reset "+k(),a).toggleClass(Z,this.options.style.def&&!a),b.content&&b.content.toggleClass(k("content"),a),b.titlebar&&b.titlebar.toggleClass(k("header"),a),b.button&&b.button.toggleClass(S+"-icon",!a)},z._storeMouse=function(a){return(this.mouse=d.event.fix(a)).type="mousemove",this},z._bind=function(a,b,c,e,f){if(a&&c&&b.length){var g="."+this._id+(e?"-"+e:"");return d(a).bind((b.split?b:b.join(g+" "))+g,d.proxy(c,f||this)),this}},z._unbind=function(a,b){return a&&d(a).unbind("."+this._id+(b?"-"+b:"")),this},z._trigger=function(a,b,c){var e=new d.Event("tooltip"+a);return e.originalEvent=c&&d.extend({},c)||this.cache.event||F,this.triggering=a,this.tooltip.trigger(e,[this].concat(b||[])),this.triggering=E,!e.isDefaultPrevented()},z._bindEvents=function(a,b,c,e,f,g){var h=c.filter(e).add(e.filter(c)),i=[];h.length&&(d.each(b,function(b,c){var e=d.inArray(c,a);e>-1&&i.push(a.splice(e,1)[0])}),i.length&&(this._bind(h,i,function(a){var b=this.rendered?this.tooltip[0].offsetWidth>0:!1;(b?g:f).call(this,a)}),c=c.not(h),e=e.not(h))),this._bind(c,a,f),this._bind(e,b,g)},z._assignInitialEvents=function(a){function b(a){return this.disabled||this.destroyed?E:(this.cache.event=a&&d.event.fix(a),this.cache.target=a&&d(a.target),clearTimeout(this.timers.show),void(this.timers.show=l.call(this,function(){this.render("object"==typeof a||c.show.ready)},c.prerender?0:c.show.delay)))}var c=this.options,e=c.show.target,f=c.hide.target,g=c.show.event?d.trim(""+c.show.event).split(" "):[],h=c.hide.event?d.trim(""+c.hide.event).split(" "):[];this._bind(this.elements.target,["remove","removeqtip"],function(){this.destroy(!0)},"destroy"),/mouse(over|enter)/i.test(c.show.event)&&!/mouse(out|leave)/i.test(c.hide.event)&&h.push("mouseleave"),this._bind(e,"mousemove",function(a){this._storeMouse(a),this.cache.onTarget=D}),this._bindEvents(g,h,e,f,b,function(){return this.timers?void clearTimeout(this.timers.show):E}),(c.show.ready||c.prerender)&&b.call(this,a)},z._assignEvents=function(){var c=this,e=this.options,f=e.position,g=this.tooltip,h=e.show.target,i=e.hide.target,j=f.container,k=f.viewport,l=d(b),q=d(a),r=e.show.event?d.trim(""+e.show.event).split(" "):[],s=e.hide.event?d.trim(""+e.hide.event).split(" "):[];d.each(e.events,function(a,b){c._bind(g,"toggle"===a?["tooltipshow","tooltiphide"]:["tooltip"+a],b,null,g)}),/mouse(out|leave)/i.test(e.hide.event)&&"window"===e.hide.leave&&this._bind(l,["mouseout","blur"],function(a){/select|option/.test(a.target.nodeName)||a.relatedTarget||this.hide(a)}),e.hide.fixed?i=i.add(g.addClass(Y)):/mouse(over|enter)/i.test(e.show.event)&&this._bind(i,"mouseleave",function(){clearTimeout(this.timers.show)}),(""+e.hide.event).indexOf("unfocus")>-1&&this._bind(j.closest("html"),["mousedown","touchstart"],function(a){var b=d(a.target),c=this.rendered&&!this.tooltip.hasClass(aa)&&this.tooltip[0].offsetWidth>0,e=b.parents(W).filter(this.tooltip[0]).length>0;b[0]===this.target[0]||b[0]===this.tooltip[0]||e||this.target.has(b[0]).length||!c||this.hide(a)}),"number"==typeof e.hide.inactive&&(this._bind(h,"qtip-"+this.id+"-inactive",o,"inactive"),this._bind(i.add(g),y.inactiveEvents,o)),this._bindEvents(r,s,h,i,m,n),this._bind(h.add(g),"mousemove",function(a){if("number"==typeof e.hide.distance){var b=this.cache.origin||{},c=this.options.hide.distance,d=Math.abs;(d(a.pageX-b.pageX)>=c||d(a.pageY-b.pageY)>=c)&&this.hide(a)}this._storeMouse(a)}),"mouse"===f.target&&f.adjust.mouse&&(e.hide.event&&this._bind(h,["mouseenter","mouseleave"],function(a){return this.cache?void(this.cache.onTarget="mouseenter"===a.type):E}),this._bind(l,"mousemove",function(a){this.rendered&&this.cache.onTarget&&!this.tooltip.hasClass(aa)&&this.tooltip[0].offsetWidth>0&&this.reposition(a)})),(f.adjust.resize||k.length)&&this._bind(d.event.special.resize?k:q,"resize",p),f.adjust.scroll&&this._bind(q.add(f.container),"scroll",p)},z._unassignEvents=function(){var c=this.options,e=c.show.target,f=c.hide.target,g=d.grep([this.elements.target[0],this.rendered&&this.tooltip[0],c.position.container[0],c.position.viewport[0],c.position.container.closest("html")[0],a,b],function(a){return"object"==typeof a});e&&e.toArray&&(g=g.concat(e.toArray())),f&&f.toArray&&(g=g.concat(f.toArray())),this._unbind(g)._unbind(g,"destroy")._unbind(g,"inactive")},d(function(){q(W,["mouseenter","mouseleave"],function(a){var b="mouseenter"===a.type,c=d(a.currentTarget),e=d(a.relatedTarget||a.target),f=this.options;b?(this.focus(a),c.hasClass(Y)&&!c.hasClass(aa)&&clearTimeout(this.timers.hide)):"mouse"===f.position.target&&f.position.adjust.mouse&&f.hide.event&&f.show.target&&!e.closest(f.show.target[0]).length&&this.hide(a),c.toggleClass(_,b)}),q("["+U+"]",X,o)}),y=d.fn.qtip=function(a,b,e){var f=(""+a).toLowerCase(),g=F,i=d.makeArray(arguments).slice(1),j=i[i.length-1],k=this[0]?d.data(this[0],S):F;return!arguments.length&&k||"api"===f?k:"string"==typeof a?(this.each(function(){var a=d.data(this,S);if(!a)return D;if(j&&j.timeStamp&&(a.cache.event=j),!b||"option"!==f&&"options"!==f)a[f]&&a[f].apply(a,i);else{if(e===c&&!d.isPlainObject(b))return g=a.get(b),E;a.set(b,e)}}),g!==F?g:this):"object"!=typeof a&&arguments.length?void 0:(k=h(d.extend(D,{},a)),this.each(function(a){var b,c;return c=d.isArray(k.id)?k.id[a]:k.id,c=!c||c===E||c.length<1||y.api[c]?y.nextid++:c,b=r(d(this),c,k),b===E?D:(y.api[c]=b,d.each(R,function(){"initialize"===this.initialize&&this(b)}),void b._assignInitialEvents(j))}))},d.qtip=e,y.api={},d.each({attr:function(a,b){if(this.length){var c=this[0],e="title",f=d.data(c,"qtip");if(a===e&&f&&f.options&&"object"==typeof f&&"object"==typeof f.options&&f.options.suppress)return arguments.length<2?d.attr(c,ca):(f&&f.options.content.attr===e&&f.cache.attr&&f.set("content.text",b),this.attr(ca,b))}return d.fn["attr"+ba].apply(this,arguments)},clone:function(a){var b=d.fn["clone"+ba].apply(this,arguments);return a||b.filter("["+ca+"]").attr("title",function(){return d.attr(this,ca)}).removeAttr(ca),b}},function(a,b){if(!b||d.fn[a+ba])return D;var c=d.fn[a+ba]=d.fn[a];d.fn[a]=function(){return b.apply(this,arguments)||c.apply(this,arguments)}}),d.ui||(d["cleanData"+ba]=d.cleanData,d.cleanData=function(a){for(var b,c=0;(b=d(a[c])).length;c++)if(b.attr(T))try{b.triggerHandler("removeqtip")}catch(e){}d["cleanData"+ba].apply(this,arguments)}),y.version="3.0.3",y.nextid=0,y.inactiveEvents=X,y.zindex=15e3,y.defaults={prerender:E,id:E,overwrite:D,suppress:D,content:{text:D,attr:"title",title:E,button:E},position:{my:"top left",at:"bottom right",target:E,container:E,viewport:E,adjust:{x:0,y:0,mouse:D,scroll:D,resize:D,method:"flipinvert flipinvert"},effect:function(a,b){d(this).animate(b,{duration:200,queue:E})}},show:{target:E,event:"mouseenter",effect:D,delay:90,solo:E,ready:E,autofocus:E},hide:{target:E,event:"mouseleave",effect:D,delay:0,fixed:E,inactive:E,leave:"window",distance:E},style:{classes:"",widget:E,width:E,height:E,def:D},events:{render:F,move:F,show:F,hide:F,toggle:F,visible:F,hidden:F,focus:F,blur:F}};var ha,ia,ja,ka,la,ma="margin",na="border",oa="color",pa="background-color",qa="transparent",ra=" !important",sa=!!b.createElement("canvas").getContext,ta=/rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i,ua={},va=["Webkit","O","Moz","ms"];sa?(ka=a.devicePixelRatio||1,la=function(){var a=b.createElement("canvas").getContext("2d");return a.backingStorePixelRatio||a.webkitBackingStorePixelRatio||a.mozBackingStorePixelRatio||a.msBackingStorePixelRatio||a.oBackingStorePixelRatio||1}(),ja=ka/la):ia=function(a,b,c){return"<qtipvml:"+a+' xmlns="urn:schemas-microsoft.com:vml" class="qtip-vml" '+(b||"")+' style="behavior: url(#default#VML); '+(c||"")+'" />'},d.extend(v.prototype,{init:function(a){var b,c;c=this.element=a.elements.tip=d("<div />",{"class":S+"-tip"}).prependTo(a.tooltip),sa?(b=d("<canvas />").appendTo(this.element)[0].getContext("2d"),b.lineJoin="miter",b.miterLimit=1e5,b.save()):(b=ia("shape",'coordorigin="0,0"',"position:absolute;"),this.element.html(b+b),a._bind(d("*",c).add(c),["click","mousedown"],function(a){a.stopPropagation()},this._ns)),a._bind(a.tooltip,"tooltipmove",this.reposition,this._ns,this),this.create()},_swapDimensions:function(){this.size[0]=this.options.height,this.size[1]=this.options.width},_resetDimensions:function(){this.size[0]=this.options.width,this.size[1]=this.options.height},_useTitle:function(a){var b=this.qtip.elements.titlebar;return b&&(a.y===K||a.y===O&&this.element.position().top+this.size[1]/2+this.options.offset<b.outerHeight(D))},_parseCorner:function(a){var b=this.qtip.options.position.my;return a===E||b===E?a=E:a===D?a=new A(b.string()):a.string||(a=new A(a),a.fixed=D),a},_parseWidth:function(a,b,c){var d=this.qtip.elements,e=na+s(b)+"Width";return(c?u(c,e):u(d.content,e)||u(this._useTitle(a)&&d.titlebar||d.content,e)||u(d.tooltip,e))||0},_parseRadius:function(a){var b=this.qtip.elements,c=na+s(a.y)+s(a.x)+"Radius";return da.ie<9?0:u(this._useTitle(a)&&b.titlebar||b.content,c)||u(b.tooltip,c)||0},_invalidColour:function(a,b,c){var d=a.css(b);return!d||c&&d===a.css(c)||ta.test(d)?E:d},_parseColours:function(a){var b=this.qtip.elements,c=this.element.css("cssText",""),e=na+s(a[a.precedance])+s(oa),f=this._useTitle(a)&&b.titlebar||b.content,g=this._invalidColour,h=[];return h[0]=g(c,pa)||g(f,pa)||g(b.content,pa)||g(b.tooltip,pa)||c.css(pa),h[1]=g(c,e,oa)||g(f,e,oa)||g(b.content,e,oa)||g(b.tooltip,e,oa)||b.tooltip.css(e),d("*",c).add(c).css("cssText",pa+":"+qa+ra+";"+na+":0"+ra+";"),h},_calculateSize:function(a){var b,c,d,e=a.precedance===H,f=this.options.width,g=this.options.height,h="c"===a.abbrev(),i=(e?f:g)*(h?.5:1),j=Math.pow,k=Math.round,l=Math.sqrt(j(i,2)+j(g,2)),m=[this.border/i*l,this.border/g*l];return m[2]=Math.sqrt(j(m[0],2)-j(this.border,2)),m[3]=Math.sqrt(j(m[1],2)-j(this.border,2)),b=l+m[2]+m[3]+(h?0:m[0]),c=b/l,d=[k(c*f),k(c*g)],e?d:d.reverse()},_calculateTip:function(a,b,c){c=c||1,b=b||this.size;var d=b[0]*c,e=b[1]*c,f=Math.ceil(d/2),g=Math.ceil(e/2),h={br:[0,0,d,e,d,0],bl:[0,0,d,0,0,e],tr:[0,e,d,0,d,e],tl:[0,0,0,e,d,e],tc:[0,e,f,0,d,e],bc:[0,0,d,0,f,e],rc:[0,0,d,g,0,e],lc:[d,0,d,e,0,g]};return h.lt=h.br,h.rt=h.bl,h.lb=h.tr,h.rb=h.tl,h[a.abbrev()]},_drawCoords:function(a,b){a.beginPath(),a.moveTo(b[0],b[1]),a.lineTo(b[2],b[3]),a.lineTo(b[4],b[5]),a.closePath()},create:function(){var a=this.corner=(sa||da.ie)&&this._parseCorner(this.options.corner);return this.enabled=!!this.corner&&"c"!==this.corner.abbrev(),this.enabled&&(this.qtip.cache.corner=a.clone(),this.update()),this.element.toggle(this.enabled),this.corner},update:function(b,c){if(!this.enabled)return this;var e,f,g,h,i,j,k,l,m=this.qtip.elements,n=this.element,o=n.children(),p=this.options,q=this.size,r=p.mimic,s=Math.round;b||(b=this.qtip.cache.corner||this.corner),r===E?r=b:(r=new A(r),r.precedance=b.precedance,"inherit"===r.x?r.x=b.x:"inherit"===r.y?r.y=b.y:r.x===r.y&&(r[b.precedance]=b[b.precedance])),f=r.precedance,b.precedance===G?this._swapDimensions():this._resetDimensions(),e=this.color=this._parseColours(b),e[1]!==qa?(l=this.border=this._parseWidth(b,b[b.precedance]),p.border&&1>l&&!ta.test(e[1])&&(e[0]=e[1]),this.border=l=p.border!==D?p.border:l):this.border=l=0,k=this.size=this._calculateSize(b),n.css({width:k[0],height:k[1],lineHeight:k[1]+"px"}),j=b.precedance===H?[s(r.x===L?l:r.x===N?k[0]-q[0]-l:(k[0]-q[0])/2),s(r.y===K?k[1]-q[1]:0)]:[s(r.x===L?k[0]-q[0]:0),s(r.y===K?l:r.y===M?k[1]-q[1]-l:(k[1]-q[1])/2)],sa?(g=o[0].getContext("2d"),g.restore(),g.save(),g.clearRect(0,0,6e3,6e3),h=this._calculateTip(r,q,ja),i=this._calculateTip(r,this.size,ja),o.attr(I,k[0]*ja).attr(J,k[1]*ja),o.css(I,k[0]).css(J,k[1]),this._drawCoords(g,i),g.fillStyle=e[1],g.fill(),g.translate(j[0]*ja,j[1]*ja),this._drawCoords(g,h),g.fillStyle=e[0],g.fill()):(h=this._calculateTip(r),h="m"+h[0]+","+h[1]+" l"+h[2]+","+h[3]+" "+h[4]+","+h[5]+" xe",j[2]=l&&/^(r|b)/i.test(b.string())?8===da.ie?2:1:0,o.css({coordsize:k[0]+l+" "+k[1]+l,antialias:""+(r.string().indexOf(O)>-1),left:j[0]-j[2]*Number(f===G),top:j[1]-j[2]*Number(f===H),width:k[0]+l,height:k[1]+l}).each(function(a){var b=d(this);b[b.prop?"prop":"attr"]({coordsize:k[0]+l+" "+k[1]+l,path:h,fillcolor:e[0],filled:!!a,stroked:!a}).toggle(!(!l&&!a)),!a&&b.html(ia("stroke",'weight="'+2*l+'px" color="'+e[1]+'" miterlimit="1000" joinstyle="miter"'))})),a.opera&&setTimeout(function(){m.tip.css({display:"inline-block",visibility:"visible"})},1),c!==E&&this.calculate(b,k)},calculate:function(a,b){if(!this.enabled)return E;var c,e,f=this,g=this.qtip.elements,h=this.element,i=this.options.offset,j={};
4
+ return a=a||this.corner,c=a.precedance,b=b||this._calculateSize(a),e=[a.x,a.y],c===G&&e.reverse(),d.each(e,function(d,e){var h,k,l;e===O?(h=c===H?L:K,j[h]="50%",j[ma+"-"+h]=-Math.round(b[c===H?0:1]/2)+i):(h=f._parseWidth(a,e,g.tooltip),k=f._parseWidth(a,e,g.content),l=f._parseRadius(a),j[e]=Math.max(-f.border,d?k:i+(l>h?l:-h)))}),j[a[c]]-=b[c===G?0:1],h.css({margin:"",top:"",bottom:"",left:"",right:""}).css(j),j},reposition:function(a,b,d){function e(a,b,c,d,e){a===Q&&j.precedance===b&&k[d]&&j[c]!==O?j.precedance=j.precedance===G?H:G:a!==Q&&k[d]&&(j[b]=j[b]===O?k[d]>0?d:e:j[b]===d?e:d)}function f(a,b,e){j[a]===O?p[ma+"-"+b]=o[a]=g[ma+"-"+b]-k[b]:(h=g[e]!==c?[k[b],-g[b]]:[-k[b],g[b]],(o[a]=Math.max(h[0],h[1]))>h[0]&&(d[b]-=k[b],o[b]=E),p[g[e]!==c?e:b]=o[a])}if(this.enabled){var g,h,i=b.cache,j=this.corner.clone(),k=d.adjusted,l=b.options.position.adjust.method.split(" "),m=l[0],n=l[1]||l[0],o={left:E,top:E,x:0,y:0},p={};this.corner.fixed!==D&&(e(m,G,H,L,N),e(n,H,G,K,M),j.string()===i.corner.string()&&i.cornerTop===k.top&&i.cornerLeft===k.left||this.update(j,E)),g=this.calculate(j),g.right!==c&&(g.left=-g.right),g.bottom!==c&&(g.top=-g.bottom),g.user=this.offset,o.left=m===Q&&!!k.left,o.left&&f(G,L,N),o.top=n===Q&&!!k.top,o.top&&f(H,K,M),this.element.css(p).toggle(!(o.x&&o.y||j.x===O&&o.y||j.y===O&&o.x)),d.left-=g.left.charAt?g.user:m!==Q||o.top||!o.left&&!o.top?g.left+this.border:0,d.top-=g.top.charAt?g.user:n!==Q||o.left||!o.left&&!o.top?g.top+this.border:0,i.cornerLeft=k.left,i.cornerTop=k.top,i.corner=j.clone()}},destroy:function(){this.qtip._unbind(this.qtip.tooltip,this._ns),this.qtip.elements.tip&&this.qtip.elements.tip.find("*").remove().end().remove()}}),ha=R.tip=function(a){return new v(a,a.options.style.tip)},ha.initialize="render",ha.sanitize=function(a){if(a.style&&"tip"in a.style){var b=a.style.tip;"object"!=typeof b&&(b=a.style.tip={corner:b}),/string|boolean/i.test(typeof b.corner)||(b.corner=D)}},B.tip={"^position.my|style.tip.(corner|mimic|border)$":function(){this.create(),this.qtip.reposition()},"^style.tip.(height|width)$":function(a){this.size=[a.width,a.height],this.update(),this.qtip.reposition()},"^content.title|style.(classes|widget)$":function(){this.update()}},d.extend(D,y.defaults,{style:{tip:{corner:D,mimic:E,width:6,height:6,border:D,offset:0}}});var wa,xa,ya="qtip-modal",za="."+ya;xa=function(){function a(a){if(d.expr[":"].focusable)return d.expr[":"].focusable;var b,c,e,f=!isNaN(d.attr(a,"tabindex")),g=a.nodeName&&a.nodeName.toLowerCase();return"area"===g?(b=a.parentNode,c=b.name,a.href&&c&&"map"===b.nodeName.toLowerCase()?(e=d("img[usemap=#"+c+"]")[0],!!e&&e.is(":visible")):!1):/input|select|textarea|button|object/.test(g)?!a.disabled:"a"===g?a.href||f:f}function c(a){j.length<1&&a.length?a.not("body").blur():j.first().focus()}function e(a){if(h.is(":visible")){var b,e=d(a.target),g=f.tooltip,i=e.closest(W);b=i.length<1?E:parseInt(i[0].style.zIndex,10)>parseInt(g[0].style.zIndex,10),b||e.closest(W)[0]===g[0]||c(e)}}var f,g,h,i=this,j={};d.extend(i,{init:function(){return h=i.elem=d("<div />",{id:"qtip-overlay",html:"<div></div>",mousedown:function(){return E}}).hide(),d(b.body).bind("focusin"+za,e),d(b).bind("keydown"+za,function(a){f&&f.options.show.modal.escape&&27===a.keyCode&&f.hide(a)}),h.bind("click"+za,function(a){f&&f.options.show.modal.blur&&f.hide(a)}),i},update:function(b){f=b,j=b.options.show.modal.stealfocus!==E?b.tooltip.find("*").filter(function(){return a(this)}):[]},toggle:function(a,e,j){var k=a.tooltip,l=a.options.show.modal,m=l.effect,n=e?"show":"hide",o=h.is(":visible"),p=d(za).filter(":visible:not(:animated)").not(k);return i.update(a),e&&l.stealfocus!==E&&c(d(":focus")),h.toggleClass("blurs",l.blur),e&&h.appendTo(b.body),h.is(":animated")&&o===e&&g!==E||!e&&p.length?i:(h.stop(D,E),d.isFunction(m)?m.call(h,e):m===E?h[n]():h.fadeTo(parseInt(j,10)||90,e?1:0,function(){e||h.hide()}),e||h.queue(function(a){h.css({left:"",top:""}),d(za).length||h.detach(),a()}),g=e,f.destroyed&&(f=F),i)}}),i.init()},xa=new xa,d.extend(w.prototype,{init:function(a){var b=a.tooltip;return this.options.on?(a.elements.overlay=xa.elem,b.addClass(ya).css("z-index",y.modal_zindex+d(za).length),a._bind(b,["tooltipshow","tooltiphide"],function(a,c,e){var f=a.originalEvent;if(a.target===b[0])if(f&&"tooltiphide"===a.type&&/mouse(leave|enter)/.test(f.type)&&d(f.relatedTarget).closest(xa.elem[0]).length)try{a.preventDefault()}catch(g){}else(!f||f&&"tooltipsolo"!==f.type)&&this.toggle(a,"tooltipshow"===a.type,e)},this._ns,this),a._bind(b,"tooltipfocus",function(a,c){if(!a.isDefaultPrevented()&&a.target===b[0]){var e=d(za),f=y.modal_zindex+e.length,g=parseInt(b[0].style.zIndex,10);xa.elem[0].style.zIndex=f-1,e.each(function(){this.style.zIndex>g&&(this.style.zIndex-=1)}),e.filter("."+$).qtip("blur",a.originalEvent),b.addClass($)[0].style.zIndex=f,xa.update(c);try{a.preventDefault()}catch(h){}}},this._ns,this),void a._bind(b,"tooltiphide",function(a){a.target===b[0]&&d(za).filter(":visible").not(b).last().qtip("focus",a)},this._ns,this)):this},toggle:function(a,b,c){return a&&a.isDefaultPrevented()?this:void xa.toggle(this.qtip,!!b,c)},destroy:function(){this.qtip.tooltip.removeClass(ya),this.qtip._unbind(this.qtip.tooltip,this._ns),xa.toggle(this.qtip,E),delete this.qtip.elements.overlay}}),wa=R.modal=function(a){return new w(a,a.options.show.modal)},wa.sanitize=function(a){a.show&&("object"!=typeof a.show.modal?a.show.modal={on:!!a.show.modal}:"undefined"==typeof a.show.modal.on&&(a.show.modal.on=D))},y.modal_zindex=y.zindex-200,wa.initialize="render",B.modal={"^show.modal.(on|blur)$":function(){this.destroy(),this.init(),this.qtip.elems.overlay.toggle(this.qtip.tooltip[0].offsetWidth>0)}},d.extend(D,y.defaults,{show:{modal:{on:E,effect:D,blur:D,stealfocus:D,escape:D}}}),R.viewport=function(c,d,e,f,g,h,i){function j(a,b,c,e,f,g,h,i,j){var k=d[f],s=u[a],t=v[a],w=c===Q,x=s===f?j:s===g?-j:-j/2,y=t===f?i:t===g?-i:-i/2,z=q[f]+r[f]-(n?0:m[f]),A=z-k,B=k+j-(h===I?o:p)-z,C=x-(u.precedance===a||s===u[b]?y:0)-(t===O?i/2:0);return w?(C=(s===f?1:-1)*x,d[f]+=A>0?A:B>0?-B:0,d[f]=Math.max(-m[f]+r[f],k-C,Math.min(Math.max(-m[f]+r[f]+(h===I?o:p),k+C),d[f],"center"===s?k-x:1e9))):(e*=c===P?2:0,A>0&&(s!==f||B>0)?(d[f]-=C+e,l.invert(a,f)):B>0&&(s!==g||A>0)&&(d[f]-=(s===O?-C:C)+e,l.invert(a,g)),d[f]<q[f]&&-d[f]>B&&(d[f]=k,l=u.clone())),d[f]-k}var k,l,m,n,o,p,q,r,s=e.target,t=c.elements.tooltip,u=e.my,v=e.at,w=e.adjust,x=w.method.split(" "),y=x[0],z=x[1]||x[0],A=e.viewport,B=e.container,C={left:0,top:0};return A.jquery&&s[0]!==a&&s[0]!==b.body&&"none"!==w.method?(m=B.offset()||C,n="static"===B.css("position"),k="fixed"===t.css("position"),o=A[0]===a?A.width():A.outerWidth(E),p=A[0]===a?A.height():A.outerHeight(E),q={left:k?0:A.scrollLeft(),top:k?0:A.scrollTop()},r=A.offset()||C,"shift"===y&&"shift"===z||(l=u.clone()),C={left:"none"!==y?j(G,H,y,w.x,L,N,I,f,h):0,top:"none"!==z?j(H,G,z,w.y,K,M,J,g,i):0,my:l}):C},R.polys={polygon:function(a,b){var c,d,e,f={width:0,height:0,position:{top:1e10,right:0,bottom:0,left:1e10},adjustable:E},g=0,h=[],i=1,j=1,k=0,l=0;for(g=a.length;g--;)c=[parseInt(a[--g],10),parseInt(a[g+1],10)],c[0]>f.position.right&&(f.position.right=c[0]),c[0]<f.position.left&&(f.position.left=c[0]),c[1]>f.position.bottom&&(f.position.bottom=c[1]),c[1]<f.position.top&&(f.position.top=c[1]),h.push(c);if(d=f.width=Math.abs(f.position.right-f.position.left),e=f.height=Math.abs(f.position.bottom-f.position.top),"c"===b.abbrev())f.position={left:f.position.left+f.width/2,top:f.position.top+f.height/2};else{for(;d>0&&e>0&&i>0&&j>0;)for(d=Math.floor(d/2),e=Math.floor(e/2),b.x===L?i=d:b.x===N?i=f.width-d:i+=Math.floor(d/2),b.y===K?j=e:b.y===M?j=f.height-e:j+=Math.floor(e/2),g=h.length;g--&&!(h.length<2);)k=h[g][0]-f.position.left,l=h[g][1]-f.position.top,(b.x===L&&k>=i||b.x===N&&i>=k||b.x===O&&(i>k||k>f.width-i)||b.y===K&&l>=j||b.y===M&&j>=l||b.y===O&&(j>l||l>f.height-j))&&h.splice(g,1);f.position={left:h[0][0],top:h[0][1]}}return f},rect:function(a,b,c,d){return{width:Math.abs(c-a),height:Math.abs(d-b),position:{left:Math.min(a,c),top:Math.min(b,d)}}},_angles:{tc:1.5,tr:7/4,tl:5/4,bc:.5,br:.25,bl:.75,rc:2,lc:1,c:0},ellipse:function(a,b,c,d,e){var f=R.polys._angles[e.abbrev()],g=0===f?0:c*Math.cos(f*Math.PI),h=d*Math.sin(f*Math.PI);return{width:2*c-Math.abs(g),height:2*d-Math.abs(h),position:{left:a+g,top:b+h},adjustable:E}},circle:function(a,b,c,d){return R.polys.ellipse(a,b,c,c,d)}},R.svg=function(a,c,e){for(var f,g,h,i,j,k,l,m,n,o=c[0],p=d(o.ownerSVGElement),q=o.ownerDocument,r=(parseInt(c.css("stroke-width"),10)||0)/2;!o.getBBox;)o=o.parentNode;if(!o.getBBox||!o.parentNode)return E;switch(o.nodeName){case"ellipse":case"circle":m=R.polys.ellipse(o.cx.baseVal.value,o.cy.baseVal.value,(o.rx||o.r).baseVal.value+r,(o.ry||o.r).baseVal.value+r,e);break;case"line":case"polygon":case"polyline":for(l=o.points||[{x:o.x1.baseVal.value,y:o.y1.baseVal.value},{x:o.x2.baseVal.value,y:o.y2.baseVal.value}],m=[],k=-1,i=l.numberOfItems||l.length;++k<i;)j=l.getItem?l.getItem(k):l[k],m.push.apply(m,[j.x,j.y]);m=R.polys.polygon(m,e);break;default:m=o.getBBox(),m={width:m.width,height:m.height,position:{left:m.x,top:m.y}}}return n=m.position,p=p[0],p.createSVGPoint&&(g=o.getScreenCTM(),l=p.createSVGPoint(),l.x=n.left,l.y=n.top,h=l.matrixTransform(g),n.left=h.x,n.top=h.y),q!==b&&"mouse"!==a.position.target&&(f=d((q.defaultView||q.parentWindow).frameElement).offset(),f&&(n.left+=f.left,n.top+=f.top)),q=d(q),n.left+=q.scrollLeft(),n.top+=q.scrollTop(),m},R.imagemap=function(a,b,c){b.jquery||(b=d(b));var e,f,g,h,i,j=(b.attr("shape")||"rect").toLowerCase().replace("poly","polygon"),k=d('img[usemap="#'+b.parent("map").attr("name")+'"]'),l=d.trim(b.attr("coords")),m=l.replace(/,$/,"").split(",");if(!k.length)return E;if("polygon"===j)h=R.polys.polygon(m,c);else{if(!R.polys[j])return E;for(g=-1,i=m.length,f=[];++g<i;)f.push(parseInt(m[g],10));h=R.polys[j].apply(this,f.concat(c))}return e=k.offset(),e.left+=Math.ceil((k.outerWidth(E)-k.width())/2),e.top+=Math.ceil((k.outerHeight(E)-k.height())/2),h.position.left+=e.left,h.position.top+=e.top,h};var Aa,Ba='<iframe class="qtip-bgiframe" frameborder="0" tabindex="-1" src="javascript:\'\';" style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=0); -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";"></iframe>';d.extend(x.prototype,{_scroll:function(){var b=this.qtip.elements.overlay;b&&(b[0].style.top=d(a).scrollTop()+"px")},init:function(c){var e=c.tooltip;d("select, object").length<1&&(this.bgiframe=c.elements.bgiframe=d(Ba).appendTo(e),c._bind(e,"tooltipmove",this.adjustBGIFrame,this._ns,this)),this.redrawContainer=d("<div/>",{id:S+"-rcontainer"}).appendTo(b.body),c.elements.overlay&&c.elements.overlay.addClass("qtipmodal-ie6fix")&&(c._bind(a,["scroll","resize"],this._scroll,this._ns,this),c._bind(e,["tooltipshow"],this._scroll,this._ns,this)),this.redraw()},adjustBGIFrame:function(){var a,b,c=this.qtip.tooltip,d={height:c.outerHeight(E),width:c.outerWidth(E)},e=this.qtip.plugins.tip,f=this.qtip.elements.tip;b=parseInt(c.css("borderLeftWidth"),10)||0,b={left:-b,top:-b},e&&f&&(a="x"===e.corner.precedance?[I,L]:[J,K],b[a[1]]-=f[a[0]]()),this.bgiframe.css(b).css(d)},redraw:function(){if(this.qtip.rendered<1||this.drawing)return this;var a,b,c,d,e=this.qtip.tooltip,f=this.qtip.options.style,g=this.qtip.options.position.container;return this.qtip.drawing=1,f.height&&e.css(J,f.height),f.width?e.css(I,f.width):(e.css(I,"").appendTo(this.redrawContainer),b=e.width(),1>b%2&&(b+=1),c=e.css("maxWidth")||"",d=e.css("minWidth")||"",a=(c+d).indexOf("%")>-1?g.width()/100:0,c=(c.indexOf("%")>-1?a:1*parseInt(c,10))||b,d=(d.indexOf("%")>-1?a:1*parseInt(d,10))||0,b=c+d?Math.min(Math.max(b,d),c):b,e.css(I,Math.round(b)).appendTo(g)),this.drawing=0,this},destroy:function(){this.bgiframe&&this.bgiframe.remove(),this.qtip._unbind([a,this.qtip.tooltip],this._ns)}}),Aa=R.ie6=function(a){return 6===da.ie?new x(a):E},Aa.initialize="render",B.ie6={"^content|style$":function(){this.redraw()}}})}(window,document);
5
+ //# sourceMappingURL=jquery.qtip.min.map
js/knockout.js CHANGED
@@ -1,123 +1,124 @@
1
  /*!
2
- * Knockout JavaScript library v3.4.0
3
- * (c) Steven Sanderson - http://knockoutjs.com/
4
  * License: MIT (http://www.opensource.org/licenses/mit-license.php)
5
  */
6
 
7
- (function() {(function(n){var x=this||(0,eval)("this"),u=x.document,M=x.navigator,v=x.jQuery,F=x.JSON;(function(n){"function"===typeof define&&define.amd?define(["exports","require"],n):"object"===typeof exports&&"object"===typeof module?n(module.exports||exports):n(x.ko={})})(function(N,O){function J(a,c){return null===a||typeof a in T?a===c:!1}function U(b,c){var d;return function(){d||(d=a.a.setTimeout(function(){d=n;b()},c))}}function V(b,c){var d;return function(){clearTimeout(d);d=a.a.setTimeout(b,c)}}function W(a,
8
- c){c&&c!==I?"beforeChange"===c?this.Kb(a):this.Ha(a,c):this.Lb(a)}function X(a,c){null!==c&&c.k&&c.k()}function Y(a,c){var d=this.Hc,e=d[s];e.R||(this.lb&&this.Ma[c]?(d.Pb(c,a,this.Ma[c]),this.Ma[c]=null,--this.lb):e.r[c]||d.Pb(c,a,e.s?{ia:a}:d.uc(a)))}function K(b,c,d,e){a.d[b]={init:function(b,g,k,l,m){var h,r;a.m(function(){var q=a.a.c(g()),p=!d!==!q,A=!r;if(A||c||p!==h)A&&a.va.Aa()&&(r=a.a.ua(a.f.childNodes(b),!0)),p?(A||a.f.da(b,a.a.ua(r)),a.eb(e?e(m,q):m,b)):a.f.xa(b),h=p},null,{i:b});return{controlsDescendantBindings:!0}}};
9
- a.h.ta[b]=!1;a.f.Z[b]=!0}var a="undefined"!==typeof N?N:{};a.b=function(b,c){for(var d=b.split("."),e=a,f=0;f<d.length-1;f++)e=e[d[f]];e[d[d.length-1]]=c};a.G=function(a,c,d){a[c]=d};a.version="3.4.0";a.b("version",a.version);a.options={deferUpdates:!1,useOnlyNativeEvents:!1};a.a=function(){function b(a,b){for(var c in a)a.hasOwnProperty(c)&&b(c,a[c])}function c(a,b){if(b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}function d(a,b){a.__proto__=b;return a}function e(b,c,d,e){var h=b[c].match(r)||
10
- [];a.a.q(d.match(r),function(b){a.a.pa(h,b,e)});b[c]=h.join(" ")}var f={__proto__:[]}instanceof Array,g="function"===typeof Symbol,k={},l={};k[M&&/Firefox\/2/i.test(M.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"];k.MouseEvents="click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave".split(" ");b(k,function(a,b){if(b.length)for(var c=0,d=b.length;c<d;c++)l[b[c]]=a});var m={propertychange:!0},h=u&&function(){for(var a=3,b=u.createElement("div"),c=
11
- b.getElementsByTagName("i");b.innerHTML="\x3c!--[if gt IE "+ ++a+"]><i></i><![endif]--\x3e",c[0];);return 4<a?a:n}(),r=/\S+/g;return{cc:["authenticity_token",/^__RequestVerificationToken(_.*)?$/],q:function(a,b){for(var c=0,d=a.length;c<d;c++)b(a[c],c)},o:function(a,b){if("function"==typeof Array.prototype.indexOf)return Array.prototype.indexOf.call(a,b);for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},Sb:function(a,b,c){for(var d=0,e=a.length;d<e;d++)if(b.call(c,a[d],d))return a[d];
12
- return null},La:function(b,c){var d=a.a.o(b,c);0<d?b.splice(d,1):0===d&&b.shift()},Tb:function(b){b=b||[];for(var c=[],d=0,e=b.length;d<e;d++)0>a.a.o(c,b[d])&&c.push(b[d]);return c},fb:function(a,b){a=a||[];for(var c=[],d=0,e=a.length;d<e;d++)c.push(b(a[d],d));return c},Ka:function(a,b){a=a||[];for(var c=[],d=0,e=a.length;d<e;d++)b(a[d],d)&&c.push(a[d]);return c},ra:function(a,b){if(b instanceof Array)a.push.apply(a,b);else for(var c=0,d=b.length;c<d;c++)a.push(b[c]);return a},pa:function(b,c,d){var e=
13
- a.a.o(a.a.zb(b),c);0>e?d&&b.push(c):d||b.splice(e,1)},ka:f,extend:c,Xa:d,Ya:f?d:c,D:b,Ca:function(a,b){if(!a)return a;var c={},d;for(d in a)a.hasOwnProperty(d)&&(c[d]=b(a[d],d,a));return c},ob:function(b){for(;b.firstChild;)a.removeNode(b.firstChild)},jc:function(b){b=a.a.V(b);for(var c=(b[0]&&b[0].ownerDocument||u).createElement("div"),d=0,e=b.length;d<e;d++)c.appendChild(a.$(b[d]));return c},ua:function(b,c){for(var d=0,e=b.length,h=[];d<e;d++){var m=b[d].cloneNode(!0);h.push(c?a.$(m):m)}return h},
14
- da:function(b,c){a.a.ob(b);if(c)for(var d=0,e=c.length;d<e;d++)b.appendChild(c[d])},qc:function(b,c){var d=b.nodeType?[b]:b;if(0<d.length){for(var e=d[0],h=e.parentNode,m=0,l=c.length;m<l;m++)h.insertBefore(c[m],e);m=0;for(l=d.length;m<l;m++)a.removeNode(d[m])}},za:function(a,b){if(a.length){for(b=8===b.nodeType&&b.parentNode||b;a.length&&a[0].parentNode!==b;)a.splice(0,1);for(;1<a.length&&a[a.length-1].parentNode!==b;)a.length--;if(1<a.length){var c=a[0],d=a[a.length-1];for(a.length=0;c!==d;)a.push(c),
15
- c=c.nextSibling;a.push(d)}}return a},sc:function(a,b){7>h?a.setAttribute("selected",b):a.selected=b},$a:function(a){return null===a||a===n?"":a.trim?a.trim():a.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},nd:function(a,b){a=a||"";return b.length>a.length?!1:a.substring(0,b.length)===b},Mc:function(a,b){if(a===b)return!0;if(11===a.nodeType)return!1;if(b.contains)return b.contains(3===a.nodeType?a.parentNode:a);if(b.compareDocumentPosition)return 16==(b.compareDocumentPosition(a)&16);for(;a&&a!=
16
- b;)a=a.parentNode;return!!a},nb:function(b){return a.a.Mc(b,b.ownerDocument.documentElement)},Qb:function(b){return!!a.a.Sb(b,a.a.nb)},A:function(a){return a&&a.tagName&&a.tagName.toLowerCase()},Wb:function(b){return a.onError?function(){try{return b.apply(this,arguments)}catch(c){throw a.onError&&a.onError(c),c;}}:b},setTimeout:function(b,c){return setTimeout(a.a.Wb(b),c)},$b:function(b){setTimeout(function(){a.onError&&a.onError(b);throw b;},0)},p:function(b,c,d){var e=a.a.Wb(d);d=h&&m[c];if(a.options.useOnlyNativeEvents||
17
- d||!v)if(d||"function"!=typeof b.addEventListener)if("undefined"!=typeof b.attachEvent){var l=function(a){e.call(b,a)},f="on"+c;b.attachEvent(f,l);a.a.F.oa(b,function(){b.detachEvent(f,l)})}else throw Error("Browser doesn't support addEventListener or attachEvent");else b.addEventListener(c,e,!1);else v(b).bind(c,e)},Da:function(b,c){if(!b||!b.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var d;"input"===a.a.A(b)&&b.type&&"click"==c.toLowerCase()?(d=b.type,d="checkbox"==
18
- d||"radio"==d):d=!1;if(a.options.useOnlyNativeEvents||!v||d)if("function"==typeof u.createEvent)if("function"==typeof b.dispatchEvent)d=u.createEvent(l[c]||"HTMLEvents"),d.initEvent(c,!0,!0,x,0,0,0,0,0,!1,!1,!1,!1,0,b),b.dispatchEvent(d);else throw Error("The supplied element doesn't support dispatchEvent");else if(d&&b.click)b.click();else if("undefined"!=typeof b.fireEvent)b.fireEvent("on"+c);else throw Error("Browser doesn't support triggering events");else v(b).trigger(c)},c:function(b){return a.H(b)?
19
- b():b},zb:function(b){return a.H(b)?b.t():b},bb:function(b,c,d){var h;c&&("object"===typeof b.classList?(h=b.classList[d?"add":"remove"],a.a.q(c.match(r),function(a){h.call(b.classList,a)})):"string"===typeof b.className.baseVal?e(b.className,"baseVal",c,d):e(b,"className",c,d))},Za:function(b,c){var d=a.a.c(c);if(null===d||d===n)d="";var e=a.f.firstChild(b);!e||3!=e.nodeType||a.f.nextSibling(e)?a.f.da(b,[b.ownerDocument.createTextNode(d)]):e.data=d;a.a.Rc(b)},rc:function(a,b){a.name=b;if(7>=h)try{a.mergeAttributes(u.createElement("<input name='"+
20
- a.name+"'/>"),!1)}catch(c){}},Rc:function(a){9<=h&&(a=1==a.nodeType?a:a.parentNode,a.style&&(a.style.zoom=a.style.zoom))},Nc:function(a){if(h){var b=a.style.width;a.style.width=0;a.style.width=b}},hd:function(b,c){b=a.a.c(b);c=a.a.c(c);for(var d=[],e=b;e<=c;e++)d.push(e);return d},V:function(a){for(var b=[],c=0,d=a.length;c<d;c++)b.push(a[c]);return b},Yb:function(a){return g?Symbol(a):a},rd:6===h,sd:7===h,C:h,ec:function(b,c){for(var d=a.a.V(b.getElementsByTagName("input")).concat(a.a.V(b.getElementsByTagName("textarea"))),
21
- e="string"==typeof c?function(a){return a.name===c}:function(a){return c.test(a.name)},h=[],m=d.length-1;0<=m;m--)e(d[m])&&h.push(d[m]);return h},ed:function(b){return"string"==typeof b&&(b=a.a.$a(b))?F&&F.parse?F.parse(b):(new Function("return "+b))():null},Eb:function(b,c,d){if(!F||!F.stringify)throw Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");
22
- return F.stringify(a.a.c(b),c,d)},fd:function(c,d,e){e=e||{};var h=e.params||{},m=e.includeFields||this.cc,l=c;if("object"==typeof c&&"form"===a.a.A(c))for(var l=c.action,f=m.length-1;0<=f;f--)for(var g=a.a.ec(c,m[f]),k=g.length-1;0<=k;k--)h[g[k].name]=g[k].value;d=a.a.c(d);var r=u.createElement("form");r.style.display="none";r.action=l;r.method="post";for(var n in d)c=u.createElement("input"),c.type="hidden",c.name=n,c.value=a.a.Eb(a.a.c(d[n])),r.appendChild(c);b(h,function(a,b){var c=u.createElement("input");
23
- c.type="hidden";c.name=a;c.value=b;r.appendChild(c)});u.body.appendChild(r);e.submitter?e.submitter(r):r.submit();setTimeout(function(){r.parentNode.removeChild(r)},0)}}}();a.b("utils",a.a);a.b("utils.arrayForEach",a.a.q);a.b("utils.arrayFirst",a.a.Sb);a.b("utils.arrayFilter",a.a.Ka);a.b("utils.arrayGetDistinctValues",a.a.Tb);a.b("utils.arrayIndexOf",a.a.o);a.b("utils.arrayMap",a.a.fb);a.b("utils.arrayPushAll",a.a.ra);a.b("utils.arrayRemoveItem",a.a.La);a.b("utils.extend",a.a.extend);a.b("utils.fieldsIncludedWithJsonPost",
24
- a.a.cc);a.b("utils.getFormFields",a.a.ec);a.b("utils.peekObservable",a.a.zb);a.b("utils.postJson",a.a.fd);a.b("utils.parseJson",a.a.ed);a.b("utils.registerEventHandler",a.a.p);a.b("utils.stringifyJson",a.a.Eb);a.b("utils.range",a.a.hd);a.b("utils.toggleDomNodeCssClass",a.a.bb);a.b("utils.triggerEvent",a.a.Da);a.b("utils.unwrapObservable",a.a.c);a.b("utils.objectForEach",a.a.D);a.b("utils.addOrRemoveItem",a.a.pa);a.b("utils.setTextContent",a.a.Za);a.b("unwrap",a.a.c);Function.prototype.bind||(Function.prototype.bind=
25
- function(a){var c=this;if(1===arguments.length)return function(){return c.apply(a,arguments)};var d=Array.prototype.slice.call(arguments,1);return function(){var e=d.slice(0);e.push.apply(e,arguments);return c.apply(a,e)}});a.a.e=new function(){function a(b,g){var k=b[d];if(!k||"null"===k||!e[k]){if(!g)return n;k=b[d]="ko"+c++;e[k]={}}return e[k]}var c=0,d="__ko__"+(new Date).getTime(),e={};return{get:function(c,d){var e=a(c,!1);return e===n?n:e[d]},set:function(c,d,e){if(e!==n||a(c,!1)!==n)a(c,!0)[d]=
26
- e},clear:function(a){var b=a[d];return b?(delete e[b],a[d]=null,!0):!1},I:function(){return c++ +d}}};a.b("utils.domData",a.a.e);a.b("utils.domData.clear",a.a.e.clear);a.a.F=new function(){function b(b,c){var e=a.a.e.get(b,d);e===n&&c&&(e=[],a.a.e.set(b,d,e));return e}function c(d){var e=b(d,!1);if(e)for(var e=e.slice(0),l=0;l<e.length;l++)e[l](d);a.a.e.clear(d);a.a.F.cleanExternalData(d);if(f[d.nodeType])for(e=d.firstChild;d=e;)e=d.nextSibling,8===d.nodeType&&c(d)}var d=a.a.e.I(),e={1:!0,8:!0,9:!0},
27
- f={1:!0,9:!0};return{oa:function(a,c){if("function"!=typeof c)throw Error("Callback must be a function");b(a,!0).push(c)},pc:function(c,e){var l=b(c,!1);l&&(a.a.La(l,e),0==l.length&&a.a.e.set(c,d,n))},$:function(b){if(e[b.nodeType]&&(c(b),f[b.nodeType])){var d=[];a.a.ra(d,b.getElementsByTagName("*"));for(var l=0,m=d.length;l<m;l++)c(d[l])}return b},removeNode:function(b){a.$(b);b.parentNode&&b.parentNode.removeChild(b)},cleanExternalData:function(a){v&&"function"==typeof v.cleanData&&v.cleanData([a])}}};
28
- a.$=a.a.F.$;a.removeNode=a.a.F.removeNode;a.b("cleanNode",a.$);a.b("removeNode",a.removeNode);a.b("utils.domNodeDisposal",a.a.F);a.b("utils.domNodeDisposal.addDisposeCallback",a.a.F.oa);a.b("utils.domNodeDisposal.removeDisposeCallback",a.a.F.pc);(function(){var b=[0,"",""],c=[1,"<table>","</table>"],d=[3,"<table><tbody><tr>","</tr></tbody></table>"],e=[1,"<select multiple='multiple'>","</select>"],f={thead:c,tbody:c,tfoot:c,tr:[2,"<table><tbody>","</tbody></table>"],td:d,th:d,option:e,optgroup:e},
29
- g=8>=a.a.C;a.a.ma=function(c,d){var e;if(v)if(v.parseHTML)e=v.parseHTML(c,d)||[];else{if((e=v.clean([c],d))&&e[0]){for(var h=e[0];h.parentNode&&11!==h.parentNode.nodeType;)h=h.parentNode;h.parentNode&&h.parentNode.removeChild(h)}}else{(e=d)||(e=u);var h=e.parentWindow||e.defaultView||x,r=a.a.$a(c).toLowerCase(),q=e.createElement("div"),p;p=(r=r.match(/^<([a-z]+)[ >]/))&&f[r[1]]||b;r=p[0];p="ignored<div>"+p[1]+c+p[2]+"</div>";"function"==typeof h.innerShiv?q.appendChild(h.innerShiv(p)):(g&&e.appendChild(q),
30
- q.innerHTML=p,g&&q.parentNode.removeChild(q));for(;r--;)q=q.lastChild;e=a.a.V(q.lastChild.childNodes)}return e};a.a.Cb=function(b,c){a.a.ob(b);c=a.a.c(c);if(null!==c&&c!==n)if("string"!=typeof c&&(c=c.toString()),v)v(b).html(c);else for(var d=a.a.ma(c,b.ownerDocument),e=0;e<d.length;e++)b.appendChild(d[e])}})();a.b("utils.parseHtmlFragment",a.a.ma);a.b("utils.setHtml",a.a.Cb);a.M=function(){function b(c,e){if(c)if(8==c.nodeType){var f=a.M.lc(c.nodeValue);null!=f&&e.push({Lc:c,cd:f})}else if(1==c.nodeType)for(var f=
31
- 0,g=c.childNodes,k=g.length;f<k;f++)b(g[f],e)}var c={};return{wb:function(a){if("function"!=typeof a)throw Error("You can only pass a function to ko.memoization.memoize()");var b=(4294967296*(1+Math.random())|0).toString(16).substring(1)+(4294967296*(1+Math.random())|0).toString(16).substring(1);c[b]=a;return"\x3c!--[ko_memo:"+b+"]--\x3e"},xc:function(a,b){var f=c[a];if(f===n)throw Error("Couldn't find any memo with ID "+a+". Perhaps it's already been unmemoized.");try{return f.apply(null,b||[]),
32
- !0}finally{delete c[a]}},yc:function(c,e){var f=[];b(c,f);for(var g=0,k=f.length;g<k;g++){var l=f[g].Lc,m=[l];e&&a.a.ra(m,e);a.M.xc(f[g].cd,m);l.nodeValue="";l.parentNode&&l.parentNode.removeChild(l)}},lc:function(a){return(a=a.match(/^\[ko_memo\:(.*?)\]$/))?a[1]:null}}}();a.b("memoization",a.M);a.b("memoization.memoize",a.M.wb);a.b("memoization.unmemoize",a.M.xc);a.b("memoization.parseMemoText",a.M.lc);a.b("memoization.unmemoizeDomNodeAndDescendants",a.M.yc);a.Y=function(){function b(){if(e)for(var b=
33
- e,c=0,m;g<e;)if(m=d[g++]){if(g>b){if(5E3<=++c){g=e;a.a.$b(Error("'Too much recursion' after processing "+c+" task groups."));break}b=e}try{m()}catch(h){a.a.$b(h)}}}function c(){b();g=e=d.length=0}var d=[],e=0,f=1,g=0;return{scheduler:x.MutationObserver?function(a){var b=u.createElement("div");(new MutationObserver(a)).observe(b,{attributes:!0});return function(){b.classList.toggle("foo")}}(c):u&&"onreadystatechange"in u.createElement("script")?function(a){var b=u.createElement("script");b.onreadystatechange=
34
- function(){b.onreadystatechange=null;u.documentElement.removeChild(b);b=null;a()};u.documentElement.appendChild(b)}:function(a){setTimeout(a,0)},Wa:function(b){e||a.Y.scheduler(c);d[e++]=b;return f++},cancel:function(a){a-=f-e;a>=g&&a<e&&(d[a]=null)},resetForTesting:function(){var a=e-g;g=e=d.length=0;return a},md:b}}();a.b("tasks",a.Y);a.b("tasks.schedule",a.Y.Wa);a.b("tasks.runEarly",a.Y.md);a.ya={throttle:function(b,c){b.throttleEvaluation=c;var d=null;return a.B({read:b,write:function(e){clearTimeout(d);
35
- d=a.a.setTimeout(function(){b(e)},c)}})},rateLimit:function(a,c){var d,e,f;"number"==typeof c?d=c:(d=c.timeout,e=c.method);a.cb=!1;f="notifyWhenChangesStop"==e?V:U;a.Ta(function(a){return f(a,d)})},deferred:function(b,c){if(!0!==c)throw Error("The 'deferred' extender only accepts the value 'true', because it is not supported to turn deferral off once enabled.");b.cb||(b.cb=!0,b.Ta(function(c){var e;return function(){a.Y.cancel(e);e=a.Y.Wa(c);b.notifySubscribers(n,"dirty")}}))},notify:function(a,c){a.equalityComparer=
36
- "always"==c?null:J}};var T={undefined:1,"boolean":1,number:1,string:1};a.b("extenders",a.ya);a.vc=function(b,c,d){this.ia=b;this.gb=c;this.Kc=d;this.R=!1;a.G(this,"dispose",this.k)};a.vc.prototype.k=function(){this.R=!0;this.Kc()};a.J=function(){a.a.Ya(this,D);D.rb(this)};var I="change",D={rb:function(a){a.K={};a.Nb=1},X:function(b,c,d){var e=this;d=d||I;var f=new a.vc(e,c?b.bind(c):b,function(){a.a.La(e.K[d],f);e.Ia&&e.Ia(d)});e.sa&&e.sa(d);e.K[d]||(e.K[d]=[]);e.K[d].push(f);return f},notifySubscribers:function(b,
37
- c){c=c||I;c===I&&this.zc();if(this.Pa(c))try{a.l.Ub();for(var d=this.K[c].slice(0),e=0,f;f=d[e];++e)f.R||f.gb(b)}finally{a.l.end()}},Na:function(){return this.Nb},Uc:function(a){return this.Na()!==a},zc:function(){++this.Nb},Ta:function(b){var c=this,d=a.H(c),e,f,g;c.Ha||(c.Ha=c.notifySubscribers,c.notifySubscribers=W);var k=b(function(){c.Mb=!1;d&&g===c&&(g=c());e=!1;c.tb(f,g)&&c.Ha(f=g)});c.Lb=function(a){c.Mb=e=!0;g=a;k()};c.Kb=function(a){e||(f=a,c.Ha(a,"beforeChange"))}},Pa:function(a){return this.K[a]&&
38
- this.K[a].length},Sc:function(b){if(b)return this.K[b]&&this.K[b].length||0;var c=0;a.a.D(this.K,function(a,b){"dirty"!==a&&(c+=b.length)});return c},tb:function(a,c){return!this.equalityComparer||!this.equalityComparer(a,c)},extend:function(b){var c=this;b&&a.a.D(b,function(b,e){var f=a.ya[b];"function"==typeof f&&(c=f(c,e)||c)});return c}};a.G(D,"subscribe",D.X);a.G(D,"extend",D.extend);a.G(D,"getSubscriptionsCount",D.Sc);a.a.ka&&a.a.Xa(D,Function.prototype);a.J.fn=D;a.hc=function(a){return null!=
39
- a&&"function"==typeof a.X&&"function"==typeof a.notifySubscribers};a.b("subscribable",a.J);a.b("isSubscribable",a.hc);a.va=a.l=function(){function b(a){d.push(e);e=a}function c(){e=d.pop()}var d=[],e,f=0;return{Ub:b,end:c,oc:function(b){if(e){if(!a.hc(b))throw Error("Only subscribable things can act as dependencies");e.gb.call(e.Gc,b,b.Cc||(b.Cc=++f))}},w:function(a,d,e){try{return b(),a.apply(d,e||[])}finally{c()}},Aa:function(){if(e)return e.m.Aa()},Sa:function(){if(e)return e.Sa}}}();a.b("computedContext",
40
- a.va);a.b("computedContext.getDependenciesCount",a.va.Aa);a.b("computedContext.isInitial",a.va.Sa);a.b("ignoreDependencies",a.qd=a.l.w);var E=a.a.Yb("_latestValue");a.N=function(b){function c(){if(0<arguments.length)return c.tb(c[E],arguments[0])&&(c.ga(),c[E]=arguments[0],c.fa()),this;a.l.oc(c);return c[E]}c[E]=b;a.a.ka||a.a.extend(c,a.J.fn);a.J.fn.rb(c);a.a.Ya(c,B);a.options.deferUpdates&&a.ya.deferred(c,!0);return c};var B={equalityComparer:J,t:function(){return this[E]},fa:function(){this.notifySubscribers(this[E])},
41
- ga:function(){this.notifySubscribers(this[E],"beforeChange")}};a.a.ka&&a.a.Xa(B,a.J.fn);var H=a.N.gd="__ko_proto__";B[H]=a.N;a.Oa=function(b,c){return null===b||b===n||b[H]===n?!1:b[H]===c?!0:a.Oa(b[H],c)};a.H=function(b){return a.Oa(b,a.N)};a.Ba=function(b){return"function"==typeof b&&b[H]===a.N||"function"==typeof b&&b[H]===a.B&&b.Vc?!0:!1};a.b("observable",a.N);a.b("isObservable",a.H);a.b("isWriteableObservable",a.Ba);a.b("isWritableObservable",a.Ba);a.b("observable.fn",B);a.G(B,"peek",B.t);a.G(B,
42
- "valueHasMutated",B.fa);a.G(B,"valueWillMutate",B.ga);a.la=function(b){b=b||[];if("object"!=typeof b||!("length"in b))throw Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");b=a.N(b);a.a.Ya(b,a.la.fn);return b.extend({trackArrayChanges:!0})};a.la.fn={remove:function(b){for(var c=this.t(),d=[],e="function"!=typeof b||a.H(b)?function(a){return a===b}:b,f=0;f<c.length;f++){var g=c[f];e(g)&&(0===d.length&&this.ga(),d.push(g),c.splice(f,1),f--)}d.length&&
43
- this.fa();return d},removeAll:function(b){if(b===n){var c=this.t(),d=c.slice(0);this.ga();c.splice(0,c.length);this.fa();return d}return b?this.remove(function(c){return 0<=a.a.o(b,c)}):[]},destroy:function(b){var c=this.t(),d="function"!=typeof b||a.H(b)?function(a){return a===b}:b;this.ga();for(var e=c.length-1;0<=e;e--)d(c[e])&&(c[e]._destroy=!0);this.fa()},destroyAll:function(b){return b===n?this.destroy(function(){return!0}):b?this.destroy(function(c){return 0<=a.a.o(b,c)}):[]},indexOf:function(b){var c=
44
- this();return a.a.o(c,b)},replace:function(a,c){var d=this.indexOf(a);0<=d&&(this.ga(),this.t()[d]=c,this.fa())}};a.a.ka&&a.a.Xa(a.la.fn,a.N.fn);a.a.q("pop push reverse shift sort splice unshift".split(" "),function(b){a.la.fn[b]=function(){var a=this.t();this.ga();this.Vb(a,b,arguments);var d=a[b].apply(a,arguments);this.fa();return d===a?this:d}});a.a.q(["slice"],function(b){a.la.fn[b]=function(){var a=this();return a[b].apply(a,arguments)}});a.b("observableArray",a.la);a.ya.trackArrayChanges=function(b,
45
- c){function d(){if(!e){e=!0;var c=b.notifySubscribers;b.notifySubscribers=function(a,b){b&&b!==I||++k;return c.apply(this,arguments)};var d=[].concat(b.t()||[]);f=null;g=b.X(function(c){c=[].concat(c||[]);if(b.Pa("arrayChange")){var e;if(!f||1<k)f=a.a.ib(d,c,b.hb);e=f}d=c;f=null;k=0;e&&e.length&&b.notifySubscribers(e,"arrayChange")})}}b.hb={};c&&"object"==typeof c&&a.a.extend(b.hb,c);b.hb.sparse=!0;if(!b.Vb){var e=!1,f=null,g,k=0,l=b.sa,m=b.Ia;b.sa=function(a){l&&l.call(b,a);"arrayChange"===a&&d()};
46
- b.Ia=function(a){m&&m.call(b,a);"arrayChange"!==a||b.Pa("arrayChange")||(g.k(),e=!1)};b.Vb=function(b,c,d){function m(a,b,c){return l[l.length]={status:a,value:b,index:c}}if(e&&!k){var l=[],g=b.length,t=d.length,G=0;switch(c){case "push":G=g;case "unshift":for(c=0;c<t;c++)m("added",d[c],G+c);break;case "pop":G=g-1;case "shift":g&&m("deleted",b[G],G);break;case "splice":c=Math.min(Math.max(0,0>d[0]?g+d[0]:d[0]),g);for(var g=1===t?g:Math.min(c+(d[1]||0),g),t=c+t-2,G=Math.max(g,t),P=[],n=[],Q=2;c<G;++c,
47
- ++Q)c<g&&n.push(m("deleted",b[c],c)),c<t&&P.push(m("added",d[Q],c));a.a.dc(n,P);break;default:return}f=l}}}};var s=a.a.Yb("_state");a.m=a.B=function(b,c,d){function e(){if(0<arguments.length){if("function"===typeof f)f.apply(g.pb,arguments);else throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");return this}a.l.oc(e);(g.S||g.s&&e.Qa())&&e.aa();return g.T}"object"===typeof b?d=b:(d=d||{},b&&(d.read=
48
- b));if("function"!=typeof d.read)throw Error("Pass a function that returns the value of the ko.computed");var f=d.write,g={T:n,S:!0,Ra:!1,Fb:!1,R:!1,Va:!1,s:!1,jd:d.read,pb:c||d.owner,i:d.disposeWhenNodeIsRemoved||d.i||null,wa:d.disposeWhen||d.wa,mb:null,r:{},L:0,bc:null};e[s]=g;e.Vc="function"===typeof f;a.a.ka||a.a.extend(e,a.J.fn);a.J.fn.rb(e);a.a.Ya(e,z);d.pure?(g.Va=!0,g.s=!0,a.a.extend(e,$)):d.deferEvaluation&&a.a.extend(e,aa);a.options.deferUpdates&&a.ya.deferred(e,!0);g.i&&(g.Fb=!0,g.i.nodeType||
49
- (g.i=null));g.s||d.deferEvaluation||e.aa();g.i&&e.ba()&&a.a.F.oa(g.i,g.mb=function(){e.k()});return e};var z={equalityComparer:J,Aa:function(){return this[s].L},Pb:function(a,c,d){if(this[s].Va&&c===this)throw Error("A 'pure' computed must not be called recursively");this[s].r[a]=d;d.Ga=this[s].L++;d.na=c.Na()},Qa:function(){var a,c,d=this[s].r;for(a in d)if(d.hasOwnProperty(a)&&(c=d[a],c.ia.Uc(c.na)))return!0},bd:function(){this.Fa&&!this[s].Ra&&this.Fa()},ba:function(){return this[s].S||0<this[s].L},
50
- ld:function(){this.Mb||this.ac()},uc:function(a){if(a.cb&&!this[s].i){var c=a.X(this.bd,this,"dirty"),d=a.X(this.ld,this);return{ia:a,k:function(){c.k();d.k()}}}return a.X(this.ac,this)},ac:function(){var b=this,c=b.throttleEvaluation;c&&0<=c?(clearTimeout(this[s].bc),this[s].bc=a.a.setTimeout(function(){b.aa(!0)},c)):b.Fa?b.Fa():b.aa(!0)},aa:function(b){var c=this[s],d=c.wa;if(!c.Ra&&!c.R){if(c.i&&!a.a.nb(c.i)||d&&d()){if(!c.Fb){this.k();return}}else c.Fb=!1;c.Ra=!0;try{this.Qc(b)}finally{c.Ra=!1}c.L||
51
- this.k()}},Qc:function(b){var c=this[s],d=c.Va?n:!c.L,e={Hc:this,Ma:c.r,lb:c.L};a.l.Ub({Gc:e,gb:Y,m:this,Sa:d});c.r={};c.L=0;e=this.Pc(c,e);this.tb(c.T,e)&&(c.s||this.notifySubscribers(c.T,"beforeChange"),c.T=e,c.s?this.zc():b&&this.notifySubscribers(c.T));d&&this.notifySubscribers(c.T,"awake")},Pc:function(b,c){try{var d=b.jd;return b.pb?d.call(b.pb):d()}finally{a.l.end(),c.lb&&!b.s&&a.a.D(c.Ma,X),b.S=!1}},t:function(){var a=this[s];(a.S&&!a.L||a.s&&this.Qa())&&this.aa();return a.T},Ta:function(b){a.J.fn.Ta.call(this,
52
- b);this.Fa=function(){this.Kb(this[s].T);this[s].S=!0;this.Lb(this)}},k:function(){var b=this[s];!b.s&&b.r&&a.a.D(b.r,function(a,b){b.k&&b.k()});b.i&&b.mb&&a.a.F.pc(b.i,b.mb);b.r=null;b.L=0;b.R=!0;b.S=!1;b.s=!1;b.i=null}},$={sa:function(b){var c=this,d=c[s];if(!d.R&&d.s&&"change"==b){d.s=!1;if(d.S||c.Qa())d.r=null,d.L=0,d.S=!0,c.aa();else{var e=[];a.a.D(d.r,function(a,b){e[b.Ga]=a});a.a.q(e,function(a,b){var e=d.r[a],l=c.uc(e.ia);l.Ga=b;l.na=e.na;d.r[a]=l})}d.R||c.notifySubscribers(d.T,"awake")}},
53
- Ia:function(b){var c=this[s];c.R||"change"!=b||this.Pa("change")||(a.a.D(c.r,function(a,b){b.k&&(c.r[a]={ia:b.ia,Ga:b.Ga,na:b.na},b.k())}),c.s=!0,this.notifySubscribers(n,"asleep"))},Na:function(){var b=this[s];b.s&&(b.S||this.Qa())&&this.aa();return a.J.fn.Na.call(this)}},aa={sa:function(a){"change"!=a&&"beforeChange"!=a||this.t()}};a.a.ka&&a.a.Xa(z,a.J.fn);var R=a.N.gd;a.m[R]=a.N;z[R]=a.m;a.Xc=function(b){return a.Oa(b,a.m)};a.Yc=function(b){return a.Oa(b,a.m)&&b[s]&&b[s].Va};a.b("computed",a.m);
54
- a.b("dependentObservable",a.m);a.b("isComputed",a.Xc);a.b("isPureComputed",a.Yc);a.b("computed.fn",z);a.G(z,"peek",z.t);a.G(z,"dispose",z.k);a.G(z,"isActive",z.ba);a.G(z,"getDependenciesCount",z.Aa);a.nc=function(b,c){if("function"===typeof b)return a.m(b,c,{pure:!0});b=a.a.extend({},b);b.pure=!0;return a.m(b,c)};a.b("pureComputed",a.nc);(function(){function b(a,f,g){g=g||new d;a=f(a);if("object"!=typeof a||null===a||a===n||a instanceof RegExp||a instanceof Date||a instanceof String||a instanceof
55
- Number||a instanceof Boolean)return a;var k=a instanceof Array?[]:{};g.save(a,k);c(a,function(c){var d=f(a[c]);switch(typeof d){case "boolean":case "number":case "string":case "function":k[c]=d;break;case "object":case "undefined":var h=g.get(d);k[c]=h!==n?h:b(d,f,g)}});return k}function c(a,b){if(a instanceof Array){for(var c=0;c<a.length;c++)b(c);"function"==typeof a.toJSON&&b("toJSON")}else for(c in a)b(c)}function d(){this.keys=[];this.Ib=[]}a.wc=function(c){if(0==arguments.length)throw Error("When calling ko.toJS, pass the object you want to convert.");
56
- return b(c,function(b){for(var c=0;a.H(b)&&10>c;c++)b=b();return b})};a.toJSON=function(b,c,d){b=a.wc(b);return a.a.Eb(b,c,d)};d.prototype={save:function(b,c){var d=a.a.o(this.keys,b);0<=d?this.Ib[d]=c:(this.keys.push(b),this.Ib.push(c))},get:function(b){b=a.a.o(this.keys,b);return 0<=b?this.Ib[b]:n}}})();a.b("toJS",a.wc);a.b("toJSON",a.toJSON);(function(){a.j={u:function(b){switch(a.a.A(b)){case "option":return!0===b.__ko__hasDomDataOptionValue__?a.a.e.get(b,a.d.options.xb):7>=a.a.C?b.getAttributeNode("value")&&
57
- b.getAttributeNode("value").specified?b.value:b.text:b.value;case "select":return 0<=b.selectedIndex?a.j.u(b.options[b.selectedIndex]):n;default:return b.value}},ha:function(b,c,d){switch(a.a.A(b)){case "option":switch(typeof c){case "string":a.a.e.set(b,a.d.options.xb,n);"__ko__hasDomDataOptionValue__"in b&&delete b.__ko__hasDomDataOptionValue__;b.value=c;break;default:a.a.e.set(b,a.d.options.xb,c),b.__ko__hasDomDataOptionValue__=!0,b.value="number"===typeof c?c:""}break;case "select":if(""===c||
58
- null===c)c=n;for(var e=-1,f=0,g=b.options.length,k;f<g;++f)if(k=a.j.u(b.options[f]),k==c||""==k&&c===n){e=f;break}if(d||0<=e||c===n&&1<b.size)b.selectedIndex=e;break;default:if(null===c||c===n)c="";b.value=c}}}})();a.b("selectExtensions",a.j);a.b("selectExtensions.readValue",a.j.u);a.b("selectExtensions.writeValue",a.j.ha);a.h=function(){function b(b){b=a.a.$a(b);123===b.charCodeAt(0)&&(b=b.slice(1,-1));var c=[],d=b.match(e),r,k=[],p=0;if(d){d.push(",");for(var A=0,y;y=d[A];++A){var t=y.charCodeAt(0);
59
- if(44===t){if(0>=p){c.push(r&&k.length?{key:r,value:k.join("")}:{unknown:r||k.join("")});r=p=0;k=[];continue}}else if(58===t){if(!p&&!r&&1===k.length){r=k.pop();continue}}else 47===t&&A&&1<y.length?(t=d[A-1].match(f))&&!g[t[0]]&&(b=b.substr(b.indexOf(y)+1),d=b.match(e),d.push(","),A=-1,y="/"):40===t||123===t||91===t?++p:41===t||125===t||93===t?--p:r||k.length||34!==t&&39!==t||(y=y.slice(1,-1));k.push(y)}}return c}var c=["true","false","null","undefined"],d=/^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i,
60
- e=RegExp("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|/(?:[^/\\\\]|\\\\.)*/w*|[^\\s:,/][^,\"'{}()/:[\\]]*[^\\s,\"'{}()/:[\\]]|[^\\s]","g"),f=/[\])"'A-Za-z0-9_$]+$/,g={"in":1,"return":1,"typeof":1},k={};return{ta:[],ea:k,yb:b,Ua:function(e,m){function h(b,e){var m;if(!A){var l=a.getBindingHandler(b);if(l&&l.preprocess&&!(e=l.preprocess(e,b,h)))return;if(l=k[b])m=e,0<=a.a.o(c,m)?m=!1:(l=m.match(d),m=null===l?!1:l[1]?"Object("+l[1]+")"+l[2]:m),l=m;l&&g.push("'"+b+"':function(_z){"+m+"=_z}")}p&&(e=
61
- "function(){return "+e+" }");f.push("'"+b+"':"+e)}m=m||{};var f=[],g=[],p=m.valueAccessors,A=m.bindingParams,y="string"===typeof e?b(e):e;a.a.q(y,function(a){h(a.key||a.unknown,a.value)});g.length&&h("_ko_property_writers","{"+g.join(",")+" }");return f.join(",")},ad:function(a,b){for(var c=0;c<a.length;c++)if(a[c].key==b)return!0;return!1},Ea:function(b,c,d,e,f){if(b&&a.H(b))!a.Ba(b)||f&&b.t()===e||b(e);else if((b=c.get("_ko_property_writers"))&&b[d])b[d](e)}}}();a.b("expressionRewriting",a.h);a.b("expressionRewriting.bindingRewriteValidators",
62
- a.h.ta);a.b("expressionRewriting.parseObjectLiteral",a.h.yb);a.b("expressionRewriting.preProcessBindings",a.h.Ua);a.b("expressionRewriting._twoWayBindings",a.h.ea);a.b("jsonExpressionRewriting",a.h);a.b("jsonExpressionRewriting.insertPropertyAccessorsIntoJson",a.h.Ua);(function(){function b(a){return 8==a.nodeType&&g.test(f?a.text:a.nodeValue)}function c(a){return 8==a.nodeType&&k.test(f?a.text:a.nodeValue)}function d(a,d){for(var e=a,f=1,l=[];e=e.nextSibling;){if(c(e)&&(f--,0===f))return l;l.push(e);
63
- b(e)&&f++}if(!d)throw Error("Cannot find closing comment tag to match: "+a.nodeValue);return null}function e(a,b){var c=d(a,b);return c?0<c.length?c[c.length-1].nextSibling:a.nextSibling:null}var f=u&&"\x3c!--test--\x3e"===u.createComment("test").text,g=f?/^\x3c!--\s*ko(?:\s+([\s\S]+))?\s*--\x3e$/:/^\s*ko(?:\s+([\s\S]+))?\s*$/,k=f?/^\x3c!--\s*\/ko\s*--\x3e$/:/^\s*\/ko\s*$/,l={ul:!0,ol:!0};a.f={Z:{},childNodes:function(a){return b(a)?d(a):a.childNodes},xa:function(c){if(b(c)){c=a.f.childNodes(c);for(var d=
64
- 0,e=c.length;d<e;d++)a.removeNode(c[d])}else a.a.ob(c)},da:function(c,d){if(b(c)){a.f.xa(c);for(var e=c.nextSibling,f=0,l=d.length;f<l;f++)e.parentNode.insertBefore(d[f],e)}else a.a.da(c,d)},mc:function(a,c){b(a)?a.parentNode.insertBefore(c,a.nextSibling):a.firstChild?a.insertBefore(c,a.firstChild):a.appendChild(c)},gc:function(c,d,e){e?b(c)?c.parentNode.insertBefore(d,e.nextSibling):e.nextSibling?c.insertBefore(d,e.nextSibling):c.appendChild(d):a.f.mc(c,d)},firstChild:function(a){return b(a)?!a.nextSibling||
65
- c(a.nextSibling)?null:a.nextSibling:a.firstChild},nextSibling:function(a){b(a)&&(a=e(a));return a.nextSibling&&c(a.nextSibling)?null:a.nextSibling},Tc:b,pd:function(a){return(a=(f?a.text:a.nodeValue).match(g))?a[1]:null},kc:function(d){if(l[a.a.A(d)]){var h=d.firstChild;if(h){do if(1===h.nodeType){var f;f=h.firstChild;var g=null;if(f){do if(g)g.push(f);else if(b(f)){var k=e(f,!0);k?f=k:g=[f]}else c(f)&&(g=[f]);while(f=f.nextSibling)}if(f=g)for(g=h.nextSibling,k=0;k<f.length;k++)g?d.insertBefore(f[k],
66
- g):d.appendChild(f[k])}while(h=h.nextSibling)}}}}})();a.b("virtualElements",a.f);a.b("virtualElements.allowedBindings",a.f.Z);a.b("virtualElements.emptyNode",a.f.xa);a.b("virtualElements.insertAfter",a.f.gc);a.b("virtualElements.prepend",a.f.mc);a.b("virtualElements.setDomNodeChildren",a.f.da);(function(){a.Q=function(){this.Fc={}};a.a.extend(a.Q.prototype,{nodeHasBindings:function(b){switch(b.nodeType){case 1:return null!=b.getAttribute("data-bind")||a.g.getComponentNameForNode(b);case 8:return a.f.Tc(b);
67
- default:return!1}},getBindings:function(b,c){var d=this.getBindingsString(b,c),d=d?this.parseBindingsString(d,c,b):null;return a.g.Ob(d,b,c,!1)},getBindingAccessors:function(b,c){var d=this.getBindingsString(b,c),d=d?this.parseBindingsString(d,c,b,{valueAccessors:!0}):null;return a.g.Ob(d,b,c,!0)},getBindingsString:function(b){switch(b.nodeType){case 1:return b.getAttribute("data-bind");case 8:return a.f.pd(b);default:return null}},parseBindingsString:function(b,c,d,e){try{var f=this.Fc,g=b+(e&&e.valueAccessors||
68
- ""),k;if(!(k=f[g])){var l,m="with($context){with($data||{}){return{"+a.h.Ua(b,e)+"}}}";l=new Function("$context","$element",m);k=f[g]=l}return k(c,d)}catch(h){throw h.message="Unable to parse bindings.\nBindings value: "+b+"\nMessage: "+h.message,h;}}});a.Q.instance=new a.Q})();a.b("bindingProvider",a.Q);(function(){function b(a){return function(){return a}}function c(a){return a()}function d(b){return a.a.Ca(a.l.w(b),function(a,c){return function(){return b()[c]}})}function e(c,e,h){return"function"===
69
- typeof c?d(c.bind(null,e,h)):a.a.Ca(c,b)}function f(a,b){return d(this.getBindings.bind(this,a,b))}function g(b,c,d){var e,h=a.f.firstChild(c),f=a.Q.instance,m=f.preprocessNode;if(m){for(;e=h;)h=a.f.nextSibling(e),m.call(f,e);h=a.f.firstChild(c)}for(;e=h;)h=a.f.nextSibling(e),k(b,e,d)}function k(b,c,d){var e=!0,h=1===c.nodeType;h&&a.f.kc(c);if(h&&d||a.Q.instance.nodeHasBindings(c))e=m(c,null,b,d).shouldBindDescendants;e&&!r[a.a.A(c)]&&g(b,c,!h)}function l(b){var c=[],d={},e=[];a.a.D(b,function Z(h){if(!d[h]){var f=
70
- a.getBindingHandler(h);f&&(f.after&&(e.push(h),a.a.q(f.after,function(c){if(b[c]){if(-1!==a.a.o(e,c))throw Error("Cannot combine the following bindings, because they have a cyclic dependency: "+e.join(", "));Z(c)}}),e.length--),c.push({key:h,fc:f}));d[h]=!0}});return c}function m(b,d,e,h){var m=a.a.e.get(b,q);if(!d){if(m)throw Error("You cannot apply bindings multiple times to the same element.");a.a.e.set(b,q,!0)}!m&&h&&a.tc(b,e);var g;if(d&&"function"!==typeof d)g=d;else{var k=a.Q.instance,r=k.getBindingAccessors||
71
- f,p=a.B(function(){(g=d?d(e,b):r.call(k,b,e))&&e.P&&e.P();return g},null,{i:b});g&&p.ba()||(p=null)}var u;if(g){var v=p?function(a){return function(){return c(p()[a])}}:function(a){return g[a]},s=function(){return a.a.Ca(p?p():g,c)};s.get=function(a){return g[a]&&c(v(a))};s.has=function(a){return a in g};h=l(g);a.a.q(h,function(c){var d=c.fc.init,h=c.fc.update,f=c.key;if(8===b.nodeType&&!a.f.Z[f])throw Error("The binding '"+f+"' cannot be used with virtual elements");try{"function"==typeof d&&a.l.w(function(){var a=
72
- d(b,v(f),s,e.$data,e);if(a&&a.controlsDescendantBindings){if(u!==n)throw Error("Multiple bindings ("+u+" and "+f+") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.");u=f}}),"function"==typeof h&&a.B(function(){h(b,v(f),s,e.$data,e)},null,{i:b})}catch(m){throw m.message='Unable to process binding "'+f+": "+g[f]+'"\nMessage: '+m.message,m;}})}return{shouldBindDescendants:u===n}}function h(b){return b&&b instanceof a.U?b:new a.U(b)}
73
- a.d={};var r={script:!0,textarea:!0,template:!0};a.getBindingHandler=function(b){return a.d[b]};a.U=function(b,c,d,e){var h=this,f="function"==typeof b&&!a.H(b),m,g=a.B(function(){var m=f?b():b,l=a.a.c(m);c?(c.P&&c.P(),a.a.extend(h,c),g&&(h.P=g)):(h.$parents=[],h.$root=l,h.ko=a);h.$rawData=m;h.$data=l;d&&(h[d]=l);e&&e(h,c,l);return h.$data},null,{wa:function(){return m&&!a.a.Qb(m)},i:!0});g.ba()&&(h.P=g,g.equalityComparer=null,m=[],g.Ac=function(b){m.push(b);a.a.F.oa(b,function(b){a.a.La(m,b);m.length||
74
- (g.k(),h.P=g=n)})})};a.U.prototype.createChildContext=function(b,c,d){return new a.U(b,this,c,function(a,b){a.$parentContext=b;a.$parent=b.$data;a.$parents=(b.$parents||[]).slice(0);a.$parents.unshift(a.$parent);d&&d(a)})};a.U.prototype.extend=function(b){return new a.U(this.P||this.$data,this,null,function(c,d){c.$rawData=d.$rawData;a.a.extend(c,"function"==typeof b?b():b)})};var q=a.a.e.I(),p=a.a.e.I();a.tc=function(b,c){if(2==arguments.length)a.a.e.set(b,p,c),c.P&&c.P.Ac(b);else return a.a.e.get(b,
75
- p)};a.Ja=function(b,c,d){1===b.nodeType&&a.f.kc(b);return m(b,c,h(d),!0)};a.Dc=function(b,c,d){d=h(d);return a.Ja(b,e(c,d,b),d)};a.eb=function(a,b){1!==b.nodeType&&8!==b.nodeType||g(h(a),b,!0)};a.Rb=function(a,b){!v&&x.jQuery&&(v=x.jQuery);if(b&&1!==b.nodeType&&8!==b.nodeType)throw Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node");b=b||x.document.body;k(h(a),b,!0)};a.kb=function(b){switch(b.nodeType){case 1:case 8:var c=a.tc(b);if(c)return c;
76
- if(b.parentNode)return a.kb(b.parentNode)}return n};a.Jc=function(b){return(b=a.kb(b))?b.$data:n};a.b("bindingHandlers",a.d);a.b("applyBindings",a.Rb);a.b("applyBindingsToDescendants",a.eb);a.b("applyBindingAccessorsToNode",a.Ja);a.b("applyBindingsToNode",a.Dc);a.b("contextFor",a.kb);a.b("dataFor",a.Jc)})();(function(b){function c(c,e){var m=f.hasOwnProperty(c)?f[c]:b,h;m?m.X(e):(m=f[c]=new a.J,m.X(e),d(c,function(b,d){var e=!(!d||!d.synchronous);g[c]={definition:b,Zc:e};delete f[c];h||e?m.notifySubscribers(b):
77
- a.Y.Wa(function(){m.notifySubscribers(b)})}),h=!0)}function d(a,b){e("getConfig",[a],function(c){c?e("loadComponent",[a,c],function(a){b(a,c)}):b(null,null)})}function e(c,d,f,h){h||(h=a.g.loaders.slice(0));var g=h.shift();if(g){var q=g[c];if(q){var p=!1;if(q.apply(g,d.concat(function(a){p?f(null):null!==a?f(a):e(c,d,f,h)}))!==b&&(p=!0,!g.suppressLoaderExceptions))throw Error("Component loaders must supply values by invoking the callback, not by returning values synchronously.");}else e(c,d,f,h)}else f(null)}
78
- var f={},g={};a.g={get:function(d,e){var f=g.hasOwnProperty(d)?g[d]:b;f?f.Zc?a.l.w(function(){e(f.definition)}):a.Y.Wa(function(){e(f.definition)}):c(d,e)},Xb:function(a){delete g[a]},Jb:e};a.g.loaders=[];a.b("components",a.g);a.b("components.get",a.g.get);a.b("components.clearCachedDefinition",a.g.Xb)})();(function(){function b(b,c,d,e){function g(){0===--y&&e(k)}var k={},y=2,t=d.template;d=d.viewModel;t?f(c,t,function(c){a.g.Jb("loadTemplate",[b,c],function(a){k.template=a;g()})}):g();d?f(c,d,function(c){a.g.Jb("loadViewModel",
79
- [b,c],function(a){k[l]=a;g()})}):g()}function c(a,b,d){if("function"===typeof b)d(function(a){return new b(a)});else if("function"===typeof b[l])d(b[l]);else if("instance"in b){var e=b.instance;d(function(){return e})}else"viewModel"in b?c(a,b.viewModel,d):a("Unknown viewModel value: "+b)}function d(b){switch(a.a.A(b)){case "script":return a.a.ma(b.text);case "textarea":return a.a.ma(b.value);case "template":if(e(b.content))return a.a.ua(b.content.childNodes)}return a.a.ua(b.childNodes)}function e(a){return x.DocumentFragment?
80
- a instanceof DocumentFragment:a&&11===a.nodeType}function f(a,b,c){"string"===typeof b.require?O||x.require?(O||x.require)([b.require],c):a("Uses require, but no AMD loader is present"):c(b)}function g(a){return function(b){throw Error("Component '"+a+"': "+b);}}var k={};a.g.register=function(b,c){if(!c)throw Error("Invalid configuration for "+b);if(a.g.ub(b))throw Error("Component "+b+" is already registered");k[b]=c};a.g.ub=function(a){return k.hasOwnProperty(a)};a.g.od=function(b){delete k[b];
81
- a.g.Xb(b)};a.g.Zb={getConfig:function(a,b){b(k.hasOwnProperty(a)?k[a]:null)},loadComponent:function(a,c,d){var e=g(a);f(e,c,function(c){b(a,e,c,d)})},loadTemplate:function(b,c,f){b=g(b);if("string"===typeof c)f(a.a.ma(c));else if(c instanceof Array)f(c);else if(e(c))f(a.a.V(c.childNodes));else if(c.element)if(c=c.element,x.HTMLElement?c instanceof HTMLElement:c&&c.tagName&&1===c.nodeType)f(d(c));else if("string"===typeof c){var l=u.getElementById(c);l?f(d(l)):b("Cannot find element with ID "+c)}else b("Unknown element type: "+
82
- c);else b("Unknown template value: "+c)},loadViewModel:function(a,b,d){c(g(a),b,d)}};var l="createViewModel";a.b("components.register",a.g.register);a.b("components.isRegistered",a.g.ub);a.b("components.unregister",a.g.od);a.b("components.defaultLoader",a.g.Zb);a.g.loaders.push(a.g.Zb);a.g.Bc=k})();(function(){function b(b,e){var f=b.getAttribute("params");if(f){var f=c.parseBindingsString(f,e,b,{valueAccessors:!0,bindingParams:!0}),f=a.a.Ca(f,function(c){return a.m(c,null,{i:b})}),g=a.a.Ca(f,function(c){var e=
83
- c.t();return c.ba()?a.m({read:function(){return a.a.c(c())},write:a.Ba(e)&&function(a){c()(a)},i:b}):e});g.hasOwnProperty("$raw")||(g.$raw=f);return g}return{$raw:{}}}a.g.getComponentNameForNode=function(b){var c=a.a.A(b);if(a.g.ub(c)&&(-1!=c.indexOf("-")||"[object HTMLUnknownElement]"==""+b||8>=a.a.C&&b.tagName===c))return c};a.g.Ob=function(c,e,f,g){if(1===e.nodeType){var k=a.g.getComponentNameForNode(e);if(k){c=c||{};if(c.component)throw Error('Cannot use the "component" binding on a custom element matching a component');
84
- var l={name:k,params:b(e,f)};c.component=g?function(){return l}:l}}return c};var c=new a.Q;9>a.a.C&&(a.g.register=function(a){return function(b){u.createElement(b);return a.apply(this,arguments)}}(a.g.register),u.createDocumentFragment=function(b){return function(){var c=b(),f=a.g.Bc,g;for(g in f)f.hasOwnProperty(g)&&c.createElement(g);return c}}(u.createDocumentFragment))})();(function(b){function c(b,c,d){c=c.template;if(!c)throw Error("Component '"+b+"' has no template");b=a.a.ua(c);a.f.da(d,b)}
85
- function d(a,b,c,d){var e=a.createViewModel;return e?e.call(a,d,{element:b,templateNodes:c}):d}var e=0;a.d.component={init:function(f,g,k,l,m){function h(){var a=r&&r.dispose;"function"===typeof a&&a.call(r);q=r=null}var r,q,p=a.a.V(a.f.childNodes(f));a.a.F.oa(f,h);a.m(function(){var l=a.a.c(g()),k,t;"string"===typeof l?k=l:(k=a.a.c(l.name),t=a.a.c(l.params));if(!k)throw Error("No component name specified");var n=q=++e;a.g.get(k,function(e){if(q===n){h();if(!e)throw Error("Unknown component '"+k+
86
- "'");c(k,e,f);var g=d(e,f,p,t);e=m.createChildContext(g,b,function(a){a.$component=g;a.$componentTemplateNodes=p});r=g;a.eb(e,f)}})},null,{i:f});return{controlsDescendantBindings:!0}}};a.f.Z.component=!0})();var S={"class":"className","for":"htmlFor"};a.d.attr={update:function(b,c){var d=a.a.c(c())||{};a.a.D(d,function(c,d){d=a.a.c(d);var g=!1===d||null===d||d===n;g&&b.removeAttribute(c);8>=a.a.C&&c in S?(c=S[c],g?b.removeAttribute(c):b[c]=d):g||b.setAttribute(c,d.toString());"name"===c&&a.a.rc(b,
87
- g?"":d.toString())})}};(function(){a.d.checked={after:["value","attr"],init:function(b,c,d){function e(){var e=b.checked,f=p?g():e;if(!a.va.Sa()&&(!l||e)){var m=a.l.w(c);if(h){var k=r?m.t():m;q!==f?(e&&(a.a.pa(k,f,!0),a.a.pa(k,q,!1)),q=f):a.a.pa(k,f,e);r&&a.Ba(m)&&m(k)}else a.h.Ea(m,d,"checked",f,!0)}}function f(){var d=a.a.c(c());b.checked=h?0<=a.a.o(d,g()):k?d:g()===d}var g=a.nc(function(){return d.has("checkedValue")?a.a.c(d.get("checkedValue")):d.has("value")?a.a.c(d.get("value")):b.value}),k=
88
- "checkbox"==b.type,l="radio"==b.type;if(k||l){var m=c(),h=k&&a.a.c(m)instanceof Array,r=!(h&&m.push&&m.splice),q=h?g():n,p=l||h;l&&!b.name&&a.d.uniqueName.init(b,function(){return!0});a.m(e,null,{i:b});a.a.p(b,"click",e);a.m(f,null,{i:b});m=n}}};a.h.ea.checked=!0;a.d.checkedValue={update:function(b,c){b.value=a.a.c(c())}}})();a.d.css={update:function(b,c){var d=a.a.c(c());null!==d&&"object"==typeof d?a.a.D(d,function(c,d){d=a.a.c(d);a.a.bb(b,c,d)}):(d=a.a.$a(String(d||"")),a.a.bb(b,b.__ko__cssValue,
89
- !1),b.__ko__cssValue=d,a.a.bb(b,d,!0))}};a.d.enable={update:function(b,c){var d=a.a.c(c());d&&b.disabled?b.removeAttribute("disabled"):d||b.disabled||(b.disabled=!0)}};a.d.disable={update:function(b,c){a.d.enable.update(b,function(){return!a.a.c(c())})}};a.d.event={init:function(b,c,d,e,f){var g=c()||{};a.a.D(g,function(g){"string"==typeof g&&a.a.p(b,g,function(b){var m,h=c()[g];if(h){try{var r=a.a.V(arguments);e=f.$data;r.unshift(e);m=h.apply(e,r)}finally{!0!==m&&(b.preventDefault?b.preventDefault():
90
- b.returnValue=!1)}!1===d.get(g+"Bubble")&&(b.cancelBubble=!0,b.stopPropagation&&b.stopPropagation())}})})}};a.d.foreach={ic:function(b){return function(){var c=b(),d=a.a.zb(c);if(!d||"number"==typeof d.length)return{foreach:c,templateEngine:a.W.sb};a.a.c(c);return{foreach:d.data,as:d.as,includeDestroyed:d.includeDestroyed,afterAdd:d.afterAdd,beforeRemove:d.beforeRemove,afterRender:d.afterRender,beforeMove:d.beforeMove,afterMove:d.afterMove,templateEngine:a.W.sb}}},init:function(b,c){return a.d.template.init(b,
91
- a.d.foreach.ic(c))},update:function(b,c,d,e,f){return a.d.template.update(b,a.d.foreach.ic(c),d,e,f)}};a.h.ta.foreach=!1;a.f.Z.foreach=!0;a.d.hasfocus={init:function(b,c,d){function e(e){b.__ko_hasfocusUpdating=!0;var f=b.ownerDocument;if("activeElement"in f){var g;try{g=f.activeElement}catch(h){g=f.body}e=g===b}f=c();a.h.Ea(f,d,"hasfocus",e,!0);b.__ko_hasfocusLastValue=e;b.__ko_hasfocusUpdating=!1}var f=e.bind(null,!0),g=e.bind(null,!1);a.a.p(b,"focus",f);a.a.p(b,"focusin",f);a.a.p(b,"blur",g);a.a.p(b,
92
- "focusout",g)},update:function(b,c){var d=!!a.a.c(c());b.__ko_hasfocusUpdating||b.__ko_hasfocusLastValue===d||(d?b.focus():b.blur(),!d&&b.__ko_hasfocusLastValue&&b.ownerDocument.body.focus(),a.l.w(a.a.Da,null,[b,d?"focusin":"focusout"]))}};a.h.ea.hasfocus=!0;a.d.hasFocus=a.d.hasfocus;a.h.ea.hasFocus=!0;a.d.html={init:function(){return{controlsDescendantBindings:!0}},update:function(b,c){a.a.Cb(b,c())}};K("if");K("ifnot",!1,!0);K("with",!0,!1,function(a,c){return a.createChildContext(c)});var L={};
93
- a.d.options={init:function(b){if("select"!==a.a.A(b))throw Error("options binding applies only to SELECT elements");for(;0<b.length;)b.remove(0);return{controlsDescendantBindings:!0}},update:function(b,c,d){function e(){return a.a.Ka(b.options,function(a){return a.selected})}function f(a,b,c){var d=typeof b;return"function"==d?b(a):"string"==d?a[b]:c}function g(c,e){if(A&&h)a.j.ha(b,a.a.c(d.get("value")),!0);else if(p.length){var f=0<=a.a.o(p,a.j.u(e[0]));a.a.sc(e[0],f);A&&!f&&a.l.w(a.a.Da,null,[b,
94
- "change"])}}var k=b.multiple,l=0!=b.length&&k?b.scrollTop:null,m=a.a.c(c()),h=d.get("valueAllowUnset")&&d.has("value"),r=d.get("optionsIncludeDestroyed");c={};var q,p=[];h||(k?p=a.a.fb(e(),a.j.u):0<=b.selectedIndex&&p.push(a.j.u(b.options[b.selectedIndex])));m&&("undefined"==typeof m.length&&(m=[m]),q=a.a.Ka(m,function(b){return r||b===n||null===b||!a.a.c(b._destroy)}),d.has("optionsCaption")&&(m=a.a.c(d.get("optionsCaption")),null!==m&&m!==n&&q.unshift(L)));var A=!1;c.beforeRemove=function(a){b.removeChild(a)};
95
- m=g;d.has("optionsAfterRender")&&"function"==typeof d.get("optionsAfterRender")&&(m=function(b,c){g(0,c);a.l.w(d.get("optionsAfterRender"),null,[c[0],b!==L?b:n])});a.a.Bb(b,q,function(c,e,g){g.length&&(p=!h&&g[0].selected?[a.j.u(g[0])]:[],A=!0);e=b.ownerDocument.createElement("option");c===L?(a.a.Za(e,d.get("optionsCaption")),a.j.ha(e,n)):(g=f(c,d.get("optionsValue"),c),a.j.ha(e,a.a.c(g)),c=f(c,d.get("optionsText"),g),a.a.Za(e,c));return[e]},c,m);a.l.w(function(){h?a.j.ha(b,a.a.c(d.get("value")),
96
- !0):(k?p.length&&e().length<p.length:p.length&&0<=b.selectedIndex?a.j.u(b.options[b.selectedIndex])!==p[0]:p.length||0<=b.selectedIndex)&&a.a.Da(b,"change")});a.a.Nc(b);l&&20<Math.abs(l-b.scrollTop)&&(b.scrollTop=l)}};a.d.options.xb=a.a.e.I();a.d.selectedOptions={after:["options","foreach"],init:function(b,c,d){a.a.p(b,"change",function(){var e=c(),f=[];a.a.q(b.getElementsByTagName("option"),function(b){b.selected&&f.push(a.j.u(b))});a.h.Ea(e,d,"selectedOptions",f)})},update:function(b,c){if("select"!=
97
- a.a.A(b))throw Error("values binding applies only to SELECT elements");var d=a.a.c(c()),e=b.scrollTop;d&&"number"==typeof d.length&&a.a.q(b.getElementsByTagName("option"),function(b){var c=0<=a.a.o(d,a.j.u(b));b.selected!=c&&a.a.sc(b,c)});b.scrollTop=e}};a.h.ea.selectedOptions=!0;a.d.style={update:function(b,c){var d=a.a.c(c()||{});a.a.D(d,function(c,d){d=a.a.c(d);if(null===d||d===n||!1===d)d="";b.style[c]=d})}};a.d.submit={init:function(b,c,d,e,f){if("function"!=typeof c())throw Error("The value for a submit binding must be a function");
98
- a.a.p(b,"submit",function(a){var d,e=c();try{d=e.call(f.$data,b)}finally{!0!==d&&(a.preventDefault?a.preventDefault():a.returnValue=!1)}})}};a.d.text={init:function(){return{controlsDescendantBindings:!0}},update:function(b,c){a.a.Za(b,c())}};a.f.Z.text=!0;(function(){if(x&&x.navigator)var b=function(a){if(a)return parseFloat(a[1])},c=x.opera&&x.opera.version&&parseInt(x.opera.version()),d=x.navigator.userAgent,e=b(d.match(/^(?:(?!chrome).)*version\/([^ ]*) safari/i)),f=b(d.match(/Firefox\/([^ ]*)/));
99
- if(10>a.a.C)var g=a.a.e.I(),k=a.a.e.I(),l=function(b){var c=this.activeElement;(c=c&&a.a.e.get(c,k))&&c(b)},m=function(b,c){var d=b.ownerDocument;a.a.e.get(d,g)||(a.a.e.set(d,g,!0),a.a.p(d,"selectionchange",l));a.a.e.set(b,k,c)};a.d.textInput={init:function(b,d,g){function l(c,d){a.a.p(b,c,d)}function k(){var c=a.a.c(d());if(null===c||c===n)c="";v!==n&&c===v?a.a.setTimeout(k,4):b.value!==c&&(u=c,b.value=c)}function y(){s||(v=b.value,s=a.a.setTimeout(t,4))}function t(){clearTimeout(s);v=s=n;var c=
100
- b.value;u!==c&&(u=c,a.h.Ea(d(),g,"textInput",c))}var u=b.value,s,v,x=9==a.a.C?y:t;10>a.a.C?(l("propertychange",function(a){"value"===a.propertyName&&x(a)}),8==a.a.C&&(l("keyup",t),l("keydown",t)),8<=a.a.C&&(m(b,x),l("dragend",y))):(l("input",t),5>e&&"textarea"===a.a.A(b)?(l("keydown",y),l("paste",y),l("cut",y)):11>c?l("keydown",y):4>f&&(l("DOMAutoComplete",t),l("dragdrop",t),l("drop",t)));l("change",t);a.m(k,null,{i:b})}};a.h.ea.textInput=!0;a.d.textinput={preprocess:function(a,b,c){c("textInput",
101
- a)}}})();a.d.uniqueName={init:function(b,c){if(c()){var d="ko_unique_"+ ++a.d.uniqueName.Ic;a.a.rc(b,d)}}};a.d.uniqueName.Ic=0;a.d.value={after:["options","foreach"],init:function(b,c,d){if("input"!=b.tagName.toLowerCase()||"checkbox"!=b.type&&"radio"!=b.type){var e=["change"],f=d.get("valueUpdate"),g=!1,k=null;f&&("string"==typeof f&&(f=[f]),a.a.ra(e,f),e=a.a.Tb(e));var l=function(){k=null;g=!1;var e=c(),f=a.j.u(b);a.h.Ea(e,d,"value",f)};!a.a.C||"input"!=b.tagName.toLowerCase()||"text"!=b.type||
102
- "off"==b.autocomplete||b.form&&"off"==b.form.autocomplete||-1!=a.a.o(e,"propertychange")||(a.a.p(b,"propertychange",function(){g=!0}),a.a.p(b,"focus",function(){g=!1}),a.a.p(b,"blur",function(){g&&l()}));a.a.q(e,function(c){var d=l;a.a.nd(c,"after")&&(d=function(){k=a.j.u(b);a.a.setTimeout(l,0)},c=c.substring(5));a.a.p(b,c,d)});var m=function(){var e=a.a.c(c()),f=a.j.u(b);if(null!==k&&e===k)a.a.setTimeout(m,0);else if(e!==f)if("select"===a.a.A(b)){var g=d.get("valueAllowUnset"),f=function(){a.j.ha(b,
103
- e,g)};f();g||e===a.j.u(b)?a.a.setTimeout(f,0):a.l.w(a.a.Da,null,[b,"change"])}else a.j.ha(b,e)};a.m(m,null,{i:b})}else a.Ja(b,{checkedValue:c})},update:function(){}};a.h.ea.value=!0;a.d.visible={update:function(b,c){var d=a.a.c(c()),e="none"!=b.style.display;d&&!e?b.style.display="":!d&&e&&(b.style.display="none")}};(function(b){a.d[b]={init:function(c,d,e,f,g){return a.d.event.init.call(this,c,function(){var a={};a[b]=d();return a},e,f,g)}}})("click");a.O=function(){};a.O.prototype.renderTemplateSource=
104
- function(){throw Error("Override renderTemplateSource");};a.O.prototype.createJavaScriptEvaluatorBlock=function(){throw Error("Override createJavaScriptEvaluatorBlock");};a.O.prototype.makeTemplateSource=function(b,c){if("string"==typeof b){c=c||u;var d=c.getElementById(b);if(!d)throw Error("Cannot find template with ID "+b);return new a.v.n(d)}if(1==b.nodeType||8==b.nodeType)return new a.v.qa(b);throw Error("Unknown template type: "+b);};a.O.prototype.renderTemplate=function(a,c,d,e){a=this.makeTemplateSource(a,
105
- e);return this.renderTemplateSource(a,c,d,e)};a.O.prototype.isTemplateRewritten=function(a,c){return!1===this.allowTemplateRewriting?!0:this.makeTemplateSource(a,c).data("isRewritten")};a.O.prototype.rewriteTemplate=function(a,c,d){a=this.makeTemplateSource(a,d);c=c(a.text());a.text(c);a.data("isRewritten",!0)};a.b("templateEngine",a.O);a.Gb=function(){function b(b,c,d,k){b=a.h.yb(b);for(var l=a.h.ta,m=0;m<b.length;m++){var h=b[m].key;if(l.hasOwnProperty(h)){var r=l[h];if("function"===typeof r){if(h=
106
- r(b[m].value))throw Error(h);}else if(!r)throw Error("This template engine does not support the '"+h+"' binding within its templates");}}d="ko.__tr_ambtns(function($context,$element){return(function(){return{ "+a.h.Ua(b,{valueAccessors:!0})+" } })()},'"+d.toLowerCase()+"')";return k.createJavaScriptEvaluatorBlock(d)+c}var c=/(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'|[^>]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,d=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g;return{Oc:function(b,
107
- c,d){c.isTemplateRewritten(b,d)||c.rewriteTemplate(b,function(b){return a.Gb.dd(b,c)},d)},dd:function(a,f){return a.replace(c,function(a,c,d,e,h){return b(h,c,d,f)}).replace(d,function(a,c){return b(c,"\x3c!-- ko --\x3e","#comment",f)})},Ec:function(b,c){return a.M.wb(function(d,k){var l=d.nextSibling;l&&l.nodeName.toLowerCase()===c&&a.Ja(l,b,k)})}}}();a.b("__tr_ambtns",a.Gb.Ec);(function(){a.v={};a.v.n=function(b){if(this.n=b){var c=a.a.A(b);this.ab="script"===c?1:"textarea"===c?2:"template"==c&&
108
- b.content&&11===b.content.nodeType?3:4}};a.v.n.prototype.text=function(){var b=1===this.ab?"text":2===this.ab?"value":"innerHTML";if(0==arguments.length)return this.n[b];var c=arguments[0];"innerHTML"===b?a.a.Cb(this.n,c):this.n[b]=c};var b=a.a.e.I()+"_";a.v.n.prototype.data=function(c){if(1===arguments.length)return a.a.e.get(this.n,b+c);a.a.e.set(this.n,b+c,arguments[1])};var c=a.a.e.I();a.v.n.prototype.nodes=function(){var b=this.n;if(0==arguments.length)return(a.a.e.get(b,c)||{}).jb||(3===this.ab?
109
- b.content:4===this.ab?b:n);a.a.e.set(b,c,{jb:arguments[0]})};a.v.qa=function(a){this.n=a};a.v.qa.prototype=new a.v.n;a.v.qa.prototype.text=function(){if(0==arguments.length){var b=a.a.e.get(this.n,c)||{};b.Hb===n&&b.jb&&(b.Hb=b.jb.innerHTML);return b.Hb}a.a.e.set(this.n,c,{Hb:arguments[0]})};a.b("templateSources",a.v);a.b("templateSources.domElement",a.v.n);a.b("templateSources.anonymousTemplate",a.v.qa)})();(function(){function b(b,c,d){var e;for(c=a.f.nextSibling(c);b&&(e=b)!==c;)b=a.f.nextSibling(e),
110
- d(e,b)}function c(c,d){if(c.length){var e=c[0],f=c[c.length-1],g=e.parentNode,k=a.Q.instance,n=k.preprocessNode;if(n){b(e,f,function(a,b){var c=a.previousSibling,d=n.call(k,a);d&&(a===e&&(e=d[0]||b),a===f&&(f=d[d.length-1]||c))});c.length=0;if(!e)return;e===f?c.push(e):(c.push(e,f),a.a.za(c,g))}b(e,f,function(b){1!==b.nodeType&&8!==b.nodeType||a.Rb(d,b)});b(e,f,function(b){1!==b.nodeType&&8!==b.nodeType||a.M.yc(b,[d])});a.a.za(c,g)}}function d(a){return a.nodeType?a:0<a.length?a[0]:null}function e(b,
111
- e,f,k,q){q=q||{};var p=(b&&d(b)||f||{}).ownerDocument,n=q.templateEngine||g;a.Gb.Oc(f,n,p);f=n.renderTemplate(f,k,q,p);if("number"!=typeof f.length||0<f.length&&"number"!=typeof f[0].nodeType)throw Error("Template engine must return an array of DOM nodes");p=!1;switch(e){case "replaceChildren":a.f.da(b,f);p=!0;break;case "replaceNode":a.a.qc(b,f);p=!0;break;case "ignoreTargetNode":break;default:throw Error("Unknown renderMode: "+e);}p&&(c(f,k),q.afterRender&&a.l.w(q.afterRender,null,[f,k.$data]));
112
- return f}function f(b,c,d){return a.H(b)?b():"function"===typeof b?b(c,d):b}var g;a.Db=function(b){if(b!=n&&!(b instanceof a.O))throw Error("templateEngine must inherit from ko.templateEngine");g=b};a.Ab=function(b,c,h,k,q){h=h||{};if((h.templateEngine||g)==n)throw Error("Set a template engine before calling renderTemplate");q=q||"replaceChildren";if(k){var p=d(k);return a.B(function(){var g=c&&c instanceof a.U?c:new a.U(a.a.c(c)),n=f(b,g.$data,g),g=e(k,q,n,g,h);"replaceNode"==q&&(k=g,p=d(k))},null,
113
- {wa:function(){return!p||!a.a.nb(p)},i:p&&"replaceNode"==q?p.parentNode:p})}return a.M.wb(function(d){a.Ab(b,c,h,d,"replaceNode")})};a.kd=function(b,d,g,k,q){function p(a,b){c(b,s);g.afterRender&&g.afterRender(b,a);s=null}function u(a,c){s=q.createChildContext(a,g.as,function(a){a.$index=c});var d=f(b,a,s);return e(null,"ignoreTargetNode",d,s,g)}var s;return a.B(function(){var b=a.a.c(d)||[];"undefined"==typeof b.length&&(b=[b]);b=a.a.Ka(b,function(b){return g.includeDestroyed||b===n||null===b||!a.a.c(b._destroy)});
114
- a.l.w(a.a.Bb,null,[k,b,u,g,p])},null,{i:k})};var k=a.a.e.I();a.d.template={init:function(b,c){var d=a.a.c(c());if("string"==typeof d||d.name)a.f.xa(b);else{if("nodes"in d){if(d=d.nodes||[],a.H(d))throw Error('The "nodes" option must be a plain, non-observable array.');}else d=a.f.childNodes(b);d=a.a.jc(d);(new a.v.qa(b)).nodes(d)}return{controlsDescendantBindings:!0}},update:function(b,c,d,e,f){var g=c(),s;c=a.a.c(g);d=!0;e=null;"string"==typeof c?c={}:(g=c.name,"if"in c&&(d=a.a.c(c["if"])),d&&"ifnot"in
115
- c&&(d=!a.a.c(c.ifnot)),s=a.a.c(c.data));"foreach"in c?e=a.kd(g||b,d&&c.foreach||[],c,b,f):d?(f="data"in c?f.createChildContext(s,c.as):f,e=a.Ab(g||b,f,c,b)):a.f.xa(b);f=e;(s=a.a.e.get(b,k))&&"function"==typeof s.k&&s.k();a.a.e.set(b,k,f&&f.ba()?f:n)}};a.h.ta.template=function(b){b=a.h.yb(b);return 1==b.length&&b[0].unknown||a.h.ad(b,"name")?null:"This template engine does not support anonymous templates nested within its templates"};a.f.Z.template=!0})();a.b("setTemplateEngine",a.Db);a.b("renderTemplate",
116
- a.Ab);a.a.dc=function(a,c,d){if(a.length&&c.length){var e,f,g,k,l;for(e=f=0;(!d||e<d)&&(k=a[f]);++f){for(g=0;l=c[g];++g)if(k.value===l.value){k.moved=l.index;l.moved=k.index;c.splice(g,1);e=g=0;break}e+=g}}};a.a.ib=function(){function b(b,d,e,f,g){var k=Math.min,l=Math.max,m=[],h,n=b.length,q,p=d.length,s=p-n||1,u=n+p+1,t,v,x;for(h=0;h<=n;h++)for(v=t,m.push(t=[]),x=k(p,h+s),q=l(0,h-1);q<=x;q++)t[q]=q?h?b[h-1]===d[q-1]?v[q-1]:k(v[q]||u,t[q-1]||u)+1:q+1:h+1;k=[];l=[];s=[];h=n;for(q=p;h||q;)p=m[h][q]-
117
- 1,q&&p===m[h][q-1]?l.push(k[k.length]={status:e,value:d[--q],index:q}):h&&p===m[h-1][q]?s.push(k[k.length]={status:f,value:b[--h],index:h}):(--q,--h,g.sparse||k.push({status:"retained",value:d[q]}));a.a.dc(s,l,!g.dontLimitMoves&&10*n);return k.reverse()}return function(a,d,e){e="boolean"===typeof e?{dontLimitMoves:e}:e||{};a=a||[];d=d||[];return a.length<d.length?b(a,d,"added","deleted",e):b(d,a,"deleted","added",e)}}();a.b("utils.compareArrays",a.a.ib);(function(){function b(b,c,d,k,l){var m=[],
118
- h=a.B(function(){var h=c(d,l,a.a.za(m,b))||[];0<m.length&&(a.a.qc(m,h),k&&a.l.w(k,null,[d,h,l]));m.length=0;a.a.ra(m,h)},null,{i:b,wa:function(){return!a.a.Qb(m)}});return{ca:m,B:h.ba()?h:n}}var c=a.a.e.I(),d=a.a.e.I();a.a.Bb=function(e,f,g,k,l){function m(b,c){w=q[c];v!==c&&(D[b]=w);w.qb(v++);a.a.za(w.ca,e);u.push(w);z.push(w)}function h(b,c){if(b)for(var d=0,e=c.length;d<e;d++)c[d]&&a.a.q(c[d].ca,function(a){b(a,d,c[d].ja)})}f=f||[];k=k||{};var r=a.a.e.get(e,c)===n,q=a.a.e.get(e,c)||[],p=a.a.fb(q,
119
- function(a){return a.ja}),s=a.a.ib(p,f,k.dontLimitMoves),u=[],t=0,v=0,x=[],z=[];f=[];for(var D=[],p=[],w,C=0,B,E;B=s[C];C++)switch(E=B.moved,B.status){case "deleted":E===n&&(w=q[t],w.B&&(w.B.k(),w.B=n),a.a.za(w.ca,e).length&&(k.beforeRemove&&(u.push(w),z.push(w),w.ja===d?w=null:f[C]=w),w&&x.push.apply(x,w.ca)));t++;break;case "retained":m(C,t++);break;case "added":E!==n?m(C,E):(w={ja:B.value,qb:a.N(v++)},u.push(w),z.push(w),r||(p[C]=w))}a.a.e.set(e,c,u);h(k.beforeMove,D);a.a.q(x,k.beforeRemove?a.$:
120
- a.removeNode);for(var C=0,r=a.f.firstChild(e),F;w=z[C];C++){w.ca||a.a.extend(w,b(e,g,w.ja,l,w.qb));for(t=0;s=w.ca[t];r=s.nextSibling,F=s,t++)s!==r&&a.f.gc(e,s,F);!w.Wc&&l&&(l(w.ja,w.ca,w.qb),w.Wc=!0)}h(k.beforeRemove,f);for(C=0;C<f.length;++C)f[C]&&(f[C].ja=d);h(k.afterMove,D);h(k.afterAdd,p)}})();a.b("utils.setDomNodeChildrenFromArrayMapping",a.a.Bb);a.W=function(){this.allowTemplateRewriting=!1};a.W.prototype=new a.O;a.W.prototype.renderTemplateSource=function(b,c,d,e){if(c=(9>a.a.C?0:b.nodes)?
121
- b.nodes():null)return a.a.V(c.cloneNode(!0).childNodes);b=b.text();return a.a.ma(b,e)};a.W.sb=new a.W;a.Db(a.W.sb);a.b("nativeTemplateEngine",a.W);(function(){a.vb=function(){var a=this.$c=function(){if(!v||!v.tmpl)return 0;try{if(0<=v.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(b,e,f,g){g=g||u;f=f||{};if(2>a)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var k=b.data("precompiled");
122
- k||(k=b.text()||"",k=v.template(null,"{{ko_with $item.koBindingContext}}"+k+"{{/ko_with}}"),b.data("precompiled",k));b=[e.$data];e=v.extend({koBindingContext:e},f.templateOptions);e=v.tmpl(k,b,e);e.appendTo(g.createElement("div"));v.fragments={};return e};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+a+" })()) }}"};this.addTemplate=function(a,b){u.write("<script type='text/html' id='"+a+"'>"+b+"\x3c/script>")};0<a&&(v.tmpl.tag.ko_code={open:"__.push($1 || '');"},
123
- v.tmpl.tag.ko_with={open:"with($1) {",close:"} "})};a.vb.prototype=new a.O;var b=new a.vb;0<b.$c&&a.Db(b);a.b("jqueryTmplTemplateEngine",a.vb)})()})})();})();
 
1
  /*!
2
+ * Knockout JavaScript library v3.4.2
3
+ * (c) The Knockout.js team - http://knockoutjs.com/
4
  * License: MIT (http://www.opensource.org/licenses/mit-license.php)
5
  */
6
 
7
+ (function() {(function(n){var x=this||(0,eval)("this"),t=x.document,M=x.navigator,u=x.jQuery,H=x.JSON;(function(n){"function"===typeof define&&define.amd?define(["exports","require"],n):"object"===typeof exports&&"object"===typeof module?n(module.exports||exports):n(x.ko={})})(function(N,O){function J(a,c){return null===a||typeof a in R?a===c:!1}function S(b,c){var d;return function(){d||(d=a.a.setTimeout(function(){d=n;b()},c))}}function T(b,c){var d;return function(){clearTimeout(d);d=a.a.setTimeout(b,c)}}function U(a,
8
+ c){c&&c!==E?"beforeChange"===c?this.Ob(a):this.Ja(a,c):this.Pb(a)}function V(a,c){null!==c&&c.k&&c.k()}function W(a,c){var d=this.Mc,e=d[s];e.T||(this.ob&&this.Oa[c]?(d.Sb(c,a,this.Oa[c]),this.Oa[c]=null,--this.ob):e.s[c]||d.Sb(c,a,e.t?{$:a}:d.yc(a)),a.Ha&&a.Hc())}function K(b,c,d,e){a.d[b]={init:function(b,g,h,l,m){var k,r;a.m(function(){var q=g(),p=a.a.c(q),p=!d!==!p,A=!r;if(A||c||p!==k)A&&a.xa.Ca()&&(r=a.a.wa(a.f.childNodes(b),!0)),p?(A||a.f.fa(b,a.a.wa(r)),a.hb(e?e(m,q):m,b)):a.f.za(b),k=p},null,
9
+ {i:b});return{controlsDescendantBindings:!0}}};a.h.va[b]=!1;a.f.aa[b]=!0}var a="undefined"!==typeof N?N:{};a.b=function(b,c){for(var d=b.split("."),e=a,f=0;f<d.length-1;f++)e=e[d[f]];e[d[d.length-1]]=c};a.H=function(a,c,d){a[c]=d};a.version="3.4.2";a.b("version",a.version);a.options={deferUpdates:!1,useOnlyNativeEvents:!1};a.a=function(){function b(a,b){for(var c in a)a.hasOwnProperty(c)&&b(c,a[c])}function c(a,b){if(b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}function d(a,b){a.__proto__=
10
+ b;return a}function e(b,c,d,e){var m=b[c].match(r)||[];a.a.r(d.match(r),function(b){a.a.ra(m,b,e)});b[c]=m.join(" ")}var f={__proto__:[]}instanceof Array,g="function"===typeof Symbol,h={},l={};h[M&&/Firefox\/2/i.test(M.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"];h.MouseEvents="click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave".split(" ");b(h,function(a,b){if(b.length)for(var c=0,d=b.length;c<d;c++)l[b[c]]=a});var m={propertychange:!0},k=
11
+ t&&function(){for(var a=3,b=t.createElement("div"),c=b.getElementsByTagName("i");b.innerHTML="\x3c!--[if gt IE "+ ++a+"]><i></i><![endif]--\x3e",c[0];);return 4<a?a:n}(),r=/\S+/g;return{gc:["authenticity_token",/^__RequestVerificationToken(_.*)?$/],r:function(a,b){for(var c=0,d=a.length;c<d;c++)b(a[c],c)},o:function(a,b){if("function"==typeof Array.prototype.indexOf)return Array.prototype.indexOf.call(a,b);for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},Vb:function(a,b,c){for(var d=
12
+ 0,e=a.length;d<e;d++)if(b.call(c,a[d],d))return a[d];return null},Na:function(b,c){var d=a.a.o(b,c);0<d?b.splice(d,1):0===d&&b.shift()},Wb:function(b){b=b||[];for(var c=[],d=0,e=b.length;d<e;d++)0>a.a.o(c,b[d])&&c.push(b[d]);return c},ib:function(a,b){a=a||[];for(var c=[],d=0,e=a.length;d<e;d++)c.push(b(a[d],d));return c},Ma:function(a,b){a=a||[];for(var c=[],d=0,e=a.length;d<e;d++)b(a[d],d)&&c.push(a[d]);return c},ta:function(a,b){if(b instanceof Array)a.push.apply(a,b);else for(var c=0,d=b.length;c<
13
+ d;c++)a.push(b[c]);return a},ra:function(b,c,d){var e=a.a.o(a.a.Bb(b),c);0>e?d&&b.push(c):d||b.splice(e,1)},la:f,extend:c,$a:d,ab:f?d:c,D:b,Ea:function(a,b){if(!a)return a;var c={},d;for(d in a)a.hasOwnProperty(d)&&(c[d]=b(a[d],d,a));return c},rb:function(b){for(;b.firstChild;)a.removeNode(b.firstChild)},nc:function(b){b=a.a.W(b);for(var c=(b[0]&&b[0].ownerDocument||t).createElement("div"),d=0,e=b.length;d<e;d++)c.appendChild(a.ba(b[d]));return c},wa:function(b,c){for(var d=0,e=b.length,m=[];d<e;d++){var k=
14
+ b[d].cloneNode(!0);m.push(c?a.ba(k):k)}return m},fa:function(b,c){a.a.rb(b);if(c)for(var d=0,e=c.length;d<e;d++)b.appendChild(c[d])},uc:function(b,c){var d=b.nodeType?[b]:b;if(0<d.length){for(var e=d[0],m=e.parentNode,k=0,f=c.length;k<f;k++)m.insertBefore(c[k],e);k=0;for(f=d.length;k<f;k++)a.removeNode(d[k])}},Ba:function(a,b){if(a.length){for(b=8===b.nodeType&&b.parentNode||b;a.length&&a[0].parentNode!==b;)a.splice(0,1);for(;1<a.length&&a[a.length-1].parentNode!==b;)a.length--;if(1<a.length){var c=
15
+ a[0],d=a[a.length-1];for(a.length=0;c!==d;)a.push(c),c=c.nextSibling;a.push(d)}}return a},wc:function(a,b){7>k?a.setAttribute("selected",b):a.selected=b},cb:function(a){return null===a||a===n?"":a.trim?a.trim():a.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},sd:function(a,b){a=a||"";return b.length>a.length?!1:a.substring(0,b.length)===b},Rc:function(a,b){if(a===b)return!0;if(11===a.nodeType)return!1;if(b.contains)return b.contains(3===a.nodeType?a.parentNode:a);if(b.compareDocumentPosition)return 16==
16
+ (b.compareDocumentPosition(a)&16);for(;a&&a!=b;)a=a.parentNode;return!!a},qb:function(b){return a.a.Rc(b,b.ownerDocument.documentElement)},Tb:function(b){return!!a.a.Vb(b,a.a.qb)},A:function(a){return a&&a.tagName&&a.tagName.toLowerCase()},Zb:function(b){return a.onError?function(){try{return b.apply(this,arguments)}catch(c){throw a.onError&&a.onError(c),c;}}:b},setTimeout:function(b,c){return setTimeout(a.a.Zb(b),c)},dc:function(b){setTimeout(function(){a.onError&&a.onError(b);throw b;},0)},q:function(b,
17
+ c,d){var e=a.a.Zb(d);d=k&&m[c];if(a.options.useOnlyNativeEvents||d||!u)if(d||"function"!=typeof b.addEventListener)if("undefined"!=typeof b.attachEvent){var f=function(a){e.call(b,a)},l="on"+c;b.attachEvent(l,f);a.a.G.qa(b,function(){b.detachEvent(l,f)})}else throw Error("Browser doesn't support addEventListener or attachEvent");else b.addEventListener(c,e,!1);else u(b).bind(c,e)},Fa:function(b,c){if(!b||!b.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var d;"input"===
18
+ a.a.A(b)&&b.type&&"click"==c.toLowerCase()?(d=b.type,d="checkbox"==d||"radio"==d):d=!1;if(a.options.useOnlyNativeEvents||!u||d)if("function"==typeof t.createEvent)if("function"==typeof b.dispatchEvent)d=t.createEvent(l[c]||"HTMLEvents"),d.initEvent(c,!0,!0,x,0,0,0,0,0,!1,!1,!1,!1,0,b),b.dispatchEvent(d);else throw Error("The supplied element doesn't support dispatchEvent");else if(d&&b.click)b.click();else if("undefined"!=typeof b.fireEvent)b.fireEvent("on"+c);else throw Error("Browser doesn't support triggering events");
19
+ else u(b).trigger(c)},c:function(b){return a.I(b)?b():b},Bb:function(b){return a.I(b)?b.p():b},fb:function(b,c,d){var k;c&&("object"===typeof b.classList?(k=b.classList[d?"add":"remove"],a.a.r(c.match(r),function(a){k.call(b.classList,a)})):"string"===typeof b.className.baseVal?e(b.className,"baseVal",c,d):e(b,"className",c,d))},bb:function(b,c){var d=a.a.c(c);if(null===d||d===n)d="";var e=a.f.firstChild(b);!e||3!=e.nodeType||a.f.nextSibling(e)?a.f.fa(b,[b.ownerDocument.createTextNode(d)]):e.data=
20
+ d;a.a.Wc(b)},vc:function(a,b){a.name=b;if(7>=k)try{a.mergeAttributes(t.createElement("<input name='"+a.name+"'/>"),!1)}catch(c){}},Wc:function(a){9<=k&&(a=1==a.nodeType?a:a.parentNode,a.style&&(a.style.zoom=a.style.zoom))},Sc:function(a){if(k){var b=a.style.width;a.style.width=0;a.style.width=b}},nd:function(b,c){b=a.a.c(b);c=a.a.c(c);for(var d=[],e=b;e<=c;e++)d.push(e);return d},W:function(a){for(var b=[],c=0,d=a.length;c<d;c++)b.push(a[c]);return b},bc:function(a){return g?Symbol(a):a},xd:6===k,
21
+ yd:7===k,C:k,ic:function(b,c){for(var d=a.a.W(b.getElementsByTagName("input")).concat(a.a.W(b.getElementsByTagName("textarea"))),e="string"==typeof c?function(a){return a.name===c}:function(a){return c.test(a.name)},k=[],m=d.length-1;0<=m;m--)e(d[m])&&k.push(d[m]);return k},kd:function(b){return"string"==typeof b&&(b=a.a.cb(b))?H&&H.parse?H.parse(b):(new Function("return "+b))():null},Gb:function(b,c,d){if(!H||!H.stringify)throw Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");
22
+ return H.stringify(a.a.c(b),c,d)},ld:function(c,d,e){e=e||{};var k=e.params||{},m=e.includeFields||this.gc,f=c;if("object"==typeof c&&"form"===a.a.A(c))for(var f=c.action,l=m.length-1;0<=l;l--)for(var g=a.a.ic(c,m[l]),h=g.length-1;0<=h;h--)k[g[h].name]=g[h].value;d=a.a.c(d);var r=t.createElement("form");r.style.display="none";r.action=f;r.method="post";for(var n in d)c=t.createElement("input"),c.type="hidden",c.name=n,c.value=a.a.Gb(a.a.c(d[n])),r.appendChild(c);b(k,function(a,b){var c=t.createElement("input");
23
+ c.type="hidden";c.name=a;c.value=b;r.appendChild(c)});t.body.appendChild(r);e.submitter?e.submitter(r):r.submit();setTimeout(function(){r.parentNode.removeChild(r)},0)}}}();a.b("utils",a.a);a.b("utils.arrayForEach",a.a.r);a.b("utils.arrayFirst",a.a.Vb);a.b("utils.arrayFilter",a.a.Ma);a.b("utils.arrayGetDistinctValues",a.a.Wb);a.b("utils.arrayIndexOf",a.a.o);a.b("utils.arrayMap",a.a.ib);a.b("utils.arrayPushAll",a.a.ta);a.b("utils.arrayRemoveItem",a.a.Na);a.b("utils.extend",a.a.extend);a.b("utils.fieldsIncludedWithJsonPost",
24
+ a.a.gc);a.b("utils.getFormFields",a.a.ic);a.b("utils.peekObservable",a.a.Bb);a.b("utils.postJson",a.a.ld);a.b("utils.parseJson",a.a.kd);a.b("utils.registerEventHandler",a.a.q);a.b("utils.stringifyJson",a.a.Gb);a.b("utils.range",a.a.nd);a.b("utils.toggleDomNodeCssClass",a.a.fb);a.b("utils.triggerEvent",a.a.Fa);a.b("utils.unwrapObservable",a.a.c);a.b("utils.objectForEach",a.a.D);a.b("utils.addOrRemoveItem",a.a.ra);a.b("utils.setTextContent",a.a.bb);a.b("unwrap",a.a.c);Function.prototype.bind||(Function.prototype.bind=
25
+ function(a){var c=this;if(1===arguments.length)return function(){return c.apply(a,arguments)};var d=Array.prototype.slice.call(arguments,1);return function(){var e=d.slice(0);e.push.apply(e,arguments);return c.apply(a,e)}});a.a.e=new function(){function a(b,g){var h=b[d];if(!h||"null"===h||!e[h]){if(!g)return n;h=b[d]="ko"+c++;e[h]={}}return e[h]}var c=0,d="__ko__"+(new Date).getTime(),e={};return{get:function(c,d){var e=a(c,!1);return e===n?n:e[d]},set:function(c,d,e){if(e!==n||a(c,!1)!==n)a(c,!0)[d]=
26
+ e},clear:function(a){var b=a[d];return b?(delete e[b],a[d]=null,!0):!1},J:function(){return c++ +d}}};a.b("utils.domData",a.a.e);a.b("utils.domData.clear",a.a.e.clear);a.a.G=new function(){function b(b,c){var e=a.a.e.get(b,d);e===n&&c&&(e=[],a.a.e.set(b,d,e));return e}function c(d){var e=b(d,!1);if(e)for(var e=e.slice(0),l=0;l<e.length;l++)e[l](d);a.a.e.clear(d);a.a.G.cleanExternalData(d);if(f[d.nodeType])for(e=d.firstChild;d=e;)e=d.nextSibling,8===d.nodeType&&c(d)}var d=a.a.e.J(),e={1:!0,8:!0,9:!0},
27
+ f={1:!0,9:!0};return{qa:function(a,c){if("function"!=typeof c)throw Error("Callback must be a function");b(a,!0).push(c)},tc:function(c,e){var f=b(c,!1);f&&(a.a.Na(f,e),0==f.length&&a.a.e.set(c,d,n))},ba:function(b){if(e[b.nodeType]&&(c(b),f[b.nodeType])){var d=[];a.a.ta(d,b.getElementsByTagName("*"));for(var l=0,m=d.length;l<m;l++)c(d[l])}return b},removeNode:function(b){a.ba(b);b.parentNode&&b.parentNode.removeChild(b)},cleanExternalData:function(a){u&&"function"==typeof u.cleanData&&u.cleanData([a])}}};
28
+ a.ba=a.a.G.ba;a.removeNode=a.a.G.removeNode;a.b("cleanNode",a.ba);a.b("removeNode",a.removeNode);a.b("utils.domNodeDisposal",a.a.G);a.b("utils.domNodeDisposal.addDisposeCallback",a.a.G.qa);a.b("utils.domNodeDisposal.removeDisposeCallback",a.a.G.tc);(function(){var b=[0,"",""],c=[1,"<table>","</table>"],d=[3,"<table><tbody><tr>","</tr></tbody></table>"],e=[1,"<select multiple='multiple'>","</select>"],f={thead:c,tbody:c,tfoot:c,tr:[2,"<table><tbody>","</tbody></table>"],td:d,th:d,option:e,optgroup:e},
29
+ g=8>=a.a.C;a.a.na=function(c,d){var e;if(u)if(u.parseHTML)e=u.parseHTML(c,d)||[];else{if((e=u.clean([c],d))&&e[0]){for(var k=e[0];k.parentNode&&11!==k.parentNode.nodeType;)k=k.parentNode;k.parentNode&&k.parentNode.removeChild(k)}}else{(e=d)||(e=t);var k=e.parentWindow||e.defaultView||x,r=a.a.cb(c).toLowerCase(),q=e.createElement("div"),p;p=(r=r.match(/^<([a-z]+)[ >]/))&&f[r[1]]||b;r=p[0];p="ignored<div>"+p[1]+c+p[2]+"</div>";"function"==typeof k.innerShiv?q.appendChild(k.innerShiv(p)):(g&&e.appendChild(q),
30
+ q.innerHTML=p,g&&q.parentNode.removeChild(q));for(;r--;)q=q.lastChild;e=a.a.W(q.lastChild.childNodes)}return e};a.a.Eb=function(b,c){a.a.rb(b);c=a.a.c(c);if(null!==c&&c!==n)if("string"!=typeof c&&(c=c.toString()),u)u(b).html(c);else for(var d=a.a.na(c,b.ownerDocument),e=0;e<d.length;e++)b.appendChild(d[e])}})();a.b("utils.parseHtmlFragment",a.a.na);a.b("utils.setHtml",a.a.Eb);a.N=function(){function b(c,e){if(c)if(8==c.nodeType){var f=a.N.pc(c.nodeValue);null!=f&&e.push({Qc:c,hd:f})}else if(1==c.nodeType)for(var f=
31
+ 0,g=c.childNodes,h=g.length;f<h;f++)b(g[f],e)}var c={};return{yb:function(a){if("function"!=typeof a)throw Error("You can only pass a function to ko.memoization.memoize()");var b=(4294967296*(1+Math.random())|0).toString(16).substring(1)+(4294967296*(1+Math.random())|0).toString(16).substring(1);c[b]=a;return"\x3c!--[ko_memo:"+b+"]--\x3e"},Bc:function(a,b){var f=c[a];if(f===n)throw Error("Couldn't find any memo with ID "+a+". Perhaps it's already been unmemoized.");try{return f.apply(null,b||[]),
32
+ !0}finally{delete c[a]}},Cc:function(c,e){var f=[];b(c,f);for(var g=0,h=f.length;g<h;g++){var l=f[g].Qc,m=[l];e&&a.a.ta(m,e);a.N.Bc(f[g].hd,m);l.nodeValue="";l.parentNode&&l.parentNode.removeChild(l)}},pc:function(a){return(a=a.match(/^\[ko_memo\:(.*?)\]$/))?a[1]:null}}}();a.b("memoization",a.N);a.b("memoization.memoize",a.N.yb);a.b("memoization.unmemoize",a.N.Bc);a.b("memoization.parseMemoText",a.N.pc);a.b("memoization.unmemoizeDomNodeAndDescendants",a.N.Cc);a.Z=function(){function b(){if(e)for(var b=
33
+ e,c=0,m;g<e;)if(m=d[g++]){if(g>b){if(5E3<=++c){g=e;a.a.dc(Error("'Too much recursion' after processing "+c+" task groups."));break}b=e}try{m()}catch(k){a.a.dc(k)}}}function c(){b();g=e=d.length=0}var d=[],e=0,f=1,g=0;return{scheduler:x.MutationObserver?function(a){var b=t.createElement("div");(new MutationObserver(a)).observe(b,{attributes:!0});return function(){b.classList.toggle("foo")}}(c):t&&"onreadystatechange"in t.createElement("script")?function(a){var b=t.createElement("script");b.onreadystatechange=
34
+ function(){b.onreadystatechange=null;t.documentElement.removeChild(b);b=null;a()};t.documentElement.appendChild(b)}:function(a){setTimeout(a,0)},Za:function(b){e||a.Z.scheduler(c);d[e++]=b;return f++},cancel:function(a){a-=f-e;a>=g&&a<e&&(d[a]=null)},resetForTesting:function(){var a=e-g;g=e=d.length=0;return a},rd:b}}();a.b("tasks",a.Z);a.b("tasks.schedule",a.Z.Za);a.b("tasks.runEarly",a.Z.rd);a.Aa={throttle:function(b,c){b.throttleEvaluation=c;var d=null;return a.B({read:b,write:function(e){clearTimeout(d);
35
+ d=a.a.setTimeout(function(){b(e)},c)}})},rateLimit:function(a,c){var d,e,f;"number"==typeof c?d=c:(d=c.timeout,e=c.method);a.gb=!1;f="notifyWhenChangesStop"==e?T:S;a.Wa(function(a){return f(a,d)})},deferred:function(b,c){if(!0!==c)throw Error("The 'deferred' extender only accepts the value 'true', because it is not supported to turn deferral off once enabled.");b.gb||(b.gb=!0,b.Wa(function(c){var e,f=!1;return function(){if(!f){a.Z.cancel(e);e=a.Z.Za(c);try{f=!0,b.notifySubscribers(n,"dirty")}finally{f=
36
+ !1}}}}))},notify:function(a,c){a.equalityComparer="always"==c?null:J}};var R={undefined:1,"boolean":1,number:1,string:1};a.b("extenders",a.Aa);a.zc=function(b,c,d){this.$=b;this.jb=c;this.Pc=d;this.T=!1;a.H(this,"dispose",this.k)};a.zc.prototype.k=function(){this.T=!0;this.Pc()};a.K=function(){a.a.ab(this,D);D.ub(this)};var E="change",D={ub:function(a){a.F={change:[]};a.Qb=1},Y:function(b,c,d){var e=this;d=d||E;var f=new a.zc(e,c?b.bind(c):b,function(){a.a.Na(e.F[d],f);e.Ka&&e.Ka(d)});e.ua&&e.ua(d);
37
+ e.F[d]||(e.F[d]=[]);e.F[d].push(f);return f},notifySubscribers:function(b,c){c=c||E;c===E&&this.Kb();if(this.Ra(c)){var d=c===E&&this.Fc||this.F[c].slice(0);try{a.l.Xb();for(var e=0,f;f=d[e];++e)f.T||f.jb(b)}finally{a.l.end()}}},Pa:function(){return this.Qb},Zc:function(a){return this.Pa()!==a},Kb:function(){++this.Qb},Wa:function(b){var c=this,d=a.I(c),e,f,g,h;c.Ja||(c.Ja=c.notifySubscribers,c.notifySubscribers=U);var l=b(function(){c.Ha=!1;d&&h===c&&(h=c.Mb?c.Mb():c());var a=f||c.Ua(g,h);f=e=!1;
38
+ a&&c.Ja(g=h)});c.Pb=function(a){c.Fc=c.F[E].slice(0);c.Ha=e=!0;h=a;l()};c.Ob=function(a){e||(g=a,c.Ja(a,"beforeChange"))};c.Hc=function(){c.Ua(g,c.p(!0))&&(f=!0)}},Ra:function(a){return this.F[a]&&this.F[a].length},Xc:function(b){if(b)return this.F[b]&&this.F[b].length||0;var c=0;a.a.D(this.F,function(a,b){"dirty"!==a&&(c+=b.length)});return c},Ua:function(a,c){return!this.equalityComparer||!this.equalityComparer(a,c)},extend:function(b){var c=this;b&&a.a.D(b,function(b,e){var f=a.Aa[b];"function"==
39
+ typeof f&&(c=f(c,e)||c)});return c}};a.H(D,"subscribe",D.Y);a.H(D,"extend",D.extend);a.H(D,"getSubscriptionsCount",D.Xc);a.a.la&&a.a.$a(D,Function.prototype);a.K.fn=D;a.lc=function(a){return null!=a&&"function"==typeof a.Y&&"function"==typeof a.notifySubscribers};a.b("subscribable",a.K);a.b("isSubscribable",a.lc);a.xa=a.l=function(){function b(a){d.push(e);e=a}function c(){e=d.pop()}var d=[],e,f=0;return{Xb:b,end:c,sc:function(b){if(e){if(!a.lc(b))throw Error("Only subscribable things can act as dependencies");
40
+ e.jb.call(e.Lc,b,b.Gc||(b.Gc=++f))}},w:function(a,d,e){try{return b(),a.apply(d,e||[])}finally{c()}},Ca:function(){if(e)return e.m.Ca()},Va:function(){if(e)return e.Va}}}();a.b("computedContext",a.xa);a.b("computedContext.getDependenciesCount",a.xa.Ca);a.b("computedContext.isInitial",a.xa.Va);a.b("ignoreDependencies",a.wd=a.l.w);var F=a.a.bc("_latestValue");a.O=function(b){function c(){if(0<arguments.length)return c.Ua(c[F],arguments[0])&&(c.ia(),c[F]=arguments[0],c.ha()),this;a.l.sc(c);return c[F]}
41
+ c[F]=b;a.a.la||a.a.extend(c,a.K.fn);a.K.fn.ub(c);a.a.ab(c,B);a.options.deferUpdates&&a.Aa.deferred(c,!0);return c};var B={equalityComparer:J,p:function(){return this[F]},ha:function(){this.notifySubscribers(this[F])},ia:function(){this.notifySubscribers(this[F],"beforeChange")}};a.a.la&&a.a.$a(B,a.K.fn);var I=a.O.md="__ko_proto__";B[I]=a.O;a.Qa=function(b,c){return null===b||b===n||b[I]===n?!1:b[I]===c?!0:a.Qa(b[I],c)};a.I=function(b){return a.Qa(b,a.O)};a.Da=function(b){return"function"==typeof b&&
42
+ b[I]===a.O||"function"==typeof b&&b[I]===a.B&&b.$c?!0:!1};a.b("observable",a.O);a.b("isObservable",a.I);a.b("isWriteableObservable",a.Da);a.b("isWritableObservable",a.Da);a.b("observable.fn",B);a.H(B,"peek",B.p);a.H(B,"valueHasMutated",B.ha);a.H(B,"valueWillMutate",B.ia);a.ma=function(b){b=b||[];if("object"!=typeof b||!("length"in b))throw Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");b=a.O(b);a.a.ab(b,a.ma.fn);return b.extend({trackArrayChanges:!0})};
43
+ a.ma.fn={remove:function(b){for(var c=this.p(),d=[],e="function"!=typeof b||a.I(b)?function(a){return a===b}:b,f=0;f<c.length;f++){var g=c[f];e(g)&&(0===d.length&&this.ia(),d.push(g),c.splice(f,1),f--)}d.length&&this.ha();return d},removeAll:function(b){if(b===n){var c=this.p(),d=c.slice(0);this.ia();c.splice(0,c.length);this.ha();return d}return b?this.remove(function(c){return 0<=a.a.o(b,c)}):[]},destroy:function(b){var c=this.p(),d="function"!=typeof b||a.I(b)?function(a){return a===b}:b;this.ia();
44
+ for(var e=c.length-1;0<=e;e--)d(c[e])&&(c[e]._destroy=!0);this.ha()},destroyAll:function(b){return b===n?this.destroy(function(){return!0}):b?this.destroy(function(c){return 0<=a.a.o(b,c)}):[]},indexOf:function(b){var c=this();return a.a.o(c,b)},replace:function(a,c){var d=this.indexOf(a);0<=d&&(this.ia(),this.p()[d]=c,this.ha())}};a.a.la&&a.a.$a(a.ma.fn,a.O.fn);a.a.r("pop push reverse shift sort splice unshift".split(" "),function(b){a.ma.fn[b]=function(){var a=this.p();this.ia();this.Yb(a,b,arguments);
45
+ var d=a[b].apply(a,arguments);this.ha();return d===a?this:d}});a.a.r(["slice"],function(b){a.ma.fn[b]=function(){var a=this();return a[b].apply(a,arguments)}});a.b("observableArray",a.ma);a.Aa.trackArrayChanges=function(b,c){function d(){if(!e){e=!0;l=b.notifySubscribers;b.notifySubscribers=function(a,b){b&&b!==E||++h;return l.apply(this,arguments)};var c=[].concat(b.p()||[]);f=null;g=b.Y(function(d){d=[].concat(d||[]);if(b.Ra("arrayChange")){var e;if(!f||1<h)f=a.a.lb(c,d,b.kb);e=f}c=d;f=null;h=0;
46
+ e&&e.length&&b.notifySubscribers(e,"arrayChange")})}}b.kb={};c&&"object"==typeof c&&a.a.extend(b.kb,c);b.kb.sparse=!0;if(!b.Yb){var e=!1,f=null,g,h=0,l,m=b.ua,k=b.Ka;b.ua=function(a){m&&m.call(b,a);"arrayChange"===a&&d()};b.Ka=function(a){k&&k.call(b,a);"arrayChange"!==a||b.Ra("arrayChange")||(l&&(b.notifySubscribers=l,l=n),g.k(),e=!1)};b.Yb=function(b,c,d){function k(a,b,c){return m[m.length]={status:a,value:b,index:c}}if(e&&!h){var m=[],l=b.length,g=d.length,G=0;switch(c){case "push":G=l;case "unshift":for(c=
47
+ 0;c<g;c++)k("added",d[c],G+c);break;case "pop":G=l-1;case "shift":l&&k("deleted",b[G],G);break;case "splice":c=Math.min(Math.max(0,0>d[0]?l+d[0]:d[0]),l);for(var l=1===g?l:Math.min(c+(d[1]||0),l),g=c+g-2,G=Math.max(l,g),n=[],s=[],w=2;c<G;++c,++w)c<l&&s.push(k("deleted",b[c],c)),c<g&&n.push(k("added",d[w],c));a.a.hc(s,n);break;default:return}f=m}}}};var s=a.a.bc("_state");a.m=a.B=function(b,c,d){function e(){if(0<arguments.length){if("function"===typeof f)f.apply(g.sb,arguments);else throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
48
+ return this}a.l.sc(e);(g.V||g.t&&e.Sa())&&e.U();return g.M}"object"===typeof b?d=b:(d=d||{},b&&(d.read=b));if("function"!=typeof d.read)throw Error("Pass a function that returns the value of the ko.computed");var f=d.write,g={M:n,da:!0,V:!0,Ta:!1,Hb:!1,T:!1,Ya:!1,t:!1,od:d.read,sb:c||d.owner,i:d.disposeWhenNodeIsRemoved||d.i||null,ya:d.disposeWhen||d.ya,pb:null,s:{},L:0,fc:null};e[s]=g;e.$c="function"===typeof f;a.a.la||a.a.extend(e,a.K.fn);a.K.fn.ub(e);a.a.ab(e,z);d.pure?(g.Ya=!0,g.t=!0,a.a.extend(e,
49
+ Y)):d.deferEvaluation&&a.a.extend(e,Z);a.options.deferUpdates&&a.Aa.deferred(e,!0);g.i&&(g.Hb=!0,g.i.nodeType||(g.i=null));g.t||d.deferEvaluation||e.U();g.i&&e.ca()&&a.a.G.qa(g.i,g.pb=function(){e.k()});return e};var z={equalityComparer:J,Ca:function(){return this[s].L},Sb:function(a,c,d){if(this[s].Ya&&c===this)throw Error("A 'pure' computed must not be called recursively");this[s].s[a]=d;d.Ia=this[s].L++;d.pa=c.Pa()},Sa:function(){var a,c,d=this[s].s;for(a in d)if(d.hasOwnProperty(a)&&(c=d[a],this.oa&&
50
+ c.$.Ha||c.$.Zc(c.pa)))return!0},gd:function(){this.oa&&!this[s].Ta&&this.oa(!1)},ca:function(){var a=this[s];return a.V||0<a.L},qd:function(){this.Ha?this[s].V&&(this[s].da=!0):this.ec()},yc:function(a){if(a.gb&&!this[s].i){var c=a.Y(this.gd,this,"dirty"),d=a.Y(this.qd,this);return{$:a,k:function(){c.k();d.k()}}}return a.Y(this.ec,this)},ec:function(){var b=this,c=b.throttleEvaluation;c&&0<=c?(clearTimeout(this[s].fc),this[s].fc=a.a.setTimeout(function(){b.U(!0)},c)):b.oa?b.oa(!0):b.U(!0)},U:function(b){var c=
51
+ this[s],d=c.ya,e=!1;if(!c.Ta&&!c.T){if(c.i&&!a.a.qb(c.i)||d&&d()){if(!c.Hb){this.k();return}}else c.Hb=!1;c.Ta=!0;try{e=this.Vc(b)}finally{c.Ta=!1}c.L||this.k();return e}},Vc:function(b){var c=this[s],d=!1,e=c.Ya?n:!c.L,f={Mc:this,Oa:c.s,ob:c.L};a.l.Xb({Lc:f,jb:W,m:this,Va:e});c.s={};c.L=0;f=this.Uc(c,f);this.Ua(c.M,f)&&(c.t||this.notifySubscribers(c.M,"beforeChange"),c.M=f,c.t?this.Kb():b&&this.notifySubscribers(c.M),d=!0);e&&this.notifySubscribers(c.M,"awake");return d},Uc:function(b,c){try{var d=
52
+ b.od;return b.sb?d.call(b.sb):d()}finally{a.l.end(),c.ob&&!b.t&&a.a.D(c.Oa,V),b.da=b.V=!1}},p:function(a){var c=this[s];(c.V&&(a||!c.L)||c.t&&this.Sa())&&this.U();return c.M},Wa:function(b){a.K.fn.Wa.call(this,b);this.Mb=function(){this[s].da?this.U():this[s].V=!1;return this[s].M};this.oa=function(a){this.Ob(this[s].M);this[s].V=!0;a&&(this[s].da=!0);this.Pb(this)}},k:function(){var b=this[s];!b.t&&b.s&&a.a.D(b.s,function(a,b){b.k&&b.k()});b.i&&b.pb&&a.a.G.tc(b.i,b.pb);b.s=null;b.L=0;b.T=!0;b.da=
53
+ !1;b.V=!1;b.t=!1;b.i=null}},Y={ua:function(b){var c=this,d=c[s];if(!d.T&&d.t&&"change"==b){d.t=!1;if(d.da||c.Sa())d.s=null,d.L=0,c.U()&&c.Kb();else{var e=[];a.a.D(d.s,function(a,b){e[b.Ia]=a});a.a.r(e,function(a,b){var e=d.s[a],l=c.yc(e.$);l.Ia=b;l.pa=e.pa;d.s[a]=l})}d.T||c.notifySubscribers(d.M,"awake")}},Ka:function(b){var c=this[s];c.T||"change"!=b||this.Ra("change")||(a.a.D(c.s,function(a,b){b.k&&(c.s[a]={$:b.$,Ia:b.Ia,pa:b.pa},b.k())}),c.t=!0,this.notifySubscribers(n,"asleep"))},Pa:function(){var b=
54
+ this[s];b.t&&(b.da||this.Sa())&&this.U();return a.K.fn.Pa.call(this)}},Z={ua:function(a){"change"!=a&&"beforeChange"!=a||this.p()}};a.a.la&&a.a.$a(z,a.K.fn);var P=a.O.md;a.m[P]=a.O;z[P]=a.m;a.bd=function(b){return a.Qa(b,a.m)};a.cd=function(b){return a.Qa(b,a.m)&&b[s]&&b[s].Ya};a.b("computed",a.m);a.b("dependentObservable",a.m);a.b("isComputed",a.bd);a.b("isPureComputed",a.cd);a.b("computed.fn",z);a.H(z,"peek",z.p);a.H(z,"dispose",z.k);a.H(z,"isActive",z.ca);a.H(z,"getDependenciesCount",z.Ca);a.rc=
55
+ function(b,c){if("function"===typeof b)return a.m(b,c,{pure:!0});b=a.a.extend({},b);b.pure=!0;return a.m(b,c)};a.b("pureComputed",a.rc);(function(){function b(a,f,g){g=g||new d;a=f(a);if("object"!=typeof a||null===a||a===n||a instanceof RegExp||a instanceof Date||a instanceof String||a instanceof Number||a instanceof Boolean)return a;var h=a instanceof Array?[]:{};g.save(a,h);c(a,function(c){var d=f(a[c]);switch(typeof d){case "boolean":case "number":case "string":case "function":h[c]=d;break;case "object":case "undefined":var k=
56
+ g.get(d);h[c]=k!==n?k:b(d,f,g)}});return h}function c(a,b){if(a instanceof Array){for(var c=0;c<a.length;c++)b(c);"function"==typeof a.toJSON&&b("toJSON")}else for(c in a)b(c)}function d(){this.keys=[];this.Lb=[]}a.Ac=function(c){if(0==arguments.length)throw Error("When calling ko.toJS, pass the object you want to convert.");return b(c,function(b){for(var c=0;a.I(b)&&10>c;c++)b=b();return b})};a.toJSON=function(b,c,d){b=a.Ac(b);return a.a.Gb(b,c,d)};d.prototype={save:function(b,c){var d=a.a.o(this.keys,
57
+ b);0<=d?this.Lb[d]=c:(this.keys.push(b),this.Lb.push(c))},get:function(b){b=a.a.o(this.keys,b);return 0<=b?this.Lb[b]:n}}})();a.b("toJS",a.Ac);a.b("toJSON",a.toJSON);(function(){a.j={u:function(b){switch(a.a.A(b)){case "option":return!0===b.__ko__hasDomDataOptionValue__?a.a.e.get(b,a.d.options.zb):7>=a.a.C?b.getAttributeNode("value")&&b.getAttributeNode("value").specified?b.value:b.text:b.value;case "select":return 0<=b.selectedIndex?a.j.u(b.options[b.selectedIndex]):n;default:return b.value}},ja:function(b,
58
+ c,d){switch(a.a.A(b)){case "option":switch(typeof c){case "string":a.a.e.set(b,a.d.options.zb,n);"__ko__hasDomDataOptionValue__"in b&&delete b.__ko__hasDomDataOptionValue__;b.value=c;break;default:a.a.e.set(b,a.d.options.zb,c),b.__ko__hasDomDataOptionValue__=!0,b.value="number"===typeof c?c:""}break;case "select":if(""===c||null===c)c=n;for(var e=-1,f=0,g=b.options.length,h;f<g;++f)if(h=a.j.u(b.options[f]),h==c||""==h&&c===n){e=f;break}if(d||0<=e||c===n&&1<b.size)b.selectedIndex=e;break;default:if(null===
59
+ c||c===n)c="";b.value=c}}}})();a.b("selectExtensions",a.j);a.b("selectExtensions.readValue",a.j.u);a.b("selectExtensions.writeValue",a.j.ja);a.h=function(){function b(b){b=a.a.cb(b);123===b.charCodeAt(0)&&(b=b.slice(1,-1));var c=[],d=b.match(e),r,h=[],p=0;if(d){d.push(",");for(var A=0,y;y=d[A];++A){var v=y.charCodeAt(0);if(44===v){if(0>=p){c.push(r&&h.length?{key:r,value:h.join("")}:{unknown:r||h.join("")});r=p=0;h=[];continue}}else if(58===v){if(!p&&!r&&1===h.length){r=h.pop();continue}}else 47===
60
+ v&&A&&1<y.length?(v=d[A-1].match(f))&&!g[v[0]]&&(b=b.substr(b.indexOf(y)+1),d=b.match(e),d.push(","),A=-1,y="/"):40===v||123===v||91===v?++p:41===v||125===v||93===v?--p:r||h.length||34!==v&&39!==v||(y=y.slice(1,-1));h.push(y)}}return c}var c=["true","false","null","undefined"],d=/^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i,e=RegExp("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|/(?:[^/\\\\]|\\\\.)*/w*|[^\\s:,/][^,\"'{}()/:[\\]]*[^\\s,\"'{}()/:[\\]]|[^\\s]","g"),f=/[\])"'A-Za-z0-9_$]+$/,
61
+ g={"in":1,"return":1,"typeof":1},h={};return{va:[],ga:h,Ab:b,Xa:function(e,m){function k(b,e){var m;if(!A){var l=a.getBindingHandler(b);if(l&&l.preprocess&&!(e=l.preprocess(e,b,k)))return;if(l=h[b])m=e,0<=a.a.o(c,m)?m=!1:(l=m.match(d),m=null===l?!1:l[1]?"Object("+l[1]+")"+l[2]:m),l=m;l&&g.push("'"+b+"':function(_z){"+m+"=_z}")}p&&(e="function(){return "+e+" }");f.push("'"+b+"':"+e)}m=m||{};var f=[],g=[],p=m.valueAccessors,A=m.bindingParams,y="string"===typeof e?b(e):e;a.a.r(y,function(a){k(a.key||
62
+ a.unknown,a.value)});g.length&&k("_ko_property_writers","{"+g.join(",")+" }");return f.join(",")},fd:function(a,b){for(var c=0;c<a.length;c++)if(a[c].key==b)return!0;return!1},Ga:function(b,c,d,e,f){if(b&&a.I(b))!a.Da(b)||f&&b.p()===e||b(e);else if((b=c.get("_ko_property_writers"))&&b[d])b[d](e)}}}();a.b("expressionRewriting",a.h);a.b("expressionRewriting.bindingRewriteValidators",a.h.va);a.b("expressionRewriting.parseObjectLiteral",a.h.Ab);a.b("expressionRewriting.preProcessBindings",a.h.Xa);a.b("expressionRewriting._twoWayBindings",
63
+ a.h.ga);a.b("jsonExpressionRewriting",a.h);a.b("jsonExpressionRewriting.insertPropertyAccessorsIntoJson",a.h.Xa);(function(){function b(a){return 8==a.nodeType&&g.test(f?a.text:a.nodeValue)}function c(a){return 8==a.nodeType&&h.test(f?a.text:a.nodeValue)}function d(a,d){for(var e=a,f=1,l=[];e=e.nextSibling;){if(c(e)&&(f--,0===f))return l;l.push(e);b(e)&&f++}if(!d)throw Error("Cannot find closing comment tag to match: "+a.nodeValue);return null}function e(a,b){var c=d(a,b);return c?0<c.length?c[c.length-
64
+ 1].nextSibling:a.nextSibling:null}var f=t&&"\x3c!--test--\x3e"===t.createComment("test").text,g=f?/^\x3c!--\s*ko(?:\s+([\s\S]+))?\s*--\x3e$/:/^\s*ko(?:\s+([\s\S]+))?\s*$/,h=f?/^\x3c!--\s*\/ko\s*--\x3e$/:/^\s*\/ko\s*$/,l={ul:!0,ol:!0};a.f={aa:{},childNodes:function(a){return b(a)?d(a):a.childNodes},za:function(c){if(b(c)){c=a.f.childNodes(c);for(var d=0,e=c.length;d<e;d++)a.removeNode(c[d])}else a.a.rb(c)},fa:function(c,d){if(b(c)){a.f.za(c);for(var e=c.nextSibling,f=0,l=d.length;f<l;f++)e.parentNode.insertBefore(d[f],
65
+ e)}else a.a.fa(c,d)},qc:function(a,c){b(a)?a.parentNode.insertBefore(c,a.nextSibling):a.firstChild?a.insertBefore(c,a.firstChild):a.appendChild(c)},kc:function(c,d,e){e?b(c)?c.parentNode.insertBefore(d,e.nextSibling):e.nextSibling?c.insertBefore(d,e.nextSibling):c.appendChild(d):a.f.qc(c,d)},firstChild:function(a){return b(a)?!a.nextSibling||c(a.nextSibling)?null:a.nextSibling:a.firstChild},nextSibling:function(a){b(a)&&(a=e(a));return a.nextSibling&&c(a.nextSibling)?null:a.nextSibling},Yc:b,vd:function(a){return(a=
66
+ (f?a.text:a.nodeValue).match(g))?a[1]:null},oc:function(d){if(l[a.a.A(d)]){var k=d.firstChild;if(k){do if(1===k.nodeType){var f;f=k.firstChild;var g=null;if(f){do if(g)g.push(f);else if(b(f)){var h=e(f,!0);h?f=h:g=[f]}else c(f)&&(g=[f]);while(f=f.nextSibling)}if(f=g)for(g=k.nextSibling,h=0;h<f.length;h++)g?d.insertBefore(f[h],g):d.appendChild(f[h])}while(k=k.nextSibling)}}}}})();a.b("virtualElements",a.f);a.b("virtualElements.allowedBindings",a.f.aa);a.b("virtualElements.emptyNode",a.f.za);a.b("virtualElements.insertAfter",
67
+ a.f.kc);a.b("virtualElements.prepend",a.f.qc);a.b("virtualElements.setDomNodeChildren",a.f.fa);(function(){a.S=function(){this.Kc={}};a.a.extend(a.S.prototype,{nodeHasBindings:function(b){switch(b.nodeType){case 1:return null!=b.getAttribute("data-bind")||a.g.getComponentNameForNode(b);case 8:return a.f.Yc(b);default:return!1}},getBindings:function(b,c){var d=this.getBindingsString(b,c),d=d?this.parseBindingsString(d,c,b):null;return a.g.Rb(d,b,c,!1)},getBindingAccessors:function(b,c){var d=this.getBindingsString(b,
68
+ c),d=d?this.parseBindingsString(d,c,b,{valueAccessors:!0}):null;return a.g.Rb(d,b,c,!0)},getBindingsString:function(b){switch(b.nodeType){case 1:return b.getAttribute("data-bind");case 8:return a.f.vd(b);default:return null}},parseBindingsString:function(b,c,d,e){try{var f=this.Kc,g=b+(e&&e.valueAccessors||""),h;if(!(h=f[g])){var l,m="with($context){with($data||{}){return{"+a.h.Xa(b,e)+"}}}";l=new Function("$context","$element",m);h=f[g]=l}return h(c,d)}catch(k){throw k.message="Unable to parse bindings.\nBindings value: "+
69
+ b+"\nMessage: "+k.message,k;}}});a.S.instance=new a.S})();a.b("bindingProvider",a.S);(function(){function b(a){return function(){return a}}function c(a){return a()}function d(b){return a.a.Ea(a.l.w(b),function(a,c){return function(){return b()[c]}})}function e(c,e,k){return"function"===typeof c?d(c.bind(null,e,k)):a.a.Ea(c,b)}function f(a,b){return d(this.getBindings.bind(this,a,b))}function g(b,c,d){var e,k=a.f.firstChild(c),f=a.S.instance,m=f.preprocessNode;if(m){for(;e=k;)k=a.f.nextSibling(e),
70
+ m.call(f,e);k=a.f.firstChild(c)}for(;e=k;)k=a.f.nextSibling(e),h(b,e,d)}function h(b,c,d){var e=!0,k=1===c.nodeType;k&&a.f.oc(c);if(k&&d||a.S.instance.nodeHasBindings(c))e=m(c,null,b,d).shouldBindDescendants;e&&!r[a.a.A(c)]&&g(b,c,!k)}function l(b){var c=[],d={},e=[];a.a.D(b,function X(k){if(!d[k]){var f=a.getBindingHandler(k);f&&(f.after&&(e.push(k),a.a.r(f.after,function(c){if(b[c]){if(-1!==a.a.o(e,c))throw Error("Cannot combine the following bindings, because they have a cyclic dependency: "+e.join(", "));
71
+ X(c)}}),e.length--),c.push({key:k,jc:f}));d[k]=!0}});return c}function m(b,d,e,k){var m=a.a.e.get(b,q);if(!d){if(m)throw Error("You cannot apply bindings multiple times to the same element.");a.a.e.set(b,q,!0)}!m&&k&&a.xc(b,e);var g;if(d&&"function"!==typeof d)g=d;else{var h=a.S.instance,r=h.getBindingAccessors||f,p=a.B(function(){(g=d?d(e,b):r.call(h,b,e))&&e.Q&&e.Q();return g},null,{i:b});g&&p.ca()||(p=null)}var s;if(g){var t=p?function(a){return function(){return c(p()[a])}}:function(a){return g[a]},
72
+ u=function(){return a.a.Ea(p?p():g,c)};u.get=function(a){return g[a]&&c(t(a))};u.has=function(a){return a in g};k=l(g);a.a.r(k,function(c){var d=c.jc.init,k=c.jc.update,f=c.key;if(8===b.nodeType&&!a.f.aa[f])throw Error("The binding '"+f+"' cannot be used with virtual elements");try{"function"==typeof d&&a.l.w(function(){var a=d(b,t(f),u,e.$data,e);if(a&&a.controlsDescendantBindings){if(s!==n)throw Error("Multiple bindings ("+s+" and "+f+") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.");
73
+ s=f}}),"function"==typeof k&&a.B(function(){k(b,t(f),u,e.$data,e)},null,{i:b})}catch(m){throw m.message='Unable to process binding "'+f+": "+g[f]+'"\nMessage: '+m.message,m;}})}return{shouldBindDescendants:s===n}}function k(b){return b&&b instanceof a.R?b:new a.R(b)}a.d={};var r={script:!0,textarea:!0,template:!0};a.getBindingHandler=function(b){return a.d[b]};a.R=function(b,c,d,e,k){function f(){var k=g?b():b,m=a.a.c(k);c?(c.Q&&c.Q(),a.a.extend(l,c),l.Q=r):(l.$parents=[],l.$root=m,l.ko=a);l.$rawData=
74
+ k;l.$data=m;d&&(l[d]=m);e&&e(l,c,m);return l.$data}function m(){return h&&!a.a.Tb(h)}var l=this,g="function"==typeof b&&!a.I(b),h,r;k&&k.exportDependencies?f():(r=a.B(f,null,{ya:m,i:!0}),r.ca()&&(l.Q=r,r.equalityComparer=null,h=[],r.Dc=function(b){h.push(b);a.a.G.qa(b,function(b){a.a.Na(h,b);h.length||(r.k(),l.Q=r=n)})}))};a.R.prototype.createChildContext=function(b,c,d,e){return new a.R(b,this,c,function(a,b){a.$parentContext=b;a.$parent=b.$data;a.$parents=(b.$parents||[]).slice(0);a.$parents.unshift(a.$parent);
75
+ d&&d(a)},e)};a.R.prototype.extend=function(b){return new a.R(this.Q||this.$data,this,null,function(c,d){c.$rawData=d.$rawData;a.a.extend(c,"function"==typeof b?b():b)})};a.R.prototype.ac=function(a,b){return this.createChildContext(a,b,null,{exportDependencies:!0})};var q=a.a.e.J(),p=a.a.e.J();a.xc=function(b,c){if(2==arguments.length)a.a.e.set(b,p,c),c.Q&&c.Q.Dc(b);else return a.a.e.get(b,p)};a.La=function(b,c,d){1===b.nodeType&&a.f.oc(b);return m(b,c,k(d),!0)};a.Ic=function(b,c,d){d=k(d);return a.La(b,
76
+ e(c,d,b),d)};a.hb=function(a,b){1!==b.nodeType&&8!==b.nodeType||g(k(a),b,!0)};a.Ub=function(a,b){!u&&x.jQuery&&(u=x.jQuery);if(b&&1!==b.nodeType&&8!==b.nodeType)throw Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node");b=b||x.document.body;h(k(a),b,!0)};a.nb=function(b){switch(b.nodeType){case 1:case 8:var c=a.xc(b);if(c)return c;if(b.parentNode)return a.nb(b.parentNode)}return n};a.Oc=function(b){return(b=a.nb(b))?b.$data:n};a.b("bindingHandlers",
77
+ a.d);a.b("applyBindings",a.Ub);a.b("applyBindingsToDescendants",a.hb);a.b("applyBindingAccessorsToNode",a.La);a.b("applyBindingsToNode",a.Ic);a.b("contextFor",a.nb);a.b("dataFor",a.Oc)})();(function(b){function c(c,e){var m=f.hasOwnProperty(c)?f[c]:b,k;m?m.Y(e):(m=f[c]=new a.K,m.Y(e),d(c,function(b,d){var e=!(!d||!d.synchronous);g[c]={definition:b,dd:e};delete f[c];k||e?m.notifySubscribers(b):a.Z.Za(function(){m.notifySubscribers(b)})}),k=!0)}function d(a,b){e("getConfig",[a],function(c){c?e("loadComponent",
78
+ [a,c],function(a){b(a,c)}):b(null,null)})}function e(c,d,f,k){k||(k=a.g.loaders.slice(0));var g=k.shift();if(g){var q=g[c];if(q){var p=!1;if(q.apply(g,d.concat(function(a){p?f(null):null!==a?f(a):e(c,d,f,k)}))!==b&&(p=!0,!g.suppressLoaderExceptions))throw Error("Component loaders must supply values by invoking the callback, not by returning values synchronously.");}else e(c,d,f,k)}else f(null)}var f={},g={};a.g={get:function(d,e){var f=g.hasOwnProperty(d)?g[d]:b;f?f.dd?a.l.w(function(){e(f.definition)}):
79
+ a.Z.Za(function(){e(f.definition)}):c(d,e)},$b:function(a){delete g[a]},Nb:e};a.g.loaders=[];a.b("components",a.g);a.b("components.get",a.g.get);a.b("components.clearCachedDefinition",a.g.$b)})();(function(){function b(b,c,d,e){function g(){0===--y&&e(h)}var h={},y=2,v=d.template;d=d.viewModel;v?f(c,v,function(c){a.g.Nb("loadTemplate",[b,c],function(a){h.template=a;g()})}):g();d?f(c,d,function(c){a.g.Nb("loadViewModel",[b,c],function(a){h[l]=a;g()})}):g()}function c(a,b,d){if("function"===typeof b)d(function(a){return new b(a)});
80
+ else if("function"===typeof b[l])d(b[l]);else if("instance"in b){var e=b.instance;d(function(){return e})}else"viewModel"in b?c(a,b.viewModel,d):a("Unknown viewModel value: "+b)}function d(b){switch(a.a.A(b)){case "script":return a.a.na(b.text);case "textarea":return a.a.na(b.value);case "template":if(e(b.content))return a.a.wa(b.content.childNodes)}return a.a.wa(b.childNodes)}function e(a){return x.DocumentFragment?a instanceof DocumentFragment:a&&11===a.nodeType}function f(a,b,c){"string"===typeof b.require?
81
+ O||x.require?(O||x.require)([b.require],c):a("Uses require, but no AMD loader is present"):c(b)}function g(a){return function(b){throw Error("Component '"+a+"': "+b);}}var h={};a.g.register=function(b,c){if(!c)throw Error("Invalid configuration for "+b);if(a.g.wb(b))throw Error("Component "+b+" is already registered");h[b]=c};a.g.wb=function(a){return h.hasOwnProperty(a)};a.g.ud=function(b){delete h[b];a.g.$b(b)};a.g.cc={getConfig:function(a,b){b(h.hasOwnProperty(a)?h[a]:null)},loadComponent:function(a,
82
+ c,d){var e=g(a);f(e,c,function(c){b(a,e,c,d)})},loadTemplate:function(b,c,f){b=g(b);if("string"===typeof c)f(a.a.na(c));else if(c instanceof Array)f(c);else if(e(c))f(a.a.W(c.childNodes));else if(c.element)if(c=c.element,x.HTMLElement?c instanceof HTMLElement:c&&c.tagName&&1===c.nodeType)f(d(c));else if("string"===typeof c){var l=t.getElementById(c);l?f(d(l)):b("Cannot find element with ID "+c)}else b("Unknown element type: "+c);else b("Unknown template value: "+c)},loadViewModel:function(a,b,d){c(g(a),
83
+ b,d)}};var l="createViewModel";a.b("components.register",a.g.register);a.b("components.isRegistered",a.g.wb);a.b("components.unregister",a.g.ud);a.b("components.defaultLoader",a.g.cc);a.g.loaders.push(a.g.cc);a.g.Ec=h})();(function(){function b(b,e){var f=b.getAttribute("params");if(f){var f=c.parseBindingsString(f,e,b,{valueAccessors:!0,bindingParams:!0}),f=a.a.Ea(f,function(c){return a.m(c,null,{i:b})}),g=a.a.Ea(f,function(c){var e=c.p();return c.ca()?a.m({read:function(){return a.a.c(c())},write:a.Da(e)&&
84
+ function(a){c()(a)},i:b}):e});g.hasOwnProperty("$raw")||(g.$raw=f);return g}return{$raw:{}}}a.g.getComponentNameForNode=function(b){var c=a.a.A(b);if(a.g.wb(c)&&(-1!=c.indexOf("-")||"[object HTMLUnknownElement]"==""+b||8>=a.a.C&&b.tagName===c))return c};a.g.Rb=function(c,e,f,g){if(1===e.nodeType){var h=a.g.getComponentNameForNode(e);if(h){c=c||{};if(c.component)throw Error('Cannot use the "component" binding on a custom element matching a component');var l={name:h,params:b(e,f)};c.component=g?function(){return l}:
85
+ l}}return c};var c=new a.S;9>a.a.C&&(a.g.register=function(a){return function(b){t.createElement(b);return a.apply(this,arguments)}}(a.g.register),t.createDocumentFragment=function(b){return function(){var c=b(),f=a.g.Ec,g;for(g in f)f.hasOwnProperty(g)&&c.createElement(g);return c}}(t.createDocumentFragment))})();(function(b){function c(b,c,d){c=c.template;if(!c)throw Error("Component '"+b+"' has no template");b=a.a.wa(c);a.f.fa(d,b)}function d(a,b,c,d){var e=a.createViewModel;return e?e.call(a,
86
+ d,{element:b,templateNodes:c}):d}var e=0;a.d.component={init:function(f,g,h,l,m){function k(){var a=r&&r.dispose;"function"===typeof a&&a.call(r);q=r=null}var r,q,p=a.a.W(a.f.childNodes(f));a.a.G.qa(f,k);a.m(function(){var l=a.a.c(g()),h,v;"string"===typeof l?h=l:(h=a.a.c(l.name),v=a.a.c(l.params));if(!h)throw Error("No component name specified");var n=q=++e;a.g.get(h,function(e){if(q===n){k();if(!e)throw Error("Unknown component '"+h+"'");c(h,e,f);var l=d(e,f,p,v);e=m.createChildContext(l,b,function(a){a.$component=
87
+ l;a.$componentTemplateNodes=p});r=l;a.hb(e,f)}})},null,{i:f});return{controlsDescendantBindings:!0}}};a.f.aa.component=!0})();var Q={"class":"className","for":"htmlFor"};a.d.attr={update:function(b,c){var d=a.a.c(c())||{};a.a.D(d,function(c,d){d=a.a.c(d);var g=!1===d||null===d||d===n;g&&b.removeAttribute(c);8>=a.a.C&&c in Q?(c=Q[c],g?b.removeAttribute(c):b[c]=d):g||b.setAttribute(c,d.toString());"name"===c&&a.a.vc(b,g?"":d.toString())})}};(function(){a.d.checked={after:["value","attr"],init:function(b,
88
+ c,d){function e(){var e=b.checked,f=p?g():e;if(!a.xa.Va()&&(!l||e)){var h=a.l.w(c);if(k){var m=r?h.p():h;q!==f?(e&&(a.a.ra(m,f,!0),a.a.ra(m,q,!1)),q=f):a.a.ra(m,f,e);r&&a.Da(h)&&h(m)}else a.h.Ga(h,d,"checked",f,!0)}}function f(){var d=a.a.c(c());b.checked=k?0<=a.a.o(d,g()):h?d:g()===d}var g=a.rc(function(){return d.has("checkedValue")?a.a.c(d.get("checkedValue")):d.has("value")?a.a.c(d.get("value")):b.value}),h="checkbox"==b.type,l="radio"==b.type;if(h||l){var m=c(),k=h&&a.a.c(m)instanceof Array,
89
+ r=!(k&&m.push&&m.splice),q=k?g():n,p=l||k;l&&!b.name&&a.d.uniqueName.init(b,function(){return!0});a.m(e,null,{i:b});a.a.q(b,"click",e);a.m(f,null,{i:b});m=n}}};a.h.ga.checked=!0;a.d.checkedValue={update:function(b,c){b.value=a.a.c(c())}}})();a.d.css={update:function(b,c){var d=a.a.c(c());null!==d&&"object"==typeof d?a.a.D(d,function(c,d){d=a.a.c(d);a.a.fb(b,c,d)}):(d=a.a.cb(String(d||"")),a.a.fb(b,b.__ko__cssValue,!1),b.__ko__cssValue=d,a.a.fb(b,d,!0))}};a.d.enable={update:function(b,c){var d=a.a.c(c());
90
+ d&&b.disabled?b.removeAttribute("disabled"):d||b.disabled||(b.disabled=!0)}};a.d.disable={update:function(b,c){a.d.enable.update(b,function(){return!a.a.c(c())})}};a.d.event={init:function(b,c,d,e,f){var g=c()||{};a.a.D(g,function(g){"string"==typeof g&&a.a.q(b,g,function(b){var m,k=c()[g];if(k){try{var r=a.a.W(arguments);e=f.$data;r.unshift(e);m=k.apply(e,r)}finally{!0!==m&&(b.preventDefault?b.preventDefault():b.returnValue=!1)}!1===d.get(g+"Bubble")&&(b.cancelBubble=!0,b.stopPropagation&&b.stopPropagation())}})})}};
91
+ a.d.foreach={mc:function(b){return function(){var c=b(),d=a.a.Bb(c);if(!d||"number"==typeof d.length)return{foreach:c,templateEngine:a.X.vb};a.a.c(c);return{foreach:d.data,as:d.as,includeDestroyed:d.includeDestroyed,afterAdd:d.afterAdd,beforeRemove:d.beforeRemove,afterRender:d.afterRender,beforeMove:d.beforeMove,afterMove:d.afterMove,templateEngine:a.X.vb}}},init:function(b,c){return a.d.template.init(b,a.d.foreach.mc(c))},update:function(b,c,d,e,f){return a.d.template.update(b,a.d.foreach.mc(c),
92
+ d,e,f)}};a.h.va.foreach=!1;a.f.aa.foreach=!0;a.d.hasfocus={init:function(b,c,d){function e(e){b.__ko_hasfocusUpdating=!0;var f=b.ownerDocument;if("activeElement"in f){var g;try{g=f.activeElement}catch(k){g=f.body}e=g===b}f=c();a.h.Ga(f,d,"hasfocus",e,!0);b.__ko_hasfocusLastValue=e;b.__ko_hasfocusUpdating=!1}var f=e.bind(null,!0),g=e.bind(null,!1);a.a.q(b,"focus",f);a.a.q(b,"focusin",f);a.a.q(b,"blur",g);a.a.q(b,"focusout",g)},update:function(b,c){var d=!!a.a.c(c());b.__ko_hasfocusUpdating||b.__ko_hasfocusLastValue===
93
+ d||(d?b.focus():b.blur(),!d&&b.__ko_hasfocusLastValue&&b.ownerDocument.body.focus(),a.l.w(a.a.Fa,null,[b,d?"focusin":"focusout"]))}};a.h.ga.hasfocus=!0;a.d.hasFocus=a.d.hasfocus;a.h.ga.hasFocus=!0;a.d.html={init:function(){return{controlsDescendantBindings:!0}},update:function(b,c){a.a.Eb(b,c())}};K("if");K("ifnot",!1,!0);K("with",!0,!1,function(a,c){return a.ac(c)});var L={};a.d.options={init:function(b){if("select"!==a.a.A(b))throw Error("options binding applies only to SELECT elements");for(;0<
94
+ b.length;)b.remove(0);return{controlsDescendantBindings:!0}},update:function(b,c,d){function e(){return a.a.Ma(b.options,function(a){return a.selected})}function f(a,b,c){var d=typeof b;return"function"==d?b(a):"string"==d?a[b]:c}function g(c,e){if(A&&k)a.j.ja(b,a.a.c(d.get("value")),!0);else if(p.length){var f=0<=a.a.o(p,a.j.u(e[0]));a.a.wc(e[0],f);A&&!f&&a.l.w(a.a.Fa,null,[b,"change"])}}var h=b.multiple,l=0!=b.length&&h?b.scrollTop:null,m=a.a.c(c()),k=d.get("valueAllowUnset")&&d.has("value"),r=
95
+ d.get("optionsIncludeDestroyed");c={};var q,p=[];k||(h?p=a.a.ib(e(),a.j.u):0<=b.selectedIndex&&p.push(a.j.u(b.options[b.selectedIndex])));m&&("undefined"==typeof m.length&&(m=[m]),q=a.a.Ma(m,function(b){return r||b===n||null===b||!a.a.c(b._destroy)}),d.has("optionsCaption")&&(m=a.a.c(d.get("optionsCaption")),null!==m&&m!==n&&q.unshift(L)));var A=!1;c.beforeRemove=function(a){b.removeChild(a)};m=g;d.has("optionsAfterRender")&&"function"==typeof d.get("optionsAfterRender")&&(m=function(b,c){g(0,c);
96
+ a.l.w(d.get("optionsAfterRender"),null,[c[0],b!==L?b:n])});a.a.Db(b,q,function(c,e,g){g.length&&(p=!k&&g[0].selected?[a.j.u(g[0])]:[],A=!0);e=b.ownerDocument.createElement("option");c===L?(a.a.bb(e,d.get("optionsCaption")),a.j.ja(e,n)):(g=f(c,d.get("optionsValue"),c),a.j.ja(e,a.a.c(g)),c=f(c,d.get("optionsText"),g),a.a.bb(e,c));return[e]},c,m);a.l.w(function(){k?a.j.ja(b,a.a.c(d.get("value")),!0):(h?p.length&&e().length<p.length:p.length&&0<=b.selectedIndex?a.j.u(b.options[b.selectedIndex])!==p[0]:
97
+ p.length||0<=b.selectedIndex)&&a.a.Fa(b,"change")});a.a.Sc(b);l&&20<Math.abs(l-b.scrollTop)&&(b.scrollTop=l)}};a.d.options.zb=a.a.e.J();a.d.selectedOptions={after:["options","foreach"],init:function(b,c,d){a.a.q(b,"change",function(){var e=c(),f=[];a.a.r(b.getElementsByTagName("option"),function(b){b.selected&&f.push(a.j.u(b))});a.h.Ga(e,d,"selectedOptions",f)})},update:function(b,c){if("select"!=a.a.A(b))throw Error("values binding applies only to SELECT elements");var d=a.a.c(c()),e=b.scrollTop;
98
+ d&&"number"==typeof d.length&&a.a.r(b.getElementsByTagName("option"),function(b){var c=0<=a.a.o(d,a.j.u(b));b.selected!=c&&a.a.wc(b,c)});b.scrollTop=e}};a.h.ga.selectedOptions=!0;a.d.style={update:function(b,c){var d=a.a.c(c()||{});a.a.D(d,function(c,d){d=a.a.c(d);if(null===d||d===n||!1===d)d="";b.style[c]=d})}};a.d.submit={init:function(b,c,d,e,f){if("function"!=typeof c())throw Error("The value for a submit binding must be a function");a.a.q(b,"submit",function(a){var d,e=c();try{d=e.call(f.$data,
99
+ b)}finally{!0!==d&&(a.preventDefault?a.preventDefault():a.returnValue=!1)}})}};a.d.text={init:function(){return{controlsDescendantBindings:!0}},update:function(b,c){a.a.bb(b,c())}};a.f.aa.text=!0;(function(){if(x&&x.navigator)var b=function(a){if(a)return parseFloat(a[1])},c=x.opera&&x.opera.version&&parseInt(x.opera.version()),d=x.navigator.userAgent,e=b(d.match(/^(?:(?!chrome).)*version\/([^ ]*) safari/i)),f=b(d.match(/Firefox\/([^ ]*)/));if(10>a.a.C)var g=a.a.e.J(),h=a.a.e.J(),l=function(b){var c=
100
+ this.activeElement;(c=c&&a.a.e.get(c,h))&&c(b)},m=function(b,c){var d=b.ownerDocument;a.a.e.get(d,g)||(a.a.e.set(d,g,!0),a.a.q(d,"selectionchange",l));a.a.e.set(b,h,c)};a.d.textInput={init:function(b,d,g){function l(c,d){a.a.q(b,c,d)}function h(){var c=a.a.c(d());if(null===c||c===n)c="";u!==n&&c===u?a.a.setTimeout(h,4):b.value!==c&&(s=c,b.value=c)}function y(){t||(u=b.value,t=a.a.setTimeout(v,4))}function v(){clearTimeout(t);u=t=n;var c=b.value;s!==c&&(s=c,a.h.Ga(d(),g,"textInput",c))}var s=b.value,
101
+ t,u,x=9==a.a.C?y:v;10>a.a.C?(l("propertychange",function(a){"value"===a.propertyName&&x(a)}),8==a.a.C&&(l("keyup",v),l("keydown",v)),8<=a.a.C&&(m(b,x),l("dragend",y))):(l("input",v),5>e&&"textarea"===a.a.A(b)?(l("keydown",y),l("paste",y),l("cut",y)):11>c?l("keydown",y):4>f&&(l("DOMAutoComplete",v),l("dragdrop",v),l("drop",v)));l("change",v);a.m(h,null,{i:b})}};a.h.ga.textInput=!0;a.d.textinput={preprocess:function(a,b,c){c("textInput",a)}}})();a.d.uniqueName={init:function(b,c){if(c()){var d="ko_unique_"+
102
+ ++a.d.uniqueName.Nc;a.a.vc(b,d)}}};a.d.uniqueName.Nc=0;a.d.value={after:["options","foreach"],init:function(b,c,d){if("input"!=b.tagName.toLowerCase()||"checkbox"!=b.type&&"radio"!=b.type){var e=["change"],f=d.get("valueUpdate"),g=!1,h=null;f&&("string"==typeof f&&(f=[f]),a.a.ta(e,f),e=a.a.Wb(e));var l=function(){h=null;g=!1;var e=c(),f=a.j.u(b);a.h.Ga(e,d,"value",f)};!a.a.C||"input"!=b.tagName.toLowerCase()||"text"!=b.type||"off"==b.autocomplete||b.form&&"off"==b.form.autocomplete||-1!=a.a.o(e,"propertychange")||
103
+ (a.a.q(b,"propertychange",function(){g=!0}),a.a.q(b,"focus",function(){g=!1}),a.a.q(b,"blur",function(){g&&l()}));a.a.r(e,function(c){var d=l;a.a.sd(c,"after")&&(d=function(){h=a.j.u(b);a.a.setTimeout(l,0)},c=c.substring(5));a.a.q(b,c,d)});var m=function(){var e=a.a.c(c()),f=a.j.u(b);if(null!==h&&e===h)a.a.setTimeout(m,0);else if(e!==f)if("select"===a.a.A(b)){var g=d.get("valueAllowUnset"),f=function(){a.j.ja(b,e,g)};f();g||e===a.j.u(b)?a.a.setTimeout(f,0):a.l.w(a.a.Fa,null,[b,"change"])}else a.j.ja(b,
104
+ e)};a.m(m,null,{i:b})}else a.La(b,{checkedValue:c})},update:function(){}};a.h.ga.value=!0;a.d.visible={update:function(b,c){var d=a.a.c(c()),e="none"!=b.style.display;d&&!e?b.style.display="":!d&&e&&(b.style.display="none")}};(function(b){a.d[b]={init:function(c,d,e,f,g){return a.d.event.init.call(this,c,function(){var a={};a[b]=d();return a},e,f,g)}}})("click");a.P=function(){};a.P.prototype.renderTemplateSource=function(){throw Error("Override renderTemplateSource");};a.P.prototype.createJavaScriptEvaluatorBlock=
105
+ function(){throw Error("Override createJavaScriptEvaluatorBlock");};a.P.prototype.makeTemplateSource=function(b,c){if("string"==typeof b){c=c||t;var d=c.getElementById(b);if(!d)throw Error("Cannot find template with ID "+b);return new a.v.n(d)}if(1==b.nodeType||8==b.nodeType)return new a.v.sa(b);throw Error("Unknown template type: "+b);};a.P.prototype.renderTemplate=function(a,c,d,e){a=this.makeTemplateSource(a,e);return this.renderTemplateSource(a,c,d,e)};a.P.prototype.isTemplateRewritten=function(a,
106
+ c){return!1===this.allowTemplateRewriting?!0:this.makeTemplateSource(a,c).data("isRewritten")};a.P.prototype.rewriteTemplate=function(a,c,d){a=this.makeTemplateSource(a,d);c=c(a.text());a.text(c);a.data("isRewritten",!0)};a.b("templateEngine",a.P);a.Ib=function(){function b(b,c,d,h){b=a.h.Ab(b);for(var l=a.h.va,m=0;m<b.length;m++){var k=b[m].key;if(l.hasOwnProperty(k)){var r=l[k];if("function"===typeof r){if(k=r(b[m].value))throw Error(k);}else if(!r)throw Error("This template engine does not support the '"+
107
+ k+"' binding within its templates");}}d="ko.__tr_ambtns(function($context,$element){return(function(){return{ "+a.h.Xa(b,{valueAccessors:!0})+" } })()},'"+d.toLowerCase()+"')";return h.createJavaScriptEvaluatorBlock(d)+c}var c=/(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'|[^>]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,d=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g;return{Tc:function(b,c,d){c.isTemplateRewritten(b,d)||c.rewriteTemplate(b,function(b){return a.Ib.jd(b,
108
+ c)},d)},jd:function(a,f){return a.replace(c,function(a,c,d,e,k){return b(k,c,d,f)}).replace(d,function(a,c){return b(c,"\x3c!-- ko --\x3e","#comment",f)})},Jc:function(b,c){return a.N.yb(function(d,h){var l=d.nextSibling;l&&l.nodeName.toLowerCase()===c&&a.La(l,b,h)})}}}();a.b("__tr_ambtns",a.Ib.Jc);(function(){a.v={};a.v.n=function(b){if(this.n=b){var c=a.a.A(b);this.eb="script"===c?1:"textarea"===c?2:"template"==c&&b.content&&11===b.content.nodeType?3:4}};a.v.n.prototype.text=function(){var b=1===
109
+ this.eb?"text":2===this.eb?"value":"innerHTML";if(0==arguments.length)return this.n[b];var c=arguments[0];"innerHTML"===b?a.a.Eb(this.n,c):this.n[b]=c};var b=a.a.e.J()+"_";a.v.n.prototype.data=function(c){if(1===arguments.length)return a.a.e.get(this.n,b+c);a.a.e.set(this.n,b+c,arguments[1])};var c=a.a.e.J();a.v.n.prototype.nodes=function(){var b=this.n;if(0==arguments.length)return(a.a.e.get(b,c)||{}).mb||(3===this.eb?b.content:4===this.eb?b:n);a.a.e.set(b,c,{mb:arguments[0]})};a.v.sa=function(a){this.n=
110
+ a};a.v.sa.prototype=new a.v.n;a.v.sa.prototype.text=function(){if(0==arguments.length){var b=a.a.e.get(this.n,c)||{};b.Jb===n&&b.mb&&(b.Jb=b.mb.innerHTML);return b.Jb}a.a.e.set(this.n,c,{Jb:arguments[0]})};a.b("templateSources",a.v);a.b("templateSources.domElement",a.v.n);a.b("templateSources.anonymousTemplate",a.v.sa)})();(function(){function b(b,c,d){var e;for(c=a.f.nextSibling(c);b&&(e=b)!==c;)b=a.f.nextSibling(e),d(e,b)}function c(c,d){if(c.length){var e=c[0],f=c[c.length-1],g=e.parentNode,h=
111
+ a.S.instance,n=h.preprocessNode;if(n){b(e,f,function(a,b){var c=a.previousSibling,d=n.call(h,a);d&&(a===e&&(e=d[0]||b),a===f&&(f=d[d.length-1]||c))});c.length=0;if(!e)return;e===f?c.push(e):(c.push(e,f),a.a.Ba(c,g))}b(e,f,function(b){1!==b.nodeType&&8!==b.nodeType||a.Ub(d,b)});b(e,f,function(b){1!==b.nodeType&&8!==b.nodeType||a.N.Cc(b,[d])});a.a.Ba(c,g)}}function d(a){return a.nodeType?a:0<a.length?a[0]:null}function e(b,e,f,h,q){q=q||{};var p=(b&&d(b)||f||{}).ownerDocument,n=q.templateEngine||g;
112
+ a.Ib.Tc(f,n,p);f=n.renderTemplate(f,h,q,p);if("number"!=typeof f.length||0<f.length&&"number"!=typeof f[0].nodeType)throw Error("Template engine must return an array of DOM nodes");p=!1;switch(e){case "replaceChildren":a.f.fa(b,f);p=!0;break;case "replaceNode":a.a.uc(b,f);p=!0;break;case "ignoreTargetNode":break;default:throw Error("Unknown renderMode: "+e);}p&&(c(f,h),q.afterRender&&a.l.w(q.afterRender,null,[f,h.$data]));return f}function f(b,c,d){return a.I(b)?b():"function"===typeof b?b(c,d):b}
113
+ var g;a.Fb=function(b){if(b!=n&&!(b instanceof a.P))throw Error("templateEngine must inherit from ko.templateEngine");g=b};a.Cb=function(b,c,k,h,q){k=k||{};if((k.templateEngine||g)==n)throw Error("Set a template engine before calling renderTemplate");q=q||"replaceChildren";if(h){var p=d(h);return a.B(function(){var g=c&&c instanceof a.R?c:new a.R(c,null,null,null,{exportDependencies:!0}),n=f(b,g.$data,g),g=e(h,q,n,g,k);"replaceNode"==q&&(h=g,p=d(h))},null,{ya:function(){return!p||!a.a.qb(p)},i:p&&
114
+ "replaceNode"==q?p.parentNode:p})}return a.N.yb(function(d){a.Cb(b,c,k,d,"replaceNode")})};a.pd=function(b,d,g,h,q){function p(a,b){c(b,t);g.afterRender&&g.afterRender(b,a);t=null}function s(a,c){t=q.createChildContext(a,g.as,function(a){a.$index=c});var d=f(b,a,t);return e(null,"ignoreTargetNode",d,t,g)}var t;return a.B(function(){var b=a.a.c(d)||[];"undefined"==typeof b.length&&(b=[b]);b=a.a.Ma(b,function(b){return g.includeDestroyed||b===n||null===b||!a.a.c(b._destroy)});a.l.w(a.a.Db,null,[h,b,
115
+ s,g,p])},null,{i:h})};var h=a.a.e.J();a.d.template={init:function(b,c){var d=a.a.c(c());if("string"==typeof d||d.name)a.f.za(b);else{if("nodes"in d){if(d=d.nodes||[],a.I(d))throw Error('The "nodes" option must be a plain, non-observable array.');}else d=a.f.childNodes(b);d=a.a.nc(d);(new a.v.sa(b)).nodes(d)}return{controlsDescendantBindings:!0}},update:function(b,c,d,e,f){var g=c();c=a.a.c(g);d=!0;e=null;"string"==typeof c?c={}:(g=c.name,"if"in c&&(d=a.a.c(c["if"])),d&&"ifnot"in c&&(d=!a.a.c(c.ifnot)));
116
+ "foreach"in c?e=a.pd(g||b,d&&c.foreach||[],c,b,f):d?(f="data"in c?f.ac(c.data,c.as):f,e=a.Cb(g||b,f,c,b)):a.f.za(b);f=e;(c=a.a.e.get(b,h))&&"function"==typeof c.k&&c.k();a.a.e.set(b,h,f&&f.ca()?f:n)}};a.h.va.template=function(b){b=a.h.Ab(b);return 1==b.length&&b[0].unknown||a.h.fd(b,"name")?null:"This template engine does not support anonymous templates nested within its templates"};a.f.aa.template=!0})();a.b("setTemplateEngine",a.Fb);a.b("renderTemplate",a.Cb);a.a.hc=function(a,c,d){if(a.length&&
117
+ c.length){var e,f,g,h,l;for(e=f=0;(!d||e<d)&&(h=a[f]);++f){for(g=0;l=c[g];++g)if(h.value===l.value){h.moved=l.index;l.moved=h.index;c.splice(g,1);e=g=0;break}e+=g}}};a.a.lb=function(){function b(b,d,e,f,g){var h=Math.min,l=Math.max,m=[],k,n=b.length,q,p=d.length,s=p-n||1,t=n+p+1,v,u,x;for(k=0;k<=n;k++)for(u=v,m.push(v=[]),x=h(p,k+s),q=l(0,k-1);q<=x;q++)v[q]=q?k?b[k-1]===d[q-1]?u[q-1]:h(u[q]||t,v[q-1]||t)+1:q+1:k+1;h=[];l=[];s=[];k=n;for(q=p;k||q;)p=m[k][q]-1,q&&p===m[k][q-1]?l.push(h[h.length]={status:e,
118
+ value:d[--q],index:q}):k&&p===m[k-1][q]?s.push(h[h.length]={status:f,value:b[--k],index:k}):(--q,--k,g.sparse||h.push({status:"retained",value:d[q]}));a.a.hc(s,l,!g.dontLimitMoves&&10*n);return h.reverse()}return function(a,d,e){e="boolean"===typeof e?{dontLimitMoves:e}:e||{};a=a||[];d=d||[];return a.length<d.length?b(a,d,"added","deleted",e):b(d,a,"deleted","added",e)}}();a.b("utils.compareArrays",a.a.lb);(function(){function b(b,c,d,h,l){var m=[],k=a.B(function(){var k=c(d,l,a.a.Ba(m,b))||[];0<
119
+ m.length&&(a.a.uc(m,k),h&&a.l.w(h,null,[d,k,l]));m.length=0;a.a.ta(m,k)},null,{i:b,ya:function(){return!a.a.Tb(m)}});return{ea:m,B:k.ca()?k:n}}var c=a.a.e.J(),d=a.a.e.J();a.a.Db=function(e,f,g,h,l){function m(b,c){w=q[c];u!==c&&(D[b]=w);w.tb(u++);a.a.Ba(w.ea,e);t.push(w);z.push(w)}function k(b,c){if(b)for(var d=0,e=c.length;d<e;d++)c[d]&&a.a.r(c[d].ea,function(a){b(a,d,c[d].ka)})}f=f||[];h=h||{};var r=a.a.e.get(e,c)===n,q=a.a.e.get(e,c)||[],p=a.a.ib(q,function(a){return a.ka}),s=a.a.lb(p,f,h.dontLimitMoves),
120
+ t=[],v=0,u=0,x=[],z=[];f=[];for(var D=[],p=[],w,C=0,B,E;B=s[C];C++)switch(E=B.moved,B.status){case "deleted":E===n&&(w=q[v],w.B&&(w.B.k(),w.B=n),a.a.Ba(w.ea,e).length&&(h.beforeRemove&&(t.push(w),z.push(w),w.ka===d?w=null:f[C]=w),w&&x.push.apply(x,w.ea)));v++;break;case "retained":m(C,v++);break;case "added":E!==n?m(C,E):(w={ka:B.value,tb:a.O(u++)},t.push(w),z.push(w),r||(p[C]=w))}a.a.e.set(e,c,t);k(h.beforeMove,D);a.a.r(x,h.beforeRemove?a.ba:a.removeNode);for(var C=0,r=a.f.firstChild(e),F;w=z[C];C++){w.ea||
121
+ a.a.extend(w,b(e,g,w.ka,l,w.tb));for(v=0;s=w.ea[v];r=s.nextSibling,F=s,v++)s!==r&&a.f.kc(e,s,F);!w.ad&&l&&(l(w.ka,w.ea,w.tb),w.ad=!0)}k(h.beforeRemove,f);for(C=0;C<f.length;++C)f[C]&&(f[C].ka=d);k(h.afterMove,D);k(h.afterAdd,p)}})();a.b("utils.setDomNodeChildrenFromArrayMapping",a.a.Db);a.X=function(){this.allowTemplateRewriting=!1};a.X.prototype=new a.P;a.X.prototype.renderTemplateSource=function(b,c,d,e){if(c=(9>a.a.C?0:b.nodes)?b.nodes():null)return a.a.W(c.cloneNode(!0).childNodes);b=b.text();
122
+ return a.a.na(b,e)};a.X.vb=new a.X;a.Fb(a.X.vb);a.b("nativeTemplateEngine",a.X);(function(){a.xb=function(){var a=this.ed=function(){if(!u||!u.tmpl)return 0;try{if(0<=u.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(b,e,f,g){g=g||t;f=f||{};if(2>a)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var h=b.data("precompiled");h||(h=b.text()||"",h=u.template(null,"{{ko_with $item.koBindingContext}}"+
123
+ h+"{{/ko_with}}"),b.data("precompiled",h));b=[e.$data];e=u.extend({koBindingContext:e},f.templateOptions);e=u.tmpl(h,b,e);e.appendTo(g.createElement("div"));u.fragments={};return e};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+a+" })()) }}"};this.addTemplate=function(a,b){t.write("<script type='text/html' id='"+a+"'>"+b+"\x3c/script>")};0<a&&(u.tmpl.tag.ko_code={open:"__.push($1 || '');"},u.tmpl.tag.ko_with={open:"with($1) {",close:"} "})};a.xb.prototype=
124
+ new a.P;var b=new a.xb;0<b.ed&&a.Fb(b);a.b("jqueryTmplTemplateEngine",a.xb)})()})})();})();
menu-editor.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Admin Menu Editor
4
  Plugin URI: http://w-shadow.com/blog/2008/12/20/admin-menu-editor-for-wordpress/
5
  Description: Lets you directly edit the WordPress admin menu. You can re-order, hide or rename existing menus, add custom menus and more.
6
- Version: 1.8.5
7
  Author: Janis Elsts
8
  Author URI: http://w-shadow.com/blog/
9
  */
@@ -12,15 +12,12 @@ if ( include(dirname(__FILE__) . '/includes/version-conflict-check.php') ) {
12
  return;
13
  }
14
 
15
- if ( !defined('AME_ROOT_DIR') ) {
16
- define('AME_ROOT_DIR', dirname(__FILE__));
17
- }
18
 
19
  //Are we running in the Dashboard?
20
  if ( is_admin() ) {
21
 
22
  //Load the plugin
23
- require 'includes/menu-editor-core.php';
24
  $wp_menu_editor = new WPMenuEditor(__FILE__, 'ws_menu_editor');
25
 
26
  }//is_admin()
3
  Plugin Name: Admin Menu Editor
4
  Plugin URI: http://w-shadow.com/blog/2008/12/20/admin-menu-editor-for-wordpress/
5
  Description: Lets you directly edit the WordPress admin menu. You can re-order, hide or rename existing menus, add custom menus and more.
6
+ Version: 1.8.6
7
  Author: Janis Elsts
8
  Author URI: http://w-shadow.com/blog/
9
  */
12
  return;
13
  }
14
 
15
+ require_once dirname(__FILE__) . '/includes/basic-dependencies.php';
 
 
16
 
17
  //Are we running in the Dashboard?
18
  if ( is_admin() ) {
19
 
20
  //Load the plugin
 
21
  $wp_menu_editor = new WPMenuEditor(__FILE__, 'ws_menu_editor');
22
 
23
  }//is_admin()
modules/actor-selector/actor-selector.js CHANGED
@@ -2,36 +2,24 @@
2
  /// <reference path="../../js/jquery-json.d.ts" />
3
  /// <reference path="../../js/actor-manager.ts" />
4
  var AmeActorSelector = /** @class */ (function () {
5
- function AmeActorSelector(actorManager, isProVersion, currentUserLogin, visibleUsers, ajaxParams) {
 
6
  var _this = this;
7
  this.selectedActor = null;
8
  this.selectedDisplayName = 'All';
9
  this.visibleUsers = [];
10
  this.subscribers = [];
11
  this.isProVersion = false;
 
12
  this.cachedVisibleActors = null;
13
  this.actorManager = actorManager;
14
- if (typeof currentUserLogin !== 'undefined') {
15
- this.currentUserLogin = currentUserLogin;
16
- }
17
- else {
18
- this.currentUserLogin = wsAmeActorSelectorData.currentUserLogin;
19
- }
20
- if (typeof visibleUsers !== 'undefined') {
21
- this.visibleUsers = visibleUsers;
22
- }
23
- else {
24
- this.visibleUsers = wsAmeActorSelectorData.visibleUsers;
25
- }
26
  if (typeof isProVersion !== 'undefined') {
27
  this.isProVersion = isProVersion;
28
  }
29
- if (ajaxParams) {
30
- this.ajaxParams = ajaxParams;
31
- }
32
- else {
33
- this.ajaxParams = wsAmeActorSelectorData;
34
- }
35
  //Discard any users that don't exist / were not loaded by the actor manager.
36
  var _ = AmeActorSelector._;
37
  this.visibleUsers = _.intersection(this.visibleUsers, _.keys(actorManager.getUsers()));
@@ -69,6 +57,7 @@ var AmeActorSelector = /** @class */ (function () {
69
  currentUserLogin: _this.currentUserLogin,
70
  users: _this.actorManager.getUsers(),
71
  visibleUsers: _this.visibleUsers,
 
72
  save: function (userDetails, selectedUsers) {
73
  _this.actorManager.addUsers(userDetails);
74
  _this.visibleUsers = selectedUsers;
@@ -90,7 +79,7 @@ var AmeActorSelector = /** @class */ (function () {
90
  this.selectedActor = actorId;
91
  this.highlightSelectedActor();
92
  if (actorId !== null) {
93
- this.selectedDisplayName = this.actorManager.getActor(actorId).displayName;
94
  }
95
  else {
96
  this.selectedDisplayName = 'All';
@@ -123,16 +112,18 @@ var AmeActorSelector = /** @class */ (function () {
123
  var isSelectedActorVisible = false;
124
  //Build the list of available actors.
125
  actorSelector.empty();
126
- actorSelector.append('<li><a href="#" class="current ws_actor_option ws_no_actor" data-text="All">All</a></li>');
 
 
127
  var visibleActors = this.getVisibleActors();
128
  for (var i = 0; i < visibleActors.length; i++) {
129
  var actor = visibleActors[i], name_1 = this.getNiceName(actor);
130
  actorSelector.append($('<li></li>').append($('<a></a>')
131
- .attr('href', '#' + actor.id)
132
  .attr('data-text', name_1)
133
  .text(name_1)
134
  .addClass('ws_actor_option')));
135
- isSelectedActorVisible = (actor.id === this.selectedActor) || isSelectedActorVisible;
136
  }
137
  if (this.isProVersion) {
138
  var moreUsersText = 'Choose users\u2026';
@@ -145,12 +136,22 @@ var AmeActorSelector = /** @class */ (function () {
145
  if (this.isProVersion) {
146
  actorSelector.show();
147
  }
148
- //If the selected actor is no longer on the list, select "All" instead.
149
  if ((this.selectedActor !== null) && !isSelectedActorVisible) {
150
- this.setSelectedActor(null);
 
 
 
 
 
 
151
  }
152
  this.highlightSelectedActor();
153
  };
 
 
 
 
154
  AmeActorSelector.prototype.getVisibleActors = function () {
155
  var _this = this;
156
  if (this.cachedVisibleActors) {
@@ -192,13 +193,14 @@ var AmeActorSelector = /** @class */ (function () {
192
  return this.actorManager.getUser(this.currentUserLogin);
193
  };
194
  AmeActorSelector.prototype.getNiceName = function (actor) {
195
- var name = actor.displayName;
196
- if (actor instanceof AmeUser) {
197
- if (actor.userLogin === this.currentUserLogin) {
198
- name = 'Current user (' + actor.userLogin + ')';
 
199
  }
200
  else {
201
- name = actor.displayName + ' (' + actor.userLogin + ')';
202
  }
203
  }
204
  return name;
2
  /// <reference path="../../js/jquery-json.d.ts" />
3
  /// <reference path="../../js/actor-manager.ts" />
4
  var AmeActorSelector = /** @class */ (function () {
5
+ function AmeActorSelector(actorManager, isProVersion, allOptionEnabled) {
6
+ if (allOptionEnabled === void 0) { allOptionEnabled = true; }
7
  var _this = this;
8
  this.selectedActor = null;
9
  this.selectedDisplayName = 'All';
10
  this.visibleUsers = [];
11
  this.subscribers = [];
12
  this.isProVersion = false;
13
+ this.allOptionEnabled = true;
14
  this.cachedVisibleActors = null;
15
  this.actorManager = actorManager;
 
 
 
 
 
 
 
 
 
 
 
 
16
  if (typeof isProVersion !== 'undefined') {
17
  this.isProVersion = isProVersion;
18
  }
19
+ this.allOptionEnabled = allOptionEnabled;
20
+ this.currentUserLogin = wsAmeActorSelectorData.currentUserLogin;
21
+ this.visibleUsers = wsAmeActorSelectorData.visibleUsers;
22
+ this.ajaxParams = wsAmeActorSelectorData;
 
 
23
  //Discard any users that don't exist / were not loaded by the actor manager.
24
  var _ = AmeActorSelector._;
25
  this.visibleUsers = _.intersection(this.visibleUsers, _.keys(actorManager.getUsers()));
57
  currentUserLogin: _this.currentUserLogin,
58
  users: _this.actorManager.getUsers(),
59
  visibleUsers: _this.visibleUsers,
60
+ actorManager: _this.actorManager,
61
  save: function (userDetails, selectedUsers) {
62
  _this.actorManager.addUsers(userDetails);
63
  _this.visibleUsers = selectedUsers;
79
  this.selectedActor = actorId;
80
  this.highlightSelectedActor();
81
  if (actorId !== null) {
82
+ this.selectedDisplayName = this.actorManager.getActor(actorId).getDisplayName();
83
  }
84
  else {
85
  this.selectedDisplayName = 'All';
112
  var isSelectedActorVisible = false;
113
  //Build the list of available actors.
114
  actorSelector.empty();
115
+ if (this.allOptionEnabled) {
116
+ actorSelector.append('<li><a href="#" class="current ws_actor_option ws_no_actor" data-text="All">All</a></li>');
117
+ }
118
  var visibleActors = this.getVisibleActors();
119
  for (var i = 0; i < visibleActors.length; i++) {
120
  var actor = visibleActors[i], name_1 = this.getNiceName(actor);
121
  actorSelector.append($('<li></li>').append($('<a></a>')
122
+ .attr('href', '#' + actor.getId())
123
  .attr('data-text', name_1)
124
  .text(name_1)
125
  .addClass('ws_actor_option')));
126
+ isSelectedActorVisible = (actor.getId() === this.selectedActor) || isSelectedActorVisible;
127
  }
128
  if (this.isProVersion) {
129
  var moreUsersText = 'Choose users\u2026';
136
  if (this.isProVersion) {
137
  actorSelector.show();
138
  }
139
+ //If the selected actor is no longer on the list, select the first available option instead.
140
  if ((this.selectedActor !== null) && !isSelectedActorVisible) {
141
+ if (this.allOptionEnabled) {
142
+ this.setSelectedActor(null);
143
+ }
144
+ else {
145
+ var availableActors = this.getVisibleActors();
146
+ this.setSelectedActor(AmeActorSelector._.first(availableActors).getId());
147
+ }
148
  }
149
  this.highlightSelectedActor();
150
  };
151
+ AmeActorSelector.prototype.repopulate = function () {
152
+ this.cachedVisibleActors = null;
153
+ this.populateActorSelector();
154
+ };
155
  AmeActorSelector.prototype.getVisibleActors = function () {
156
  var _this = this;
157
  if (this.cachedVisibleActors) {
193
  return this.actorManager.getUser(this.currentUserLogin);
194
  };
195
  AmeActorSelector.prototype.getNiceName = function (actor) {
196
+ var name = actor.getDisplayName();
197
+ if (actor.hasOwnProperty('userLogin')) {
198
+ var user = actor;
199
+ if (user.userLogin === this.currentUserLogin) {
200
+ name = 'Current user (' + user.userLogin + ')';
201
  }
202
  else {
203
+ name = user.getDisplayName() + ' (' + user.userLogin + ')';
204
  }
205
  }
206
  return name;
modules/actor-selector/actor-selector.ts CHANGED
@@ -31,37 +31,31 @@ class AmeActorSelector {
31
 
32
  private visibleUsers: string[] = [];
33
  private subscribers: SelectedActorChangedCallback[] = [];
34
- private actorManager: AmeActorManager;
35
- private currentUserLogin: string;
36
- private isProVersion: boolean = false;
37
  private ajaxParams: SaveVisibleActorAjaxParams;
 
38
 
39
- private cachedVisibleActors: AmeBaseActor[] = null;
40
 
41
  private selectorNode;
42
 
43
- constructor(actorManager: AmeActorManager, isProVersion?: boolean, currentUserLogin?: string, visibleUsers?: string[], ajaxParams?: SaveVisibleActorAjaxParams) {
 
 
 
 
44
  this.actorManager = actorManager;
45
 
46
- if (typeof currentUserLogin !== 'undefined') {
47
- this.currentUserLogin = currentUserLogin;
48
- } else {
49
- this.currentUserLogin = wsAmeActorSelectorData.currentUserLogin;
50
- }
51
- if (typeof visibleUsers !== 'undefined') {
52
- this.visibleUsers = visibleUsers;
53
- } else {
54
- this.visibleUsers = wsAmeActorSelectorData.visibleUsers;
55
- }
56
  if (typeof isProVersion !== 'undefined') {
57
  this.isProVersion = isProVersion;
58
  }
 
59
 
60
- if (ajaxParams) {
61
- this.ajaxParams = ajaxParams;
62
- } else {
63
- this.ajaxParams = wsAmeActorSelectorData;
64
- }
65
 
66
  //Discard any users that don't exist / were not loaded by the actor manager.
67
  const _ = AmeActorSelector._;
@@ -104,6 +98,7 @@ class AmeActorSelector {
104
  currentUserLogin: this.currentUserLogin,
105
  users: this.actorManager.getUsers(),
106
  visibleUsers: this.visibleUsers,
 
107
 
108
  save: (userDetails, selectedUsers) => {
109
  this.actorManager.addUsers(userDetails);
@@ -130,7 +125,7 @@ class AmeActorSelector {
130
  this.highlightSelectedActor();
131
 
132
  if (actorId !== null) {
133
- this.selectedDisplayName = this.actorManager.getActor(actorId).displayName;
134
  } else {
135
  this.selectedDisplayName = 'All';
136
  }
@@ -168,7 +163,9 @@ class AmeActorSelector {
168
 
169
  //Build the list of available actors.
170
  actorSelector.empty();
171
- actorSelector.append('<li><a href="#" class="current ws_actor_option ws_no_actor" data-text="All">All</a></li>');
 
 
172
 
173
  const visibleActors = this.getVisibleActors();
174
  for (let i = 0; i < visibleActors.length; i++) {
@@ -178,13 +175,13 @@ class AmeActorSelector {
178
  actorSelector.append(
179
  $('<li></li>').append(
180
  $('<a></a>')
181
- .attr('href', '#' + actor.id)
182
  .attr('data-text', name)
183
  .text(name)
184
  .addClass('ws_actor_option')
185
  )
186
  );
187
- isSelectedActorVisible = (actor.id === this.selectedActor) || isSelectedActorVisible;
188
  }
189
 
190
  if (this.isProVersion) {
@@ -204,15 +201,25 @@ class AmeActorSelector {
204
  actorSelector.show();
205
  }
206
 
207
- //If the selected actor is no longer on the list, select "All" instead.
208
  if ((this.selectedActor !== null) && !isSelectedActorVisible) {
209
- this.setSelectedActor(null);
 
 
 
 
 
210
  }
211
 
212
  this.highlightSelectedActor();
213
  }
214
 
215
- getVisibleActors(): AmeBaseActor[] {
 
 
 
 
 
216
  if (this.cachedVisibleActors) {
217
  return this.cachedVisibleActors;
218
  }
@@ -257,17 +264,18 @@ class AmeActorSelector {
257
  );
258
  }
259
 
260
- getCurrentUserActor(): AmeUser {
261
  return this.actorManager.getUser(this.currentUserLogin);
262
  }
263
 
264
- getNiceName(actor: AmeBaseActor): string {
265
- let name = actor.displayName;
266
- if (actor instanceof AmeUser) {
267
- if (actor.userLogin === this.currentUserLogin) {
268
- name = 'Current user (' + actor.userLogin + ')';
 
269
  } else {
270
- name = actor.displayName + ' (' + actor.userLogin + ')';
271
  }
272
  }
273
  return name;
31
 
32
  private visibleUsers: string[] = [];
33
  private subscribers: SelectedActorChangedCallback[] = [];
34
+ private readonly actorManager: AmeActorManagerInterface;
35
+ private readonly currentUserLogin: string;
36
+ private readonly isProVersion: boolean = false;
37
  private ajaxParams: SaveVisibleActorAjaxParams;
38
+ private readonly allOptionEnabled: boolean = true;
39
 
40
+ private cachedVisibleActors: IAmeActor[] = null;
41
 
42
  private selectorNode;
43
 
44
+ constructor(
45
+ actorManager: AmeActorManagerInterface,
46
+ isProVersion?: boolean,
47
+ allOptionEnabled: boolean = true
48
+ ) {
49
  this.actorManager = actorManager;
50
 
 
 
 
 
 
 
 
 
 
 
51
  if (typeof isProVersion !== 'undefined') {
52
  this.isProVersion = isProVersion;
53
  }
54
+ this.allOptionEnabled = allOptionEnabled;
55
 
56
+ this.currentUserLogin = wsAmeActorSelectorData.currentUserLogin;
57
+ this.visibleUsers = wsAmeActorSelectorData.visibleUsers;
58
+ this.ajaxParams = wsAmeActorSelectorData;
 
 
59
 
60
  //Discard any users that don't exist / were not loaded by the actor manager.
61
  const _ = AmeActorSelector._;
98
  currentUserLogin: this.currentUserLogin,
99
  users: this.actorManager.getUsers(),
100
  visibleUsers: this.visibleUsers,
101
+ actorManager: this.actorManager,
102
 
103
  save: (userDetails, selectedUsers) => {
104
  this.actorManager.addUsers(userDetails);
125
  this.highlightSelectedActor();
126
 
127
  if (actorId !== null) {
128
+ this.selectedDisplayName = this.actorManager.getActor(actorId).getDisplayName();
129
  } else {
130
  this.selectedDisplayName = 'All';
131
  }
163
 
164
  //Build the list of available actors.
165
  actorSelector.empty();
166
+ if (this.allOptionEnabled) {
167
+ actorSelector.append('<li><a href="#" class="current ws_actor_option ws_no_actor" data-text="All">All</a></li>');
168
+ }
169
 
170
  const visibleActors = this.getVisibleActors();
171
  for (let i = 0; i < visibleActors.length; i++) {
175
  actorSelector.append(
176
  $('<li></li>').append(
177
  $('<a></a>')
178
+ .attr('href', '#' + actor.getId())
179
  .attr('data-text', name)
180
  .text(name)
181
  .addClass('ws_actor_option')
182
  )
183
  );
184
+ isSelectedActorVisible = (actor.getId() === this.selectedActor) || isSelectedActorVisible;
185
  }
186
 
187
  if (this.isProVersion) {
201
  actorSelector.show();
202
  }
203
 
204
+ //If the selected actor is no longer on the list, select the first available option instead.
205
  if ((this.selectedActor !== null) && !isSelectedActorVisible) {
206
+ if (this.allOptionEnabled) {
207
+ this.setSelectedActor(null);
208
+ } else {
209
+ const availableActors = this.getVisibleActors();
210
+ this.setSelectedActor(AmeActorSelector._.first(availableActors).getId());
211
+ }
212
  }
213
 
214
  this.highlightSelectedActor();
215
  }
216
 
217
+ repopulate() {
218
+ this.cachedVisibleActors = null;
219
+ this.populateActorSelector();
220
+ }
221
+
222
+ getVisibleActors(): IAmeActor[] {
223
  if (this.cachedVisibleActors) {
224
  return this.cachedVisibleActors;
225
  }
264
  );
265
  }
266
 
267
+ getCurrentUserActor(): IAmeUser {
268
  return this.actorManager.getUser(this.currentUserLogin);
269
  }
270
 
271
+ getNiceName(actor: IAmeActor): string {
272
+ let name = actor.getDisplayName();
273
+ if (actor.hasOwnProperty('userLogin')) {
274
+ const user = actor as IAmeUser;
275
+ if (user.userLogin === this.currentUserLogin) {
276
+ name = 'Current user (' + user.userLogin + ')';
277
  } else {
278
+ name = user.getDisplayName() + ' (' + user.userLogin + ')';
279
  }
280
  }
281
  return name;
modules/plugin-visibility/plugin-visibility-template.php CHANGED
@@ -2,8 +2,6 @@
2
  /**
3
  * @var string $tabUrl Fully qualified URL of the "Plugins" tab.
4
  */
5
-
6
- do_action('admin_menu_editor-display_header');
7
  ?>
8
 
9
  <div id="ame-plugin-visibility-editor">
@@ -143,5 +141,3 @@ do_action('admin_menu_editor-display_header');
143
  </table>
144
 
145
  </div> <!-- /module container -->
146
-
147
- <?php do_action('admin_menu_editor-display_footer'); ?>
2
  /**
3
  * @var string $tabUrl Fully qualified URL of the "Plugins" tab.
4
  */
 
 
5
  ?>
6
 
7
  <div id="ame-plugin-visibility-editor">
141
  </table>
142
 
143
  </div> <!-- /module container -->
 
 
modules/plugin-visibility/plugin-visibility.php CHANGED
@@ -1,24 +1,33 @@
1
  <?php
2
- class amePluginVisibility {
3
- const OPTION_NAME = 'ws_ame_plugin_visibility';
4
- const TAB_SLUG = 'plugin-visibility';
5
-
6
  const HIDE_USAGE_NOTICE_FLAG = 'ws_ame_hide_pv_notice';
7
 
 
 
 
 
 
 
 
 
 
 
 
8
  private static $lastInstance = null;
9
 
10
  /**
11
- * @var WPMenuEditor
12
  */
13
- private $menuEditor;
14
- private $settings = array();
15
-
16
  private $dismissNoticeAction;
17
 
18
  public function __construct($menuEditor) {
19
- $this->menuEditor = $menuEditor;
20
  self::$lastInstance = $this;
21
 
 
 
 
 
22
  //Remove "hidden" plugins from the list on the "Plugins -> Installed Plugins" page.
23
  add_filter('all_plugins', array($this, 'filterPluginList'), 15);
24
 
@@ -28,14 +37,8 @@ class amePluginVisibility {
28
  add_action('check_admin_referer', array($this, 'authorizePluginAction'));
29
 
30
  //Register the plugin visibility tab.
31
- add_action('admin_menu_editor-tabs', array($this, 'addSettingsTab'), 20);
32
- add_action('admin_menu_editor-section-' . self::TAB_SLUG, array($this, 'displayUi'));
33
  add_action('admin_menu_editor-header', array($this, 'handleFormSubmission'), 10, 2);
34
 
35
- //Enqueue scripts and styles.
36
- add_action('admin_menu_editor-enqueue_scripts-' . self::TAB_SLUG, array($this, 'enqueueScripts'));
37
- add_action('admin_menu_editor-enqueue_styles-' . self::TAB_SLUG, array($this, 'enqueueStyles'));
38
-
39
  //Display a usage hint in our tab.
40
  add_action('admin_notices', array($this, 'displayUsageNotice'));
41
  $this->dismissNoticeAction = ajaw_v1_CreateAction('ws_ame_dismiss_pv_usage_notice')
@@ -45,44 +48,6 @@ class amePluginVisibility {
45
  ->register();
46
  }
47
 
48
- public function getSettings() {
49
- if (!empty($this->settings)) {
50
- return $this->settings;
51
- }
52
-
53
- if ( $this->menuEditor->get_plugin_option('menu_config_scope') === 'site' ) {
54
- $json = get_option(self::OPTION_NAME, null);
55
- } else {
56
- $json = get_site_option(self::OPTION_NAME, null);
57
- }
58
-
59
- if ( is_string($json) ) {
60
- $settings = json_decode($json, true);
61
- } else {
62
- $settings = array();
63
- }
64
-
65
- $this->settings = array_merge(
66
- array(
67
- 'plugins' => array(),
68
- 'grantAccessByDefault' => array(),
69
- ),
70
- $settings
71
- );
72
-
73
- return $this->settings;
74
- }
75
-
76
- private function saveSettings() {
77
- //Save per site or site-wide based on plugin configuration.
78
- $settings = json_encode($this->settings);
79
- if ($this->menuEditor->get_plugin_option('menu_config_scope') === 'site') {
80
- update_option(self::OPTION_NAME, $settings);
81
- } else {
82
- WPMenuEditor::atomic_update_site_option(self::OPTION_NAME, $settings);
83
- }
84
- }
85
-
86
  /**
87
  * Check if a plugin is visible to the current user.
88
  *
@@ -107,7 +72,7 @@ class amePluginVisibility {
107
  if ($user === null) {
108
  $user = wp_get_current_user();
109
  }
110
- $settings = $this->getSettings();
111
 
112
  //Do we have custom settings for this plugin?
113
  if (isset($settings['plugins'][$pluginFileName])) {
@@ -190,7 +155,7 @@ class amePluginVisibility {
190
  */
191
  public function filterPluginList($plugins) {
192
  $user = wp_get_current_user();
193
- $settings = $this->getSettings();
194
 
195
  //Don't try to hide plugins outside the WP admin. It prevents WP-CLI from seeing all installed plugins.
196
  if ( !$user->exists() || !is_admin() ) {
@@ -288,15 +253,14 @@ class amePluginVisibility {
288
  }
289
 
290
  public function addSettingsTab($tabs) {
291
- $tabs[self::TAB_SLUG] = 'Plugins';
292
  return $tabs;
293
  }
294
 
295
- public function displayUi() {
296
- /** @noinspection PhpUnusedLocalVariableInspection Used in the "action" attribute of the settings form. */
297
- $tabUrl = $this->getTabUrl();
298
-
299
- require dirname(__FILE__) . '/plugin-visibility-template.php';
300
  }
301
 
302
  public function handleFormSubmission($action, $post = array()) {
@@ -319,15 +283,7 @@ class amePluginVisibility {
319
  }
320
  }
321
 
322
- private function getTabUrl($queryParameters = array()) {
323
- $queryParameters = array_merge(
324
- array('sub_section' => self::TAB_SLUG),
325
- $queryParameters
326
- );
327
- return $this->menuEditor->get_plugin_page_url($queryParameters);
328
- }
329
-
330
- public function enqueueScripts() {
331
  wp_register_auto_versioned_script(
332
  'ame-plugin-visibility',
333
  plugins_url('plugin-visibility.js', __FILE__),
@@ -385,7 +341,7 @@ class amePluginVisibility {
385
  }
386
 
387
  return array(
388
- 'settings' => $this->getSettings(),
389
  'installedPlugins' => $plugins,
390
  'canManagePlugins' => $canManagePlugins,
391
  'isMultisite' => is_multisite(),
@@ -393,7 +349,7 @@ class amePluginVisibility {
393
  );
394
  }
395
 
396
- public function enqueueStyles() {
397
  wp_enqueue_auto_versioned_style(
398
  'ame-plugin-visibility-css',
399
  plugins_url('plugin-visibility.css', __FILE__)
@@ -401,12 +357,12 @@ class amePluginVisibility {
401
  }
402
 
403
  public function displayUsageNotice() {
404
- if ( !$this->menuEditor->is_tab_open(self::TAB_SLUG) ) {
405
  return;
406
  }
407
 
408
  //If the user has already made some changes, they probably don't need to see this notice any more.
409
- $settings = $this->getSettings();
410
  if ( !empty($settings['plugins']) ) {
411
  return;
412
  }
@@ -445,7 +401,7 @@ class amePluginVisibility {
445
  * @param string $pluginFile
446
  */
447
  public function forgetPlugin($pluginFile) {
448
- $settings = $this->getSettings();
449
  unset($settings['plugins'][$pluginFile]);
450
  $this->settings = $settings;
451
  $this->saveSettings();
1
  <?php
2
+ class amePluginVisibility extends amePersistentModule {
 
 
 
3
  const HIDE_USAGE_NOTICE_FLAG = 'ws_ame_hide_pv_notice';
4
 
5
+ protected $optionName = 'ws_ame_plugin_visibility';
6
+
7
+ protected $tabSlug = 'plugin-visibility';
8
+ protected $tabTitle = 'Plugins';
9
+ protected $tabOrder = 20;
10
+
11
+ protected $defaultSettings = array(
12
+ 'plugins' => array(),
13
+ 'grantAccessByDefault' => array(),
14
+ );
15
+
16
  private static $lastInstance = null;
17
 
18
  /**
19
+ * @var Ajaw_v1_Action
20
  */
 
 
 
21
  private $dismissNoticeAction;
22
 
23
  public function __construct($menuEditor) {
24
+ parent::__construct($menuEditor);
25
  self::$lastInstance = $this;
26
 
27
+ if ( !$this->isEnabledForRequest() ) {
28
+ return;
29
+ }
30
+
31
  //Remove "hidden" plugins from the list on the "Plugins -> Installed Plugins" page.
32
  add_filter('all_plugins', array($this, 'filterPluginList'), 15);
33
 
37
  add_action('check_admin_referer', array($this, 'authorizePluginAction'));
38
 
39
  //Register the plugin visibility tab.
 
 
40
  add_action('admin_menu_editor-header', array($this, 'handleFormSubmission'), 10, 2);
41
 
 
 
 
 
42
  //Display a usage hint in our tab.
43
  add_action('admin_notices', array($this, 'displayUsageNotice'));
44
  $this->dismissNoticeAction = ajaw_v1_CreateAction('ws_ame_dismiss_pv_usage_notice')
48
  ->register();
49
  }
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  /**
52
  * Check if a plugin is visible to the current user.
53
  *
72
  if ($user === null) {
73
  $user = wp_get_current_user();
74
  }
75
+ $settings = $this->loadSettings();
76
 
77
  //Do we have custom settings for this plugin?
78
  if (isset($settings['plugins'][$pluginFileName])) {
155
  */
156
  public function filterPluginList($plugins) {
157
  $user = wp_get_current_user();
158
+ $settings = $this->loadSettings();
159
 
160
  //Don't try to hide plugins outside the WP admin. It prevents WP-CLI from seeing all installed plugins.
161
  if ( !$user->exists() || !is_admin() ) {
253
  }
254
 
255
  public function addSettingsTab($tabs) {
256
+ $tabs[$this->tabSlug] = 'Plugins';
257
  return $tabs;
258
  }
259
 
260
+ protected function getTemplateVariables($templateName) {
261
+ $result = parent::getTemplateVariables($templateName);
262
+ $result['tabUrl'] = $this->getTabUrl();
263
+ return $result;
 
264
  }
265
 
266
  public function handleFormSubmission($action, $post = array()) {
283
  }
284
  }
285
 
286
+ public function enqueueTabScripts() {
 
 
 
 
 
 
 
 
287
  wp_register_auto_versioned_script(
288
  'ame-plugin-visibility',
289
  plugins_url('plugin-visibility.js', __FILE__),
341
  }
342
 
343
  return array(
344
+ 'settings' => $this->loadSettings(),
345
  'installedPlugins' => $plugins,
346
  'canManagePlugins' => $canManagePlugins,
347
  'isMultisite' => is_multisite(),
349
  );
350
  }
351
 
352
+ public function enqueueTabStyles() {
353
  wp_enqueue_auto_versioned_style(
354
  'ame-plugin-visibility-css',
355
  plugins_url('plugin-visibility.css', __FILE__)
357
  }
358
 
359
  public function displayUsageNotice() {
360
+ if ( !$this->menuEditor->is_tab_open($this->tabSlug) ) {
361
  return;
362
  }
363
 
364
  //If the user has already made some changes, they probably don't need to see this notice any more.
365
+ $settings = $this->loadSettings();
366
  if ( !empty($settings['plugins']) ) {
367
  return;
368
  }
401
  * @param string $pluginFile
402
  */
403
  public function forgetPlugin($pluginFile) {
404
+ $settings = $this->loadSettings();
405
  unset($settings['plugins'][$pluginFile]);
406
  $this->settings = $settings;
407
  $this->saveSettings();
modules/plugin-visibility/plugin-visibility.ts CHANGED
@@ -61,7 +61,7 @@ class AmePluginVisibilityModule {
61
  * Actors that don't lose access to a plugin when you uncheck it in the "All" view.
62
  * This is a convenience feature that lets the user quickly hide a bunch of plugins from everyone else.
63
  */
64
- private privilegedActors: Array<AmeBaseActor>;
65
 
66
  constructor(scriptData: PluginVisibilityScriptData) {
67
  const _ = AmePluginVisibilityModule._;
61
  * Actors that don't lose access to a plugin when you uncheck it in the "All" view.
62
  * This is a convenience feature that lets the user quickly hide a bunch of plugins from everyone else.
63
  */
64
+ private privilegedActors: Array<IAmeActor>;
65
 
66
  constructor(scriptData: PluginVisibilityScriptData) {
67
  const _ = AmePluginVisibilityModule._;
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: whiteshadow
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A6P9S6CE3SRSW
4
  Tags: admin, dashboard, menu, security, wpmu
5
  Requires at least: 4.1
6
- Tested up to: 4.9
7
- Stable tag: 1.8.4
8
 
9
  Lets you edit the WordPress admin menu. You can re-order, hide or rename menus, add custom menus and more.
10
 
@@ -33,9 +33,9 @@ The [Pro version](http://w-shadow.com/AdminMenuEditor/) lets you set per-role me
33
  **Normal installation**
34
 
35
  1. Download the admin-menu-editor.zip file to your computer.
36
- 1. Unzip the file.
37
- 1. Upload the `admin-menu-editor` directory to your `/wp-content/plugins/` directory.
38
- 1. Activate the plugin through the 'Plugins' menu in WordPress.
39
 
40
  That's it. You can access the the menu editor by going to *Settings -> Menu Editor*. The plugin will automatically load your current menu configuration the first time you run it.
41
 
@@ -44,10 +44,10 @@ That's it. You can access the the menu editor by going to *Settings -> Menu Edit
44
  If you have WordPress set up in Multisite ("Network") mode, you can also install Admin Menu Editor as a global plugin. This will enable you to edit the Dashboard menu for all sites and users at once.
45
 
46
  1. Download the admin-menu-editor.zip file to your computer.
47
- 1. Unzip the file.
48
- 1. Create a new directory named `mu-plugins` in your site's `wp-content` directory (unless it already exists).
49
- 1. Upload the `admin-menu-editor` directory to `/wp-content/mu-plugins/`.
50
- 1. Move `admin-menu-editor-mu.php` from `admin-menu-editor/includes` to `/wp-content/mu-plugins/`.
51
 
52
  Plugins installed in the `mu-plugins` directory are treated as "always on", so you don't need to explicitly activate the menu editor. Just go to *Settings -> Menu Editor* and start customizing your admin menu :)
53
 
@@ -63,6 +63,13 @@ Plugins installed in the `mu-plugins` directory are treated as "always on", so y
63
 
64
  == Changelog ==
65
 
 
 
 
 
 
 
 
66
  = 1.8.5 =
67
  * Fixed a bug where very long submenus wouldn't be scrollable if the current item was one that was moved to the current submenu from a different top level menu.
68
  * Fixed an obscure bug where clicking on an item in the current submenu could cause the entire submenu to "jump" up or down.
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A6P9S6CE3SRSW
4
  Tags: admin, dashboard, menu, security, wpmu
5
  Requires at least: 4.1
6
+ Tested up to: 5.0
7
+ Stable tag: 1.8.6
8
 
9
  Lets you edit the WordPress admin menu. You can re-order, hide or rename menus, add custom menus and more.
10
 
33
  **Normal installation**
34
 
35
  1. Download the admin-menu-editor.zip file to your computer.
36
+ 2. Unzip the file.
37
+ 3. Upload the `admin-menu-editor` directory to your `/wp-content/plugins/` directory.
38
+ 4. Activate the plugin through the 'Plugins' menu in WordPress.
39
 
40
  That's it. You can access the the menu editor by going to *Settings -> Menu Editor*. The plugin will automatically load your current menu configuration the first time you run it.
41
 
44
  If you have WordPress set up in Multisite ("Network") mode, you can also install Admin Menu Editor as a global plugin. This will enable you to edit the Dashboard menu for all sites and users at once.
45
 
46
  1. Download the admin-menu-editor.zip file to your computer.
47
+ 2. Unzip the file.
48
+ 3. Create a new directory named `mu-plugins` in your site's `wp-content` directory (unless it already exists).
49
+ 4. Upload the `admin-menu-editor` directory to `/wp-content/mu-plugins/`.
50
+ 5. Move `admin-menu-editor-mu.php` from `admin-menu-editor/includes` to `/wp-content/mu-plugins/`.
51
 
52
  Plugins installed in the `mu-plugins` directory are treated as "always on", so you don't need to explicitly activate the menu editor. Just go to *Settings -> Menu Editor* and start customizing your admin menu :)
53
 
63
 
64
  == Changelog ==
65
 
66
+ = 1.8.6 =
67
+ * Fixed a PHP warning being thrown when the WPMU_PLUGIN_DIR constant is not a valid path or the full path cannot be determined.
68
+ * Fixed a rare PHP warning "parameter 1 to be array, null given in menu-editor-core.php on line 4254" that was most likely caused by an unidentified plugin conflict.
69
+ * Fixed a rare warning about a class being redefined.
70
+ * Updated a number of internal dependencies.
71
+ * Tested with WP 5.0.
72
+
73
  = 1.8.5 =
74
  * Fixed a bug where very long submenus wouldn't be scrollable if the current item was one that was moved to the current submenu from a different top level menu.
75
  * Fixed an obscure bug where clicking on an item in the current submenu could cause the entire submenu to "jump" up or down.