Admin Columns - Version 2.2.4

Version Description

  • [Added] New filter cpac/storage_model/columns_default for filtering the columns that should be loaded if there are no stored columns
  • [Added] Option (column property hidden) to hide column types from the dropdown list of column types
  • [Added] Use tooltip library for enhanced column value representation
  • [Added] Box for direct feedback on Admin Columns settings screen
  • [Added] Added method for retrieving current storage model (for overview pages such as the posts and page overviews)
  • [Added] Added WooCommerce add-on to list of add-ons
  • [Updated] Hide ACF5 field group post type from list of post types columns settings
  • [Updated] Updated structure of scripts and styles and way of enqueuing them
Download this release

Release Info

Developer engelen
Plugin Icon 128x128 Admin Columns
Version 2.2.4
Comparing to
See all releases

Code changes from version 2.2.3 to 2.2.4

assets/css/admin-column.css CHANGED
@@ -367,6 +367,9 @@ h2.cpac-nav-tab-wrapper {
367
  -webkit-border-radius: 3px;
368
  border-radius: 3px;
369
  }
 
 
 
370
  .cpac-column .column-form table tr.column_width div.description {
371
  font-size: 11px;
372
  width: 12%;
@@ -714,7 +717,7 @@ h2.cpac-nav-tab-wrapper {
714
  text-align: center;
715
  line-height: 64px;
716
  font-weight: bold;
717
- color: #CCC;
718
  display: inline-block;
719
  text-decoration: none;
720
  }
@@ -775,6 +778,9 @@ h2.cpac-nav-tab-wrapper {
775
  .columns-right .sidebox#direct-feedback .inside ul.share li:first-child {
776
  margin-left: 0;
777
  }
 
 
 
778
  /**
779
  * Setting Tab
780
  * ----------------------------------------------------------------------------
367
  -webkit-border-radius: 3px;
368
  border-radius: 3px;
369
  }
370
+ .cpac-column .column-form table tr td.input .section {
371
+ padding: 12px;
372
+ }
373
  .cpac-column .column-form table tr.column_width div.description {
374
  font-size: 11px;
375
  width: 12%;
717
  text-align: center;
718
  line-height: 64px;
719
  font-weight: bold;
720
+ color: #222;
721
  display: inline-block;
722
  text-decoration: none;
723
  }
778
  .columns-right .sidebox#direct-feedback .inside ul.share li:first-child {
779
  margin-left: 0;
780
  }
781
+ .columns-right .sidebox#direct-feedback #feedback-support .inside ul.share li {
782
+ width: 48%;
783
+ }
784
  /**
785
  * Setting Tab
786
  * ----------------------------------------------------------------------------
assets/css/column.css CHANGED
@@ -70,3 +70,29 @@ div.cpac-color span {
70
  div.sizes span.not-available {
71
  color: #999;
72
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  div.sizes span.not-available {
71
  color: #999;
72
  }
73
+ /* =Actions column
74
+ -------------------------------------------------------------- */
75
+ .button.cpac-button-action {
76
+ position: relative;
77
+ text-indent: 9999px;
78
+ margin-right: 4px;
79
+ padding: 0 13px;
80
+ }
81
+ .button.cpac-button-action:before {
82
+ position: absolute;
83
+ top: 0;
84
+ left: 0;
85
+ width: 100%;
86
+ height: 100%;
87
+ text-indent: 0;
88
+ }
89
+ /* =qTip2
90
+ -------------------------------------------------------------- */
91
+ .cpac-tip {
92
+ display: inline-block;
93
+ }
94
+ .qtip.qtip-tipsy {
95
+ background: rgba(0, 0, 0, 0.75);
96
+ font-weight: normal;
97
+ min-width: 25px;
98
+ }
assets/images/addon_sortable_1.png CHANGED
File without changes
assets/images/addons/woocommerce.png ADDED
Binary file
assets/images/arrows.png CHANGED
File without changes
assets/images/checkbox.png CHANGED
File without changes
assets/images/checkmark.png CHANGED
File without changes
assets/images/checkmark_single.png CHANGED
File without changes
assets/images/comment_edit.png CHANGED
File without changes
assets/images/cross.png CHANGED
File without changes
assets/images/facebook.png CHANGED
File without changes
assets/images/icon.png CHANGED
File without changes
assets/images/import_export.png CHANGED
File without changes
assets/images/information.png CHANGED
File without changes
assets/images/loading.gif CHANGED
File without changes
assets/images/no.png CHANGED
File without changes
assets/images/settings.png CHANGED
File without changes
assets/images/sort.png CHANGED
File without changes
assets/images/square.png CHANGED
File without changes
assets/images/trash.png CHANGED
File without changes
assets/images/twitter.png CHANGED
File without changes
assets/js/admin-columns.js CHANGED
@@ -1,648 +1,43 @@
1
- /*
2
- * Fires when the dom is ready
3
- *
4
- */
5
- jQuery(document).ready(function() {
6
-
7
- if ( jQuery('#cpac').length === 0 )
8
- return false;
9
-
10
- // General
11
- cpac_pointer();
12
- cpac_submit_form();
13
-
14
- // Settings Page
15
- cpac_clear_input_defaults();
16
-
17
- // Columns Page
18
- cpac_sortable();
19
- cpac_menu();
20
- cpac_help();
21
- cpac_add_column();
22
- cpac_sidebar_scroll();
23
- cpac_addons();
24
- cpac_importexport();
25
- cpac_sidebar_feedback();
26
-
27
- // we start by binding the toggle and remove events.
28
- jQuery('.cpac-column').each( function( i, col ) {
29
- jQuery( col ).column_bind_toggle();
30
- jQuery( col ).column_bind_remove();
31
- jQuery( col ).cpac_bind_container_addon_events();
32
- });
33
- });
34
-
35
- function cpac_importexport() {
36
- jQuery( '#php-export-results textarea' ).on( 'focus, mouseup', function() {
37
- jQuery( this ).select();
38
- } ).select().focus();
39
- }
40
 
41
  /**
42
- * Handle addons settings screen
43
- *
44
- * @since 2.2
45
- */
46
- function cpac_addons() {
47
-
48
-
49
- }
50
-
51
- /*
52
- * Submit Form
53
- *
54
- * @since 2.0.2
55
- */
56
- function cpac_submit_form() {
57
- jQuery('.form-update a.submit-update').click( function(e){
58
- e.preventDefault();
59
-
60
- jQuery(this).closest('.columns-container').find('.cpac-columns form').submit();
61
- });
62
- }
63
-
64
- /*
65
- * Column: bind toggle events
66
- *
67
- * For performance we bind all other events after the click event.
68
- *
69
- * @since 2.0
70
- */
71
- jQuery.fn.column_bind_toggle = function() {
72
-
73
- var column = jQuery(this);
74
-
75
- column.find( 'td.column_type a, td.column_edit, td.column_label a.toggle, td.column_label .edit-button' ).click( function( e ) {
76
- e.preventDefault();
77
-
78
- column.toggleClass( 'opened' ).find( '.column-form' ).slideToggle( 150 );
79
-
80
- if ( ! column.hasClass( 'events-binded' ) ) {
81
- column.column_bind_events();
82
- }
83
-
84
- column.addClass('events-binded');
85
-
86
- // hook for addons
87
- jQuery( document ).trigger( 'column_init', column );
88
- } );
89
- };
90
-
91
- /*
92
- * Column: bind remove events
93
- *
94
- * @since 2.0
95
- */
96
- jQuery.fn.column_bind_remove = function() {
97
-
98
- jQuery(this).find('.remove-button').click( function(e) {
99
- jQuery(this).closest('.cpac-column').column_remove();
100
-
101
- e.preventDefault();
102
- });
103
- };
104
-
105
- jQuery.fn.cpac_column_refresh = function() {
106
- var el = jQuery( this );
107
-
108
- // Mark column as loading
109
- el.addClass( 'loading' );
110
- el.find( '.column-form' ).prepend( '<span class="spinner" />' );
111
-
112
- // Fetch new form HTML
113
- jQuery.post( ajaxurl, {
114
- action: 'cpac_column_refresh',
115
- column: jQuery( this ).find( 'input.column-name' ).val(),
116
- formdata: jQuery( this ).parents( 'form' ).serialize()
117
- }, function( data ) {
118
- // Replace current form by new form
119
- var newel = jQuery( '<div>' + data + '</div>' ).children();
120
- el.replaceWith( newel );
121
- el = newel;
122
-
123
- // Bind events
124
- el.column_bind_toggle();
125
- el.column_bind_remove();
126
- el.column_bind_events();
127
-
128
- // Remove "loading" marking from column
129
- el.removeClass( 'loading' ).addClass( 'opened' ).find( '.column-form' ).show();
130
-
131
- // Allow plugins to hook into this event
132
- jQuery( document ).trigger( 'column_change', el );
133
- } );
134
- };
135
-
136
- /*
137
- * Form Events
138
- *
139
- * @since 2.0
140
- */
141
- jQuery.fn.column_bind_events = function() {
142
-
143
- var column = jQuery( this );
144
- var container = column.closest( '.columns-container ');
145
- var storage_model = container.attr( 'data-type' );
146
-
147
- // Current column type
148
- var default_value = column.find( '.column_type select option:selected' ).val();
149
-
150
- column.find( '.column_type select' ).change( function() {
151
- var option = jQuery( 'optgroup', this ).children( ':selected' );
152
- var type = option.val();
153
- var label = option.text();
154
- var msg = jQuery( this ).next( '.msg' ).hide();
155
-
156
- // Find template element for this field type
157
- var template = container.find( '.for-cloning-only .cpac-column[data-type="' + type + '"]' );
158
-
159
- if ( template.length ) {
160
- if ( template.find( '.is-disabled' ).length ) {
161
- msg.html( template.find( '.is-disabled' ).html() ).show();
162
-
163
- // Set to default
164
- jQuery(this).find( 'option' ).removeAttr( 'selected' );
165
- jQuery(this).find( 'option[value="' + default_value + '"]' ).attr( 'selected', 'selected' );
166
- }
167
- // Prevent column types that do not allow it to have multiple instances
168
- else if ( typeof template.attr( 'data-clone' ) === 'undefined' && jQuery( '.cpac-columns', container ).find( '[data-type="' + type + '"]' ).length ) {
169
- msg.html( cpac_i18n.clone.replace( '%s', '<strong>' + label + '</strong>' ) ).show();
170
-
171
- // Set to default
172
- jQuery(this).find('option').removeAttr('selected');
173
- jQuery(this).find('option[value="' + default_value + '"]').attr('selected', 'selected');
174
-
175
- return;
176
- }
177
- else {
178
- var clone = template.clone();
179
-
180
- // Open settings
181
- clone.addClass('opened').find('.column-form').show();
182
- clone.find( '.column-meta' ).replaceWith( column.find( '.column-meta' ) );
183
- clone.find( '.column-form' ).replaceWith( column.find( '.column-form' ) );
184
-
185
- // Increment clone id
186
- clone.cpac_update_clone_id( storage_model );
187
-
188
- // Load clone
189
- column.replaceWith( clone );
190
- clone.cpac_column_refresh();
191
- }
192
  }
193
  } );
194
-
195
- /** change label */
196
- column.find('.column_label .input input').bind( 'keyup change', function() {
197
-
198
- var value = jQuery( this ).val();
199
- jQuery(this).closest('.cpac-column').find( 'td.column_label .inner > a.toggle' ).text( value );
200
- });
201
-
202
- /** width slider */
203
- column.find('.input-width-range').each( function(){
204
-
205
- var input = jQuery(this).closest('td').find('.input-width');
206
- var descr = jQuery(this).closest('td').find('.width-decription');
207
- var input_default = jQuery(input)[0].defaultValue;
208
- var translation_default = descr.attr('title');
209
-
210
- // add slider
211
- jQuery(this).slider({
212
- range: 'min',
213
- min: 0,
214
- max: 100,
215
- value: input_default,
216
- slide: function( event, ui ) {
217
-
218
- // set default
219
- var descr_value = ui.value > 0 ? ui.value + '%' : translation_default;
220
-
221
- // set input value
222
- jQuery(input).val( ui.value );
223
-
224
- // set description
225
- jQuery(descr).text( descr_value );
226
- }
227
- });
228
- });
229
-
230
- /** display custom image size */
231
- column.find('.column_image_size label.custom-size').click( function(){
232
-
233
- var parent = jQuery(this).closest('.input');
234
-
235
- if ( jQuery(this).hasClass('image-size-custom') ) {
236
- jQuery('.custom-size-w', parent).removeClass('hidden');
237
- jQuery('.custom-size-h', parent).removeClass('hidden');
238
- }
239
-
240
- else {
241
- jQuery('.custom-size-w', parent).addClass('hidden');
242
- jQuery('.custom-size-h', parent).addClass('hidden');
243
- }
244
- });
245
-
246
- /** tooltip */
247
- column.find('.column-form .label label').hover(function(){
248
- jQuery(this).find('p.description').show();
249
- },function(){
250
- jQuery(this).find('p.description').hide();
251
- });
252
-
253
- if ( column.find( '.column_type select' ).val() == 'column-meta' ) {
254
- column.find( '.column_field_type select' ).change( function() {
255
- column.cpac_column_refresh();
256
- } );
257
- }
258
- };
259
-
260
- /*
261
- * Column: remove from DOM
262
- *
263
- * @since 2.0
264
- */
265
- jQuery.fn.column_remove = function() {
266
- jQuery(this).addClass('deleting').animate({ opacity : 0, height: 0 }, 350, function(e) {
267
- jQuery(this).remove();
268
- });
269
- };
270
-
271
- /*
272
- * Update clone ID
273
- *
274
- * @since 2.0
275
- */
276
- jQuery.fn.cpac_update_clone_id = function( storage_model ) {
277
-
278
- var el = jQuery( this );
279
-
280
- var type = el.attr( 'data-type' );
281
- var all_columns = jQuery( '.columns-container[data-type="' + storage_model + '"]').find( '.cpac-columns' );
282
- var columns = jQuery( all_columns ).find( '*[data-type="' + type + '"]' ).not( el );
283
-
284
- /* var type = el.attr( 'data-type' );
285
- var all_columns = el.closest( '.cpac-boxes' ).find( '.cpac-columns' );
286
- var columns = jQuery( all_columns ).find( '*[data-type="' + type + '"]' ).not( el );*/
287
-
288
- // get clone ID
289
- var ids = jQuery.map( columns, function( e, i ) {
290
- if ( jQuery(e).attr('data-clone') ){
291
- return parseInt( jQuery( e ).attr( 'data-clone' ), 10 );
292
- }
293
- return 0;
294
- });
295
- ids.sort();
296
- var max_id = Math.max.apply( null, ids ) + 1;
297
- for ( var id=0; id<=max_id; id++ ) {
298
- if ( -1 === jQuery.inArray( id, ids ) )
299
- break;
300
- }
301
-
302
- // only increment when needed
303
- if ( 0 === id )
304
- return;
305
-
306
- // set clone ID
307
- el.attr( 'data-clone', id );
308
- el.find( 'input.clone' ).val( id );
309
- el.find( 'input.column-name' ).val( type + '-' + id );
310
-
311
- // update input names with clone ID
312
- var inputs = el.find( 'input, select, label' );
313
- jQuery( inputs ).each( function( i, v ) {
314
-
315
- var new_name = type + '-' + id;
316
-
317
- // name
318
- if( jQuery(v).attr( 'name' ) ) {
319
- jQuery(v).attr( 'name', jQuery(v).attr( 'name' ).replace( type, new_name) );
320
- }
321
-
322
- // for
323
- if( jQuery(v).attr( 'for' ) ) {
324
- jQuery(v).attr( 'for', jQuery(v).attr( 'for' ).replace( type, new_name ) );
325
- }
326
-
327
- // id
328
- if( jQuery(v).attr( 'id' ) ) {
329
- jQuery(v).attr( 'id', jQuery(v).attr( 'id' ).replace( type, new_name ) );
330
- }
331
- });
332
- };
333
-
334
- /*
335
- * Add Column
336
- *
337
- * @since 2.0
338
- */
339
- function cpac_add_column() {
340
-
341
- jQuery('#cpac .add_column').click( function(e){
342
-
343
- var container = jQuery(this).closest('.columns-container');
344
-
345
- var clone = jQuery('.for-cloning-only .cpac-column', container ).first().clone();
346
-
347
- var storage_model = container.attr('data-type');
348
-
349
- if ( clone.length > 0 ) {
350
-
351
- // increment clone id ( before adding to DOM, otherwise radio buttons will reset )
352
- clone.cpac_update_clone_id( storage_model );
353
-
354
- // add to DOM
355
- jQuery('.cpac-columns form', container).append( clone );
356
-
357
- // rebind toggle events
358
- clone.column_bind_toggle();
359
-
360
- // rebind remove events
361
- clone.column_bind_remove();
362
-
363
- // rebind all other events
364
- clone.column_bind_events();
365
-
366
- // open settings
367
- clone.addClass('opened').find('.column-form').slideDown(150, function(){
368
- jQuery('html, body').animate({ scrollTop: clone.offset().top - 58 }, 300);
369
- });
370
-
371
- cpac_sortable();
372
-
373
- // hook for addons
374
- jQuery(document).trigger( 'column_add', clone );
375
- }
376
-
377
- e.preventDefault();
378
- });
379
  }
380
 
381
  /**
382
- * @since 2.2.1
383
  */
384
- function cpac_sidebar_feedback() {
385
- jQuery( function( $ ) {
386
- var sidebox = $( '.sidebox#direct-feedback' );
387
-
388
- sidebox.find( '#feedback-choice a.no' ).click( function( e ) {
389
- e.preventDefault();
390
-
391
- sidebox.find( '#feedback-choice' ).slideUp();
392
- sidebox.find( '#feedback-support' ).slideDown();
393
- } );
394
-
395
- sidebox.find( '#feedback-choice a.yes' ).click( function( e ) {
396
- e.preventDefault();
397
 
398
- sidebox.find( '#feedback-choice' ).slideUp();
399
- sidebox.find( '#feedback-rate' ).slideDown();
400
- } );
401
- } );
402
- }
403
-
404
- /*
405
- * Sidebar Scroll
406
- *
407
- * @since 1.5
408
- */
409
- function cpac_sidebar_scroll() {
410
-
411
- if( jQuery('.columns-right-inside').length === 0 )
412
- return;
413
-
414
- if ( jQuery('.columns-right-inside:visible').offset() ) {
415
-
416
- // top position of the sidebar on loading
417
- var top = jQuery('.columns-right-inside:visible').offset().top - parseFloat( jQuery('.columns-right-inside:visible').css('margin-top').replace(/auto/, 0) ) - 70;
418
-
419
- jQuery(window).scroll(function (event) {
420
- // y position of the scroll
421
- var y = jQuery(this).scrollTop();
422
-
423
- // top position of div#cpac is calculated everytime incase of an opened help screen
424
- var offset = jQuery('#cpac').offset().top - parseFloat( jQuery('#cpac').css('margin-top').replace(/auto/, 0) );
425
-
426
- // whether that's below
427
- if (y >= top + offset ) {
428
- // if so, ad the fixed class
429
- jQuery('.columns-right-inside:visible').addClass('fixed');
430
- } else {
431
- // otherwise remove it
432
- jQuery('.columns-right-inside:visible').removeClass('fixed');
433
- }
434
- });
435
  }
436
- }
437
-
438
- /*
439
- * Clear Input Defaults
440
- *
441
- */
442
- function cpac_clear_input_defaults() {
443
- jQuery.fn.cleardefault = function() {
444
- return this.focus(function() {
445
- if( this.value == this.defaultValue ) {
446
- this.value = "";
447
- }
448
- }).blur(function() {
449
- if( !this.value.length ) {
450
- this.value = this.defaultValue;
451
- }
452
- });
453
- };
454
- jQuery("#cpac-box-plugin_settings .addons input").cleardefault();
455
- }
456
-
457
- /*
458
- * Help
459
- *
460
- * usage: <a href="javascript:;" class="help" data-help="tab-2"></a>
461
- */
462
- function cpac_help() {
463
- jQuery('#cpac a.help').click( function(e) {
464
- e.preventDefault();
465
-
466
- var panel = jQuery('#contextual-help-wrap');
467
-
468
- panel.parent().show();
469
- jQuery('a[href="#tab-panel-cpac-' + jQuery(this).attr('data-help') + '"]', panel).trigger('click');
470
- panel.slideDown( 'fast', function() {
471
- panel.focus();
472
- });
473
- });
474
- }
475
-
476
- /*
477
- * WP Pointer
478
- *
479
- */
480
- function cpac_pointer() {
481
- jQuery('.cpac-pointer').each(function(){
482
 
483
- // vars
484
- var el = jQuery(this),
485
- html = el.attr('rel'),
486
- pos = el.attr('data-pos');
487
-
488
- var position = {
489
- at: 'left top', // position of wp-pointer relative to the element which triggers the pointer event
490
- my: 'right top', // position of wp-pointer relative to the at-coordinates
491
- edge: 'right', // position of arrow
492
- offset: '0 0' // offset for wp-pointer
493
- };
494
-
495
- if ( 'right' == pos ) {
496
- position = {
497
- at: 'right middle',
498
- my: 'left middle',
499
- edge: 'left'
500
- };
501
- }
502
-
503
- // create pointer
504
- el.pointer({
505
- content: jQuery('#' + html).html(),
506
- position: position,
507
- pointerWidth: 250,
508
- close: function() {
509
- el.removeClass('open');
510
- },
511
-
512
- // bug fix. with an arrow on the right side the position of wp-pointer is incorrect. it does not take
513
- // into account the padding of the arrow. adding "wp-pointer-' + position.edge" will fix that.
514
- pointerClass: 'wp-pointer wp-pointer-' + position.edge
515
- });
516
-
517
- // click
518
- el.click( function() {
519
- if( el.hasClass('open') ) {
520
- el.removeClass('open');
521
- }
522
- else {
523
- el.addClass('open');
524
- }
525
- });
526
-
527
- // show on hover
528
- el.hover( function() {
529
- jQuery(this).pointer('open');
530
- }, function() {
531
- if( ! el.hasClass('open') ) {
532
- jQuery(this).pointer('close');
533
- }
534
-
535
- });
536
- });
537
- }
538
-
539
- /*
540
- * Sortable
541
- *
542
- * @since 1.5
543
- */
544
- function cpac_sortable() {
545
- jQuery( 'div.cpac-columns' ).each( function() {
546
- if ( jQuery( this ).hasClass( 'ui-sortable' ) ) {
547
- jQuery( this ).sortable( 'refresh' );
548
- }
549
- else {
550
- jQuery( this ).sortable( {
551
- items : '.cpac-column'
552
- } );
553
- }
554
  } );
555
- }
556
-
557
- /*
558
- * Menu
559
- *
560
- * @since 1.5
561
- */
562
- function cpac_menu() {
563
-
564
- var menu = jQuery('#cpac div.cpac-menu');
565
- // click
566
- menu.find('a').click( function(e, el) {
567
-
568
- var id = jQuery(this).attr('href');
569
-
570
- if ( id ) {
571
-
572
- var type = id.replace('#cpac-box-','');
573
-
574
- // remove current
575
- jQuery('.cpac-menu a').removeClass('current');
576
- jQuery('.columns-container').hide();
577
-
578
- // set current
579
- jQuery(this).addClass('current');
580
- var container = jQuery('.columns-container[data-type="' + type + '"]').show();
581
- var columns = container.find( '.cpac-columns' );
582
 
583
- // hook for addons
584
- jQuery( document ).trigger( 'cac_menu_change', columns );
585
- }
586
-
587
- e.preventDefault();
588
- });
589
-
590
- // activate first menu
591
- menu.find('a.current').trigger('click');
592
- }
593
-
594
- /*
595
- * Bind events: triggered after column is init, changed or added
596
- *
597
- */
598
- jQuery( document ).bind('column_init column_change column_add', function( e, column ){
599
- jQuery( column ).cpac_bind_column_addon_events();
600
- jQuery( column ).cpac_bind_container_addon_events();
601
- });
602
-
603
- /*
604
- * Radio Click events
605
- *
606
- */
607
- jQuery.fn.cpac_bind_column_addon_events = function() {
608
-
609
- var column = jQuery( this );
610
- var inputs = column.find('[data-toggle-id] label');
611
-
612
- // Enable editing: radio button
613
- inputs.click( function(){
614
-
615
- var id = jQuery( this ).closest('td.input').data('toggle-id');
616
- var label = column.find('[data-indicator-id="' + id + '"]' ).removeClass( 'on' );
617
- var status = jQuery( 'input', this ).val();
618
-
619
- if ( 'on' == status ) {
620
- label.addClass( 'on' );
621
- }
622
- });
623
- };
624
-
625
- /*
626
- * Indicator Click Events
627
- *
628
- */
629
- jQuery.fn.cpac_bind_container_addon_events = function() {
630
-
631
- var column = jQuery( this );
632
- var indicator = column.find('[data-indicator-id]');
633
-
634
- indicator.unbind('click').click( function() {
635
-
636
- var id = jQuery( this ).data('indicator-id');
637
- var radio = column.find('[data-toggle-id="' + id + '"] input' );
638
-
639
- if ( jQuery( this ).hasClass('on') ) {
640
- jQuery( this ).removeClass('on').addClass('off');
641
- radio.filter('[value=off]').prop('checked', true);
642
- }
643
- else {
644
- jQuery( this ).removeClass('off').addClass('on');
645
- radio.filter('[value=on]').prop('checked', true);
646
- }
647
- });
648
- };
1
+ jQuery( document ).ready( function( $ ) {
2
+ cpac_tooltips();
3
+
4
+ if ( typeof CPAC.storage_model !== 'undefined' && CPAC.storage_model.is_table_header_fixed ) {
5
+ cpac_floatingheader();
6
+ }
7
+ } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  /**
10
+ * @since 2.2.4
11
+ */
12
+ function cpac_tooltips() {
13
+ jQuery( '.cpac-tip' ).qtip( {
14
+ content: {
15
+ attr: 'data-tip'
16
+ },
17
+ position: {
18
+ my: 'top center',
19
+ at: 'bottom center'
20
+ },
21
+ style: {
22
+ tip: true,
23
+ classes: 'qtip-tipsy'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  }
25
  } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
27
 
28
  /**
29
+ * @since 2.2.4
30
  */
31
+ function cpac_floatingheader() {
32
+ var table = jQuery( 'table.wp-list-table.widefat' );
33
+ var topscroll = 0;
 
 
 
 
 
 
 
 
 
 
34
 
35
+ if ( jQuery( '#wpadminbar' ) ) {
36
+ topscroll = 32;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
+ table.floatThead( {
40
+ scrollingTop: topscroll
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/js/admin-columns.min.js CHANGED
@@ -1,4 +1 @@
1
- /*
2
- * Fires when the dom is ready
3
- *
4
- */function cpac_importexport(){jQuery("#php-export-results textarea").on("focus, mouseup",function(){jQuery(this).select()}).select().focus()}function cpac_addons(){}function cpac_submit_form(){jQuery(".form-update a.submit-update").click(function(e){e.preventDefault();jQuery(this).closest(".columns-container").find(".cpac-columns form").submit()})}function cpac_add_column(){jQuery("#cpac .add_column").click(function(e){var t=jQuery(this).closest(".columns-container"),n=jQuery(".for-cloning-only .cpac-column",t).first().clone(),r=t.attr("data-type");if(n.length>0){n.cpac_update_clone_id(r);jQuery(".cpac-columns form",t).append(n);n.column_bind_toggle();n.column_bind_remove();n.column_bind_events();n.addClass("opened").find(".column-form").slideDown(150,function(){jQuery("html, body").animate({scrollTop:n.offset().top-58},300)});cpac_sortable();jQuery(document).trigger("column_add",n)}e.preventDefault()})}function cpac_sidebar_feedback(){jQuery(function(e){var t=e(".sidebox#direct-feedback");t.find("#feedback-choice a.no").click(function(e){e.preventDefault();t.find("#feedback-choice").slideUp();t.find("#feedback-support").slideDown()});t.find("#feedback-choice a.yes").click(function(e){e.preventDefault();t.find("#feedback-choice").slideUp();t.find("#feedback-rate").slideDown()})})}function cpac_sidebar_scroll(){if(jQuery(".columns-right-inside").length===0)return;if(jQuery(".columns-right-inside:visible").offset()){var e=jQuery(".columns-right-inside:visible").offset().top-parseFloat(jQuery(".columns-right-inside:visible").css("margin-top").replace(/auto/,0))-70;jQuery(window).scroll(function(t){var n=jQuery(this).scrollTop(),r=jQuery("#cpac").offset().top-parseFloat(jQuery("#cpac").css("margin-top").replace(/auto/,0));n>=e+r?jQuery(".columns-right-inside:visible").addClass("fixed"):jQuery(".columns-right-inside:visible").removeClass("fixed")})}}function cpac_clear_input_defaults(){jQuery.fn.cleardefault=function(){return this.focus(function(){this.value==this.defaultValue&&(this.value="")}).blur(function(){this.value.length||(this.value=this.defaultValue)})};jQuery("#cpac-box-plugin_settings .addons input").cleardefault()}function cpac_help(){jQuery("#cpac a.help").click(function(e){e.preventDefault();var t=jQuery("#contextual-help-wrap");t.parent().show();jQuery('a[href="#tab-panel-cpac-'+jQuery(this).attr("data-help")+'"]',t).trigger("click");t.slideDown("fast",function(){t.focus()})})}function cpac_pointer(){jQuery(".cpac-pointer").each(function(){var e=jQuery(this),t=e.attr("rel"),n=e.attr("data-pos"),r={at:"left top",my:"right top",edge:"right",offset:"0 0"};"right"==n&&(r={at:"right middle",my:"left middle",edge:"left"});e.pointer({content:jQuery("#"+t).html(),position:r,pointerWidth:250,close:function(){e.removeClass("open")},pointerClass:"wp-pointer wp-pointer-"+r.edge});e.click(function(){e.hasClass("open")?e.removeClass("open"):e.addClass("open")});e.hover(function(){jQuery(this).pointer("open")},function(){e.hasClass("open")||jQuery(this).pointer("close")})})}function cpac_sortable(){jQuery("div.cpac-columns").each(function(){jQuery(this).hasClass("ui-sortable")?jQuery(this).sortable("refresh"):jQuery(this).sortable({items:".cpac-column"})})}function cpac_menu(){var e=jQuery("#cpac div.cpac-menu");e.find("a").click(function(e,t){var n=jQuery(this).attr("href");if(n){var r=n.replace("#cpac-box-","");jQuery(".cpac-menu a").removeClass("current");jQuery(".columns-container").hide();jQuery(this).addClass("current");var i=jQuery('.columns-container[data-type="'+r+'"]').show(),s=i.find(".cpac-columns");jQuery(document).trigger("cac_menu_change",s)}e.preventDefault()});e.find("a.current").trigger("click")}jQuery(document).ready(function(){if(jQuery("#cpac").length===0)return!1;cpac_pointer();cpac_submit_form();cpac_clear_input_defaults();cpac_sortable();cpac_menu();cpac_help();cpac_add_column();cpac_sidebar_scroll();cpac_addons();cpac_importexport();cpac_sidebar_feedback();jQuery(".cpac-column").each(function(e,t){jQuery(t).column_bind_toggle();jQuery(t).column_bind_remove();jQuery(t).cpac_bind_container_addon_events()})});jQuery.fn.column_bind_toggle=function(){var e=jQuery(this);e.find("td.column_type a, td.column_edit, td.column_label a.toggle, td.column_label .edit-button").click(function(t){t.preventDefault();e.toggleClass("opened").find(".column-form").slideToggle(150);e.hasClass("events-binded")||e.column_bind_events();e.addClass("events-binded");jQuery(document).trigger("column_init",e)})};jQuery.fn.column_bind_remove=function(){jQuery(this).find(".remove-button").click(function(e){jQuery(this).closest(".cpac-column").column_remove();e.preventDefault()})};jQuery.fn.cpac_column_refresh=function(){var e=jQuery(this);e.addClass("loading");e.find(".column-form").prepend('<span class="spinner" />');jQuery.post(ajaxurl,{action:"cpac_column_refresh",column:jQuery(this).find("input.column-name").val(),formdata:jQuery(this).parents("form").serialize()},function(t){var n=jQuery("<div>"+t+"</div>").children();e.replaceWith(n);e=n;e.column_bind_toggle();e.column_bind_remove();e.column_bind_events();e.removeClass("loading").addClass("opened").find(".column-form").show();jQuery(document).trigger("column_change",e)})};jQuery.fn.column_bind_events=function(){var e=jQuery(this),t=e.closest(".columns-container "),n=t.attr("data-type"),r=e.find(".column_type select option:selected").val();e.find(".column_type select").change(function(){var i=jQuery("optgroup",this).children(":selected"),s=i.val(),o=i.text(),u=jQuery(this).next(".msg").hide(),a=t.find('.for-cloning-only .cpac-column[data-type="'+s+'"]');if(a.length)if(a.find(".is-disabled").length){u.html(a.find(".is-disabled").html()).show();jQuery(this).find("option").removeAttr("selected");jQuery(this).find('option[value="'+r+'"]').attr("selected","selected")}else{if(typeof a.attr("data-clone")=="undefined"&&jQuery(".cpac-columns",t).find('[data-type="'+s+'"]').length){u.html(cpac_i18n.clone.replace("%s","<strong>"+o+"</strong>")).show();jQuery(this).find("option").removeAttr("selected");jQuery(this).find('option[value="'+r+'"]').attr("selected","selected");return}var f=a.clone();f.addClass("opened").find(".column-form").show();f.find(".column-meta").replaceWith(e.find(".column-meta"));f.find(".column-form").replaceWith(e.find(".column-form"));f.cpac_update_clone_id(n);e.replaceWith(f);f.cpac_column_refresh()}});e.find(".column_label .input input").bind("keyup change",function(){var e=jQuery(this).val();jQuery(this).closest(".cpac-column").find("td.column_label .inner > a.toggle").text(e)});e.find(".input-width-range").each(function(){var e=jQuery(this).closest("td").find(".input-width"),t=jQuery(this).closest("td").find(".width-decription"),n=jQuery(e)[0].defaultValue,r=t.attr("title");jQuery(this).slider({range:"min",min:0,max:100,value:n,slide:function(n,i){var s=i.value>0?i.value+"%":r;jQuery(e).val(i.value);jQuery(t).text(s)}})});e.find(".column_image_size label.custom-size").click(function(){var e=jQuery(this).closest(".input");if(jQuery(this).hasClass("image-size-custom")){jQuery(".custom-size-w",e).removeClass("hidden");jQuery(".custom-size-h",e).removeClass("hidden")}else{jQuery(".custom-size-w",e).addClass("hidden");jQuery(".custom-size-h",e).addClass("hidden")}});e.find(".column-form .label label").hover(function(){jQuery(this).find("p.description").show()},function(){jQuery(this).find("p.description").hide()});e.find(".column_type select").val()=="column-meta"&&e.find(".column_field_type select").change(function(){e.cpac_column_refresh()})};jQuery.fn.column_remove=function(){jQuery(this).addClass("deleting").animate({opacity:0,height:0},350,function(e){jQuery(this).remove()})};jQuery.fn.cpac_update_clone_id=function(e){var t=jQuery(this),n=t.attr("data-type"),r=jQuery('.columns-container[data-type="'+e+'"]').find(".cpac-columns"),i=jQuery(r).find('*[data-type="'+n+'"]').not(t),s=jQuery.map(i,function(e,t){return jQuery(e).attr("data-clone")?parseInt(jQuery(e).attr("data-clone"),10):0});s.sort();var o=Math.max.apply(null,s)+1;for(var u=0;u<=o;u++)if(-1===jQuery.inArray(u,s))break;if(0===u)return;t.attr("data-clone",u);t.find("input.clone").val(u);t.find("input.column-name").val(n+"-"+u);var a=t.find("input, select, label");jQuery(a).each(function(e,t){var r=n+"-"+u;jQuery(t).attr("name")&&jQuery(t).attr("name",jQuery(t).attr("name").replace(n,r));jQuery(t).attr("for")&&jQuery(t).attr("for",jQuery(t).attr("for").replace(n,r));jQuery(t).attr("id")&&jQuery(t).attr("id",jQuery(t).attr("id").replace(n,r))})};jQuery(document).bind("column_init column_change column_add",function(e,t){jQuery(t).cpac_bind_column_addon_events();jQuery(t).cpac_bind_container_addon_events()});jQuery.fn.cpac_bind_column_addon_events=function(){var e=jQuery(this),t=e.find("[data-toggle-id] label");t.click(function(){var t=jQuery(this).closest("td.input").data("toggle-id"),n=e.find('[data-indicator-id="'+t+'"]').removeClass("on"),r=jQuery("input",this).val();"on"==r&&n.addClass("on")})};jQuery.fn.cpac_bind_container_addon_events=function(){var e=jQuery(this),t=e.find("[data-indicator-id]");t.unbind("click").click(function(){var t=jQuery(this).data("indicator-id"),n=e.find('[data-toggle-id="'+t+'"] input');if(jQuery(this).hasClass("on")){jQuery(this).removeClass("on").addClass("off");n.filter("[value=off]").prop("checked",!0)}else{jQuery(this).removeClass("off").addClass("on");n.filter("[value=on]").prop("checked",!0)}})};
1
+ function cpac_tooltips(){jQuery(".cpac-tip").qtip({content:{attr:"data-tip"},position:{my:"top center",at:"bottom center"},style:{tip:!0,classes:"qtip-tipsy"}})}function cpac_floatingheader(){var e=jQuery("table.wp-list-table.widefat"),t=0;jQuery("#wpadminbar")&&(t=32);e.floatThead({scrollingTop:t})}jQuery(document).ready(function(e){cpac_tooltips();typeof CPAC.storage_model!="undefined"&&CPAC.storage_model.is_table_header_fixed&&cpac_floatingheader()});
 
 
 
assets/js/admin-settings.js ADDED
@@ -0,0 +1,652 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Fires when the dom is ready
3
+ *
4
+ */
5
+ jQuery(document).ready(function() {
6
+
7
+ if ( jQuery('#cpac').length === 0 )
8
+ return false;
9
+
10
+ // General
11
+ cpac_pointer();
12
+ cpac_submit_form();
13
+
14
+ // Settings Page
15
+ cpac_clear_input_defaults();
16
+
17
+ // Columns Page
18
+ cpac_sortable();
19
+ cpac_menu();
20
+ cpac_help();
21
+ cpac_add_column();
22
+ cpac_addons();
23
+ cpac_importexport();
24
+ cpac_sidebar_feedback();
25
+ //cpac_sidebar_scroll();
26
+
27
+ // we start by binding the toggle and remove events.
28
+ jQuery('.cpac-column').each( function( i, col ) {
29
+ jQuery( col ).column_bind_toggle();
30
+ jQuery( col ).column_bind_remove();
31
+ jQuery( col ).cpac_bind_container_addon_events();
32
+ });
33
+ });
34
+
35
+ function cpac_importexport() {
36
+ jQuery( '#php-export-results textarea' ).on( 'focus, mouseup', function() {
37
+ jQuery( this ).select();
38
+ } ).select().focus();
39
+ }
40
+
41
+ /**
42
+ * Handle addons settings screen
43
+ *
44
+ * @since 2.2
45
+ */
46
+ function cpac_addons() {
47
+
48
+
49
+ }
50
+
51
+ /*
52
+ * Submit Form
53
+ *
54
+ * @since 2.0.2
55
+ */
56
+ function cpac_submit_form() {
57
+ jQuery('.form-update a.submit-update').click( function(e){
58
+ e.preventDefault();
59
+
60
+ jQuery(this).closest('.columns-container').find('.cpac-columns form').submit();
61
+ });
62
+ }
63
+
64
+ /*
65
+ * Column: bind toggle events
66
+ *
67
+ * For performance we bind all other events after the click event.
68
+ *
69
+ * @since 2.0
70
+ */
71
+ jQuery.fn.column_bind_toggle = function() {
72
+
73
+ var column = jQuery(this);
74
+
75
+ column.find( 'td.column_type a, td.column_edit, td.column_label a.toggle, td.column_label .edit-button' ).click( function( e ) {
76
+ e.preventDefault();
77
+
78
+ column.toggleClass( 'opened' ).find( '.column-form' ).slideToggle( 150 );
79
+
80
+ if ( ! column.hasClass( 'events-binded' ) ) {
81
+ column.column_bind_events();
82
+ }
83
+
84
+ column.addClass('events-binded');
85
+
86
+ // hook for addons
87
+ jQuery( document ).trigger( 'column_init', column );
88
+ } );
89
+ };
90
+
91
+ /*
92
+ * Column: bind remove events
93
+ *
94
+ * @since 2.0
95
+ */
96
+ jQuery.fn.column_bind_remove = function() {
97
+
98
+ jQuery(this).find('.remove-button').click( function(e) {
99
+ jQuery(this).closest('.cpac-column').column_remove();
100
+
101
+ e.preventDefault();
102
+ });
103
+ };
104
+
105
+ jQuery.fn.cpac_column_refresh = function() {
106
+ var el = jQuery( this );
107
+
108
+ // Mark column as loading
109
+ el.addClass( 'loading' );
110
+ el.find( '.column-form' ).prepend( '<span class="spinner" />' );
111
+
112
+ // Fetch new form HTML
113
+ jQuery.post( ajaxurl, {
114
+ action: 'cpac_column_refresh',
115
+ column: jQuery( this ).find( 'input.column-name' ).val(),
116
+ formdata: jQuery( this ).parents( 'form' ).serialize()
117
+ }, function( data ) {
118
+ console.log(data);
119
+ // Replace current form by new form
120
+ var newel = jQuery( '<div>' + data + '</div>' ).children();
121
+ el.replaceWith( newel );
122
+ el = newel;
123
+
124
+ // Bind events
125
+ el.column_bind_toggle();
126
+ el.column_bind_remove();
127
+ el.column_bind_events();
128
+
129
+ // Remove "loading" marking from column
130
+ el.removeClass( 'loading' ).addClass( 'opened' ).find( '.column-form' ).show();
131
+
132
+ // Allow plugins to hook into this event
133
+ jQuery( document ).trigger( 'column_change', el );
134
+ } );
135
+ };
136
+
137
+ /*
138
+ * Form Events
139
+ *
140
+ * @since 2.0
141
+ */
142
+ jQuery.fn.column_bind_events = function() {
143
+
144
+ var column = jQuery( this );
145
+ var container = column.closest( '.columns-container ');
146
+ var storage_model = container.attr( 'data-type' );
147
+
148
+ // Current column type
149
+ var default_value = column.find( '.column_type select option:selected' ).val();
150
+
151
+ column.find( '.column_type select' ).change( function() {
152
+ var option = jQuery( 'optgroup', this ).children( ':selected' );
153
+ var type = option.val();
154
+ var label = option.text();
155
+ var msg = jQuery( this ).next( '.msg' ).hide();
156
+
157
+ // Find template element for this field type
158
+ var template = container.find( '.for-cloning-only .cpac-column[data-type="' + type + '"]' );
159
+
160
+ if ( template.length ) {
161
+ if ( template.find( '.is-disabled' ).length ) {
162
+ msg.html( template.find( '.is-disabled' ).html() ).show();
163
+
164
+ // Set to default
165
+ jQuery(this).find( 'option' ).removeAttr( 'selected' );
166
+ jQuery(this).find( 'option[value="' + default_value + '"]' ).attr( 'selected', 'selected' );
167
+ }
168
+ // Prevent column types that do not allow it to have multiple instances
169
+ else if ( typeof template.attr( 'data-clone' ) === 'undefined' && jQuery( '.cpac-columns', container ).find( '[data-type="' + type + '"]' ).length ) {
170
+ msg.html( cpac_i18n.clone.replace( '%s', '<strong>' + label + '</strong>' ) ).show();
171
+
172
+ // Set to default
173
+ jQuery(this).find('option').removeAttr('selected');
174
+ jQuery(this).find('option[value="' + default_value + '"]').attr('selected', 'selected');
175
+
176
+ return;
177
+ }
178
+ else {
179
+ var clone = template.clone();
180
+
181
+ // Open settings
182
+ clone.addClass('opened').find('.column-form').show();
183
+ clone.find( '.column-meta' ).replaceWith( column.find( '.column-meta' ) );
184
+ clone.find( '.column-form' ).replaceWith( column.find( '.column-form' ) );
185
+
186
+ // Increment clone id
187
+ clone.cpac_update_clone_id( storage_model );
188
+
189
+ // Load clone
190
+ column.replaceWith( clone );
191
+ clone.cpac_column_refresh();
192
+ }
193
+ }
194
+ } );
195
+
196
+ /** change label */
197
+ column.find('.column_label .input input').bind( 'keyup change', function() {
198
+
199
+ var value = jQuery( this ).val();
200
+ jQuery(this).closest('.cpac-column').find( 'td.column_label .inner > a.toggle' ).text( value );
201
+ });
202
+
203
+ /** width slider */
204
+ column.find('.input-width-range').each( function(){
205
+
206
+ var input = jQuery(this).closest('td').find('.input-width');
207
+ var descr = jQuery(this).closest('td').find('.width-decription');
208
+ var input_default = jQuery(input)[0].defaultValue;
209
+ var translation_default = descr.attr('title');
210
+
211
+ // add slider
212
+ jQuery(this).slider({
213
+ range: 'min',
214
+ min: 0,
215
+ max: 100,
216
+ value: input_default,
217
+ slide: function( event, ui ) {
218
+
219
+ // set default
220
+ var descr_value = ui.value > 0 ? ui.value + '%' : translation_default;
221
+
222
+ // set input value
223
+ jQuery(input).val( ui.value );
224
+
225
+ // set description
226
+ jQuery(descr).text( descr_value );
227
+ }
228
+ });
229
+ });
230
+
231
+ /** display custom image size */
232
+ column.find('.column_image_size label.custom-size').click( function(){
233
+
234
+ var parent = jQuery(this).closest('.input');
235
+
236
+ if ( jQuery(this).hasClass('image-size-custom') ) {
237
+ jQuery('.custom-size-w', parent).removeClass('hidden');
238
+ jQuery('.custom-size-h', parent).removeClass('hidden');
239
+ }
240
+
241
+ else {
242
+ jQuery('.custom-size-w', parent).addClass('hidden');
243
+ jQuery('.custom-size-h', parent).addClass('hidden');
244
+ }
245
+ });
246
+
247
+ /** tooltip */
248
+ column.find('.column-form .label label').hover(function(){
249
+ jQuery(this).find('p.description').show();
250
+ },function(){
251
+ jQuery(this).find('p.description').hide();
252
+ });
253
+
254
+ if ( column.find( '.column_type select' ).val() == 'column-meta' ) {
255
+ column.find( '.column_field_type select' ).change( function() {
256
+ column.cpac_column_refresh();
257
+ } );
258
+ }
259
+ };
260
+
261
+ /*
262
+ * Column: remove from DOM
263
+ *
264
+ * @since 2.0
265
+ */
266
+ jQuery.fn.column_remove = function() {
267
+ jQuery(this).addClass('deleting').animate({ opacity : 0, height: 0 }, 350, function(e) {
268
+ jQuery(this).remove();
269
+ });
270
+ };
271
+
272
+ /*
273
+ * Update clone ID
274
+ *
275
+ * @since 2.0
276
+ */
277
+ jQuery.fn.cpac_update_clone_id = function( storage_model ) {
278
+
279
+ var el = jQuery( this );
280
+
281
+ var type = el.attr( 'data-type' );
282
+ var all_columns = jQuery( '.columns-container[data-type="' + storage_model + '"]').find( '.cpac-columns' );
283
+ var columns = jQuery( all_columns ).find( '*[data-type="' + type + '"]' ).not( el );
284
+
285
+ /* var type = el.attr( 'data-type' );
286
+ var all_columns = el.closest( '.cpac-boxes' ).find( '.cpac-columns' );
287
+ var columns = jQuery( all_columns ).find( '*[data-type="' + type + '"]' ).not( el );*/
288
+
289
+ // get clone ID
290
+ var ids = jQuery.map( columns, function( e, i ) {
291
+ if ( jQuery(e).attr('data-clone') ){
292
+ return parseInt( jQuery( e ).attr( 'data-clone' ), 10 );
293
+ }
294
+ return 0;
295
+ });
296
+ ids.sort();
297
+ var max_id = Math.max.apply( null, ids ) + 1;
298
+ for ( var id=0; id<=max_id; id++ ) {
299
+ if ( -1 === jQuery.inArray( id, ids ) )
300
+ break;
301
+ }
302
+
303
+ // only increment when needed
304
+ if ( 0 === id )
305
+ return;
306
+
307
+ // set clone ID
308
+ el.attr( 'data-clone', id );
309
+ el.find( 'input.clone' ).val( id );
310
+ el.find( 'input.column-name' ).val( type + '-' + id );
311
+
312
+ // update input names with clone ID
313
+ var inputs = el.find( 'input, select, label' );
314
+ jQuery( inputs ).each( function( i, v ) {
315
+
316
+ var new_name = type + '-' + id;
317
+
318
+ // name
319
+ if( jQuery(v).attr( 'name' ) ) {
320
+ jQuery(v).attr( 'name', jQuery(v).attr( 'name' ).replace( type, new_name) );
321
+ }
322
+
323
+ // for
324
+ if( jQuery(v).attr( 'for' ) ) {
325
+ jQuery(v).attr( 'for', jQuery(v).attr( 'for' ).replace( type, new_name ) );
326
+ }
327
+
328
+ // id
329
+ if( jQuery(v).attr( 'id' ) ) {
330
+ jQuery(v).attr( 'id', jQuery(v).attr( 'id' ).replace( type, new_name ) );
331
+ }
332
+ });
333
+ };
334
+
335
+ /*
336
+ * Add Column
337
+ *
338
+ * @since 2.0
339
+ */
340
+ function cpac_add_column() {
341
+
342
+ jQuery('#cpac .add_column').click( function(e){
343
+
344
+ var container = jQuery(this).closest('.columns-container');
345
+
346
+ var clone = jQuery('.for-cloning-only .cpac-column', container ).first().clone();
347
+
348
+ var storage_model = container.attr('data-type');
349
+
350
+ if ( clone.length > 0 ) {
351
+
352
+ // increment clone id ( before adding to DOM, otherwise radio buttons will reset )
353
+ clone.cpac_update_clone_id( storage_model );
354
+
355
+ // add to DOM
356
+ jQuery('.cpac-columns form', container).append( clone );
357
+
358
+ // rebind toggle events
359
+ clone.column_bind_toggle();
360
+
361
+ // rebind remove events
362
+ clone.column_bind_remove();
363
+
364
+ // rebind all other events
365
+ clone.column_bind_events();
366
+
367
+ // open settings
368
+ clone.addClass('opened').find('.column-form').slideDown(150, function(){
369
+ jQuery('html, body').animate({ scrollTop: clone.offset().top - 58 }, 300);
370
+ });
371
+
372
+ cpac_sortable();
373
+
374
+ // hook for addons
375
+ jQuery(document).trigger( 'column_add', clone );
376
+ }
377
+
378
+ e.preventDefault();
379
+ });
380
+ }
381
+
382
+ /**
383
+ * @since 2.2.1
384
+ */
385
+ function cpac_sidebar_feedback() {
386
+ jQuery( function( $ ) {
387
+ var sidebox = $( '.sidebox#direct-feedback' );
388
+
389
+ sidebox.find( '#feedback-choice a.no' ).click( function( e ) {
390
+ e.preventDefault();
391
+
392
+ sidebox.find( '#feedback-choice' ).slideUp();
393
+ sidebox.find( '#feedback-support' ).slideDown();
394
+ } );
395
+
396
+ sidebox.find( '#feedback-choice a.yes' ).click( function( e ) {
397
+ e.preventDefault();
398
+
399
+ sidebox.find( '#feedback-choice' ).slideUp();
400
+ sidebox.find( '#feedback-rate' ).slideDown();
401
+ } );
402
+ } );
403
+ }
404
+
405
+ /*
406
+ * Sidebar Scroll
407
+ *
408
+ * @since 1.5
409
+ */
410
+ /*function cpac_sidebar_scroll() {
411
+
412
+ if ( jQuery('.columns-right-inside').length === 0 ) {
413
+ return;
414
+ }
415
+
416
+ if ( jQuery('.columns-right-inside:visible').offset() ) {
417
+ var sidebar = jQuery('.columns-right-inside:visible');
418
+ var top = sidebar.offset().top - parseFloat( sidebar.css('margin-top').replace(/auto/, 0) ) - 70;
419
+ var viewport_height = jQuery(window).height();
420
+ var sidebar_height = sidebar.height();
421
+
422
+ jQuery(window).scroll(function (event) {
423
+ var y = jQuery(this).scrollTop();
424
+
425
+ // top position of div#cpac is calculated everytime incase of an opened help screen
426
+ var offset = jQuery('#cpac').offset().top - parseFloat( jQuery('#cpac').css('margin-top').replace(/auto/, 0) );
427
+ var sidebar_fits_on_screen = sidebar_height < ( viewport_height - 32 ); // adminbar
428
+
429
+ // whether that's below
430
+ if ( ( y >= top + offset ) && sidebar_fits_on_screen ) {
431
+ jQuery('.columns-right-inside:visible').addClass('fixed');
432
+ } else {
433
+ jQuery('.columns-right-inside:visible').removeClass('fixed');
434
+ }
435
+ });
436
+ }
437
+ }*/
438
+
439
+ /*
440
+ * Clear Input Defaults
441
+ *
442
+ */
443
+ function cpac_clear_input_defaults() {
444
+ jQuery.fn.cleardefault = function() {
445
+ return this.focus(function() {
446
+ if( this.value == this.defaultValue ) {
447
+ this.value = "";
448
+ }
449
+ }).blur(function() {
450
+ if( !this.value.length ) {
451
+ this.value = this.defaultValue;
452
+ }
453
+ });
454
+ };
455
+ jQuery("#cpac-box-plugin_settings .addons input").cleardefault();
456
+ }
457
+
458
+ /*
459
+ * Help
460
+ *
461
+ * usage: <a href="javascript:;" class="help" data-help="tab-2"></a>
462
+ */
463
+ function cpac_help() {
464
+ jQuery('#cpac a.help').click( function(e) {
465
+ e.preventDefault();
466
+
467
+ var panel = jQuery('#contextual-help-wrap');
468
+
469
+ panel.parent().show();
470
+ jQuery('a[href="#tab-panel-cpac-' + jQuery(this).attr('data-help') + '"]', panel).trigger('click');
471
+ panel.slideDown( 'fast', function() {
472
+ panel.focus();
473
+ });
474
+ });
475
+ }
476
+
477
+ /*
478
+ * WP Pointer
479
+ *
480
+ */
481
+ function cpac_pointer() {
482
+ jQuery('.cpac-pointer').each(function(){
483
+
484
+ // vars
485
+ var el = jQuery(this),
486
+ html = el.attr('rel'),
487
+ pos = el.attr('data-pos');
488
+
489
+ var position = {
490
+ at: 'left top', // position of wp-pointer relative to the element which triggers the pointer event
491
+ my: 'right top', // position of wp-pointer relative to the at-coordinates
492
+ edge: 'right', // position of arrow
493
+ offset: '0 0' // offset for wp-pointer
494
+ };
495
+
496
+ if ( 'right' == pos ) {
497
+ position = {
498
+ at: 'right middle',
499
+ my: 'left middle',
500
+ edge: 'left'
501
+ };
502
+ }
503
+
504
+ // create pointer
505
+ el.pointer({
506
+ content: jQuery('#' + html).html(),
507
+ position: position,
508
+ pointerWidth: 250,
509
+ close: function() {
510
+ el.removeClass('open');
511
+ },
512
+
513
+ // bug fix. with an arrow on the right side the position of wp-pointer is incorrect. it does not take
514
+ // into account the padding of the arrow. adding "wp-pointer-' + position.edge" will fix that.
515
+ pointerClass: 'wp-pointer wp-pointer-' + position.edge
516
+ });
517
+
518
+ // click
519
+ el.click( function() {
520
+ if( el.hasClass('open') ) {
521
+ el.removeClass('open');
522
+ }
523
+ else {
524
+ el.addClass('open');
525
+ }
526
+ });
527
+
528
+ // show on hover
529
+ el.hover( function() {
530
+ jQuery(this).pointer('open');
531
+ }, function() {
532
+ if( ! el.hasClass('open') ) {
533
+ jQuery(this).pointer('close');
534
+ }
535
+
536
+ });
537
+ });
538
+ }
539
+
540
+ /*
541
+ * Sortable
542
+ *
543
+ * @since 1.5
544
+ */
545
+ function cpac_sortable() {
546
+ jQuery( 'div.cpac-columns' ).each( function() {
547
+ if ( jQuery( this ).hasClass( 'ui-sortable' ) ) {
548
+ jQuery( this ).sortable( 'refresh' );
549
+ }
550
+ else {
551
+ jQuery( this ).sortable( {
552
+ items : '.cpac-column'
553
+ } );
554
+ }
555
+ } );
556
+ }
557
+
558
+ /*
559
+ * Menu
560
+ *
561
+ * @since 1.5
562
+ */
563
+ function cpac_menu() {
564
+
565
+ var menu = jQuery('#cpac div.cpac-menu');
566
+ // click
567
+ menu.find('a').click( function(e, el) {
568
+
569
+ var id = jQuery(this).attr('href');
570
+
571
+ if ( id ) {
572
+
573
+ var type = id.replace('#cpac-box-','');
574
+
575
+ // remove current
576
+ jQuery('.cpac-menu a').removeClass('current');
577
+ jQuery('.columns-container').hide();
578
+
579
+ // set current
580
+ jQuery(this).addClass('current');
581
+ var container = jQuery('.columns-container[data-type="' + type + '"]').show();
582
+ var columns = container.find( '.cpac-columns' );
583
+
584
+ // hook for addons
585
+ jQuery( document ).trigger( 'cac_menu_change', columns );
586
+ }
587
+
588
+ // re init sidebar scroll
589
+ //cpac_sidebar_scroll();
590
+
591
+ e.preventDefault();
592
+ });
593
+
594
+ // activate first menu
595
+ menu.find('a.current').trigger('click');
596
+ }
597
+
598
+ /*
599
+ * Bind events: triggered after column is init, changed or added
600
+ *
601
+ */
602
+ jQuery( document ).bind('column_init column_change column_add', function( e, column ){
603
+ jQuery( column ).cpac_bind_column_addon_events();
604
+ jQuery( column ).cpac_bind_container_addon_events();
605
+ });
606
+
607
+ /*
608
+ * Radio Click events
609
+ *
610
+ */
611
+ jQuery.fn.cpac_bind_column_addon_events = function() {
612
+
613
+ var column = jQuery( this );
614
+ var inputs = column.find('[data-toggle-id] label');
615
+
616
+ // Enable editing: radio button
617
+ inputs.click( function(){
618
+
619
+ var id = jQuery( this ).closest('td.input').data('toggle-id');
620
+ var label = column.find('[data-indicator-id="' + id + '"]' ).removeClass( 'on' );
621
+ var status = jQuery( 'input', this ).val();
622
+
623
+ if ( 'on' == status ) {
624
+ label.addClass( 'on' );
625
+ }
626
+ });
627
+ };
628
+
629
+ /*
630
+ * Indicator Click Events
631
+ *
632
+ */
633
+ jQuery.fn.cpac_bind_container_addon_events = function() {
634
+
635
+ var column = jQuery( this );
636
+ var indicator = column.find('[data-indicator-id]');
637
+
638
+ indicator.unbind('click').click( function() {
639
+
640
+ var id = jQuery( this ).data('indicator-id');
641
+ var radio = column.find('[data-toggle-id="' + id + '"] input' );
642
+
643
+ if ( jQuery( this ).hasClass('on') ) {
644
+ jQuery( this ).removeClass('on').addClass('off');
645
+ radio.filter('[value=off]').prop('checked', true);
646
+ }
647
+ else {
648
+ jQuery( this ).removeClass('off').addClass('on');
649
+ radio.filter('[value=on]').prop('checked', true);
650
+ }
651
+ });
652
+ };
assets/js/admin-settings.min.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ /*
2
+ * Fires when the dom is ready
3
+ *
4
+ */function cpac_importexport(){jQuery("#php-export-results textarea").on("focus, mouseup",function(){jQuery(this).select()}).select().focus()}function cpac_addons(){}function cpac_submit_form(){jQuery(".form-update a.submit-update").click(function(e){e.preventDefault();jQuery(this).closest(".columns-container").find(".cpac-columns form").submit()})}function cpac_add_column(){jQuery("#cpac .add_column").click(function(e){var t=jQuery(this).closest(".columns-container"),n=jQuery(".for-cloning-only .cpac-column",t).first().clone(),r=t.attr("data-type");if(n.length>0){n.cpac_update_clone_id(r);jQuery(".cpac-columns form",t).append(n);n.column_bind_toggle();n.column_bind_remove();n.column_bind_events();n.addClass("opened").find(".column-form").slideDown(150,function(){jQuery("html, body").animate({scrollTop:n.offset().top-58},300)});cpac_sortable();jQuery(document).trigger("column_add",n)}e.preventDefault()})}function cpac_sidebar_feedback(){jQuery(function(e){var t=e(".sidebox#direct-feedback");t.find("#feedback-choice a.no").click(function(e){e.preventDefault();t.find("#feedback-choice").slideUp();t.find("#feedback-support").slideDown()});t.find("#feedback-choice a.yes").click(function(e){e.preventDefault();t.find("#feedback-choice").slideUp();t.find("#feedback-rate").slideDown()})})}function cpac_clear_input_defaults(){jQuery.fn.cleardefault=function(){return this.focus(function(){this.value==this.defaultValue&&(this.value="")}).blur(function(){this.value.length||(this.value=this.defaultValue)})};jQuery("#cpac-box-plugin_settings .addons input").cleardefault()}function cpac_help(){jQuery("#cpac a.help").click(function(e){e.preventDefault();var t=jQuery("#contextual-help-wrap");t.parent().show();jQuery('a[href="#tab-panel-cpac-'+jQuery(this).attr("data-help")+'"]',t).trigger("click");t.slideDown("fast",function(){t.focus()})})}function cpac_pointer(){jQuery(".cpac-pointer").each(function(){var e=jQuery(this),t=e.attr("rel"),n=e.attr("data-pos"),r={at:"left top",my:"right top",edge:"right",offset:"0 0"};"right"==n&&(r={at:"right middle",my:"left middle",edge:"left"});e.pointer({content:jQuery("#"+t).html(),position:r,pointerWidth:250,close:function(){e.removeClass("open")},pointerClass:"wp-pointer wp-pointer-"+r.edge});e.click(function(){e.hasClass("open")?e.removeClass("open"):e.addClass("open")});e.hover(function(){jQuery(this).pointer("open")},function(){e.hasClass("open")||jQuery(this).pointer("close")})})}function cpac_sortable(){jQuery("div.cpac-columns").each(function(){jQuery(this).hasClass("ui-sortable")?jQuery(this).sortable("refresh"):jQuery(this).sortable({items:".cpac-column"})})}function cpac_menu(){var e=jQuery("#cpac div.cpac-menu");e.find("a").click(function(e,t){var n=jQuery(this).attr("href");if(n){var r=n.replace("#cpac-box-","");jQuery(".cpac-menu a").removeClass("current");jQuery(".columns-container").hide();jQuery(this).addClass("current");var i=jQuery('.columns-container[data-type="'+r+'"]').show(),s=i.find(".cpac-columns");jQuery(document).trigger("cac_menu_change",s)}e.preventDefault()});e.find("a.current").trigger("click")}jQuery(document).ready(function(){if(jQuery("#cpac").length===0)return!1;cpac_pointer();cpac_submit_form();cpac_clear_input_defaults();cpac_sortable();cpac_menu();cpac_help();cpac_add_column();cpac_addons();cpac_importexport();cpac_sidebar_feedback();jQuery(".cpac-column").each(function(e,t){jQuery(t).column_bind_toggle();jQuery(t).column_bind_remove();jQuery(t).cpac_bind_container_addon_events()})});jQuery.fn.column_bind_toggle=function(){var e=jQuery(this);e.find("td.column_type a, td.column_edit, td.column_label a.toggle, td.column_label .edit-button").click(function(t){t.preventDefault();e.toggleClass("opened").find(".column-form").slideToggle(150);e.hasClass("events-binded")||e.column_bind_events();e.addClass("events-binded");jQuery(document).trigger("column_init",e)})};jQuery.fn.column_bind_remove=function(){jQuery(this).find(".remove-button").click(function(e){jQuery(this).closest(".cpac-column").column_remove();e.preventDefault()})};jQuery.fn.cpac_column_refresh=function(){var e=jQuery(this);e.addClass("loading");e.find(".column-form").prepend('<span class="spinner" />');jQuery.post(ajaxurl,{action:"cpac_column_refresh",column:jQuery(this).find("input.column-name").val(),formdata:jQuery(this).parents("form").serialize()},function(t){console.log(t);var n=jQuery("<div>"+t+"</div>").children();e.replaceWith(n);e=n;e.column_bind_toggle();e.column_bind_remove();e.column_bind_events();e.removeClass("loading").addClass("opened").find(".column-form").show();jQuery(document).trigger("column_change",e)})};jQuery.fn.column_bind_events=function(){var e=jQuery(this),t=e.closest(".columns-container "),n=t.attr("data-type"),r=e.find(".column_type select option:selected").val();e.find(".column_type select").change(function(){var i=jQuery("optgroup",this).children(":selected"),s=i.val(),o=i.text(),u=jQuery(this).next(".msg").hide(),a=t.find('.for-cloning-only .cpac-column[data-type="'+s+'"]');if(a.length)if(a.find(".is-disabled").length){u.html(a.find(".is-disabled").html()).show();jQuery(this).find("option").removeAttr("selected");jQuery(this).find('option[value="'+r+'"]').attr("selected","selected")}else{if(typeof a.attr("data-clone")=="undefined"&&jQuery(".cpac-columns",t).find('[data-type="'+s+'"]').length){u.html(cpac_i18n.clone.replace("%s","<strong>"+o+"</strong>")).show();jQuery(this).find("option").removeAttr("selected");jQuery(this).find('option[value="'+r+'"]').attr("selected","selected");return}var f=a.clone();f.addClass("opened").find(".column-form").show();f.find(".column-meta").replaceWith(e.find(".column-meta"));f.find(".column-form").replaceWith(e.find(".column-form"));f.cpac_update_clone_id(n);e.replaceWith(f);f.cpac_column_refresh()}});e.find(".column_label .input input").bind("keyup change",function(){var e=jQuery(this).val();jQuery(this).closest(".cpac-column").find("td.column_label .inner > a.toggle").text(e)});e.find(".input-width-range").each(function(){var e=jQuery(this).closest("td").find(".input-width"),t=jQuery(this).closest("td").find(".width-decription"),n=jQuery(e)[0].defaultValue,r=t.attr("title");jQuery(this).slider({range:"min",min:0,max:100,value:n,slide:function(n,i){var s=i.value>0?i.value+"%":r;jQuery(e).val(i.value);jQuery(t).text(s)}})});e.find(".column_image_size label.custom-size").click(function(){var e=jQuery(this).closest(".input");if(jQuery(this).hasClass("image-size-custom")){jQuery(".custom-size-w",e).removeClass("hidden");jQuery(".custom-size-h",e).removeClass("hidden")}else{jQuery(".custom-size-w",e).addClass("hidden");jQuery(".custom-size-h",e).addClass("hidden")}});e.find(".column-form .label label").hover(function(){jQuery(this).find("p.description").show()},function(){jQuery(this).find("p.description").hide()});e.find(".column_type select").val()=="column-meta"&&e.find(".column_field_type select").change(function(){e.cpac_column_refresh()})};jQuery.fn.column_remove=function(){jQuery(this).addClass("deleting").animate({opacity:0,height:0},350,function(e){jQuery(this).remove()})};jQuery.fn.cpac_update_clone_id=function(e){var t=jQuery(this),n=t.attr("data-type"),r=jQuery('.columns-container[data-type="'+e+'"]').find(".cpac-columns"),i=jQuery(r).find('*[data-type="'+n+'"]').not(t),s=jQuery.map(i,function(e,t){return jQuery(e).attr("data-clone")?parseInt(jQuery(e).attr("data-clone"),10):0});s.sort();var o=Math.max.apply(null,s)+1;for(var u=0;u<=o;u++)if(-1===jQuery.inArray(u,s))break;if(0===u)return;t.attr("data-clone",u);t.find("input.clone").val(u);t.find("input.column-name").val(n+"-"+u);var a=t.find("input, select, label");jQuery(a).each(function(e,t){var r=n+"-"+u;jQuery(t).attr("name")&&jQuery(t).attr("name",jQuery(t).attr("name").replace(n,r));jQuery(t).attr("for")&&jQuery(t).attr("for",jQuery(t).attr("for").replace(n,r));jQuery(t).attr("id")&&jQuery(t).attr("id",jQuery(t).attr("id").replace(n,r))})};jQuery(document).bind("column_init column_change column_add",function(e,t){jQuery(t).cpac_bind_column_addon_events();jQuery(t).cpac_bind_container_addon_events()});jQuery.fn.cpac_bind_column_addon_events=function(){var e=jQuery(this),t=e.find("[data-toggle-id] label");t.click(function(){var t=jQuery(this).closest("td.input").data("toggle-id"),n=e.find('[data-indicator-id="'+t+'"]').removeClass("on"),r=jQuery("input",this).val();"on"==r&&n.addClass("on")})};jQuery.fn.cpac_bind_container_addon_events=function(){var e=jQuery(this),t=e.find("[data-indicator-id]");t.unbind("click").click(function(){var t=jQuery(this).data("indicator-id"),n=e.find('[data-toggle-id="'+t+'"] input');if(jQuery(this).hasClass("on")){jQuery(this).removeClass("on").addClass("off");n.filter("[value=off]").prop("checked",!0)}else{jQuery(this).removeClass("off").addClass("on");n.filter("[value=on]").prop("checked",!0)}})};
assets/less/admin-column.less CHANGED
@@ -433,6 +433,7 @@ h2.cpac-nav-tab-wrapper {
433
  padding-left: 10px;
434
  padding-right: 0;
435
  }
 
436
  div.msg {
437
  margin-top: 5px;
438
  display: none;
@@ -444,6 +445,10 @@ h2.cpac-nav-tab-wrapper {
444
  -webkit-border-radius: 3px;
445
  border-radius: 3px;
446
  }
 
 
 
 
447
  }
448
  }
449
 
@@ -796,6 +801,7 @@ h2.cpac-nav-tab-wrapper {
796
  &#pro-version {
797
  .cta {
798
  background: transparent url(../images/get_the_addon.png) no-repeat 0 0;
 
799
  }
800
  .padding-box {
801
  padding: 8px 15px 0;
@@ -860,7 +866,7 @@ h2.cpac-nav-tab-wrapper {
860
  text-align: center;
861
  line-height: 64px;
862
  font-weight: bold;
863
- color: #CCC;
864
  display: inline-block;
865
  text-decoration: none;
866
 
@@ -936,6 +942,10 @@ h2.cpac-nav-tab-wrapper {
936
  }
937
  }
938
  }
 
 
 
 
939
  }
940
  }
941
  }
@@ -1241,4 +1251,4 @@ body.rtl {
1241
  margin-right: 3px;
1242
  }
1243
  }
1244
- }
433
  padding-left: 10px;
434
  padding-right: 0;
435
  }
436
+
437
  div.msg {
438
  margin-top: 5px;
439
  display: none;
445
  -webkit-border-radius: 3px;
446
  border-radius: 3px;
447
  }
448
+
449
+ .section {
450
+ padding: 12px;
451
+ }
452
  }
453
  }
454
 
801
  &#pro-version {
802
  .cta {
803
  background: transparent url(../images/get_the_addon.png) no-repeat 0 0;
804
+ background-size: cover;
805
  }
806
  .padding-box {
807
  padding: 8px 15px 0;
866
  text-align: center;
867
  line-height: 64px;
868
  font-weight: bold;
869
+ color: #222;
870
  display: inline-block;
871
  text-decoration: none;
872
 
942
  }
943
  }
944
  }
945
+
946
+ #feedback-support .inside ul.share li {
947
+ width: 48%;
948
+ }
949
  }
950
  }
951
  }
1251
  margin-right: 3px;
1252
  }
1253
  }
1254
+ }
assets/less/column.less CHANGED
@@ -74,3 +74,35 @@ div.cpac-color span {
74
  div.sizes span.not-available {
75
  color: #999;
76
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  div.sizes span.not-available {
75
  color: #999;
76
  }
77
+
78
+ /* =Actions column
79
+ -------------------------------------------------------------- */
80
+
81
+
82
+ .button.cpac-button-action {
83
+ position: relative;
84
+ text-indent: 9999px;
85
+ margin-right: 4px;
86
+ padding: 0 13px;
87
+
88
+ &:before {
89
+ position: absolute;
90
+ top: 0;
91
+ left: 0;
92
+ width: 100%;
93
+ height: 100%;
94
+ text-indent: 0;
95
+ }
96
+ }
97
+
98
+ /* =qTip2
99
+ -------------------------------------------------------------- */
100
+ .cpac-tip {
101
+ display: inline-block;
102
+ }
103
+
104
+ .qtip.qtip-tipsy {
105
+ background: rgba( 0, 0, 0, .75 );
106
+ font-weight: normal;
107
+ min-width: 25px;
108
+ }
classes/addons.php CHANGED
@@ -136,6 +136,12 @@ class CPAC_Addons {
136
  'description' => __( 'Display and edit Advanced Custom Fields fields in the posts overview in seconds!', 'cpac' ),
137
  'group' => 'integration',
138
  'image' => CPAC_URL . 'assets/images/addons/acf.png'
 
 
 
 
 
 
139
  )
140
  );
141
 
136
  'description' => __( 'Display and edit Advanced Custom Fields fields in the posts overview in seconds!', 'cpac' ),
137
  'group' => 'integration',
138
  'image' => CPAC_URL . 'assets/images/addons/acf.png'
139
+ ),
140
+ 'cac-addon-woocommerce' => array(
141
+ 'title' => __( 'WooCommerce', 'cpac' ),
142
+ 'description' => __( 'Enhance the products, orders and coupons overviews with new columns and inline editing.', 'cpac' ),
143
+ 'group' => 'integration',
144
+ 'image' => CPAC_URL . 'assets/images/addons/woocommerce.png'
145
  )
146
  );
147
 
classes/column.php CHANGED
@@ -129,7 +129,8 @@ class CPAC_Column {
129
  'is_registered' => true, // Should the column be registered based on conditional logic, example usage see: 'post/page-template.php'
130
  'is_cloneable' => true, // Should the column be cloneable
131
  'default' => false, // Is this a WP default column,
132
- 'group' => 'custom'
 
133
  );
134
 
135
  foreach ( $default_properties as $property => $value ) {
@@ -879,9 +880,15 @@ class CPAC_Column {
879
 
880
  // sort by alphabet
881
  $_columns = array();
 
882
  foreach ( $columns as $column ) {
883
- $_columns[ $column->properties->type ] = 0 === strlen( strip_tags( $column->properties->label ) ) ? ucfirst( $column->properties->type ) : $column->properties->label;
 
 
 
 
884
  }
 
885
  asort( $_columns );
886
 
887
  $list = "<optgroup label='{$label}'>";
129
  'is_registered' => true, // Should the column be registered based on conditional logic, example usage see: 'post/page-template.php'
130
  'is_cloneable' => true, // Should the column be cloneable
131
  'default' => false, // Is this a WP default column,
132
+ 'group' => 'custom',
133
+ 'hidden' => false
134
  );
135
 
136
  foreach ( $default_properties as $property => $value ) {
880
 
881
  // sort by alphabet
882
  $_columns = array();
883
+
884
  foreach ( $columns as $column ) {
885
+ if ( $column->properties->hidden ) {
886
+ continue;
887
+ }
888
+
889
+ $_columns[ $column->properties->type ] = ( 0 === strlen( strip_tags( $column->properties->label ) ) ) ? ucfirst( $column->properties->type ) : $column->properties->label;
890
  }
891
+
892
  asort( $_columns );
893
 
894
  $list = "<optgroup label='{$label}'>";
classes/column/link/actions.php CHANGED
@@ -50,4 +50,4 @@ class CPAC_Column_Link_Actions extends CPAC_Column {
50
 
51
  return implode( ' | ', $actions );
52
  }
53
- }
50
 
51
  return implode( ' | ', $actions );
52
  }
53
+ }
classes/settings.php CHANGED
@@ -196,10 +196,10 @@ class CPAC_Settings {
196
 
197
  $minified = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
198
 
199
- wp_enqueue_script( 'cpac-admin-columns', CPAC_URL . "assets/js/admin-columns{$minified}.js", array( 'jquery', 'dashboard', 'jquery-ui-slider', 'jquery-ui-sortable' ), CPAC_VERSION );
200
 
201
  // javascript translations
202
- wp_localize_script( 'cpac-admin-columns', 'cpac_i18n', array(
203
  'clone' => __( '%s column is already present and can not be duplicated.', 'cpac' ),
204
  ));
205
  }
@@ -717,7 +717,7 @@ class CPAC_Settings {
717
  </p>
718
  </div>
719
  </div>
720
-
721
 
722
  <?php
723
  // @todo: add newsletter
@@ -740,7 +740,76 @@ class CPAC_Settings {
740
  </form>
741
  </div>
742
  <?php */ ?>
743
- </div><!--pro-version-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
744
  <?php endif; ?>
745
 
746
  <div class="sidebox" id="plugin-support">
196
 
197
  $minified = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
198
 
199
+ wp_enqueue_script( 'cpac-admin-settings', CPAC_URL . "assets/js/admin-settings{$minified}.js", array( 'jquery', 'dashboard', 'jquery-ui-slider', 'jquery-ui-sortable' ), CPAC_VERSION );
200
 
201
  // javascript translations
202
+ wp_localize_script( 'cpac-admin-settings', 'cpac_i18n', array(
203
  'clone' => __( '%s column is already present and can not be duplicated.', 'cpac' ),
204
  ));
205
  }
717
  </p>
718
  </div>
719
  </div>
720
+ </div>
721
 
722
  <?php
723
  // @todo: add newsletter
740
  </form>
741
  </div>
742
  <?php */ ?>
743
+
744
+
745
+ <div class="sidebox" id="direct-feedback">
746
+ <div id="feedback-choice">
747
+ <h3><?php _e( 'Are you happy with Admin Columns?', 'cpac' ); ?></h3>
748
+ <div class="inside">
749
+ <a href="#" class="yes">Yes</a>
750
+ <a href="#" class="no">No</a>
751
+ </div>
752
+ </div>
753
+ <div id="feedback-support">
754
+ <div class="inside">
755
+ <p><?php _e( "What's wrong? Need help? Let us know!", 'cpac' ); ?></p>
756
+ <p><?php _e( 'Check out our extensive documentation, or you can open a support topic on WordPress.org!', 'cpac' ); ?></p>
757
+ <ul class="share">
758
+ <li>
759
+ <a href="<?php echo add_query_arg( array(
760
+ 'utm_source' => 'plugin-installation',
761
+ 'utm_medium' => 'feedback-docs-button',
762
+ 'utm_campaign' => 'plugin-installation'
763
+ ), $this->get_url( 'documentation' ) ); ?>" target="_blank">
764
+ <div class="dashicons dashicons-editor-help"></div> <?php _e( 'Docs', 'cpac' ); ?>
765
+ </a>
766
+ </li>
767
+ <li>
768
+ <a href="https://wordpress.org/support/plugin/codepress-admin-columns" target="_blank">
769
+ <div class="dashicons dashicons-wordpress"></div> <?php _e( 'Forums', 'cpac' ); ?>
770
+ </a>
771
+ </li>
772
+ </ul>
773
+ <div class="clear"></div>
774
+ </div>
775
+ </div>
776
+ <div id="feedback-rate">
777
+ <div class="inside">
778
+ <p><?php _e( "Woohoo! We're glad to hear that!", 'cpac' ); ?></p>
779
+ <p><?php _e( 'We would really love it if you could show your appreciation by giving us a rating on WordPress.org or tweet about Admin Columns!', 'cpac' ); ?></p>
780
+ <ul class="share">
781
+ <li>
782
+ <a href="http://wordpress.org/support/view/plugin-reviews/codepress-admin-columns#postform" target="_blank">
783
+ <div class="dashicons dashicons-star-empty"></div> <?php _e( 'Rate', 'cpac' ); ?>
784
+ </a>
785
+ </li>
786
+
787
+ <li>
788
+ <a href="<?php echo add_query_arg( array(
789
+ 'hashtags' => 'wordpress',
790
+ 'text' => urlencode( "I'm using Admin Columns for WordPress!" ),
791
+ 'url' => urlencode( 'http://wordpress.org/plugins/codepress-admin-columns/' ),
792
+ 'via' => 'wpcolumns'
793
+ ), 'https://twitter.com/intent/tweet' ); ?>" target="_blank">
794
+ <div class="dashicons dashicons-twitter"></div> <?php _e( 'Tweet', 'cpac' ); ?>
795
+ </a>
796
+ </li>
797
+
798
+ <li>
799
+ <a href="<?php echo add_query_arg( array(
800
+ 'utm_source' => 'plugin-installation',
801
+ 'utm_medium' => 'feedback-purchase-button',
802
+ 'utm_campaign' => 'plugin-installation'
803
+ ), $this->get_url( 'admincolumnspro' ) ); ?>" target="_blank">
804
+ <div class="dashicons dashicons-cart"></div> <?php _e( 'Buy Pro', 'cpac' ); ?>
805
+ </a>
806
+ </li>
807
+ </ul>
808
+ <div class="clear"></div>
809
+ </div>
810
+ </div>
811
+ </div>
812
+
813
  <?php endif; ?>
814
 
815
  <div class="sidebox" id="plugin-support">
classes/storage_model.php CHANGED
@@ -606,6 +606,16 @@ abstract class CPAC_Storage_Model {
606
  $columns[ $name ] = clone $registered_columns[ $name ];
607
  }
608
  }
 
 
 
 
 
 
 
 
 
 
609
  }
610
 
611
  do_action( "cac/columns", $columns );
@@ -792,4 +802,17 @@ abstract class CPAC_Storage_Model {
792
 
793
  return $options[ $option ];
794
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
795
  }
606
  $columns[ $name ] = clone $registered_columns[ $name ];
607
  }
608
  }
609
+
610
+ /**
611
+ * Filter the columns that should be loaded if there were no stored columns
612
+ *
613
+ * @since 2.2.4
614
+ *
615
+ * @param array $columns List of columns ([column name] => [column instance])
616
+ * @param CPAC_Storage_Model $storage_model_instance Storage model class instance
617
+ */
618
+ $columns = apply_filters( 'cpac/storage_model/columns_default', $columns, $this );
619
  }
620
 
621
  do_action( "cac/columns", $columns );
802
 
803
  return $options[ $option ];
804
  }
805
+
806
+ /**
807
+ * @since 2.2.4
808
+ */
809
+ public function is_table_header_fixed() {
810
+
811
+ /**
812
+ * @since 2.2.4
813
+ */
814
+ $fixed = apply_filters( 'cpac/storage_model/table_header_fixed', false, $this );
815
+
816
+ return $fixed;
817
+ }
818
  }
classes/third_party.php CHANGED
@@ -70,6 +70,7 @@ add_action( 'cac/get_columns', 'cac_add_wpml_columns' );
70
  function cpac_remove_acf_from_cpac_post_types( $post_types ) {
71
  if ( class_exists('Acf') ) {
72
  unset( $post_types['acf'] );
 
73
  }
74
 
75
  return $post_types;
70
  function cpac_remove_acf_from_cpac_post_types( $post_types ) {
71
  if ( class_exists('Acf') ) {
72
  unset( $post_types['acf'] );
73
+ unset( $post_types['acf-field-group'] );
74
  }
75
 
76
  return $post_types;
codepress-admin-columns.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
 
4
  Plugin Name: Codepress Admin Columns
5
- Version: 2.2.3
6
  Description: Customize columns on the administration screens for post(types), pages, media, comments, links and users with an easy to use drag-and-drop interface.
7
  Author: Codepress
8
  Author URI: http://www.codepresshq.com
@@ -33,7 +33,7 @@ if ( ! defined( 'ABSPATH' ) ) {
33
  }
34
 
35
  // Plugin information
36
- define( 'CPAC_VERSION', '2.2.3' ); // current plugin version
37
  define( 'CPAC_UPGRADE_VERSION', '2.0.0' ); // this is the latest version which requires an upgrade
38
  define( 'CPAC_URL', plugin_dir_url( __FILE__ ) );
39
  define( 'CPAC_DIR', plugin_dir_path( __FILE__ ) );
@@ -105,8 +105,8 @@ class CPAC {
105
  // Add settings link
106
  add_filter( 'plugin_action_links', array( $this, 'add_settings_link' ), 1, 2 );
107
 
108
- // Load scripts
109
- $this->init_scripts();
110
 
111
  // Settings
112
  include_once CPAC_DIR . 'classes/settings.php';
@@ -228,16 +228,31 @@ class CPAC {
228
  }
229
 
230
  /**
231
- * @since 2.1.1
232
  */
233
- public function init_scripts() {
234
 
235
  add_action( 'admin_head', array( $this, 'global_head_scripts') );
236
 
 
 
237
  if ( $this->is_columns_screen() ) {
238
- add_action( 'admin_enqueue_scripts' , array( $this, 'column_styles') );
239
  add_filter( 'admin_body_class', array( $this, 'admin_class' ) );
240
  add_action( 'admin_head', array( $this, 'admin_scripts') );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  }
242
  }
243
 
@@ -315,6 +330,20 @@ class CPAC {
315
  return false;
316
  }
317
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  /**
319
  * @since 1.0
320
  * @return array Posttypes
@@ -361,7 +390,13 @@ class CPAC {
361
  */
362
  public function column_styles() {
363
 
364
- wp_enqueue_style( 'cpac-columns', CPAC_URL . 'assets/css/column.css', array(), CPAC_VERSION, 'all' );
 
 
 
 
 
 
365
  }
366
 
367
  /**
2
  /*
3
 
4
  Plugin Name: Codepress Admin Columns
5
+ Version: 2.2.4
6
  Description: Customize columns on the administration screens for post(types), pages, media, comments, links and users with an easy to use drag-and-drop interface.
7
  Author: Codepress
8
  Author URI: http://www.codepresshq.com
33
  }
34
 
35
  // Plugin information
36
+ define( 'CPAC_VERSION', '2.2.4' ); // current plugin version
37
  define( 'CPAC_UPGRADE_VERSION', '2.0.0' ); // this is the latest version which requires an upgrade
38
  define( 'CPAC_URL', plugin_dir_url( __FILE__ ) );
39
  define( 'CPAC_DIR', plugin_dir_path( __FILE__ ) );
105
  // Add settings link
106
  add_filter( 'plugin_action_links', array( $this, 'add_settings_link' ), 1, 2 );
107
 
108
+ // Scripts
109
+ add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
110
 
111
  // Settings
112
  include_once CPAC_DIR . 'classes/settings.php';
228
  }
229
 
230
  /**
231
+ * @since 2.2.4
232
  */
233
+ public function scripts() {
234
 
235
  add_action( 'admin_head', array( $this, 'global_head_scripts') );
236
 
237
+ wp_register_script( 'cpac-admin-columns', CPAC_URL . 'assets/js/admin-columns.js', array( 'jquery', 'jquery-qtip2' ), CPAC_VERSION );
238
+
239
  if ( $this->is_columns_screen() ) {
 
240
  add_filter( 'admin_body_class', array( $this, 'admin_class' ) );
241
  add_action( 'admin_head', array( $this, 'admin_scripts') );
242
+
243
+ wp_enqueue_script( 'cpac-admin-columns' );
244
+
245
+ $data = array();
246
+
247
+ if ( $storage_model = $this->get_current_storage_model() ) {
248
+ $data['storage_model'] = array(
249
+ 'is_table_header_fixed' => $storage_model->is_table_header_fixed()
250
+ );
251
+ }
252
+
253
+ wp_localize_script( 'cpac-admin-columns', 'CPAC', $data );
254
+
255
+ $this->column_styles();
256
  }
257
  }
258
 
330
  return false;
331
  }
332
 
333
+ /**
334
+ * @since 2.2.4
335
+ */
336
+ public function get_current_storage_model() {
337
+
338
+ if ( $this->storage_models ) {
339
+ foreach ( $this->storage_models as $storage_model ) {
340
+ if ( $storage_model->is_columns_screen() ) {
341
+ return $storage_model;
342
+ }
343
+ }
344
+ }
345
+ }
346
+
347
  /**
348
  * @since 1.0
349
  * @return array Posttypes
390
  */
391
  public function column_styles() {
392
 
393
+ wp_register_script( 'jquery-qtip2', CPAC_URL . 'external/qtip2/jquery.qtip.min.js', array( 'jquery' ), CPAC_VERSION );
394
+ wp_register_style( 'jquery-qtip2', CPAC_URL . 'external/qtip2/jquery.qtip.min.css', array(), CPAC_VERSION, 'all' );
395
+ wp_register_style( 'cpac-columns', CPAC_URL . 'assets/css/column.css', array(), CPAC_VERSION, 'all' );
396
+
397
+ wp_enqueue_script( 'jquery-qtip2' );
398
+ wp_enqueue_style( 'jquery-qtip2' );
399
+ wp_enqueue_style( 'cpac-columns' );
400
  }
401
 
402
  /**
external/qtip2/jquery.qtip.css ADDED
@@ -0,0 +1,490 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * qTip2 - Pretty powerful tooltips - v2.2.0
3
+ * http://qtip2.com
4
+ *
5
+ * Copyright (c) 2014 Craig Michael Thompson
6
+ * Released under the MIT, GPL licenses
7
+ * http://jquery.org/license
8
+ *
9
+ * Date: Sun Mar 16 2014 05:53 EDT-0400
10
+ * Plugins: tips viewport
11
+ * Styles: css3
12
+ */
13
+ .qtip{
14
+ position: absolute;
15
+ left: -28000px;
16
+ top: -28000px;
17
+ display: none;
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;
35
+
36
+ text-align: left;
37
+ word-wrap: break-word;
38
+ }
39
+
40
+ .qtip-titlebar{
41
+ position: relative;
42
+ padding: 5px 35px 5px 10px;
43
+ overflow: hidden;
44
+
45
+ border-width: 0 0 1px;
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
+
56
+ cursor: pointer;
57
+ outline: medium none;
58
+
59
+ border-width: 1px;
60
+ border-style: solid;
61
+ border-color: transparent;
62
+ }
63
+
64
+ .qtip-titlebar .qtip-close{
65
+ right: 4px; top: 50%;
66
+ margin-top: -9px;
67
+ }
68
+
69
+ * html .qtip-titlebar .qtip-close{ top: 16px; } /* IE fix */
70
+
71
+ .qtip-titlebar .ui-icon,
72
+ .qtip-icon .ui-icon{
73
+ display: block;
74
+ text-indent: -1000em;
75
+ direction: ltr;
76
+ }
77
+
78
+ .qtip-icon, .qtip-icon .ui-icon{
79
+ -moz-border-radius: 3px;
80
+ -webkit-border-radius: 3px;
81
+ border-radius: 3px;
82
+ text-decoration: none;
83
+ }
84
+
85
+ .qtip-icon .ui-icon{
86
+ width: 18px;
87
+ height: 14px;
88
+
89
+ line-height: 14px;
90
+ text-align: center;
91
+ text-indent: 0;
92
+ font: normal bold 10px/13px Tahoma,sans-serif;
93
+
94
+ color: inherit;
95
+ background: transparent none no-repeat -100em -100em;
96
+ }
97
+
98
+ /* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */
99
+ .qtip-focus{}
100
+
101
+ /* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */
102
+ .qtip-hover{}
103
+
104
+ /* Default tooltip style */
105
+ .qtip-default{
106
+ border-width: 1px;
107
+ border-style: solid;
108
+ border-color: #F1D031;
109
+
110
+ background-color: #FFFFA3;
111
+ color: #555;
112
+ }
113
+
114
+ .qtip-default .qtip-titlebar{
115
+ background-color: #FFEF93;
116
+ }
117
+
118
+ .qtip-default .qtip-icon{
119
+ border-color: #CCC;
120
+ background: #F1F1F1;
121
+ color: #777;
122
+ }
123
+
124
+ .qtip-default .qtip-titlebar .qtip-close{
125
+ border-color: #AAA;
126
+ color: #111;
127
+ }
128
+
129
+
130
+
131
+ .qtip-shadow{
132
+ -webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
133
+ -moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
134
+ box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
135
+ }
136
+
137
+ /* Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */
138
+ .qtip-rounded,
139
+ .qtip-tipsy,
140
+ .qtip-bootstrap{
141
+ -moz-border-radius: 5px;
142
+ -webkit-border-radius: 5px;
143
+ border-radius: 5px;
144
+ }
145
+
146
+ .qtip-rounded .qtip-titlebar{
147
+ -moz-border-radius: 4px 4px 0 0;
148
+ -webkit-border-radius: 4px 4px 0 0;
149
+ border-radius: 4px 4px 0 0;
150
+ }
151
+
152
+ /* Youtube tooltip style */
153
+ .qtip-youtube{
154
+ -moz-border-radius: 2px;
155
+ -webkit-border-radius: 2px;
156
+ border-radius: 2px;
157
+
158
+ -webkit-box-shadow: 0 0 3px #333;
159
+ -moz-box-shadow: 0 0 3px #333;
160
+ box-shadow: 0 0 3px #333;
161
+
162
+ color: white;
163
+ border-width: 0;
164
+
165
+ background: #4A4A4A;
166
+ background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,black));
167
+ background-image: -webkit-linear-gradient(top,#4A4A4A 0,black 100%);
168
+ background-image: -moz-linear-gradient(top,#4A4A4A 0,black 100%);
169
+ background-image: -ms-linear-gradient(top,#4A4A4A 0,black 100%);
170
+ background-image: -o-linear-gradient(top,#4A4A4A 0,black 100%);
171
+ }
172
+
173
+ .qtip-youtube .qtip-titlebar{
174
+ background-color: #4A4A4A;
175
+ background-color: rgba(0,0,0,0);
176
+ }
177
+
178
+ .qtip-youtube .qtip-content{
179
+ padding: .75em;
180
+ font: 12px arial,sans-serif;
181
+
182
+ filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);
183
+ -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);";
184
+ }
185
+
186
+ .qtip-youtube .qtip-icon{
187
+ border-color: #222;
188
+ }
189
+
190
+ .qtip-youtube .qtip-titlebar .ui-state-hover{
191
+ border-color: #303030;
192
+ }
193
+
194
+
195
+ /* jQuery TOOLS Tooltip style */
196
+ .qtip-jtools{
197
+ background: #232323;
198
+ background: rgba(0, 0, 0, 0.7);
199
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323));
200
+ background-image: -moz-linear-gradient(top, #717171, #232323);
201
+ background-image: -webkit-linear-gradient(top, #717171, #232323);
202
+ background-image: -ms-linear-gradient(top, #717171, #232323);
203
+ background-image: -o-linear-gradient(top, #717171, #232323);
204
+
205
+ border: 2px solid #ddd;
206
+ border: 2px solid rgba(241,241,241,1);
207
+
208
+ -moz-border-radius: 2px;
209
+ -webkit-border-radius: 2px;
210
+ border-radius: 2px;
211
+
212
+ -webkit-box-shadow: 0 0 12px #333;
213
+ -moz-box-shadow: 0 0 12px #333;
214
+ box-shadow: 0 0 12px #333;
215
+ }
216
+
217
+ /* IE Specific */
218
+ .qtip-jtools .qtip-titlebar{
219
+ background-color: transparent;
220
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);
221
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)";
222
+ }
223
+ .qtip-jtools .qtip-content{
224
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);
225
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)";
226
+ }
227
+
228
+ .qtip-jtools .qtip-titlebar,
229
+ .qtip-jtools .qtip-content{
230
+ background: transparent;
231
+ color: white;
232
+ border: 0 dashed transparent;
233
+ }
234
+
235
+ .qtip-jtools .qtip-icon{
236
+ border-color: #555;
237
+ }
238
+
239
+ .qtip-jtools .qtip-titlebar .ui-state-hover{
240
+ border-color: #333;
241
+ }
242
+
243
+
244
+ /* Cluetip style */
245
+ .qtip-cluetip{
246
+ -webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
247
+ -moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
248
+ box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
249
+
250
+ background-color: #D9D9C2;
251
+ color: #111;
252
+ border: 0 dashed transparent;
253
+ }
254
+
255
+ .qtip-cluetip .qtip-titlebar{
256
+ background-color: #87876A;
257
+ color: white;
258
+ border: 0 dashed transparent;
259
+ }
260
+
261
+ .qtip-cluetip .qtip-icon{
262
+ border-color: #808064;
263
+ }
264
+
265
+ .qtip-cluetip .qtip-titlebar .ui-state-hover{
266
+ border-color: #696952;
267
+ color: #696952;
268
+ }
269
+
270
+
271
+ /* Tipsy style */
272
+ .qtip-tipsy{
273
+ background: black;
274
+ background: rgba(0, 0, 0, .87);
275
+
276
+ color: white;
277
+ border: 0 solid transparent;
278
+
279
+ font-size: 11px;
280
+ font-family: 'Lucida Grande', sans-serif;
281
+ font-weight: bold;
282
+ line-height: 16px;
283
+ text-shadow: 0 1px black;
284
+ }
285
+
286
+ .qtip-tipsy .qtip-titlebar{
287
+ padding: 6px 35px 0 10px;
288
+ background-color: transparent;
289
+ }
290
+
291
+ .qtip-tipsy .qtip-content{
292
+ padding: 6px 10px;
293
+ }
294
+
295
+ .qtip-tipsy .qtip-icon{
296
+ border-color: #222;
297
+ text-shadow: none;
298
+ }
299
+
300
+ .qtip-tipsy .qtip-titlebar .ui-state-hover{
301
+ border-color: #303030;
302
+ }
303
+
304
+
305
+ /* Tipped style */
306
+ .qtip-tipped{
307
+ border: 3px solid #959FA9;
308
+
309
+ -moz-border-radius: 3px;
310
+ -webkit-border-radius: 3px;
311
+ border-radius: 3px;
312
+
313
+ background-color: #F9F9F9;
314
+ color: #454545;
315
+
316
+ font-weight: normal;
317
+ font-family: serif;
318
+ }
319
+
320
+ .qtip-tipped .qtip-titlebar{
321
+ border-bottom-width: 0;
322
+
323
+ color: white;
324
+ background: #3A79B8;
325
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#3A79B8), to(#2E629D));
326
+ background-image: -webkit-linear-gradient(top, #3A79B8, #2E629D);
327
+ background-image: -moz-linear-gradient(top, #3A79B8, #2E629D);
328
+ background-image: -ms-linear-gradient(top, #3A79B8, #2E629D);
329
+ background-image: -o-linear-gradient(top, #3A79B8, #2E629D);
330
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D);
331
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)";
332
+ }
333
+
334
+ .qtip-tipped .qtip-icon{
335
+ border: 2px solid #285589;
336
+ background: #285589;
337
+ }
338
+
339
+ .qtip-tipped .qtip-icon .ui-icon{
340
+ background-color: #FBFBFB;
341
+ color: #555;
342
+ }
343
+
344
+
345
+ /**
346
+ * Twitter Bootstrap style.
347
+ *
348
+ * Tested with IE 8, IE 9, Chrome 18, Firefox 9, Opera 11.
349
+ * Does not work with IE 7.
350
+ */
351
+ .qtip-bootstrap{
352
+ /** Taken from Bootstrap body */
353
+ font-size: 14px;
354
+ line-height: 20px;
355
+ color: #333333;
356
+
357
+ /** Taken from Bootstrap .popover */
358
+ padding: 1px;
359
+ background-color: #ffffff;
360
+ border: 1px solid #ccc;
361
+ border: 1px solid rgba(0, 0, 0, 0.2);
362
+ -webkit-border-radius: 6px;
363
+ -moz-border-radius: 6px;
364
+ border-radius: 6px;
365
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
366
+ -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
367
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
368
+ -webkit-background-clip: padding-box;
369
+ -moz-background-clip: padding;
370
+ background-clip: padding-box;
371
+ }
372
+
373
+ .qtip-bootstrap .qtip-titlebar{
374
+ /** Taken from Bootstrap .popover-title */
375
+ padding: 8px 14px;
376
+ margin: 0;
377
+ font-size: 14px;
378
+ font-weight: normal;
379
+ line-height: 18px;
380
+ background-color: #f7f7f7;
381
+ border-bottom: 1px solid #ebebeb;
382
+ -webkit-border-radius: 5px 5px 0 0;
383
+ -moz-border-radius: 5px 5px 0 0;
384
+ border-radius: 5px 5px 0 0;
385
+ }
386
+
387
+ .qtip-bootstrap .qtip-titlebar .qtip-close{
388
+ /**
389
+ * Overrides qTip2:
390
+ * .qtip-titlebar .qtip-close{
391
+ * [...]
392
+ * right: 4px;
393
+ * top: 50%;
394
+ * [...]
395
+ * border-style: solid;
396
+ * }
397
+ */
398
+ right: 11px;
399
+ top: 45%;
400
+ border-style: none;
401
+ }
402
+
403
+ .qtip-bootstrap .qtip-content{
404
+ /** Taken from Bootstrap .popover-content */
405
+ padding: 9px 14px;
406
+ }
407
+
408
+ .qtip-bootstrap .qtip-icon{
409
+ /**
410
+ * Overrides qTip2:
411
+ * .qtip-default .qtip-icon {
412
+ * border-color: #CCC;
413
+ * background: #F1F1F1;
414
+ * color: #777;
415
+ * }
416
+ */
417
+ background: transparent;
418
+ }
419
+
420
+ .qtip-bootstrap .qtip-icon .ui-icon{
421
+ /**
422
+ * Overrides qTip2:
423
+ * .qtip-icon .ui-icon{
424
+ * width: 18px;
425
+ * height: 14px;
426
+ * }
427
+ */
428
+ width: auto;
429
+ height: auto;
430
+
431
+ /* Taken from Bootstrap .close */
432
+ float: right;
433
+ font-size: 20px;
434
+ font-weight: bold;
435
+ line-height: 18px;
436
+ color: #000000;
437
+ text-shadow: 0 1px 0 #ffffff;
438
+ opacity: 0.2;
439
+ filter: alpha(opacity=20);
440
+ }
441
+
442
+ .qtip-bootstrap .qtip-icon .ui-icon:hover{
443
+ /* Taken from Bootstrap .close:hover */
444
+ color: #000000;
445
+ text-decoration: none;
446
+ cursor: pointer;
447
+ opacity: 0.4;
448
+ filter: alpha(opacity=40);
449
+ }
450
+
451
+
452
+ /* IE9 fix - removes all filters */
453
+ .qtip:not(.ie9haxors) div.qtip-content,
454
+ .qtip:not(.ie9haxors) div.qtip-titlebar{
455
+ filter: none;
456
+ -ms-filter: none;
457
+ }
458
+
459
+
460
+
461
+ .qtip .qtip-tip{
462
+ margin: 0 auto;
463
+ overflow: hidden;
464
+ z-index: 10;
465
+
466
+ }
467
+
468
+ /* Opera bug #357 - Incorrect tip position
469
+ https://github.com/Craga89/qTip2/issues/367 */
470
+ x:-o-prefocus, .qtip .qtip-tip{
471
+ visibility: hidden;
472
+ }
473
+
474
+ .qtip .qtip-tip,
475
+ .qtip .qtip-tip .qtip-vml,
476
+ .qtip .qtip-tip canvas{
477
+ position: absolute;
478
+
479
+ color: #123456;
480
+ background: transparent;
481
+ border: 0 dashed transparent;
482
+ }
483
+
484
+ .qtip .qtip-tip canvas{ top: 0; left: 0; }
485
+
486
+ .qtip .qtip-tip .qtip-vml{
487
+ behavior: url(#default#VML);
488
+ display: inline-block;
489
+ visibility: visible;
490
+ }
external/qtip2/jquery.qtip.js ADDED
@@ -0,0 +1,2713 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * qTip2 - Pretty powerful tooltips - v2.2.0
3
+ * http://qtip2.com
4
+ *
5
+ * Copyright (c) 2014 Craig Michael Thompson
6
+ * Released under the MIT, GPL licenses
7
+ * http://jquery.org/license
8
+ *
9
+ * Date: Sun Mar 16 2014 05:53 EDT-0400
10
+ * Plugins: tips viewport
11
+ * Styles: css3
12
+ */
13
+ /*global window: false, jQuery: false, console: false, define: false */
14
+
15
+ /* Cache window, document, undefined */
16
+ (function( window, document, undefined ) {
17
+
18
+ // Uses AMD or browser globals to create a jQuery plugin.
19
+ (function( factory ) {
20
+ "use strict";
21
+ if(typeof define === 'function' && define.amd) {
22
+ define(['jquery'], factory);
23
+ }
24
+ else if(jQuery && !jQuery.fn.qtip) {
25
+ factory(jQuery);
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
+
31
+ ;// Munge the primitives - Paul Irish tip
32
+ var TRUE = true,
33
+ FALSE = false,
34
+ NULL = null,
35
+
36
+ // Common variables
37
+ X = 'x', Y = 'y',
38
+ WIDTH = 'width',
39
+ HEIGHT = 'height',
40
+
41
+ // Positioning sides
42
+ TOP = 'top',
43
+ LEFT = 'left',
44
+ BOTTOM = 'bottom',
45
+ RIGHT = 'right',
46
+ CENTER = 'center',
47
+
48
+ // Position adjustment types
49
+ FLIP = 'flip',
50
+ FLIPINVERT = 'flipinvert',
51
+ SHIFT = 'shift',
52
+
53
+ // Shortcut vars
54
+ QTIP, PROTOTYPE, CORNER, CHECKS,
55
+ PLUGINS = {},
56
+ NAMESPACE = 'qtip',
57
+ ATTR_HAS = 'data-hasqtip',
58
+ ATTR_ID = 'data-qtip-id',
59
+ WIDGET = ['ui-widget', 'ui-tooltip'],
60
+ SELECTOR = '.'+NAMESPACE,
61
+ INACTIVE_EVENTS = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' '),
62
+
63
+ CLASS_FIXED = NAMESPACE+'-fixed',
64
+ CLASS_DEFAULT = NAMESPACE + '-default',
65
+ CLASS_FOCUS = NAMESPACE + '-focus',
66
+ CLASS_HOVER = NAMESPACE + '-hover',
67
+ CLASS_DISABLED = NAMESPACE+'-disabled',
68
+
69
+ replaceSuffix = '_replacedByqTip',
70
+ oldtitle = 'oldtitle',
71
+ trackingBound,
72
+
73
+ // Browser detection
74
+ BROWSER = {
75
+ /*
76
+ * IE version detection
77
+ *
78
+ * Adapted from: http://ajaxian.com/archives/attack-of-the-ie-conditional-comment
79
+ * Credit to James Padolsey for the original implemntation!
80
+ */
81
+ ie: (function(){
82
+ var v = 3, div = document.createElement('div');
83
+ while ((div.innerHTML = '<!--[if gt IE '+(++v)+']><i></i><![endif]-->')) {
84
+ if(!div.getElementsByTagName('i')[0]) { break; }
85
+ }
86
+ return v > 4 ? v : NaN;
87
+ }()),
88
+
89
+ /*
90
+ * iOS version detection
91
+ */
92
+ iOS: parseFloat(
93
+ ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1])
94
+ .replace('undefined', '3_2').replace('_', '.').replace('_', '')
95
+ ) || FALSE
96
+ };
97
+
98
+ ;function QTip(target, options, id, attr) {
99
+ // Elements and ID
100
+ this.id = id;
101
+ this.target = target;
102
+ this.tooltip = NULL;
103
+ this.elements = { target: target };
104
+
105
+ // Internal constructs
106
+ this._id = NAMESPACE + '-' + id;
107
+ this.timers = { img: {} };
108
+ this.options = options;
109
+ this.plugins = {};
110
+
111
+ // Cache object
112
+ this.cache = {
113
+ event: {},
114
+ target: $(),
115
+ disabled: FALSE,
116
+ attr: attr,
117
+ onTooltip: FALSE,
118
+ lastClass: ''
119
+ };
120
+
121
+ // Set the initial flags
122
+ this.rendered = this.destroyed = this.disabled = this.waiting =
123
+ this.hiddenDuringWait = this.positioning = this.triggering = FALSE;
124
+ }
125
+ PROTOTYPE = QTip.prototype;
126
+
127
+ PROTOTYPE._when = function(deferreds) {
128
+ return $.when.apply($, deferreds);
129
+ };
130
+
131
+ PROTOTYPE.render = function(show) {
132
+ if(this.rendered || this.destroyed) { return this; } // If tooltip has already been rendered, exit
133
+
134
+ var self = this,
135
+ options = this.options,
136
+ cache = this.cache,
137
+ elements = this.elements,
138
+ text = options.content.text,
139
+ title = options.content.title,
140
+ button = options.content.button,
141
+ posOptions = options.position,
142
+ namespace = '.'+this._id+' ',
143
+ deferreds = [],
144
+ tooltip;
145
+
146
+ // Add ARIA attributes to target
147
+ $.attr(this.target[0], 'aria-describedby', this._id);
148
+
149
+ // Create tooltip element
150
+ this.tooltip = elements.tooltip = tooltip = $('<div/>', {
151
+ 'id': this._id,
152
+ 'class': [ NAMESPACE, CLASS_DEFAULT, options.style.classes, NAMESPACE + '-pos-' + options.position.my.abbrev() ].join(' '),
153
+ 'width': options.style.width || '',
154
+ 'height': options.style.height || '',
155
+ 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse,
156
+
157
+ /* ARIA specific attributes */
158
+ 'role': 'alert',
159
+ 'aria-live': 'polite',
160
+ 'aria-atomic': FALSE,
161
+ 'aria-describedby': this._id + '-content',
162
+ 'aria-hidden': TRUE
163
+ })
164
+ .toggleClass(CLASS_DISABLED, this.disabled)
165
+ .attr(ATTR_ID, this.id)
166
+ .data(NAMESPACE, this)
167
+ .appendTo(posOptions.container)
168
+ .append(
169
+ // Create content element
170
+ elements.content = $('<div />', {
171
+ 'class': NAMESPACE + '-content',
172
+ 'id': this._id + '-content',
173
+ 'aria-atomic': TRUE
174
+ })
175
+ );
176
+
177
+ // Set rendered flag and prevent redundant reposition calls for now
178
+ this.rendered = -1;
179
+ this.positioning = TRUE;
180
+
181
+ // Create title...
182
+ if(title) {
183
+ this._createTitle();
184
+
185
+ // Update title only if its not a callback (called in toggle if so)
186
+ if(!$.isFunction(title)) {
187
+ deferreds.push( this._updateTitle(title, FALSE) );
188
+ }
189
+ }
190
+
191
+ // Create button
192
+ if(button) { this._createButton(); }
193
+
194
+ // Set proper rendered flag and update content if not a callback function (called in toggle)
195
+ if(!$.isFunction(text)) {
196
+ deferreds.push( this._updateContent(text, FALSE) );
197
+ }
198
+ this.rendered = TRUE;
199
+
200
+ // Setup widget classes
201
+ this._setWidget();
202
+
203
+ // Initialize 'render' plugins
204
+ $.each(PLUGINS, function(name) {
205
+ var instance;
206
+ if(this.initialize === 'render' && (instance = this(self))) {
207
+ self.plugins[name] = instance;
208
+ }
209
+ });
210
+
211
+ // Unassign initial events and assign proper events
212
+ this._unassignEvents();
213
+ this._assignEvents();
214
+
215
+ // When deferreds have completed
216
+ this._when(deferreds).then(function() {
217
+ // tooltiprender event
218
+ self._trigger('render');
219
+
220
+ // Reset flags
221
+ self.positioning = FALSE;
222
+
223
+ // Show tooltip if not hidden during wait period
224
+ if(!self.hiddenDuringWait && (options.show.ready || show)) {
225
+ self.toggle(TRUE, cache.event, FALSE);
226
+ }
227
+ self.hiddenDuringWait = FALSE;
228
+ });
229
+
230
+ // Expose API
231
+ QTIP.api[this.id] = this;
232
+
233
+ return this;
234
+ };
235
+
236
+ PROTOTYPE.destroy = function(immediate) {
237
+ // Set flag the signify destroy is taking place to plugins
238
+ // and ensure it only gets destroyed once!
239
+ if(this.destroyed) { return this.target; }
240
+
241
+ function process() {
242
+ if(this.destroyed) { return; }
243
+ this.destroyed = TRUE;
244
+
245
+ var target = this.target,
246
+ title = target.attr(oldtitle);
247
+
248
+ // Destroy tooltip if rendered
249
+ if(this.rendered) {
250
+ this.tooltip.stop(1,0).find('*').remove().end().remove();
251
+ }
252
+
253
+ // Destroy all plugins
254
+ $.each(this.plugins, function(name) {
255
+ this.destroy && this.destroy();
256
+ });
257
+
258
+ // Clear timers and remove bound events
259
+ clearTimeout(this.timers.show);
260
+ clearTimeout(this.timers.hide);
261
+ this._unassignEvents();
262
+
263
+ // Remove api object and ARIA attributes
264
+ target.removeData(NAMESPACE)
265
+ .removeAttr(ATTR_ID)
266
+ .removeAttr(ATTR_HAS)
267
+ .removeAttr('aria-describedby');
268
+
269
+ // Reset old title attribute if removed
270
+ if(this.options.suppress && title) {
271
+ target.attr('title', title).removeAttr(oldtitle);
272
+ }
273
+
274
+ // Remove qTip events associated with this API
275
+ this._unbind(target);
276
+
277
+ // Remove ID from used id objects, and delete object references
278
+ // for better garbage collection and leak protection
279
+ this.options = this.elements = this.cache = this.timers =
280
+ this.plugins = this.mouse = NULL;
281
+
282
+ // Delete epoxsed API object
283
+ delete QTIP.api[this.id];
284
+ }
285
+
286
+ // If an immediate destory is needed
287
+ if((immediate !== TRUE || this.triggering === 'hide') && this.rendered) {
288
+ this.tooltip.one('tooltiphidden', $.proxy(process, this));
289
+ !this.triggering && this.hide();
290
+ }
291
+
292
+ // If we're not in the process of hiding... process
293
+ else { process.call(this); }
294
+
295
+ return this.target;
296
+ };
297
+
298
+ ;function invalidOpt(a) {
299
+ return a === NULL || $.type(a) !== 'object';
300
+ }
301
+
302
+ function invalidContent(c) {
303
+ return !( $.isFunction(c) || (c && c.attr) || c.length || ($.type(c) === 'object' && (c.jquery || c.then) ));
304
+ }
305
+
306
+ // Option object sanitizer
307
+ function sanitizeOptions(opts) {
308
+ var content, text, ajax, once;
309
+
310
+ if(invalidOpt(opts)) { return FALSE; }
311
+
312
+ if(invalidOpt(opts.metadata)) {
313
+ opts.metadata = { type: opts.metadata };
314
+ }
315
+
316
+ if('content' in opts) {
317
+ content = opts.content;
318
+
319
+ if(invalidOpt(content) || content.jquery || content.done) {
320
+ content = opts.content = {
321
+ text: (text = invalidContent(content) ? FALSE : content)
322
+ };
323
+ }
324
+ else { text = content.text; }
325
+
326
+ // DEPRECATED - Old content.ajax plugin functionality
327
+ // Converts it into the proper Deferred syntax
328
+ if('ajax' in content) {
329
+ ajax = content.ajax;
330
+ once = ajax && ajax.once !== FALSE;
331
+ delete content.ajax;
332
+
333
+ content.text = function(event, api) {
334
+ var loading = text || $(this).attr(api.options.content.attr) || 'Loading...',
335
+
336
+ deferred = $.ajax(
337
+ $.extend({}, ajax, { context: api })
338
+ )
339
+ .then(ajax.success, NULL, ajax.error)
340
+ .then(function(content) {
341
+ if(content && once) { api.set('content.text', content); }
342
+ return content;
343
+ },
344
+ function(xhr, status, error) {
345
+ if(api.destroyed || xhr.status === 0) { return; }
346
+ api.set('content.text', status + ': ' + error);
347
+ });
348
+
349
+ return !once ? (api.set('content.text', loading), deferred) : loading;
350
+ };
351
+ }
352
+
353
+ if('title' in content) {
354
+ if(!invalidOpt(content.title)) {
355
+ content.button = content.title.button;
356
+ content.title = content.title.text;
357
+ }
358
+
359
+ if(invalidContent(content.title || FALSE)) {
360
+ content.title = FALSE;
361
+ }
362
+ }
363
+ }
364
+
365
+ if('position' in opts && invalidOpt(opts.position)) {
366
+ opts.position = { my: opts.position, at: opts.position };
367
+ }
368
+
369
+ if('show' in opts && invalidOpt(opts.show)) {
370
+ opts.show = opts.show.jquery ? { target: opts.show } :
371
+ opts.show === TRUE ? { ready: TRUE } : { event: opts.show };
372
+ }
373
+
374
+ if('hide' in opts && invalidOpt(opts.hide)) {
375
+ opts.hide = opts.hide.jquery ? { target: opts.hide } : { event: opts.hide };
376
+ }
377
+
378
+ if('style' in opts && invalidOpt(opts.style)) {
379
+ opts.style = { classes: opts.style };
380
+ }
381
+
382
+ // Sanitize plugin options
383
+ $.each(PLUGINS, function() {
384
+ this.sanitize && this.sanitize(opts);
385
+ });
386
+
387
+ return opts;
388
+ }
389
+
390
+ // Setup builtin .set() option checks
391
+ CHECKS = PROTOTYPE.checks = {
392
+ builtin: {
393
+ // Core checks
394
+ '^id$': function(obj, o, v, prev) {
395
+ var id = v === TRUE ? QTIP.nextid : v,
396
+ new_id = NAMESPACE + '-' + id;
397
+
398
+ if(id !== FALSE && id.length > 0 && !$('#'+new_id).length) {
399
+ this._id = new_id;
400
+
401
+ if(this.rendered) {
402
+ this.tooltip[0].id = this._id;
403
+ this.elements.content[0].id = this._id + '-content';
404
+ this.elements.title[0].id = this._id + '-title';
405
+ }
406
+ }
407
+ else { obj[o] = prev; }
408
+ },
409
+ '^prerender': function(obj, o, v) {
410
+ v && !this.rendered && this.render(this.options.show.ready);
411
+ },
412
+
413
+ // Content checks
414
+ '^content.text$': function(obj, o, v) {
415
+ this._updateContent(v);
416
+ },
417
+ '^content.attr$': function(obj, o, v, prev) {
418
+ if(this.options.content.text === this.target.attr(prev)) {
419
+ this._updateContent( this.target.attr(v) );
420
+ }
421
+ },
422
+ '^content.title$': function(obj, o, v) {
423
+ // Remove title if content is null
424
+ if(!v) { return this._removeTitle(); }
425
+
426
+ // If title isn't already created, create it now and update
427
+ v && !this.elements.title && this._createTitle();
428
+ this._updateTitle(v);
429
+ },
430
+ '^content.button$': function(obj, o, v) {
431
+ this._updateButton(v);
432
+ },
433
+ '^content.title.(text|button)$': function(obj, o, v) {
434
+ this.set('content.'+o, v); // Backwards title.text/button compat
435
+ },
436
+
437
+ // Position checks
438
+ '^position.(my|at)$': function(obj, o, v){
439
+ 'string' === typeof v && (obj[o] = new CORNER(v, o === 'at'));
440
+ },
441
+ '^position.container$': function(obj, o, v){
442
+ this.rendered && this.tooltip.appendTo(v);
443
+ },
444
+
445
+ // Show checks
446
+ '^show.ready$': function(obj, o, v) {
447
+ v && (!this.rendered && this.render(TRUE) || this.toggle(TRUE));
448
+ },
449
+
450
+ // Style checks
451
+ '^style.classes$': function(obj, o, v, p) {
452
+ this.rendered && this.tooltip.removeClass(p).addClass(v);
453
+ },
454
+ '^style.(width|height)': function(obj, o, v) {
455
+ this.rendered && this.tooltip.css(o, v);
456
+ },
457
+ '^style.widget|content.title': function() {
458
+ this.rendered && this._setWidget();
459
+ },
460
+ '^style.def': function(obj, o, v) {
461
+ this.rendered && this.tooltip.toggleClass(CLASS_DEFAULT, !!v);
462
+ },
463
+
464
+ // Events check
465
+ '^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) {
466
+ this.rendered && this.tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v);
467
+ },
468
+
469
+ // Properties which require event reassignment
470
+ '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() {
471
+ if(!this.rendered) { return; }
472
+
473
+ // Set tracking flag
474
+ var posOptions = this.options.position;
475
+ this.tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse);
476
+
477
+ // Reassign events
478
+ this._unassignEvents();
479
+ this._assignEvents();
480
+ }
481
+ }
482
+ };
483
+
484
+ // Dot notation converter
485
+ function convertNotation(options, notation) {
486
+ var i = 0, obj, option = options,
487
+
488
+ // Split notation into array
489
+ levels = notation.split('.');
490
+
491
+ // Loop through
492
+ while( option = option[ levels[i++] ] ) {
493
+ if(i < levels.length) { obj = option; }
494
+ }
495
+
496
+ return [obj || options, levels.pop()];
497
+ }
498
+
499
+ PROTOTYPE.get = function(notation) {
500
+ if(this.destroyed) { return this; }
501
+
502
+ var o = convertNotation(this.options, notation.toLowerCase()),
503
+ result = o[0][ o[1] ];
504
+
505
+ return result.precedance ? result.string() : result;
506
+ };
507
+
508
+ function setCallback(notation, args) {
509
+ var category, rule, match;
510
+
511
+ for(category in this.checks) {
512
+ for(rule in this.checks[category]) {
513
+ if(match = (new RegExp(rule, 'i')).exec(notation)) {
514
+ args.push(match);
515
+
516
+ if(category === 'builtin' || this.plugins[category]) {
517
+ this.checks[category][rule].apply(
518
+ this.plugins[category] || this, args
519
+ );
520
+ }
521
+ }
522
+ }
523
+ }
524
+ }
525
+
526
+ var rmove = /^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i,
527
+ rrender = /^prerender|show\.ready/i;
528
+
529
+ PROTOTYPE.set = function(option, value) {
530
+ if(this.destroyed) { return this; }
531
+
532
+ var rendered = this.rendered,
533
+ reposition = FALSE,
534
+ options = this.options,
535
+ checks = this.checks,
536
+ name;
537
+
538
+ // Convert singular option/value pair into object form
539
+ if('string' === typeof option) {
540
+ name = option; option = {}; option[name] = value;
541
+ }
542
+ else { option = $.extend({}, option); }
543
+
544
+ // Set all of the defined options to their new values
545
+ $.each(option, function(notation, value) {
546
+ if(rendered && rrender.test(notation)) {
547
+ delete option[notation]; return;
548
+ }
549
+
550
+ // Set new obj value
551
+ var obj = convertNotation(options, notation.toLowerCase()), previous;
552
+ previous = obj[0][ obj[1] ];
553
+ obj[0][ obj[1] ] = value && value.nodeType ? $(value) : value;
554
+
555
+ // Also check if we need to reposition
556
+ reposition = rmove.test(notation) || reposition;
557
+
558
+ // Set the new params for the callback
559
+ option[notation] = [obj[0], obj[1], value, previous];
560
+ });
561
+
562
+ // Re-sanitize options
563
+ sanitizeOptions(options);
564
+
565
+ /*
566
+ * Execute any valid callbacks for the set options
567
+ * Also set positioning flag so we don't get loads of redundant repositioning calls.
568
+ */
569
+ this.positioning = TRUE;
570
+ $.each(option, $.proxy(setCallback, this));
571
+ this.positioning = FALSE;
572
+
573
+ // Update position if needed
574
+ if(this.rendered && this.tooltip[0].offsetWidth > 0 && reposition) {
575
+ this.reposition( options.position.target === 'mouse' ? NULL : this.cache.event );
576
+ }
577
+
578
+ return this;
579
+ };
580
+
581
+ ;PROTOTYPE._update = function(content, element, reposition) {
582
+ var self = this,
583
+ cache = this.cache;
584
+
585
+ // Make sure tooltip is rendered and content is defined. If not return
586
+ if(!this.rendered || !content) { return FALSE; }
587
+
588
+ // Use function to parse content
589
+ if($.isFunction(content)) {
590
+ content = content.call(this.elements.target, cache.event, this) || '';
591
+ }
592
+
593
+ // Handle deferred content
594
+ if($.isFunction(content.then)) {
595
+ cache.waiting = TRUE;
596
+ return content.then(function(c) {
597
+ cache.waiting = FALSE;
598
+ return self._update(c, element);
599
+ }, NULL, function(e) {
600
+ return self._update(e, element);
601
+ });
602
+ }
603
+
604
+ // If content is null... return false
605
+ if(content === FALSE || (!content && content !== '')) { return FALSE; }
606
+
607
+ // Append new content if its a DOM array and show it if hidden
608
+ if(content.jquery && content.length > 0) {
609
+ element.empty().append(
610
+ content.css({ display: 'block', visibility: 'visible' })
611
+ );
612
+ }
613
+
614
+ // Content is a regular string, insert the new content
615
+ else { element.html(content); }
616
+
617
+ // Wait for content to be loaded, and reposition
618
+ return this._waitForContent(element).then(function(images) {
619
+ if(images.images && images.images.length && self.rendered && self.tooltip[0].offsetWidth > 0) {
620
+ self.reposition(cache.event, !images.length);
621
+ }
622
+ });
623
+ };
624
+
625
+ PROTOTYPE._waitForContent = function(element) {
626
+ var cache = this.cache;
627
+
628
+ // Set flag
629
+ cache.waiting = TRUE;
630
+
631
+ // If imagesLoaded is included, ensure images have loaded and return promise
632
+ return ( $.fn.imagesLoaded ? element.imagesLoaded() : $.Deferred().resolve([]) )
633
+ .done(function() { cache.waiting = FALSE; })
634
+ .promise();
635
+ };
636
+
637
+ PROTOTYPE._updateContent = function(content, reposition) {
638
+ this._update(content, this.elements.content, reposition);
639
+ };
640
+
641
+ PROTOTYPE._updateTitle = function(content, reposition) {
642
+ if(this._update(content, this.elements.title, reposition) === FALSE) {
643
+ this._removeTitle(FALSE);
644
+ }
645
+ };
646
+
647
+ PROTOTYPE._createTitle = function()
648
+ {
649
+ var elements = this.elements,
650
+ id = this._id+'-title';
651
+
652
+ // Destroy previous title element, if present
653
+ if(elements.titlebar) { this._removeTitle(); }
654
+
655
+ // Create title bar and title elements
656
+ elements.titlebar = $('<div />', {
657
+ 'class': NAMESPACE + '-titlebar ' + (this.options.style.widget ? createWidgetClass('header') : '')
658
+ })
659
+ .append(
660
+ elements.title = $('<div />', {
661
+ 'id': id,
662
+ 'class': NAMESPACE + '-title',
663
+ 'aria-atomic': TRUE
664
+ })
665
+ )
666
+ .insertBefore(elements.content)
667
+
668
+ // Button-specific events
669
+ .delegate('.qtip-close', 'mousedown keydown mouseup keyup mouseout', function(event) {
670
+ $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down');
671
+ })
672
+ .delegate('.qtip-close', 'mouseover mouseout', function(event){
673
+ $(this).toggleClass('ui-state-hover', event.type === 'mouseover');
674
+ });
675
+
676
+ // Create button if enabled
677
+ if(this.options.content.button) { this._createButton(); }
678
+ };
679
+
680
+ PROTOTYPE._removeTitle = function(reposition)
681
+ {
682
+ var elements = this.elements;
683
+
684
+ if(elements.title) {
685
+ elements.titlebar.remove();
686
+ elements.titlebar = elements.title = elements.button = NULL;
687
+
688
+ // Reposition if enabled
689
+ if(reposition !== FALSE) { this.reposition(); }
690
+ }
691
+ };
692
+
693
+ ;PROTOTYPE.reposition = function(event, effect) {
694
+ if(!this.rendered || this.positioning || this.destroyed) { return this; }
695
+
696
+ // Set positioning flag
697
+ this.positioning = TRUE;
698
+
699
+ var cache = this.cache,
700
+ tooltip = this.tooltip,
701
+ posOptions = this.options.position,
702
+ target = posOptions.target,
703
+ my = posOptions.my,
704
+ at = posOptions.at,
705
+ viewport = posOptions.viewport,
706
+ container = posOptions.container,
707
+ adjust = posOptions.adjust,
708
+ method = adjust.method.split(' '),
709
+ tooltipWidth = tooltip.outerWidth(FALSE),
710
+ tooltipHeight = tooltip.outerHeight(FALSE),
711
+ targetWidth = 0,
712
+ targetHeight = 0,
713
+ type = tooltip.css('position'),
714
+ position = { left: 0, top: 0 },
715
+ visible = tooltip[0].offsetWidth > 0,
716
+ isScroll = event && event.type === 'scroll',
717
+ win = $(window),
718
+ doc = container[0].ownerDocument,
719
+ mouse = this.mouse,
720
+ pluginCalculations, offset;
721
+
722
+ // Check if absolute position was passed
723
+ if($.isArray(target) && target.length === 2) {
724
+ // Force left top and set position
725
+ at = { x: LEFT, y: TOP };
726
+ position = { left: target[0], top: target[1] };
727
+ }
728
+
729
+ // Check if mouse was the target
730
+ else if(target === 'mouse') {
731
+ // Force left top to allow flipping
732
+ at = { x: LEFT, y: TOP };
733
+
734
+ // Use the cached mouse coordinates if available, or passed event has no coordinates
735
+ if(mouse && mouse.pageX && (adjust.mouse || !event || !event.pageX) ) {
736
+ event = mouse;
737
+ }
738
+
739
+ // If the passed event has no coordinates (such as a scroll event)
740
+ else if(!event || !event.pageX) {
741
+ // Use the mouse origin that caused the show event, if distance hiding is enabled
742
+ if((!adjust.mouse || this.options.show.distance) && cache.origin && cache.origin.pageX) {
743
+ event = cache.origin;
744
+ }
745
+
746
+ // Use cached event for resize/scroll events
747
+ else if(!event || (event && (event.type === 'resize' || event.type === 'scroll'))) {
748
+ event = cache.event;
749
+ }
750
+ }
751
+
752
+ // Calculate body and container offset and take them into account below
753
+ if(type !== 'static') { position = container.offset(); }
754
+ if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) {
755
+ offset = $(document.body).offset();
756
+ }
757
+
758
+ // Use event coordinates for position
759
+ position = {
760
+ left: event.pageX - position.left + (offset && offset.left || 0),
761
+ top: event.pageY - position.top + (offset && offset.top || 0)
762
+ };
763
+
764
+ // Scroll events are a pain, some browsers
765
+ if(adjust.mouse && isScroll && mouse) {
766
+ position.left -= (mouse.scrollX || 0) - win.scrollLeft();
767
+ position.top -= (mouse.scrollY || 0) - win.scrollTop();
768
+ }
769
+ }
770
+
771
+ // Target wasn't mouse or absolute...
772
+ else {
773
+ // Check if event targetting is being used
774
+ if(target === 'event') {
775
+ if(event && event.target && event.type !== 'scroll' && event.type !== 'resize') {
776
+ cache.target = $(event.target);
777
+ }
778
+ else if(!event.target) {
779
+ cache.target = this.elements.target;
780
+ }
781
+ }
782
+ else if(target !== 'event'){
783
+ cache.target = $(target.jquery ? target : this.elements.target);
784
+ }
785
+ target = cache.target;
786
+
787
+ // Parse the target into a jQuery object and make sure there's an element present
788
+ target = $(target).eq(0);
789
+ if(target.length === 0) { return this; }
790
+
791
+ // Check if window or document is the target
792
+ else if(target[0] === document || target[0] === window) {
793
+ targetWidth = BROWSER.iOS ? window.innerWidth : target.width();
794
+ targetHeight = BROWSER.iOS ? window.innerHeight : target.height();
795
+
796
+ if(target[0] === window) {
797
+ position = {
798
+ top: (viewport || target).scrollTop(),
799
+ left: (viewport || target).scrollLeft()
800
+ };
801
+ }
802
+ }
803
+
804
+ // Check if the target is an <AREA> element
805
+ else if(PLUGINS.imagemap && target.is('area')) {
806
+ pluginCalculations = PLUGINS.imagemap(this, target, at, PLUGINS.viewport ? method : FALSE);
807
+ }
808
+
809
+ // Check if the target is an SVG element
810
+ else if(PLUGINS.svg && target && target[0].ownerSVGElement) {
811
+ pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.viewport ? method : FALSE);
812
+ }
813
+
814
+ // Otherwise use regular jQuery methods
815
+ else {
816
+ targetWidth = target.outerWidth(FALSE);
817
+ targetHeight = target.outerHeight(FALSE);
818
+ position = target.offset();
819
+ }
820
+
821
+ // Parse returned plugin values into proper variables
822
+ if(pluginCalculations) {
823
+ targetWidth = pluginCalculations.width;
824
+ targetHeight = pluginCalculations.height;
825
+ offset = pluginCalculations.offset;
826
+ position = pluginCalculations.position;
827
+ }
828
+
829
+ // Adjust position to take into account offset parents
830
+ position = this.reposition.offset(target, position, container);
831
+
832
+ // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2)
833
+ if((BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1) ||
834
+ (BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33) ||
835
+ (!BROWSER.iOS && type === 'fixed')
836
+ ){
837
+ position.left -= win.scrollLeft();
838
+ position.top -= win.scrollTop();
839
+ }
840
+
841
+ // Adjust position relative to target
842
+ if(!pluginCalculations || (pluginCalculations && pluginCalculations.adjustable !== FALSE)) {
843
+ position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0;
844
+ position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0;
845
+ }
846
+ }
847
+
848
+ // Adjust position relative to tooltip
849
+ position.left += adjust.x + (my.x === RIGHT ? -tooltipWidth : my.x === CENTER ? -tooltipWidth / 2 : 0);
850
+ position.top += adjust.y + (my.y === BOTTOM ? -tooltipHeight : my.y === CENTER ? -tooltipHeight / 2 : 0);
851
+
852
+ // Use viewport adjustment plugin if enabled
853
+ if(PLUGINS.viewport) {
854
+ position.adjusted = PLUGINS.viewport(
855
+ this, position, posOptions, targetWidth, targetHeight, tooltipWidth, tooltipHeight
856
+ );
857
+
858
+ // Apply offsets supplied by positioning plugin (if used)
859
+ if(offset && position.adjusted.left) { position.left += offset.left; }
860
+ if(offset && position.adjusted.top) { position.top += offset.top; }
861
+ }
862
+
863
+ // Viewport adjustment is disabled, set values to zero
864
+ else { position.adjusted = { left: 0, top: 0 }; }
865
+
866
+ // tooltipmove event
867
+ if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; }
868
+ delete position.adjusted;
869
+
870
+ // If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly
871
+ if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) {
872
+ tooltip.css(position);
873
+ }
874
+
875
+ // Use custom function if provided
876
+ else if($.isFunction(posOptions.effect)) {
877
+ posOptions.effect.call(tooltip, this, $.extend({}, position));
878
+ tooltip.queue(function(next) {
879
+ // Reset attributes to avoid cross-browser rendering bugs
880
+ $(this).css({ opacity: '', height: '' });
881
+ if(BROWSER.ie) { this.style.removeAttribute('filter'); }
882
+
883
+ next();
884
+ });
885
+ }
886
+
887
+ // Set positioning flag
888
+ this.positioning = FALSE;
889
+
890
+ return this;
891
+ };
892
+
893
+ // Custom (more correct for qTip!) offset calculator
894
+ PROTOTYPE.reposition.offset = function(elem, pos, container) {
895
+ if(!container[0]) { return pos; }
896
+
897
+ var ownerDocument = $(elem[0].ownerDocument),
898
+ quirks = !!BROWSER.ie && document.compatMode !== 'CSS1Compat',
899
+ parent = container[0],
900
+ scrolled, position, parentOffset, overflow;
901
+
902
+ function scroll(e, i) {
903
+ pos.left += i * e.scrollLeft();
904
+ pos.top += i * e.scrollTop();
905
+ }
906
+
907
+ // Compensate for non-static containers offset
908
+ do {
909
+ if((position = $.css(parent, 'position')) !== 'static') {
910
+ if(position === 'fixed') {
911
+ parentOffset = parent.getBoundingClientRect();
912
+ scroll(ownerDocument, -1);
913
+ }
914
+ else {
915
+ parentOffset = $(parent).position();
916
+ parentOffset.left += (parseFloat($.css(parent, 'borderLeftWidth')) || 0);
917
+ parentOffset.top += (parseFloat($.css(parent, 'borderTopWidth')) || 0);
918
+ }
919
+
920
+ pos.left -= parentOffset.left + (parseFloat($.css(parent, 'marginLeft')) || 0);
921
+ pos.top -= parentOffset.top + (parseFloat($.css(parent, 'marginTop')) || 0);
922
+
923
+ // If this is the first parent element with an overflow of "scroll" or "auto", store it
924
+ if(!scrolled && (overflow = $.css(parent, 'overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = $(parent); }
925
+ }
926
+ }
927
+ while((parent = parent.offsetParent));
928
+
929
+ // Compensate for containers scroll if it also has an offsetParent (or in IE quirks mode)
930
+ if(scrolled && (scrolled[0] !== ownerDocument[0] || quirks)) {
931
+ scroll(scrolled, 1);
932
+ }
933
+
934
+ return pos;
935
+ };
936
+
937
+ // Corner class
938
+ var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) {
939
+ corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase();
940
+ this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase();
941
+ this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase();
942
+ this.forceY = !!forceY;
943
+
944
+ var f = corner.charAt(0);
945
+ this.precedance = (f === 't' || f === 'b' ? Y : X);
946
+ }).prototype;
947
+
948
+ C.invert = function(z, center) {
949
+ this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z];
950
+ };
951
+
952
+ C.string = function() {
953
+ var x = this.x, y = this.y;
954
+ return x === y ? x : this.precedance === Y || (this.forceY && y !== 'center') ? y+' '+x : x+' '+y;
955
+ };
956
+
957
+ C.abbrev = function() {
958
+ var result = this.string().split(' ');
959
+ return result[0].charAt(0) + (result[1] && result[1].charAt(0) || '');
960
+ };
961
+
962
+ C.clone = function() {
963
+ return new CORNER( this.string(), this.forceY );
964
+ };;
965
+ PROTOTYPE.toggle = function(state, event) {
966
+ var cache = this.cache,
967
+ options = this.options,
968
+ tooltip = this.tooltip;
969
+
970
+ // Try to prevent flickering when tooltip overlaps show element
971
+ if(event) {
972
+ if((/over|enter/).test(event.type) && (/out|leave/).test(cache.event.type) &&
973
+ options.show.target.add(event.target).length === options.show.target.length &&
974
+ tooltip.has(event.relatedTarget).length) {
975
+ return this;
976
+ }
977
+
978
+ // Cache event
979
+ cache.event = cloneEvent(event);
980
+ }
981
+
982
+ // If we're currently waiting and we've just hidden... stop it
983
+ this.waiting && !state && (this.hiddenDuringWait = TRUE);
984
+
985
+ // Render the tooltip if showing and it isn't already
986
+ if(!this.rendered) { return state ? this.render(1) : this; }
987
+ else if(this.destroyed || this.disabled) { return this; }
988
+
989
+ var type = state ? 'show' : 'hide',
990
+ opts = this.options[type],
991
+ otherOpts = this.options[ !state ? 'show' : 'hide' ],
992
+ posOptions = this.options.position,
993
+ contentOptions = this.options.content,
994
+ width = this.tooltip.css('width'),
995
+ visible = this.tooltip.is(':visible'),
996
+ animate = state || opts.target.length === 1,
997
+ sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target,
998
+ identicalState, allow, showEvent, delay, after;
999
+
1000
+ // Detect state if valid one isn't provided
1001
+ if((typeof state).search('boolean|number')) { state = !visible; }
1002
+
1003
+ // Check if the tooltip is in an identical state to the new would-be state
1004
+ identicalState = !tooltip.is(':animated') && visible === state && sameTarget;
1005
+
1006
+ // Fire tooltip(show/hide) event and check if destroyed
1007
+ allow = !identicalState ? !!this._trigger(type, [90]) : NULL;
1008
+
1009
+ // Check to make sure the tooltip wasn't destroyed in the callback
1010
+ if(this.destroyed) { return this; }
1011
+
1012
+ // If the user didn't stop the method prematurely and we're showing the tooltip, focus it
1013
+ if(allow !== FALSE && state) { this.focus(event); }
1014
+
1015
+ // If the state hasn't changed or the user stopped it, return early
1016
+ if(!allow || identicalState) { return this; }
1017
+
1018
+ // Set ARIA hidden attribute
1019
+ $.attr(tooltip[0], 'aria-hidden', !!!state);
1020
+
1021
+ // Execute state specific properties
1022
+ if(state) {
1023
+ // Store show origin coordinates
1024
+ cache.origin = cloneEvent(this.mouse);
1025
+
1026
+ // Update tooltip content & title if it's a dynamic function
1027
+ if($.isFunction(contentOptions.text)) { this._updateContent(contentOptions.text, FALSE); }
1028
+ if($.isFunction(contentOptions.title)) { this._updateTitle(contentOptions.title, FALSE); }
1029
+
1030
+ // Cache mousemove events for positioning purposes (if not already tracking)
1031
+ if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) {
1032
+ $(document).bind('mousemove.'+NAMESPACE, this._storeMouse);
1033
+ trackingBound = TRUE;
1034
+ }
1035
+
1036
+ // Update the tooltip position (set width first to prevent viewport/max-width issues)
1037
+ if(!width) { tooltip.css('width', tooltip.outerWidth(FALSE)); }
1038
+ this.reposition(event, arguments[2]);
1039
+ if(!width) { tooltip.css('width', ''); }
1040
+
1041
+ // Hide other tooltips if tooltip is solo
1042
+ if(!!opts.solo) {
1043
+ (typeof opts.solo === 'string' ? $(opts.solo) : $(SELECTOR, opts.solo))
1044
+ .not(tooltip).not(opts.target).qtip('hide', $.Event('tooltipsolo'));
1045
+ }
1046
+ }
1047
+ else {
1048
+ // Clear show timer if we're hiding
1049
+ clearTimeout(this.timers.show);
1050
+
1051
+ // Remove cached origin on hide
1052
+ delete cache.origin;
1053
+
1054
+ // Remove mouse tracking event if not needed (all tracking qTips are hidden)
1055
+ if(trackingBound && !$(SELECTOR+'[tracking="true"]:visible', opts.solo).not(tooltip).length) {
1056
+ $(document).unbind('mousemove.'+NAMESPACE);
1057
+ trackingBound = FALSE;
1058
+ }
1059
+
1060
+ // Blur the tooltip
1061
+ this.blur(event);
1062
+ }
1063
+
1064
+ // Define post-animation, state specific properties
1065
+ after = $.proxy(function() {
1066
+ if(state) {
1067
+ // Prevent antialias from disappearing in IE by removing filter
1068
+ if(BROWSER.ie) { tooltip[0].style.removeAttribute('filter'); }
1069
+
1070
+ // Remove overflow setting to prevent tip bugs
1071
+ tooltip.css('overflow', '');
1072
+
1073
+ // Autofocus elements if enabled
1074
+ if('string' === typeof opts.autofocus) {
1075
+ $(this.options.show.autofocus, tooltip).focus();
1076
+ }
1077
+
1078
+ // If set, hide tooltip when inactive for delay period
1079
+ this.options.show.target.trigger('qtip-'+this.id+'-inactive');
1080
+ }
1081
+ else {
1082
+ // Reset CSS states
1083
+ tooltip.css({
1084
+ display: '',
1085
+ visibility: '',
1086
+ opacity: '',
1087
+ left: '',
1088
+ top: ''
1089
+ });
1090
+ }
1091
+
1092
+ // tooltipvisible/tooltiphidden events
1093
+ this._trigger(state ? 'visible' : 'hidden');
1094
+ }, this);
1095
+
1096
+ // If no effect type is supplied, use a simple toggle
1097
+ if(opts.effect === FALSE || animate === FALSE) {
1098
+ tooltip[ type ]();
1099
+ after();
1100
+ }
1101
+
1102
+ // Use custom function if provided
1103
+ else if($.isFunction(opts.effect)) {
1104
+ tooltip.stop(1, 1);
1105
+ opts.effect.call(tooltip, this);
1106
+ tooltip.queue('fx', function(n) {
1107
+ after(); n();
1108
+ });
1109
+ }
1110
+
1111
+ // Use basic fade function by default
1112
+ else { tooltip.fadeTo(90, state ? 1 : 0, after); }
1113
+
1114
+ // If inactive hide method is set, active it
1115
+ if(state) { opts.target.trigger('qtip-'+this.id+'-inactive'); }
1116
+
1117
+ return this;
1118
+ };
1119
+
1120
+ PROTOTYPE.show = function(event) { return this.toggle(TRUE, event); };
1121
+
1122
+ PROTOTYPE.hide = function(event) { return this.toggle(FALSE, event); };
1123
+
1124
+ ;PROTOTYPE.focus = function(event) {
1125
+ if(!this.rendered || this.destroyed) { return this; }
1126
+
1127
+ var qtips = $(SELECTOR),
1128
+ tooltip = this.tooltip,
1129
+ curIndex = parseInt(tooltip[0].style.zIndex, 10),
1130
+ newIndex = QTIP.zindex + qtips.length,
1131
+ focusedElem;
1132
+
1133
+ // Only update the z-index if it has changed and tooltip is not already focused
1134
+ if(!tooltip.hasClass(CLASS_FOCUS)) {
1135
+ // tooltipfocus event
1136
+ if(this._trigger('focus', [newIndex], event)) {
1137
+ // Only update z-index's if they've changed
1138
+ if(curIndex !== newIndex) {
1139
+ // Reduce our z-index's and keep them properly ordered
1140
+ qtips.each(function() {
1141
+ if(this.style.zIndex > curIndex) {
1142
+ this.style.zIndex = this.style.zIndex - 1;
1143
+ }
1144
+ });
1145
+
1146
+ // Fire blur event for focused tooltip
1147
+ qtips.filter('.' + CLASS_FOCUS).qtip('blur', event);
1148
+ }
1149
+
1150
+ // Set the new z-index
1151
+ tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex;
1152
+ }
1153
+ }
1154
+
1155
+ return this;
1156
+ };
1157
+
1158
+ PROTOTYPE.blur = function(event) {
1159
+ if(!this.rendered || this.destroyed) { return this; }
1160
+
1161
+ // Set focused status to FALSE
1162
+ this.tooltip.removeClass(CLASS_FOCUS);
1163
+
1164
+ // tooltipblur event
1165
+ this._trigger('blur', [ this.tooltip.css('zIndex') ], event);
1166
+
1167
+ return this;
1168
+ };
1169
+
1170
+ ;PROTOTYPE.disable = function(state) {
1171
+ if(this.destroyed) { return this; }
1172
+
1173
+ // If 'toggle' is passed, toggle the current state
1174
+ if(state === 'toggle') {
1175
+ state = !(this.rendered ? this.tooltip.hasClass(CLASS_DISABLED) : this.disabled);
1176
+ }
1177
+
1178
+ // Disable if no state passed
1179
+ else if('boolean' !== typeof state) {
1180
+ state = TRUE;
1181
+ }
1182
+
1183
+ if(this.rendered) {
1184
+ this.tooltip.toggleClass(CLASS_DISABLED, state)
1185
+ .attr('aria-disabled', state);
1186
+ }
1187
+
1188
+ this.disabled = !!state;
1189
+
1190
+ return this;
1191
+ };
1192
+
1193
+ PROTOTYPE.enable = function() { return this.disable(FALSE); };
1194
+
1195
+ ;PROTOTYPE._createButton = function()
1196
+ {
1197
+ var self = this,
1198
+ elements = this.elements,
1199
+ tooltip = elements.tooltip,
1200
+ button = this.options.content.button,
1201
+ isString = typeof button === 'string',
1202
+ close = isString ? button : 'Close tooltip';
1203
+
1204
+ if(elements.button) { elements.button.remove(); }
1205
+
1206
+ // Use custom button if one was supplied by user, else use default
1207
+ if(button.jquery) {
1208
+ elements.button = button;
1209
+ }
1210
+ else {
1211
+ elements.button = $('<a />', {
1212
+ 'class': 'qtip-close ' + (this.options.style.widget ? '' : NAMESPACE+'-icon'),
1213
+ 'title': close,
1214
+ 'aria-label': close
1215
+ })
1216
+ .prepend(
1217
+ $('<span />', {
1218
+ 'class': 'ui-icon ui-icon-close',
1219
+ 'html': '&times;'
1220
+ })
1221
+ );
1222
+ }
1223
+
1224
+ // Create button and setup attributes
1225
+ elements.button.appendTo(elements.titlebar || tooltip)
1226
+ .attr('role', 'button')
1227
+ .click(function(event) {
1228
+ if(!tooltip.hasClass(CLASS_DISABLED)) { self.hide(event); }
1229
+ return FALSE;
1230
+ });
1231
+ };
1232
+
1233
+ PROTOTYPE._updateButton = function(button)
1234
+ {
1235
+ // Make sure tooltip is rendered and if not, return
1236
+ if(!this.rendered) { return FALSE; }
1237
+
1238
+ var elem = this.elements.button;
1239
+ if(button) { this._createButton(); }
1240
+ else { elem.remove(); }
1241
+ };
1242
+
1243
+ ;// Widget class creator
1244
+ function createWidgetClass(cls) {
1245
+ return WIDGET.concat('').join(cls ? '-'+cls+' ' : ' ');
1246
+ }
1247
+
1248
+ // Widget class setter method
1249
+ PROTOTYPE._setWidget = function()
1250
+ {
1251
+ var on = this.options.style.widget,
1252
+ elements = this.elements,
1253
+ tooltip = elements.tooltip,
1254
+ disabled = tooltip.hasClass(CLASS_DISABLED);
1255
+
1256
+ tooltip.removeClass(CLASS_DISABLED);
1257
+ CLASS_DISABLED = on ? 'ui-state-disabled' : 'qtip-disabled';
1258
+ tooltip.toggleClass(CLASS_DISABLED, disabled);
1259
+
1260
+ tooltip.toggleClass('ui-helper-reset '+createWidgetClass(), on).toggleClass(CLASS_DEFAULT, this.options.style.def && !on);
1261
+
1262
+ if(elements.content) {
1263
+ elements.content.toggleClass( createWidgetClass('content'), on);
1264
+ }
1265
+ if(elements.titlebar) {
1266
+ elements.titlebar.toggleClass( createWidgetClass('header'), on);
1267
+ }
1268
+ if(elements.button) {
1269
+ elements.button.toggleClass(NAMESPACE+'-icon', !on);
1270
+ }
1271
+ };;function cloneEvent(event) {
1272
+ return event && {
1273
+ type: event.type,
1274
+ pageX: event.pageX,
1275
+ pageY: event.pageY,
1276
+ target: event.target,
1277
+ relatedTarget: event.relatedTarget,
1278
+ scrollX: event.scrollX || window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft,
1279
+ scrollY: event.scrollY || window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop
1280
+ } || {};
1281
+ }
1282
+
1283
+ function delay(callback, duration) {
1284
+ // If tooltip has displayed, start hide timer
1285
+ if(duration > 0) {
1286
+ return setTimeout(
1287
+ $.proxy(callback, this), duration
1288
+ );
1289
+ }
1290
+ else{ callback.call(this); }
1291
+ }
1292
+
1293
+ function showMethod(event) {
1294
+ if(this.tooltip.hasClass(CLASS_DISABLED)) { return FALSE; }
1295
+
1296
+ // Clear hide timers
1297
+ clearTimeout(this.timers.show);
1298
+ clearTimeout(this.timers.hide);
1299
+
1300
+ // Start show timer
1301
+ this.timers.show = delay.call(this,
1302
+ function() { this.toggle(TRUE, event); },
1303
+ this.options.show.delay
1304
+ );
1305
+ }
1306
+
1307
+ function hideMethod(event) {
1308
+ if(this.tooltip.hasClass(CLASS_DISABLED)) { return FALSE; }
1309
+
1310
+ // Check if new target was actually the tooltip element
1311
+ var relatedTarget = $(event.relatedTarget),
1312
+ ontoTooltip = relatedTarget.closest(SELECTOR)[0] === this.tooltip[0],
1313
+ ontoTarget = relatedTarget[0] === this.options.show.target[0];
1314
+
1315
+ // Clear timers and stop animation queue
1316
+ clearTimeout(this.timers.show);
1317
+ clearTimeout(this.timers.hide);
1318
+
1319
+ // Prevent hiding if tooltip is fixed and event target is the tooltip.
1320
+ // Or if mouse positioning is enabled and cursor momentarily overlaps
1321
+ if(this !== relatedTarget[0] &&
1322
+ (this.options.position.target === 'mouse' && ontoTooltip) ||
1323
+ (this.options.hide.fixed && (
1324
+ (/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget))
1325
+ ))
1326
+ {
1327
+ try {
1328
+ event.preventDefault();
1329
+ event.stopImmediatePropagation();
1330
+ } catch(e) {}
1331
+
1332
+ return;
1333
+ }
1334
+
1335
+ // If tooltip has displayed, start hide timer
1336
+ this.timers.hide = delay.call(this,
1337
+ function() { this.toggle(FALSE, event); },
1338
+ this.options.hide.delay,
1339
+ this
1340
+ );
1341
+ }
1342
+
1343
+ function inactiveMethod(event) {
1344
+ if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return FALSE; }
1345
+
1346
+ // Clear timer
1347
+ clearTimeout(this.timers.inactive);
1348
+
1349
+ this.timers.inactive = delay.call(this,
1350
+ function(){ this.hide(event); },
1351
+ this.options.hide.inactive
1352
+ );
1353
+ }
1354
+
1355
+ function repositionMethod(event) {
1356
+ if(this.rendered && this.tooltip[0].offsetWidth > 0) { this.reposition(event); }
1357
+ }
1358
+
1359
+ // Store mouse coordinates
1360
+ PROTOTYPE._storeMouse = function(event) {
1361
+ (this.mouse = cloneEvent(event)).type = 'mousemove';
1362
+ };
1363
+
1364
+ // Bind events
1365
+ PROTOTYPE._bind = function(targets, events, method, suffix, context) {
1366
+ var ns = '.' + this._id + (suffix ? '-'+suffix : '');
1367
+ events.length && $(targets).bind(
1368
+ (events.split ? events : events.join(ns + ' ')) + ns,
1369
+ $.proxy(method, context || this)
1370
+ );
1371
+ };
1372
+ PROTOTYPE._unbind = function(targets, suffix) {
1373
+ $(targets).unbind('.' + this._id + (suffix ? '-'+suffix : ''));
1374
+ };
1375
+
1376
+ // Apply common event handlers using delegate (avoids excessive .bind calls!)
1377
+ var ns = '.'+NAMESPACE;
1378
+ function delegate(selector, events, method) {
1379
+ $(document.body).delegate(selector,
1380
+ (events.split ? events : events.join(ns + ' ')) + ns,
1381
+ function() {
1382
+ var api = QTIP.api[ $.attr(this, ATTR_ID) ];
1383
+ api && !api.disabled && method.apply(api, arguments);
1384
+ }
1385
+ );
1386
+ }
1387
+
1388
+ $(function() {
1389
+ delegate(SELECTOR, ['mouseenter', 'mouseleave'], function(event) {
1390
+ var state = event.type === 'mouseenter',
1391
+ tooltip = $(event.currentTarget),
1392
+ target = $(event.relatedTarget || event.target),
1393
+ options = this.options;
1394
+
1395
+ // On mouseenter...
1396
+ if(state) {
1397
+ // Focus the tooltip on mouseenter (z-index stacking)
1398
+ this.focus(event);
1399
+
1400
+ // Clear hide timer on tooltip hover to prevent it from closing
1401
+ tooltip.hasClass(CLASS_FIXED) && !tooltip.hasClass(CLASS_DISABLED) && clearTimeout(this.timers.hide);
1402
+ }
1403
+
1404
+ // On mouseleave...
1405
+ else {
1406
+ // Hide when we leave the tooltip and not onto the show target (if a hide event is set)
1407
+ if(options.position.target === 'mouse' && options.hide.event &&
1408
+ options.show.target && !target.closest(options.show.target[0]).length) {
1409
+ this.hide(event);
1410
+ }
1411
+ }
1412
+
1413
+ // Add hover class
1414
+ tooltip.toggleClass(CLASS_HOVER, state);
1415
+ });
1416
+
1417
+ // Define events which reset the 'inactive' event handler
1418
+ delegate('['+ATTR_ID+']', INACTIVE_EVENTS, inactiveMethod);
1419
+ });
1420
+
1421
+ // Event trigger
1422
+ PROTOTYPE._trigger = function(type, args, event) {
1423
+ var callback = $.Event('tooltip'+type);
1424
+ callback.originalEvent = (event && $.extend({}, event)) || this.cache.event || NULL;
1425
+
1426
+ this.triggering = type;
1427
+ this.tooltip.trigger(callback, [this].concat(args || []));
1428
+ this.triggering = FALSE;
1429
+
1430
+ return !callback.isDefaultPrevented();
1431
+ };
1432
+
1433
+ PROTOTYPE._bindEvents = function(showEvents, hideEvents, showTarget, hideTarget, showMethod, hideMethod) {
1434
+ // If hide and show targets are the same...
1435
+ if(hideTarget.add(showTarget).length === hideTarget.length) {
1436
+ var toggleEvents = [];
1437
+
1438
+ // Filter identical show/hide events
1439
+ hideEvents = $.map(hideEvents, function(type) {
1440
+ var showIndex = $.inArray(type, showEvents);
1441
+
1442
+ // Both events are identical, remove from both hide and show events
1443
+ // and append to toggleEvents
1444
+ if(showIndex > -1) {
1445
+ toggleEvents.push( showEvents.splice( showIndex, 1 )[0] );
1446
+ return;
1447
+ }
1448
+
1449
+ return type;
1450
+ });
1451
+
1452
+ // Toggle events are special case of identical show/hide events, which happen in sequence
1453
+ toggleEvents.length && this._bind(showTarget, toggleEvents, function(event) {
1454
+ var state = this.rendered ? this.tooltip[0].offsetWidth > 0 : false;
1455
+ (state ? hideMethod : showMethod).call(this, event);
1456
+ });
1457
+ }
1458
+
1459
+ // Apply show/hide/toggle events
1460
+ this._bind(showTarget, showEvents, showMethod);
1461
+ this._bind(hideTarget, hideEvents, hideMethod);
1462
+ };
1463
+
1464
+ PROTOTYPE._assignInitialEvents = function(event) {
1465
+ var options = this.options,
1466
+ showTarget = options.show.target,
1467
+ hideTarget = options.hide.target,
1468
+ showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [],
1469
+ hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : [];
1470
+
1471
+ /*
1472
+ * Make sure hoverIntent functions properly by using mouseleave as a hide event if
1473
+ * mouseenter/mouseout is used for show.event, even if it isn't in the users options.
1474
+ */
1475
+ if(/mouse(over|enter)/i.test(options.show.event) && !/mouse(out|leave)/i.test(options.hide.event)) {
1476
+ hideEvents.push('mouseleave');
1477
+ }
1478
+
1479
+ /*
1480
+ * Also make sure initial mouse targetting works correctly by caching mousemove coords
1481
+ * on show targets before the tooltip has rendered. Also set onTarget when triggered to
1482
+ * keep mouse tracking working.
1483
+ */
1484
+ this._bind(showTarget, 'mousemove', function(event) {
1485
+ this._storeMouse(event);
1486
+ this.cache.onTarget = TRUE;
1487
+ });
1488
+
1489
+ // Define hoverIntent function
1490
+ function hoverIntent(event) {
1491
+ // Only continue if tooltip isn't disabled
1492
+ if(this.disabled || this.destroyed) { return FALSE; }
1493
+
1494
+ // Cache the event data
1495
+ this.cache.event = cloneEvent(event);
1496
+ this.cache.target = event ? $(event.target) : [undefined];
1497
+
1498
+ // Start the event sequence
1499
+ clearTimeout(this.timers.show);
1500
+ this.timers.show = delay.call(this,
1501
+ function() { this.render(typeof event === 'object' || options.show.ready); },
1502
+ options.show.delay
1503
+ );
1504
+ }
1505
+
1506
+ // Filter and bind events
1507
+ this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, hoverIntent, function() {
1508
+ clearTimeout(this.timers.show);
1509
+ });
1510
+
1511
+ // Prerendering is enabled, create tooltip now
1512
+ if(options.show.ready || options.prerender) { hoverIntent.call(this, event); }
1513
+ };
1514
+
1515
+ // Event assignment method
1516
+ PROTOTYPE._assignEvents = function() {
1517
+ var self = this,
1518
+ options = this.options,
1519
+ posOptions = options.position,
1520
+
1521
+ tooltip = this.tooltip,
1522
+ showTarget = options.show.target,
1523
+ hideTarget = options.hide.target,
1524
+ containerTarget = posOptions.container,
1525
+ viewportTarget = posOptions.viewport,
1526
+ documentTarget = $(document),
1527
+ bodyTarget = $(document.body),
1528
+ windowTarget = $(window),
1529
+
1530
+ showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [],
1531
+ hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : [];
1532
+
1533
+
1534
+ // Assign passed event callbacks
1535
+ $.each(options.events, function(name, callback) {
1536
+ self._bind(tooltip, name === 'toggle' ? ['tooltipshow','tooltiphide'] : ['tooltip'+name], callback, null, tooltip);
1537
+ });
1538
+
1539
+ // Hide tooltips when leaving current window/frame (but not select/option elements)
1540
+ if(/mouse(out|leave)/i.test(options.hide.event) && options.hide.leave === 'window') {
1541
+ this._bind(documentTarget, ['mouseout', 'blur'], function(event) {
1542
+ if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) {
1543
+ this.hide(event);
1544
+ }
1545
+ });
1546
+ }
1547
+
1548
+ // Enable hide.fixed by adding appropriate class
1549
+ if(options.hide.fixed) {
1550
+ hideTarget = hideTarget.add( tooltip.addClass(CLASS_FIXED) );
1551
+ }
1552
+
1553
+ /*
1554
+ * Make sure hoverIntent functions properly by using mouseleave to clear show timer if
1555
+ * mouseenter/mouseout is used for show.event, even if it isn't in the users options.
1556
+ */
1557
+ else if(/mouse(over|enter)/i.test(options.show.event)) {
1558
+ this._bind(hideTarget, 'mouseleave', function() {
1559
+ clearTimeout(this.timers.show);
1560
+ });
1561
+ }
1562
+
1563
+ // Hide tooltip on document mousedown if unfocus events are enabled
1564
+ if(('' + options.hide.event).indexOf('unfocus') > -1) {
1565
+ this._bind(containerTarget.closest('html'), ['mousedown', 'touchstart'], function(event) {
1566
+ var elem = $(event.target),
1567
+ enabled = this.rendered && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0,
1568
+ isAncestor = elem.parents(SELECTOR).filter(this.tooltip[0]).length > 0;
1569
+
1570
+ if(elem[0] !== this.target[0] && elem[0] !== this.tooltip[0] && !isAncestor &&
1571
+ !this.target.has(elem[0]).length && enabled
1572
+ ) {
1573
+ this.hide(event);
1574
+ }
1575
+ });
1576
+ }
1577
+
1578
+ // Check if the tooltip hides when inactive
1579
+ if('number' === typeof options.hide.inactive) {
1580
+ // Bind inactive method to show target(s) as a custom event
1581
+ this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod);
1582
+
1583
+ // Define events which reset the 'inactive' event handler
1584
+ this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod, '-inactive');
1585
+ }
1586
+
1587
+ // Filter and bind events
1588
+ this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, showMethod, hideMethod);
1589
+
1590
+ // Mouse movement bindings
1591
+ this._bind(showTarget.add(tooltip), 'mousemove', function(event) {
1592
+ // Check if the tooltip hides when mouse is moved a certain distance
1593
+ if('number' === typeof options.hide.distance) {
1594
+ var origin = this.cache.origin || {},
1595
+ limit = this.options.hide.distance,
1596
+ abs = Math.abs;
1597
+
1598
+ // Check if the movement has gone beyond the limit, and hide it if so
1599
+ if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) {
1600
+ this.hide(event);
1601
+ }
1602
+ }
1603
+
1604
+ // Cache mousemove coords on show targets
1605
+ this._storeMouse(event);
1606
+ });
1607
+
1608
+ // Mouse positioning events
1609
+ if(posOptions.target === 'mouse') {
1610
+ // If mouse adjustment is on...
1611
+ if(posOptions.adjust.mouse) {
1612
+ // Apply a mouseleave event so we don't get problems with overlapping
1613
+ if(options.hide.event) {
1614
+ // Track if we're on the target or not
1615
+ this._bind(showTarget, ['mouseenter', 'mouseleave'], function(event) {
1616
+ this.cache.onTarget = event.type === 'mouseenter';
1617
+ });
1618
+ }
1619
+
1620
+ // Update tooltip position on mousemove
1621
+ this._bind(documentTarget, 'mousemove', function(event) {
1622
+ // Update the tooltip position only if the tooltip is visible and adjustment is enabled
1623
+ if(this.rendered && this.cache.onTarget && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0) {
1624
+ this.reposition(event);
1625
+ }
1626
+ });
1627
+ }
1628
+ }
1629
+
1630
+ // Adjust positions of the tooltip on window resize if enabled
1631
+ if(posOptions.adjust.resize || viewportTarget.length) {
1632
+ this._bind( $.event.special.resize ? viewportTarget : windowTarget, 'resize', repositionMethod );
1633
+ }
1634
+
1635
+ // Adjust tooltip position on scroll of the window or viewport element if present
1636
+ if(posOptions.adjust.scroll) {
1637
+ this._bind( windowTarget.add(posOptions.container), 'scroll', repositionMethod );
1638
+ }
1639
+ };
1640
+
1641
+ // Un-assignment method
1642
+ PROTOTYPE._unassignEvents = function() {
1643
+ var targets = [
1644
+ this.options.show.target[0],
1645
+ this.options.hide.target[0],
1646
+ this.rendered && this.tooltip[0],
1647
+ this.options.position.container[0],
1648
+ this.options.position.viewport[0],
1649
+ this.options.position.container.closest('html')[0], // unfocus
1650
+ window,
1651
+ document
1652
+ ];
1653
+
1654
+ this._unbind($([]).pushStack( $.grep(targets, function(i) {
1655
+ return typeof i === 'object';
1656
+ })));
1657
+ };
1658
+
1659
+ ;// Initialization method
1660
+ function init(elem, id, opts) {
1661
+ var obj, posOptions, attr, config, title,
1662
+
1663
+ // Setup element references
1664
+ docBody = $(document.body),
1665
+
1666
+ // Use document body instead of document element if needed
1667
+ newTarget = elem[0] === document ? docBody : elem,
1668
+
1669
+ // Grab metadata from element if plugin is present
1670
+ metadata = (elem.metadata) ? elem.metadata(opts.metadata) : NULL,
1671
+
1672
+ // If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise
1673
+ metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL,
1674
+
1675
+ // Grab data from metadata.name (or data-qtipopts as fallback) using .data() method,
1676
+ html5 = elem.data(opts.metadata.name || 'qtipopts');
1677
+
1678
+ // If we don't get an object returned attempt to parse it manualyl without parseJSON
1679
+ try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; } catch(e) {}
1680
+
1681
+ // Merge in and sanitize metadata
1682
+ config = $.extend(TRUE, {}, QTIP.defaults, opts,
1683
+ typeof html5 === 'object' ? sanitizeOptions(html5) : NULL,
1684
+ sanitizeOptions(metadata5 || metadata));
1685
+
1686
+ // Re-grab our positioning options now we've merged our metadata and set id to passed value
1687
+ posOptions = config.position;
1688
+ config.id = id;
1689
+
1690
+ // Setup missing content if none is detected
1691
+ if('boolean' === typeof config.content.text) {
1692
+ attr = elem.attr(config.content.attr);
1693
+
1694
+ // Grab from supplied attribute if available
1695
+ if(config.content.attr !== FALSE && attr) { config.content.text = attr; }
1696
+
1697
+ // No valid content was found, abort render
1698
+ else { return FALSE; }
1699
+ }
1700
+
1701
+ // Setup target options
1702
+ if(!posOptions.container.length) { posOptions.container = docBody; }
1703
+ if(posOptions.target === FALSE) { posOptions.target = newTarget; }
1704
+ if(config.show.target === FALSE) { config.show.target = newTarget; }
1705
+ if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); }
1706
+ if(config.hide.target === FALSE) { config.hide.target = newTarget; }
1707
+ if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; }
1708
+
1709
+ // Ensure we only use a single container
1710
+ posOptions.container = posOptions.container.eq(0);
1711
+
1712
+ // Convert position corner values into x and y strings
1713
+ posOptions.at = new CORNER(posOptions.at, TRUE);
1714
+ posOptions.my = new CORNER(posOptions.my);
1715
+
1716
+ // Destroy previous tooltip if overwrite is enabled, or skip element if not
1717
+ if(elem.data(NAMESPACE)) {
1718
+ if(config.overwrite) {
1719
+ elem.qtip('destroy', true);
1720
+ }
1721
+ else if(config.overwrite === FALSE) {
1722
+ return FALSE;
1723
+ }
1724
+ }
1725
+
1726
+ // Add has-qtip attribute
1727
+ elem.attr(ATTR_HAS, id);
1728
+
1729
+ // Remove title attribute and store it if present
1730
+ if(config.suppress && (title = elem.attr('title'))) {
1731
+ // Final attr call fixes event delegatiom and IE default tooltip showing problem
1732
+ elem.removeAttr('title').attr(oldtitle, title).attr('title', '');
1733
+ }
1734
+
1735
+ // Initialize the tooltip and add API reference
1736
+ obj = new QTip(elem, config, id, !!attr);
1737
+ elem.data(NAMESPACE, obj);
1738
+
1739
+ // Catch remove/removeqtip events on target element to destroy redundant tooltip
1740
+ elem.one('remove.qtip-'+id+' removeqtip.qtip-'+id, function() {
1741
+ var api; if((api = $(this).data(NAMESPACE))) { api.destroy(true); }
1742
+ });
1743
+
1744
+ return obj;
1745
+ }
1746
+
1747
+ // jQuery $.fn extension method
1748
+ QTIP = $.fn.qtip = function(options, notation, newValue)
1749
+ {
1750
+ var command = ('' + options).toLowerCase(), // Parse command
1751
+ returned = NULL,
1752
+ args = $.makeArray(arguments).slice(1),
1753
+ event = args[args.length - 1],
1754
+ opts = this[0] ? $.data(this[0], NAMESPACE) : NULL;
1755
+
1756
+ // Check for API request
1757
+ if((!arguments.length && opts) || command === 'api') {
1758
+ return opts;
1759
+ }
1760
+
1761
+ // Execute API command if present
1762
+ else if('string' === typeof options) {
1763
+ this.each(function() {
1764
+ var api = $.data(this, NAMESPACE);
1765
+ if(!api) { return TRUE; }
1766
+
1767
+ // Cache the event if possible
1768
+ if(event && event.timeStamp) { api.cache.event = event; }
1769
+
1770
+ // Check for specific API commands
1771
+ if(notation && (command === 'option' || command === 'options')) {
1772
+ if(newValue !== undefined || $.isPlainObject(notation)) {
1773
+ api.set(notation, newValue);
1774
+ }
1775
+ else {
1776
+ returned = api.get(notation);
1777
+ return FALSE;
1778
+ }
1779
+ }
1780
+
1781
+ // Execute API command
1782
+ else if(api[command]) {
1783
+ api[command].apply(api, args);
1784
+ }
1785
+ });
1786
+
1787
+ return returned !== NULL ? returned : this;
1788
+ }
1789
+
1790
+ // No API commands. validate provided options and setup qTips
1791
+ else if('object' === typeof options || !arguments.length) {
1792
+ // Sanitize options first
1793
+ opts = sanitizeOptions($.extend(TRUE, {}, options));
1794
+
1795
+ return this.each(function(i) {
1796
+ var api, id;
1797
+
1798
+ // Find next available ID, or use custom ID if provided
1799
+ id = $.isArray(opts.id) ? opts.id[i] : opts.id;
1800
+ id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ? QTIP.nextid++ : id;
1801
+
1802
+ // Initialize the qTip and re-grab newly sanitized options
1803
+ api = init($(this), id, opts);
1804
+ if(api === FALSE) { return TRUE; }
1805
+ else { QTIP.api[id] = api; }
1806
+
1807
+ // Initialize plugins
1808
+ $.each(PLUGINS, function() {
1809
+ if(this.initialize === 'initialize') { this(api); }
1810
+ });
1811
+
1812
+ // Assign initial pre-render events
1813
+ api._assignInitialEvents(event);
1814
+ });
1815
+ }
1816
+ };
1817
+
1818
+ // Expose class
1819
+ $.qtip = QTip;
1820
+
1821
+ // Populated in render method
1822
+ QTIP.api = {};
1823
+ ;$.each({
1824
+ /* Allow other plugins to successfully retrieve the title of an element with a qTip applied */
1825
+ attr: function(attr, val) {
1826
+ if(this.length) {
1827
+ var self = this[0],
1828
+ title = 'title',
1829
+ api = $.data(self, 'qtip');
1830
+
1831
+ if(attr === title && api && 'object' === typeof api && api.options.suppress) {
1832
+ if(arguments.length < 2) {
1833
+ return $.attr(self, oldtitle);
1834
+ }
1835
+
1836
+ // If qTip is rendered and title was originally used as content, update it
1837
+ if(api && api.options.content.attr === title && api.cache.attr) {
1838
+ api.set('content.text', val);
1839
+ }
1840
+
1841
+ // Use the regular attr method to set, then cache the result
1842
+ return this.attr(oldtitle, val);
1843
+ }
1844
+ }
1845
+
1846
+ return $.fn['attr'+replaceSuffix].apply(this, arguments);
1847
+ },
1848
+
1849
+ /* Allow clone to correctly retrieve cached title attributes */
1850
+ clone: function(keepData) {
1851
+ var titles = $([]), title = 'title',
1852
+
1853
+ // Clone our element using the real clone method
1854
+ elems = $.fn['clone'+replaceSuffix].apply(this, arguments);
1855
+
1856
+ // Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false
1857
+ if(!keepData) {
1858
+ elems.filter('['+oldtitle+']').attr('title', function() {
1859
+ return $.attr(this, oldtitle);
1860
+ })
1861
+ .removeAttr(oldtitle);
1862
+ }
1863
+
1864
+ return elems;
1865
+ }
1866
+ }, function(name, func) {
1867
+ if(!func || $.fn[name+replaceSuffix]) { return TRUE; }
1868
+
1869
+ var old = $.fn[name+replaceSuffix] = $.fn[name];
1870
+ $.fn[name] = function() {
1871
+ return func.apply(this, arguments) || old.apply(this, arguments);
1872
+ };
1873
+ });
1874
+
1875
+ /* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar).
1876
+ * This snippet is taken directly from jQuery UI source code found here:
1877
+ * http://code.jquery.com/ui/jquery-ui-git.js
1878
+ */
1879
+ if(!$.ui) {
1880
+ $['cleanData'+replaceSuffix] = $.cleanData;
1881
+ $.cleanData = function( elems ) {
1882
+ for(var i = 0, elem; (elem = $( elems[i] )).length; i++) {
1883
+ if(elem.attr(ATTR_HAS)) {
1884
+ try { elem.triggerHandler('removeqtip'); }
1885
+ catch( e ) {}
1886
+ }
1887
+ }
1888
+ $['cleanData'+replaceSuffix].apply(this, arguments);
1889
+ };
1890
+ }
1891
+
1892
+ ;// qTip version
1893
+ QTIP.version = '2.2.0';
1894
+
1895
+ // Base ID for all qTips
1896
+ QTIP.nextid = 0;
1897
+
1898
+ // Inactive events array
1899
+ QTIP.inactiveEvents = INACTIVE_EVENTS;
1900
+
1901
+ // Base z-index for all qTips
1902
+ QTIP.zindex = 15000;
1903
+
1904
+ // Define configuration defaults
1905
+ QTIP.defaults = {
1906
+ prerender: FALSE,
1907
+ id: FALSE,
1908
+ overwrite: TRUE,
1909
+ suppress: TRUE,
1910
+ content: {
1911
+ text: TRUE,
1912
+ attr: 'title',
1913
+ title: FALSE,
1914
+ button: FALSE
1915
+ },
1916
+ position: {
1917
+ my: 'top left',
1918
+ at: 'bottom right',
1919
+ target: FALSE,
1920
+ container: FALSE,
1921
+ viewport: FALSE,
1922
+ adjust: {
1923
+ x: 0, y: 0,
1924
+ mouse: TRUE,
1925
+ scroll: TRUE,
1926
+ resize: TRUE,
1927
+ method: 'flipinvert flipinvert'
1928
+ },
1929
+ effect: function(api, pos, viewport) {
1930
+ $(this).animate(pos, {
1931
+ duration: 200,
1932
+ queue: FALSE
1933
+ });
1934
+ }
1935
+ },
1936
+ show: {
1937
+ target: FALSE,
1938
+ event: 'mouseenter',
1939
+ effect: TRUE,
1940
+ delay: 90,
1941
+ solo: FALSE,
1942
+ ready: FALSE,
1943
+ autofocus: FALSE
1944
+ },
1945
+ hide: {
1946
+ target: FALSE,
1947
+ event: 'mouseleave',
1948
+ effect: TRUE,
1949
+ delay: 0,
1950
+ fixed: FALSE,
1951
+ inactive: FALSE,
1952
+ leave: 'window',
1953
+ distance: FALSE
1954
+ },
1955
+ style: {
1956
+ classes: '',
1957
+ widget: FALSE,
1958
+ width: FALSE,
1959
+ height: FALSE,
1960
+ def: TRUE
1961
+ },
1962
+ events: {
1963
+ render: NULL,
1964
+ move: NULL,
1965
+ show: NULL,
1966
+ hide: NULL,
1967
+ toggle: NULL,
1968
+ visible: NULL,
1969
+ hidden: NULL,
1970
+ focus: NULL,
1971
+ blur: NULL
1972
+ }
1973
+ };
1974
+
1975
+ ;var TIP,
1976
+
1977
+ // .bind()/.on() namespace
1978
+ TIPNS = '.qtip-tip',
1979
+
1980
+ // Common CSS strings
1981
+ MARGIN = 'margin',
1982
+ BORDER = 'border',
1983
+ COLOR = 'color',
1984
+ BG_COLOR = 'background-color',
1985
+ TRANSPARENT = 'transparent',
1986
+ IMPORTANT = ' !important',
1987
+
1988
+ // Check if the browser supports <canvas/> elements
1989
+ HASCANVAS = !!document.createElement('canvas').getContext,
1990
+
1991
+ // Invalid colour values used in parseColours()
1992
+ INVALID = /rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i;
1993
+
1994
+ // Camel-case method, taken from jQuery source
1995
+ // http://code.jquery.com/jquery-1.8.0.js
1996
+ function camel(s) { return s.charAt(0).toUpperCase() + s.slice(1); }
1997
+
1998
+ /*
1999
+ * Modified from Modernizr's testPropsAll()
2000
+ * http://modernizr.com/downloads/modernizr-latest.js
2001
+ */
2002
+ var cssProps = {}, cssPrefixes = ["Webkit", "O", "Moz", "ms"];
2003
+ function vendorCss(elem, prop) {
2004
+ var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
2005
+ props = (prop + ' ' + cssPrefixes.join(ucProp + ' ') + ucProp).split(' '),
2006
+ cur, val, i = 0;
2007
+
2008
+ // If the property has already been mapped...
2009
+ if(cssProps[prop]) { return elem.css(cssProps[prop]); }
2010
+
2011
+ while((cur = props[i++])) {
2012
+ if((val = elem.css(cur)) !== undefined) {
2013
+ return cssProps[prop] = cur, val;
2014
+ }
2015
+ }
2016
+ }
2017
+
2018
+ // Parse a given elements CSS property into an int
2019
+ function intCss(elem, prop) {
2020
+ return Math.ceil(parseFloat(vendorCss(elem, prop)));
2021
+ }
2022
+
2023
+
2024
+ // VML creation (for IE only)
2025
+ if(!HASCANVAS) {
2026
+ var createVML = function(tag, props, style) {
2027
+ return '<qtipvml:'+tag+' xmlns="urn:schemas-microsoft.com:vml" class="qtip-vml" '+(props||'')+
2028
+ ' style="behavior: url(#default#VML); '+(style||'')+ '" />';
2029
+ };
2030
+ }
2031
+
2032
+ // Canvas only definitions
2033
+ else {
2034
+ var PIXEL_RATIO = window.devicePixelRatio || 1,
2035
+ BACKING_STORE_RATIO = (function() {
2036
+ var context = document.createElement('canvas').getContext('2d');
2037
+ return context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio ||
2038
+ context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || 1;
2039
+ }()),
2040
+ SCALE = PIXEL_RATIO / BACKING_STORE_RATIO;
2041
+ }
2042
+
2043
+
2044
+ function Tip(qtip, options) {
2045
+ this._ns = 'tip';
2046
+ this.options = options;
2047
+ this.offset = options.offset;
2048
+ this.size = [ options.width, options.height ];
2049
+
2050
+ // Initialize
2051
+ this.init( (this.qtip = qtip) );
2052
+ }
2053
+
2054
+ $.extend(Tip.prototype, {
2055
+ init: function(qtip) {
2056
+ var context, tip;
2057
+
2058
+ // Create tip element and prepend to the tooltip
2059
+ tip = this.element = qtip.elements.tip = $('<div />', { 'class': NAMESPACE+'-tip' }).prependTo(qtip.tooltip);
2060
+
2061
+ // Create tip drawing element(s)
2062
+ if(HASCANVAS) {
2063
+ // save() as soon as we create the canvas element so FF2 doesn't bork on our first restore()!
2064
+ context = $('<canvas />').appendTo(this.element)[0].getContext('2d');
2065
+
2066
+ // Setup constant parameters
2067
+ context.lineJoin = 'miter';
2068
+ context.miterLimit = 100000;
2069
+ context.save();
2070
+ }
2071
+ else {
2072
+ context = createVML('shape', 'coordorigin="0,0"', 'position:absolute;');
2073
+ this.element.html(context + context);
2074
+
2075
+ // Prevent mousing down on the tip since it causes problems with .live() handling in IE due to VML
2076
+ qtip._bind( $('*', tip).add(tip), ['click', 'mousedown'], function(event) { event.stopPropagation(); }, this._ns);
2077
+ }
2078
+
2079
+ // Bind update events
2080
+ qtip._bind(qtip.tooltip, 'tooltipmove', this.reposition, this._ns, this);
2081
+
2082
+ // Create it
2083
+ this.create();
2084
+ },
2085
+
2086
+ _swapDimensions: function() {
2087
+ this.size[0] = this.options.height;
2088
+ this.size[1] = this.options.width;
2089
+ },
2090
+ _resetDimensions: function() {
2091
+ this.size[0] = this.options.width;
2092
+ this.size[1] = this.options.height;
2093
+ },
2094
+
2095
+ _useTitle: function(corner) {
2096
+ var titlebar = this.qtip.elements.titlebar;
2097
+ return titlebar && (
2098
+ corner.y === TOP || (corner.y === CENTER && this.element.position().top + (this.size[1] / 2) + this.options.offset < titlebar.outerHeight(TRUE))
2099
+ );
2100
+ },
2101
+
2102
+ _parseCorner: function(corner) {
2103
+ var my = this.qtip.options.position.my;
2104
+
2105
+ // Detect corner and mimic properties
2106
+ if(corner === FALSE || my === FALSE) {
2107
+ corner = FALSE;
2108
+ }
2109
+ else if(corner === TRUE) {
2110
+ corner = new CORNER( my.string() );
2111
+ }
2112
+ else if(!corner.string) {
2113
+ corner = new CORNER(corner);
2114
+ corner.fixed = TRUE;
2115
+ }
2116
+
2117
+ return corner;
2118
+ },
2119
+
2120
+ _parseWidth: function(corner, side, use) {
2121
+ var elements = this.qtip.elements,
2122
+ prop = BORDER + camel(side) + 'Width';
2123
+
2124
+ return (use ? intCss(use, prop) : (
2125
+ intCss(elements.content, prop) ||
2126
+ intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) ||
2127
+ intCss(elements.tooltip, prop)
2128
+ )) || 0;
2129
+ },
2130
+
2131
+ _parseRadius: function(corner) {
2132
+ var elements = this.qtip.elements,
2133
+ prop = BORDER + camel(corner.y) + camel(corner.x) + 'Radius';
2134
+
2135
+ return BROWSER.ie < 9 ? 0 :
2136
+ intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) ||
2137
+ intCss(elements.tooltip, prop) || 0;
2138
+ },
2139
+
2140
+ _invalidColour: function(elem, prop, compare) {
2141
+ var val = elem.css(prop);
2142
+ return !val || (compare && val === elem.css(compare)) || INVALID.test(val) ? FALSE : val;
2143
+ },
2144
+
2145
+ _parseColours: function(corner) {
2146
+ var elements = this.qtip.elements,
2147
+ tip = this.element.css('cssText', ''),
2148
+ borderSide = BORDER + camel(corner[ corner.precedance ]) + camel(COLOR),
2149
+ colorElem = this._useTitle(corner) && elements.titlebar || elements.content,
2150
+ css = this._invalidColour, color = [];
2151
+
2152
+ // Attempt to detect the background colour from various elements, left-to-right precedance
2153
+ color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css(elements.content, BG_COLOR) ||
2154
+ css(elements.tooltip, BG_COLOR) || tip.css(BG_COLOR);
2155
+
2156
+ // Attempt to detect the correct border side colour from various elements, left-to-right precedance
2157
+ color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderSide, COLOR) ||
2158
+ css(elements.content, borderSide, COLOR) || css(elements.tooltip, borderSide, COLOR) || elements.tooltip.css(borderSide);
2159
+
2160
+ // Reset background and border colours
2161
+ $('*', tip).add(tip).css('cssText', BG_COLOR+':'+TRANSPARENT+IMPORTANT+';'+BORDER+':0'+IMPORTANT+';');
2162
+
2163
+ return color;
2164
+ },
2165
+
2166
+ _calculateSize: function(corner) {
2167
+ var y = corner.precedance === Y,
2168
+ width = this.options['width'],
2169
+ height = this.options['height'],
2170
+ isCenter = corner.abbrev() === 'c',
2171
+ base = (y ? width: height) * (isCenter ? 0.5 : 1),
2172
+ pow = Math.pow,
2173
+ round = Math.round,
2174
+ bigHyp, ratio, result,
2175
+
2176
+ smallHyp = Math.sqrt( pow(base, 2) + pow(height, 2) ),
2177
+ hyp = [ (this.border / base) * smallHyp, (this.border / height) * smallHyp ];
2178
+
2179
+ hyp[2] = Math.sqrt( pow(hyp[0], 2) - pow(this.border, 2) );
2180
+ hyp[3] = Math.sqrt( pow(hyp[1], 2) - pow(this.border, 2) );
2181
+
2182
+ bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]);
2183
+ ratio = bigHyp / smallHyp;
2184
+
2185
+ result = [ round(ratio * width), round(ratio * height) ];
2186
+ return y ? result : result.reverse();
2187
+ },
2188
+
2189
+ // Tip coordinates calculator
2190
+ _calculateTip: function(corner, size, scale) {
2191
+ scale = scale || 1;
2192
+ size = size || this.size;
2193
+
2194
+ var width = size[0] * scale,
2195
+ height = size[1] * scale,
2196
+ width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2),
2197
+
2198
+ // Define tip coordinates in terms of height and width values
2199
+ tips = {
2200
+ br: [0,0, width,height, width,0],
2201
+ bl: [0,0, width,0, 0,height],
2202
+ tr: [0,height, width,0, width,height],
2203
+ tl: [0,0, 0,height, width,height],
2204
+ tc: [0,height, width2,0, width,height],
2205
+ bc: [0,0, width,0, width2,height],
2206
+ rc: [0,0, width,height2, 0,height],
2207
+ lc: [width,0, width,height, 0,height2]
2208
+ };
2209
+
2210
+ // Set common side shapes
2211
+ tips.lt = tips.br; tips.rt = tips.bl;
2212
+ tips.lb = tips.tr; tips.rb = tips.tl;
2213
+
2214
+ return tips[ corner.abbrev() ];
2215
+ },
2216
+
2217
+ // Tip coordinates drawer (canvas)
2218
+ _drawCoords: function(context, coords) {
2219
+ context.beginPath();
2220
+ context.moveTo(coords[0], coords[1]);
2221
+ context.lineTo(coords[2], coords[3]);
2222
+ context.lineTo(coords[4], coords[5]);
2223
+ context.closePath();
2224
+ },
2225
+
2226
+ create: function() {
2227
+ // Determine tip corner
2228
+ var c = this.corner = (HASCANVAS || BROWSER.ie) && this._parseCorner(this.options.corner);
2229
+
2230
+ // If we have a tip corner...
2231
+ if( (this.enabled = !!this.corner && this.corner.abbrev() !== 'c') ) {
2232
+ // Cache it
2233
+ this.qtip.cache.corner = c.clone();
2234
+
2235
+ // Create it
2236
+ this.update();
2237
+ }
2238
+
2239
+ // Toggle tip element
2240
+ this.element.toggle(this.enabled);
2241
+
2242
+ return this.corner;
2243
+ },
2244
+
2245
+ update: function(corner, position) {
2246
+ if(!this.enabled) { return this; }
2247
+
2248
+ var elements = this.qtip.elements,
2249
+ tip = this.element,
2250
+ inner = tip.children(),
2251
+ options = this.options,
2252
+ curSize = this.size,
2253
+ mimic = options.mimic,
2254
+ round = Math.round,
2255
+ color, precedance, context,
2256
+ coords, bigCoords, translate, newSize, border, BACKING_STORE_RATIO;
2257
+
2258
+ // Re-determine tip if not already set
2259
+ if(!corner) { corner = this.qtip.cache.corner || this.corner; }
2260
+
2261
+ // Use corner property if we detect an invalid mimic value
2262
+ if(mimic === FALSE) { mimic = corner; }
2263
+
2264
+ // Otherwise inherit mimic properties from the corner object as necessary
2265
+ else {
2266
+ mimic = new CORNER(mimic);
2267
+ mimic.precedance = corner.precedance;
2268
+
2269
+ if(mimic.x === 'inherit') { mimic.x = corner.x; }
2270
+ else if(mimic.y === 'inherit') { mimic.y = corner.y; }
2271
+ else if(mimic.x === mimic.y) {
2272
+ mimic[ corner.precedance ] = corner[ corner.precedance ];
2273
+ }
2274
+ }
2275
+ precedance = mimic.precedance;
2276
+
2277
+ // Ensure the tip width.height are relative to the tip position
2278
+ if(corner.precedance === X) { this._swapDimensions(); }
2279
+ else { this._resetDimensions(); }
2280
+
2281
+ // Update our colours
2282
+ color = this.color = this._parseColours(corner);
2283
+
2284
+ // Detect border width, taking into account colours
2285
+ if(color[1] !== TRANSPARENT) {
2286
+ // Grab border width
2287
+ border = this.border = this._parseWidth(corner, corner[corner.precedance]);
2288
+
2289
+ // If border width isn't zero, use border color as fill if it's not invalid (1.0 style tips)
2290
+ if(options.border && border < 1 && !INVALID.test(color[1])) { color[0] = color[1]; }
2291
+
2292
+ // Set border width (use detected border width if options.border is true)
2293
+ this.border = border = options.border !== TRUE ? options.border : border;
2294
+ }
2295
+
2296
+ // Border colour was invalid, set border to zero
2297
+ else { this.border = border = 0; }
2298
+
2299
+ // Determine tip size
2300
+ newSize = this.size = this._calculateSize(corner);
2301
+ tip.css({
2302
+ width: newSize[0],
2303
+ height: newSize[1],
2304
+ lineHeight: newSize[1]+'px'
2305
+ });
2306
+
2307
+ // Calculate tip translation
2308
+ if(corner.precedance === Y) {
2309
+ translate = [
2310
+ round(mimic.x === LEFT ? border : mimic.x === RIGHT ? newSize[0] - curSize[0] - border : (newSize[0] - curSize[0]) / 2),
2311
+ round(mimic.y === TOP ? newSize[1] - curSize[1] : 0)
2312
+ ];
2313
+ }
2314
+ else {
2315
+ translate = [
2316
+ round(mimic.x === LEFT ? newSize[0] - curSize[0] : 0),
2317
+ round(mimic.y === TOP ? border : mimic.y === BOTTOM ? newSize[1] - curSize[1] - border : (newSize[1] - curSize[1]) / 2)
2318
+ ];
2319
+ }
2320
+
2321
+ // Canvas drawing implementation
2322
+ if(HASCANVAS) {
2323
+ // Grab canvas context and clear/save it
2324
+ context = inner[0].getContext('2d');
2325
+ context.restore(); context.save();
2326
+ context.clearRect(0,0,6000,6000);
2327
+
2328
+ // Calculate coordinates
2329
+ coords = this._calculateTip(mimic, curSize, SCALE);
2330
+ bigCoords = this._calculateTip(mimic, this.size, SCALE);
2331
+
2332
+ // Set the canvas size using calculated size
2333
+ inner.attr(WIDTH, newSize[0] * SCALE).attr(HEIGHT, newSize[1] * SCALE);
2334
+ inner.css(WIDTH, newSize[0]).css(HEIGHT, newSize[1]);
2335
+
2336
+ // Draw the outer-stroke tip
2337
+ this._drawCoords(context, bigCoords);
2338
+ context.fillStyle = color[1];
2339
+ context.fill();
2340
+
2341
+ // Draw the actual tip
2342
+ context.translate(translate[0] * SCALE, translate[1] * SCALE);
2343
+ this._drawCoords(context, coords);
2344
+ context.fillStyle = color[0];
2345
+ context.fill();
2346
+ }
2347
+
2348
+ // VML (IE Proprietary implementation)
2349
+ else {
2350
+ // Calculate coordinates
2351
+ coords = this._calculateTip(mimic);
2352
+
2353
+ // Setup coordinates string
2354
+ coords = 'm' + coords[0] + ',' + coords[1] + ' l' + coords[2] +
2355
+ ',' + coords[3] + ' ' + coords[4] + ',' + coords[5] + ' xe';
2356
+
2357
+ // Setup VML-specific offset for pixel-perfection
2358
+ translate[2] = border && /^(r|b)/i.test(corner.string()) ?
2359
+ BROWSER.ie === 8 ? 2 : 1 : 0;
2360
+
2361
+ // Set initial CSS
2362
+ inner.css({
2363
+ coordsize: (newSize[0]+border) + ' ' + (newSize[1]+border),
2364
+ antialias: ''+(mimic.string().indexOf(CENTER) > -1),
2365
+ left: translate[0] - (translate[2] * Number(precedance === X)),
2366
+ top: translate[1] - (translate[2] * Number(precedance === Y)),
2367
+ width: newSize[0] + border,
2368
+ height: newSize[1] + border
2369
+ })
2370
+ .each(function(i) {
2371
+ var $this = $(this);
2372
+
2373
+ // Set shape specific attributes
2374
+ $this[ $this.prop ? 'prop' : 'attr' ]({
2375
+ coordsize: (newSize[0]+border) + ' ' + (newSize[1]+border),
2376
+ path: coords,
2377
+ fillcolor: color[0],
2378
+ filled: !!i,
2379
+ stroked: !i
2380
+ })
2381
+ .toggle(!!(border || i));
2382
+
2383
+ // Check if border is enabled and add stroke element
2384
+ !i && $this.html( createVML(
2385
+ 'stroke', 'weight="'+(border*2)+'px" color="'+color[1]+'" miterlimit="1000" joinstyle="miter"'
2386
+ ) );
2387
+ });
2388
+ }
2389
+
2390
+ // Opera bug #357 - Incorrect tip position
2391
+ // https://github.com/Craga89/qTip2/issues/367
2392
+ window.opera && setTimeout(function() {
2393
+ elements.tip.css({
2394
+ display: 'inline-block',
2395
+ visibility: 'visible'
2396
+ });
2397
+ }, 1);
2398
+
2399
+ // Position if needed
2400
+ if(position !== FALSE) { this.calculate(corner, newSize); }
2401
+ },
2402
+
2403
+ calculate: function(corner, size) {
2404
+ if(!this.enabled) { return FALSE; }
2405
+
2406
+ var self = this,
2407
+ elements = this.qtip.elements,
2408
+ tip = this.element,
2409
+ userOffset = this.options.offset,
2410
+ isWidget = elements.tooltip.hasClass('ui-widget'),
2411
+ position = { },
2412
+ precedance, corners;
2413
+
2414
+ // Inherit corner if not provided
2415
+ corner = corner || this.corner;
2416
+ precedance = corner.precedance;
2417
+
2418
+ // Determine which tip dimension to use for adjustment
2419
+ size = size || this._calculateSize(corner);
2420
+
2421
+ // Setup corners and offset array
2422
+ corners = [ corner.x, corner.y ];
2423
+ if(precedance === X) { corners.reverse(); }
2424
+
2425
+ // Calculate tip position
2426
+ $.each(corners, function(i, side) {
2427
+ var b, bc, br;
2428
+
2429
+ if(side === CENTER) {
2430
+ b = precedance === Y ? LEFT : TOP;
2431
+ position[ b ] = '50%';
2432
+ position[MARGIN+'-' + b] = -Math.round(size[ precedance === Y ? 0 : 1 ] / 2) + userOffset;
2433
+ }
2434
+ else {
2435
+ b = self._parseWidth(corner, side, elements.tooltip);
2436
+ bc = self._parseWidth(corner, side, elements.content);
2437
+ br = self._parseRadius(corner);
2438
+
2439
+ position[ side ] = Math.max(-self.border, i ? bc : (userOffset + (br > b ? br : -b)));
2440
+ }
2441
+ });
2442
+
2443
+ // Adjust for tip size
2444
+ position[ corner[precedance] ] -= size[ precedance === X ? 0 : 1 ];
2445
+
2446
+ // Set and return new position
2447
+ tip.css({ margin: '', top: '', bottom: '', left: '', right: '' }).css(position);
2448
+ return position;
2449
+ },
2450
+
2451
+ reposition: function(event, api, pos, viewport) {
2452
+ if(!this.enabled) { return; }
2453
+
2454
+ var cache = api.cache,
2455
+ newCorner = this.corner.clone(),
2456
+ adjust = pos.adjusted,
2457
+ method = api.options.position.adjust.method.split(' '),
2458
+ horizontal = method[0],
2459
+ vertical = method[1] || method[0],
2460
+ shift = { left: FALSE, top: FALSE, x: 0, y: 0 },
2461
+ offset, css = {}, props;
2462
+
2463
+ function shiftflip(direction, precedance, popposite, side, opposite) {
2464
+ // Horizontal - Shift or flip method
2465
+ if(direction === SHIFT && newCorner.precedance === precedance && adjust[side] && newCorner[popposite] !== CENTER) {
2466
+ newCorner.precedance = newCorner.precedance === X ? Y : X;
2467
+ }
2468
+ else if(direction !== SHIFT && adjust[side]){
2469
+ newCorner[precedance] = newCorner[precedance] === CENTER ?
2470
+ (adjust[side] > 0 ? side : opposite) : (newCorner[precedance] === side ? opposite : side);
2471
+ }
2472
+ }
2473
+
2474
+ function shiftonly(xy, side, opposite) {
2475
+ if(newCorner[xy] === CENTER) {
2476
+ css[MARGIN+'-'+side] = shift[xy] = offset[MARGIN+'-'+side] - adjust[side];
2477
+ }
2478
+ else {
2479
+ props = offset[opposite] !== undefined ?
2480
+ [ adjust[side], -offset[side] ] : [ -adjust[side], offset[side] ];
2481
+
2482
+ if( (shift[xy] = Math.max(props[0], props[1])) > props[0] ) {
2483
+ pos[side] -= adjust[side];
2484
+ shift[side] = FALSE;
2485
+ }
2486
+
2487
+ css[ offset[opposite] !== undefined ? opposite : side ] = shift[xy];
2488
+ }
2489
+ }
2490
+
2491
+ // If our tip position isn't fixed e.g. doesn't adjust with viewport...
2492
+ if(this.corner.fixed !== TRUE) {
2493
+ // Perform shift/flip adjustments
2494
+ shiftflip(horizontal, X, Y, LEFT, RIGHT);
2495
+ shiftflip(vertical, Y, X, TOP, BOTTOM);
2496
+
2497
+ // Update and redraw the tip if needed (check cached details of last drawn tip)
2498
+ if(newCorner.string() !== cache.corner.string() && (cache.cornerTop !== adjust.top || cache.cornerLeft !== adjust.left)) {
2499
+ this.update(newCorner, FALSE);
2500
+ }
2501
+ }
2502
+
2503
+ // Setup tip offset properties
2504
+ offset = this.calculate(newCorner);
2505
+
2506
+ // Readjust offset object to make it left/top
2507
+ if(offset.right !== undefined) { offset.left = -offset.right; }
2508
+ if(offset.bottom !== undefined) { offset.top = -offset.bottom; }
2509
+ offset.user = this.offset;
2510
+
2511
+ // Perform shift adjustments
2512
+ if(shift.left = (horizontal === SHIFT && !!adjust.left)) { shiftonly(X, LEFT, RIGHT); }
2513
+ if(shift.top = (vertical === SHIFT && !!adjust.top)) { shiftonly(Y, TOP, BOTTOM); }
2514
+
2515
+ /*
2516
+ * If the tip is adjusted in both dimensions, or in a
2517
+ * direction that would cause it to be anywhere but the
2518
+ * outer border, hide it!
2519
+ */
2520
+ this.element.css(css).toggle(
2521
+ !((shift.x && shift.y) || (newCorner.x === CENTER && shift.y) || (newCorner.y === CENTER && shift.x))
2522
+ );
2523
+
2524
+ // Adjust position to accomodate tip dimensions
2525
+ pos.left -= offset.left.charAt ? offset.user :
2526
+ horizontal !== SHIFT || shift.top || !shift.left && !shift.top ? offset.left + this.border : 0;
2527
+ pos.top -= offset.top.charAt ? offset.user :
2528
+ vertical !== SHIFT || shift.left || !shift.left && !shift.top ? offset.top + this.border : 0;
2529
+
2530
+ // Cache details
2531
+ cache.cornerLeft = adjust.left; cache.cornerTop = adjust.top;
2532
+ cache.corner = newCorner.clone();
2533
+ },
2534
+
2535
+ destroy: function() {
2536
+ // Unbind events
2537
+ this.qtip._unbind(this.qtip.tooltip, this._ns);
2538
+
2539
+ // Remove the tip element(s)
2540
+ if(this.qtip.elements.tip) {
2541
+ this.qtip.elements.tip.find('*')
2542
+ .remove().end().remove();
2543
+ }
2544
+ }
2545
+ });
2546
+
2547
+ TIP = PLUGINS.tip = function(api) {
2548
+ return new Tip(api, api.options.style.tip);
2549
+ };
2550
+
2551
+ // Initialize tip on render
2552
+ TIP.initialize = 'render';
2553
+
2554
+ // Setup plugin sanitization options
2555
+ TIP.sanitize = function(options) {
2556
+ if(options.style && 'tip' in options.style) {
2557
+ var opts = options.style.tip;
2558
+ if(typeof opts !== 'object') { opts = options.style.tip = { corner: opts }; }
2559
+ if(!(/string|boolean/i).test(typeof opts.corner)) { opts.corner = TRUE; }
2560
+ }
2561
+ };
2562
+
2563
+ // Add new option checks for the plugin
2564
+ CHECKS.tip = {
2565
+ '^position.my|style.tip.(corner|mimic|border)$': function() {
2566
+ // Make sure a tip can be drawn
2567
+ this.create();
2568
+
2569
+ // Reposition the tooltip
2570
+ this.qtip.reposition();
2571
+ },
2572
+ '^style.tip.(height|width)$': function(obj) {
2573
+ // Re-set dimensions and redraw the tip
2574
+ this.size = [ obj.width, obj.height ];
2575
+ this.update();
2576
+
2577
+ // Reposition the tooltip
2578
+ this.qtip.reposition();
2579
+ },
2580
+ '^content.title|style.(classes|widget)$': function() {
2581
+ this.update();
2582
+ }
2583
+ };
2584
+
2585
+ // Extend original qTip defaults
2586
+ $.extend(TRUE, QTIP.defaults, {
2587
+ style: {
2588
+ tip: {
2589
+ corner: TRUE,
2590
+ mimic: FALSE,
2591
+ width: 6,
2592
+ height: 6,
2593
+ border: TRUE,
2594
+ offset: 0
2595
+ }
2596
+ }
2597
+ });
2598
+
2599
+ ;PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight)
2600
+ {
2601
+ var target = posOptions.target,
2602
+ tooltip = api.elements.tooltip,
2603
+ my = posOptions.my,
2604
+ at = posOptions.at,
2605
+ adjust = posOptions.adjust,
2606
+ method = adjust.method.split(' '),
2607
+ methodX = method[0],
2608
+ methodY = method[1] || method[0],
2609
+ viewport = posOptions.viewport,
2610
+ container = posOptions.container,
2611
+ cache = api.cache,
2612
+ adjusted = { left: 0, top: 0 },
2613
+ fixed, newMy, newClass, containerOffset, containerStatic,
2614
+ viewportWidth, viewportHeight, viewportScroll, viewportOffset;
2615
+
2616
+ // If viewport is not a jQuery element, or it's the window/document, or no adjustment method is used... return
2617
+ if(!viewport.jquery || target[0] === window || target[0] === document.body || adjust.method === 'none') {
2618
+ return adjusted;
2619
+ }
2620
+
2621
+ // Cach container details
2622
+ containerOffset = container.offset() || adjusted;
2623
+ containerStatic = container.css('position') === 'static';
2624
+
2625
+ // Cache our viewport details
2626
+ fixed = tooltip.css('position') === 'fixed';
2627
+ viewportWidth = viewport[0] === window ? viewport.width() : viewport.outerWidth(FALSE);
2628
+ viewportHeight = viewport[0] === window ? viewport.height() : viewport.outerHeight(FALSE);
2629
+ viewportScroll = { left: fixed ? 0 : viewport.scrollLeft(), top: fixed ? 0 : viewport.scrollTop() };
2630
+ viewportOffset = viewport.offset() || adjusted;
2631
+
2632
+ // Generic calculation method
2633
+ function calculate(side, otherSide, type, adjust, side1, side2, lengthName, targetLength, elemLength) {
2634
+ var initialPos = position[side1],
2635
+ mySide = my[side],
2636
+ atSide = at[side],
2637
+ isShift = type === SHIFT,
2638
+ myLength = mySide === side1 ? elemLength : mySide === side2 ? -elemLength : -elemLength / 2,
2639
+ atLength = atSide === side1 ? targetLength : atSide === side2 ? -targetLength : -targetLength / 2,
2640
+ sideOffset = viewportScroll[side1] + viewportOffset[side1] - (containerStatic ? 0 : containerOffset[side1]),
2641
+ overflow1 = sideOffset - initialPos,
2642
+ overflow2 = initialPos + elemLength - (lengthName === WIDTH ? viewportWidth : viewportHeight) - sideOffset,
2643
+ offset = myLength - (my.precedance === side || mySide === my[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0);
2644
+
2645
+ // shift
2646
+ if(isShift) {
2647
+ offset = (mySide === side1 ? 1 : -1) * myLength;
2648
+
2649
+ // Adjust position but keep it within viewport dimensions
2650
+ position[side1] += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0;
2651
+ position[side1] = Math.max(
2652
+ -containerOffset[side1] + viewportOffset[side1],
2653
+ initialPos - offset,
2654
+ Math.min(
2655
+ Math.max(
2656
+ -containerOffset[side1] + viewportOffset[side1] + (lengthName === WIDTH ? viewportWidth : viewportHeight),
2657
+ initialPos + offset
2658
+ ),
2659
+ position[side1],
2660
+
2661
+ // Make sure we don't adjust complete off the element when using 'center'
2662
+ mySide === 'center' ? initialPos - myLength : 1E9
2663
+ )
2664
+ );
2665
+
2666
+ }
2667
+
2668
+ // flip/flipinvert
2669
+ else {
2670
+ // Update adjustment amount depending on if using flipinvert or flip
2671
+ adjust *= (type === FLIPINVERT ? 2 : 0);
2672
+
2673
+ // Check for overflow on the left/top
2674
+ if(overflow1 > 0 && (mySide !== side1 || overflow2 > 0)) {
2675
+ position[side1] -= offset + adjust;
2676
+ newMy.invert(side, side1);
2677
+ }
2678
+
2679
+ // Check for overflow on the bottom/right
2680
+ else if(overflow2 > 0 && (mySide !== side2 || overflow1 > 0) ) {
2681
+ position[side1] -= (mySide === CENTER ? -offset : offset) + adjust;
2682
+ newMy.invert(side, side2);
2683
+ }
2684
+
2685
+ // Make sure we haven't made things worse with the adjustment and reset if so
2686
+ if(position[side1] < viewportScroll && -position[side1] > overflow2) {
2687
+ position[side1] = initialPos; newMy = my.clone();
2688
+ }
2689
+ }
2690
+
2691
+ return position[side1] - initialPos;
2692
+ }
2693
+
2694
+ // Set newMy if using flip or flipinvert methods
2695
+ if(methodX !== 'shift' || methodY !== 'shift') { newMy = my.clone(); }
2696
+
2697
+ // Adjust position based onviewport and adjustment options
2698
+ adjusted = {
2699
+ left: methodX !== 'none' ? calculate( X, Y, methodX, adjust.x, LEFT, RIGHT, WIDTH, targetWidth, elemWidth ) : 0,
2700
+ top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0
2701
+ };
2702
+
2703
+ // Set tooltip position class if it's changed
2704
+ if(newMy && cache.lastClass !== (newClass = NAMESPACE + '-pos-' + newMy.abbrev())) {
2705
+ tooltip.removeClass(api.cache.lastClass).addClass( (api.cache.lastClass = newClass) );
2706
+ }
2707
+
2708
+ return adjusted;
2709
+ };
2710
+ ;}));
2711
+ }( window, document ));
2712
+
2713
+
external/qtip2/jquery.qtip.min.css ADDED
@@ -0,0 +1,2 @@
 
 
1
+ /* qTip2 v2.2.0 css3 | qtip2.com | Licensed MIT, GPL | Sun Mar 16 2014 17:53:30 */
2
+ .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{position:relative;padding:5px 9px;overflow:hidden;text-align:left;word-wrap:break-word}.qtip-titlebar{position:relative;padding:5px 35px 5px 10px;overflow:hidden;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;cursor:pointer;outline:medium none;border-width:1px;border-style:solid;border-color:transparent}.qtip-titlebar .qtip-close{right:4px;top:50%;margin-top:-9px}* html .qtip-titlebar .qtip-close{top:16px}.qtip-titlebar .ui-icon,.qtip-icon .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:400 bold 10px/13px Tahoma,sans-serif;color:inherit;background:transparent none no-repeat -100em -100em}.qtip-focus{}.qtip-hover{}.qtip-default{border-width:1px;border-style:solid;border-color:#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-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-rounded,.qtip-tipsy,.qtip-bootstrap{-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-width:0;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-titlebar,.qtip-jtools .qtip-content{background:transparent;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:transparent}.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-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}x:-o-prefocus,.qtip .qtip-tip{visibility:hidden}.qtip .qtip-tip,.qtip .qtip-tip .qtip-vml,.qtip .qtip-tip canvas{position:absolute;color:#123456;background:transparent;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}
external/qtip2/jquery.qtip.min.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ /* qTip2 v2.2.0 tips viewport | qtip2.com | Licensed MIT, GPL | Sun Mar 16 2014 17:53:29 */
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=E,this.elements={target:a},this._id=R+"-"+c,this.timers={img:{}},this.options=b,this.plugins={},this.cache={event:{},target:d(),disabled:D,attr:e,onTooltip:D,lastClass:""},this.rendered=this.destroyed=this.disabled=this.waiting=this.hiddenDuringWait=this.positioning=this.triggering=D}function f(a){return a===E||"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)?D:(f(a.metadata)&&(a.metadata={type:a.metadata}),"content"in a&&(b=a.content,f(b)||b.jquery||b.done?b=a.content={text:c=g(b)?D:b}:c=b.text,"ajax"in b&&(e=b.ajax,h=e&&e.once!==D,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,E,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&&(f(b.title)||(b.button=b.title.button,b.title=b.title.text),g(b.title||D)&&(b.title=D))),"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===C?{ready:C}:{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(Q,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)for(d in this.checks[c])(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 U.concat("").join(a?"-"+a+" ":" ")}function l(c){return c&&{type:c.type,pageX:c.pageX,pageY:c.pageY,target:c.target,relatedTarget:c.relatedTarget,scrollX:c.scrollX||a.pageXOffset||b.body.scrollLeft||b.documentElement.scrollLeft,scrollY:c.scrollY||a.pageYOffset||b.body.scrollTop||b.documentElement.scrollTop}||{}}function m(a,b){return b>0?setTimeout(d.proxy(a,this),b):(a.call(this),void 0)}function n(a){return this.tooltip.hasClass(_)?D:(clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this.timers.show=m.call(this,function(){this.toggle(C,a)},this.options.show.delay),void 0)}function o(a){if(this.tooltip.hasClass(_))return D;var b=d(a.relatedTarget),c=b.closest(V)[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=m.call(this,function(){this.toggle(D,a)},this.options.hide.delay,this)}function p(a){return this.tooltip.hasClass(_)||!this.options.hide.inactive?D:(clearTimeout(this.timers.inactive),this.timers.inactive=m.call(this,function(){this.hide(a)},this.options.hide.inactive),void 0)}function q(a){this.rendered&&this.tooltip[0].offsetWidth>0&&this.reposition(a)}function r(a,c,e){d(b.body).delegate(a,(c.split?c:c.join(gb+" "))+gb,function(){var a=x.api[d.attr(this,T)];a&&!a.disabled&&e.apply(a,arguments)})}function s(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):E,p="html5"===f.metadata.type&&o?o[f.metadata.name]:E,q=a.data(f.metadata.name||"qtipopts");try{q="string"==typeof q?d.parseJSON(q):q}catch(r){}if(k=d.extend(C,{},x.defaults,f,"object"==typeof q?h(q):E,h(p||o)),i=k.position,k.id=c,"boolean"==typeof k.content.text){if(j=a.attr(k.content.attr),k.content.attr===D||!j)return D;k.content.text=j}if(i.container.length||(i.container=m),i.target===D&&(i.target=n),k.show.target===D&&(k.show.target=n),k.show.solo===C&&(k.show.solo=i.container.closest("body")),k.hide.target===D&&(k.hide.target=n),k.position.viewport===C&&(k.position.viewport=i.container),i.container=i.container.eq(0),i.at=new z(i.at,C),i.my=new z(i.my),a.data(R))if(k.overwrite)a.qtip("destroy",!0);else if(k.overwrite===D)return D;return a.attr(S,c),k.suppress&&(l=a.attr("title"))&&a.removeAttr("title").attr(bb,l).attr("title",""),g=new e(a,k,c,!!j),a.data(R,g),a.one("remove.qtip-"+c+" removeqtip.qtip-"+c,function(){var a;(a=d(this).data(R))&&a.destroy(!0)}),g}function t(a){return a.charAt(0).toUpperCase()+a.slice(1)}function u(a,b){var d,e,f=b.charAt(0).toUpperCase()+b.slice(1),g=(b+" "+rb.join(f+" ")+f).split(" "),h=0;if(qb[b])return a.css(qb[b]);for(;d=g[h++];)if((e=a.css(d))!==c)return qb[b]=d,e}function v(a,b){return Math.ceil(parseFloat(u(a,b)))}function w(a,b){this._ns="tip",this.options=b,this.offset=b.offset,this.size=[b.width,b.height],this.init(this.qtip=a)}var x,y,z,A,B,C=!0,D=!1,E=null,F="x",G="y",H="width",I="height",J="top",K="left",L="bottom",M="right",N="center",O="flipinvert",P="shift",Q={},R="qtip",S="data-hasqtip",T="data-qtip-id",U=["ui-widget","ui-tooltip"],V="."+R,W="click dblclick mousedown mouseup mousemove mouseleave mouseenter".split(" "),X=R+"-fixed",Y=R+"-default",Z=R+"-focus",$=R+"-hover",_=R+"-disabled",ab="_replacedByqTip",bb="oldtitle",cb={ie:function(){for(var a=3,c=b.createElement("div");(c.innerHTML="<!--[if gt IE "+ ++a+"]><i></i><![endif]-->")&&c.getElementsByTagName("i")[0];);return a>4?a:0/0}(),iOS:parseFloat((""+(/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))||D};y=e.prototype,y._when=function(a){return d.when.apply(d,a)},y.render=function(a){if(this.rendered||this.destroyed)return this;var b,c=this,e=this.options,f=this.cache,g=this.elements,h=e.content.text,i=e.content.title,j=e.content.button,k=e.position,l=("."+this._id+" ",[]);return d.attr(this.target[0],"aria-describedby",this._id),this.tooltip=g.tooltip=b=d("<div/>",{id:this._id,"class":[R,Y,e.style.classes,R+"-pos-"+e.position.my.abbrev()].join(" "),width:e.style.width||"",height:e.style.height||"",tracking:"mouse"===k.target&&k.adjust.mouse,role:"alert","aria-live":"polite","aria-atomic":D,"aria-describedby":this._id+"-content","aria-hidden":C}).toggleClass(_,this.disabled).attr(T,this.id).data(R,this).appendTo(k.container).append(g.content=d("<div />",{"class":R+"-content",id:this._id+"-content","aria-atomic":C})),this.rendered=-1,this.positioning=C,i&&(this._createTitle(),d.isFunction(i)||l.push(this._updateTitle(i,D))),j&&this._createButton(),d.isFunction(h)||l.push(this._updateContent(h,D)),this.rendered=C,this._setWidget(),d.each(Q,function(a){var b;"render"===this.initialize&&(b=this(c))&&(c.plugins[a]=b)}),this._unassignEvents(),this._assignEvents(),this._when(l).then(function(){c._trigger("render"),c.positioning=D,c.hiddenDuringWait||!e.show.ready&&!a||c.toggle(C,f.event,D),c.hiddenDuringWait=D}),x.api[this.id]=this,this},y.destroy=function(a){function b(){if(!this.destroyed){this.destroyed=C;var a=this.target,b=a.attr(bb);this.rendered&&this.tooltip.stop(1,0).find("*").remove().end().remove(),d.each(this.plugins,function(){this.destroy&&this.destroy()}),clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this._unassignEvents(),a.removeData(R).removeAttr(T).removeAttr(S).removeAttr("aria-describedby"),this.options.suppress&&b&&a.attr("title",b).removeAttr(bb),this._unbind(a),this.options=this.elements=this.cache=this.timers=this.plugins=this.mouse=E,delete x.api[this.id]}}return this.destroyed?this.target:(a===C&&"hide"!==this.triggering||!this.rendered?b.call(this):(this.tooltip.one("tooltiphidden",d.proxy(b,this)),!this.triggering&&this.hide()),this.target)},A=y.checks={builtin:{"^id$":function(a,b,c,e){var f=c===C?x.nextid:c,g=R+"-"+f;f!==D&&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(),this._updateTitle(c),void 0):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&&(a[b]=new z(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(C)||this.toggle(C))},"^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(Y,!!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()}}}},y.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 db=/^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i,eb=/^prerender|show\.ready/i;y.set=function(a,b){if(this.destroyed)return this;{var c,e=this.rendered,f=D,g=this.options;this.checks}return"string"==typeof a?(c=a,a={},a[c]=b):a=d.extend({},a),d.each(a,function(b,c){if(e&&eb.test(b))return delete a[b],void 0;var h,j=i(g,b.toLowerCase());h=j[0][j[1]],j[0][j[1]]=c&&c.nodeType?d(c):c,f=db.test(b)||f,a[b]=[j[0],j[1],c,h]}),h(g),this.positioning=C,d.each(a,d.proxy(j,this)),this.positioning=D,this.rendered&&this.tooltip[0].offsetWidth>0&&f&&this.reposition("mouse"===g.position.target?E:this.cache.event),this},y._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=C,a.then(function(a){return e.waiting=D,c._update(a,b)},E,function(a){return c._update(a,b)})):a===D||!a&&""!==a?D:(a.jquery&&a.length>0?b.empty().append(a.css({display:"block",visibility:"visible"})):b.html(a),this._waitForContent(b).then(function(a){a.images&&a.images.length&&c.rendered&&c.tooltip[0].offsetWidth>0&&c.reposition(e.event,!a.length)}))):D},y._waitForContent=function(a){var b=this.cache;return b.waiting=C,(d.fn.imagesLoaded?a.imagesLoaded():d.Deferred().resolve([])).done(function(){b.waiting=D}).promise()},y._updateContent=function(a,b){this._update(a,this.elements.content,b)},y._updateTitle=function(a,b){this._update(a,this.elements.title,b)===D&&this._removeTitle(D)},y._createTitle=function(){var a=this.elements,b=this._id+"-title";a.titlebar&&this._removeTitle(),a.titlebar=d("<div />",{"class":R+"-titlebar "+(this.options.style.widget?k("header"):"")}).append(a.title=d("<div />",{id:b,"class":R+"-title","aria-atomic":C})).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()},y._removeTitle=function(a){var b=this.elements;b.title&&(b.titlebar.remove(),b.titlebar=b.title=b.button=E,a!==D&&this.reposition())},y.reposition=function(c,e){if(!this.rendered||this.positioning||this.destroyed)return this;this.positioning=C;var f,g,h=this.cache,i=this.tooltip,j=this.options.position,k=j.target,l=j.my,m=j.at,n=j.viewport,o=j.container,p=j.adjust,q=p.method.split(" "),r=i.outerWidth(D),s=i.outerHeight(D),t=0,u=0,v=i.css("position"),w={left:0,top:0},x=i[0].offsetWidth>0,y=c&&"scroll"===c.type,z=d(a),A=o[0].ownerDocument,B=this.mouse;if(d.isArray(k)&&2===k.length)m={x:K,y:J},w={left:k[0],top:k[1]};else if("mouse"===k)m={x:K,y:J},!B||!B.pageX||!p.mouse&&c&&c.pageX?c&&c.pageX||((!p.mouse||this.options.show.distance)&&h.origin&&h.origin.pageX?c=h.origin:(!c||c&&("resize"===c.type||"scroll"===c.type))&&(c=h.event)):c=B,"static"!==v&&(w=o.offset()),A.body.offsetWidth!==(a.innerWidth||A.documentElement.clientWidth)&&(g=d(b.body).offset()),w={left:c.pageX-w.left+(g&&g.left||0),top:c.pageY-w.top+(g&&g.top||0)},p.mouse&&y&&B&&(w.left-=(B.scrollX||0)-z.scrollLeft(),w.top-=(B.scrollY||0)-z.scrollTop());else{if("event"===k?c&&c.target&&"scroll"!==c.type&&"resize"!==c.type?h.target=d(c.target):c.target||(h.target=this.elements.target):"event"!==k&&(h.target=d(k.jquery?k:this.elements.target)),k=h.target,k=d(k).eq(0),0===k.length)return this;k[0]===b||k[0]===a?(t=cb.iOS?a.innerWidth:k.width(),u=cb.iOS?a.innerHeight:k.height(),k[0]===a&&(w={top:(n||k).scrollTop(),left:(n||k).scrollLeft()})):Q.imagemap&&k.is("area")?f=Q.imagemap(this,k,m,Q.viewport?q:D):Q.svg&&k&&k[0].ownerSVGElement?f=Q.svg(this,k,m,Q.viewport?q:D):(t=k.outerWidth(D),u=k.outerHeight(D),w=k.offset()),f&&(t=f.width,u=f.height,g=f.offset,w=f.position),w=this.reposition.offset(k,w,o),(cb.iOS>3.1&&cb.iOS<4.1||cb.iOS>=4.3&&cb.iOS<4.33||!cb.iOS&&"fixed"===v)&&(w.left-=z.scrollLeft(),w.top-=z.scrollTop()),(!f||f&&f.adjustable!==D)&&(w.left+=m.x===M?t:m.x===N?t/2:0,w.top+=m.y===L?u:m.y===N?u/2:0)}return w.left+=p.x+(l.x===M?-r:l.x===N?-r/2:0),w.top+=p.y+(l.y===L?-s:l.y===N?-s/2:0),Q.viewport?(w.adjusted=Q.viewport(this,w,j,t,u,r,s),g&&w.adjusted.left&&(w.left+=g.left),g&&w.adjusted.top&&(w.top+=g.top)):w.adjusted={left:0,top:0},this._trigger("move",[w,n.elem||n],c)?(delete w.adjusted,e===D||!x||isNaN(w.left)||isNaN(w.top)||"mouse"===k||!d.isFunction(j.effect)?i.css(w):d.isFunction(j.effect)&&(j.effect.call(i,this,d.extend({},w)),i.queue(function(a){d(this).css({opacity:"",height:""}),cb.ie&&this.style.removeAttribute("filter"),a()})),this.positioning=D,this):this},y.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=!!cb.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 fb=(z=y.reposition.Corner=function(a,b){a=(""+a).replace(/([A-Z])/," $1").replace(/middle/gi,N).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?G:F}).prototype;fb.invert=function(a,b){this[a]=this[a]===K?M:this[a]===M?K:b||this[a]},fb.string=function(){var a=this.x,b=this.y;return a===b?a:this.precedance===G||this.forceY&&"center"!==b?b+" "+a:a+" "+b},fb.abbrev=function(){var a=this.string().split(" ");return a[0].charAt(0)+(a[1]&&a[1].charAt(0)||"")},fb.clone=function(){return new z(this.string(),this.forceY)},y.toggle=function(a,c){var e=this.cache,f=this.options,g=this.tooltip;if(c){if(/over|enter/.test(c.type)&&/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=l(c)}if(this.waiting&&!a&&(this.hiddenDuringWait=C),!this.rendered)return a?this.render(1):this;if(this.destroyed||this.disabled)return this;var h,i,j,k=a?"show":"hide",m=this.options[k],n=(this.options[a?"hide":"show"],this.options.position),o=this.options.content,p=this.tooltip.css("width"),q=this.tooltip.is(":visible"),r=a||1===m.target.length,s=!c||m.target.length<2||e.target[0]===c.target;return(typeof a).search("boolean|number")&&(a=!q),h=!g.is(":animated")&&q===a&&s,i=h?E:!!this._trigger(k,[90]),this.destroyed?this:(i!==D&&a&&this.focus(c),!i||h?this:(d.attr(g[0],"aria-hidden",!a),a?(e.origin=l(this.mouse),d.isFunction(o.text)&&this._updateContent(o.text,D),d.isFunction(o.title)&&this._updateTitle(o.title,D),!B&&"mouse"===n.target&&n.adjust.mouse&&(d(b).bind("mousemove."+R,this._storeMouse),B=C),p||g.css("width",g.outerWidth(D)),this.reposition(c,arguments[2]),p||g.css("width",""),m.solo&&("string"==typeof m.solo?d(m.solo):d(V,m.solo)).not(g).not(m.target).qtip("hide",d.Event("tooltipsolo"))):(clearTimeout(this.timers.show),delete e.origin,B&&!d(V+'[tracking="true"]:visible',m.solo).not(g).length&&(d(b).unbind("mousemove."+R),B=D),this.blur(c)),j=d.proxy(function(){a?(cb.ie&&g[0].style.removeAttribute("filter"),g.css("overflow",""),"string"==typeof m.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),m.effect===D||r===D?(g[k](),j()):d.isFunction(m.effect)?(g.stop(1,1),m.effect.call(g,this),g.queue("fx",function(a){j(),a()})):g.fadeTo(90,a?1:0,j),a&&m.target.trigger("qtip-"+this.id+"-inactive"),this))},y.show=function(a){return this.toggle(C,a)},y.hide=function(a){return this.toggle(D,a)},y.focus=function(a){if(!this.rendered||this.destroyed)return this;var b=d(V),c=this.tooltip,e=parseInt(c[0].style.zIndex,10),f=x.zindex+b.length;return c.hasClass(Z)||this._trigger("focus",[f],a)&&(e!==f&&(b.each(function(){this.style.zIndex>e&&(this.style.zIndex=this.style.zIndex-1)}),b.filter("."+Z).qtip("blur",a)),c.addClass(Z)[0].style.zIndex=f),this},y.blur=function(a){return!this.rendered||this.destroyed?this:(this.tooltip.removeClass(Z),this._trigger("blur",[this.tooltip.css("zIndex")],a),this)},y.disable=function(a){return this.destroyed?this:("toggle"===a?a=!(this.rendered?this.tooltip.hasClass(_):this.disabled):"boolean"!=typeof a&&(a=C),this.rendered&&this.tooltip.toggleClass(_,a).attr("aria-disabled",a),this.disabled=!!a,this)},y.enable=function(){return this.disable(D)},y._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(),b.button=e.jquery?e:d("<a />",{"class":"qtip-close "+(this.options.style.widget?"":R+"-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(_)||a.hide(b),D})},y._updateButton=function(a){if(!this.rendered)return D;var b=this.elements.button;a?this._createButton():b.remove()},y._setWidget=function(){var a=this.options.style.widget,b=this.elements,c=b.tooltip,d=c.hasClass(_);c.removeClass(_),_=a?"ui-state-disabled":"qtip-disabled",c.toggleClass(_,d),c.toggleClass("ui-helper-reset "+k(),a).toggleClass(Y,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(R+"-icon",!a)},y._storeMouse=function(a){(this.mouse=l(a)).type="mousemove"},y._bind=function(a,b,c,e,f){var g="."+this._id+(e?"-"+e:"");b.length&&d(a).bind((b.split?b:b.join(g+" "))+g,d.proxy(c,f||this))},y._unbind=function(a,b){d(a).unbind("."+this._id+(b?"-"+b:""))};var gb="."+R;d(function(){r(V,["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(X)&&!c.hasClass(_)&&clearTimeout(this.timers.hide)):"mouse"===f.position.target&&f.hide.event&&f.show.target&&!e.closest(f.show.target[0]).length&&this.hide(a),c.toggleClass($,b)}),r("["+T+"]",W,p)}),y._trigger=function(a,b,c){var e=d.Event("tooltip"+a);return e.originalEvent=c&&d.extend({},c)||this.cache.event||E,this.triggering=a,this.tooltip.trigger(e,[this].concat(b||[])),this.triggering=D,!e.isDefaultPrevented()},y._bindEvents=function(a,b,c,e,f,g){if(e.add(c).length===e.length){var h=[];b=d.map(b,function(b){var c=d.inArray(b,a);return c>-1?(h.push(a.splice(c,1)[0]),void 0):b}),h.length&&this._bind(c,h,function(a){var b=this.rendered?this.tooltip[0].offsetWidth>0:!1;(b?g:f).call(this,a)})}this._bind(c,a,f),this._bind(e,b,g)},y._assignInitialEvents=function(a){function b(a){return this.disabled||this.destroyed?D:(this.cache.event=l(a),this.cache.target=a?d(a.target):[c],clearTimeout(this.timers.show),this.timers.show=m.call(this,function(){this.render("object"==typeof a||e.show.ready)},e.show.delay),void 0)}var e=this.options,f=e.show.target,g=e.hide.target,h=e.show.event?d.trim(""+e.show.event).split(" "):[],i=e.hide.event?d.trim(""+e.hide.event).split(" "):[];/mouse(over|enter)/i.test(e.show.event)&&!/mouse(out|leave)/i.test(e.hide.event)&&i.push("mouseleave"),this._bind(f,"mousemove",function(a){this._storeMouse(a),this.cache.onTarget=C}),this._bindEvents(h,i,f,g,b,function(){clearTimeout(this.timers.show)}),(e.show.ready||e.prerender)&&b.call(this,a)},y._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),m=(d(b.body),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(X)):/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(_)&&this.tooltip[0].offsetWidth>0,e=b.parents(V).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",p),this._bind(i.add(g),x.inactiveEvents,p,"-inactive")),this._bindEvents(r,s,h,i,n,o),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){this.cache.onTarget="mouseenter"===a.type}),this._bind(l,"mousemove",function(a){this.rendered&&this.cache.onTarget&&!this.tooltip.hasClass(_)&&this.tooltip[0].offsetWidth>0&&this.reposition(a)})),(f.adjust.resize||k.length)&&this._bind(d.event.special.resize?k:m,"resize",q),f.adjust.scroll&&this._bind(m.add(f.container),"scroll",q)},y._unassignEvents=function(){var c=[this.options.show.target[0],this.options.hide.target[0],this.rendered&&this.tooltip[0],this.options.position.container[0],this.options.position.viewport[0],this.options.position.container.closest("html")[0],a,b];this._unbind(d([]).pushStack(d.grep(c,function(a){return"object"==typeof a})))},x=d.fn.qtip=function(a,b,e){var f=(""+a).toLowerCase(),g=E,i=d.makeArray(arguments).slice(1),j=i[i.length-1],k=this[0]?d.data(this[0],R):E;return!arguments.length&&k||"api"===f?k:"string"==typeof a?(this.each(function(){var a=d.data(this,R);if(!a)return C;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),D;a.set(b,e)}}),g!==E?g:this):"object"!=typeof a&&arguments.length?void 0:(k=h(d.extend(C,{},a)),this.each(function(a){var b,c;return c=d.isArray(k.id)?k.id[a]:k.id,c=!c||c===D||c.length<1||x.api[c]?x.nextid++:c,b=s(d(this),c,k),b===D?C:(x.api[c]=b,d.each(Q,function(){"initialize"===this.initialize&&this(b)}),b._assignInitialEvents(j),void 0)}))},d.qtip=e,x.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&&"object"==typeof f&&f.options.suppress)return arguments.length<2?d.attr(c,bb):(f&&f.options.content.attr===e&&f.cache.attr&&f.set("content.text",b),this.attr(bb,b))}return d.fn["attr"+ab].apply(this,arguments)},clone:function(a){var b=(d([]),d.fn["clone"+ab].apply(this,arguments));return a||b.filter("["+bb+"]").attr("title",function(){return d.attr(this,bb)}).removeAttr(bb),b}},function(a,b){if(!b||d.fn[a+ab])return C;var c=d.fn[a+ab]=d.fn[a];d.fn[a]=function(){return b.apply(this,arguments)||c.apply(this,arguments)}}),d.ui||(d["cleanData"+ab]=d.cleanData,d.cleanData=function(a){for(var b,c=0;(b=d(a[c])).length;c++)if(b.attr(S))try{b.triggerHandler("removeqtip")}catch(e){}d["cleanData"+ab].apply(this,arguments)}),x.version="2.2.0",x.nextid=0,x.inactiveEvents=W,x.zindex=15e3,x.defaults={prerender:D,id:D,overwrite:C,suppress:C,content:{text:C,attr:"title",title:D,button:D},position:{my:"top left",at:"bottom right",target:D,container:D,viewport:D,adjust:{x:0,y:0,mouse:C,scroll:C,resize:C,method:"flipinvert flipinvert"},effect:function(a,b){d(this).animate(b,{duration:200,queue:D})}},show:{target:D,event:"mouseenter",effect:C,delay:90,solo:D,ready:D,autofocus:D},hide:{target:D,event:"mouseleave",effect:C,delay:0,fixed:D,inactive:D,leave:"window",distance:D},style:{classes:"",widget:D,width:D,height:D,def:C},events:{render:E,move:E,show:E,hide:E,toggle:E,visible:E,hidden:E,focus:E,blur:E}};var hb,ib="margin",jb="border",kb="color",lb="background-color",mb="transparent",nb=" !important",ob=!!b.createElement("canvas").getContext,pb=/rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i,qb={},rb=["Webkit","O","Moz","ms"];if(ob)var sb=a.devicePixelRatio||1,tb=function(){var a=b.createElement("canvas").getContext("2d");return a.backingStorePixelRatio||a.webkitBackingStorePixelRatio||a.mozBackingStorePixelRatio||a.msBackingStorePixelRatio||a.oBackingStorePixelRatio||1}(),ub=sb/tb;else var vb=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(w.prototype,{init:function(a){var b,c;c=this.element=a.elements.tip=d("<div />",{"class":R+"-tip"}).prependTo(a.tooltip),ob?(b=d("<canvas />").appendTo(this.element)[0].getContext("2d"),b.lineJoin="miter",b.miterLimit=1e5,b.save()):(b=vb("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===J||a.y===N&&this.element.position().top+this.size[1]/2+this.options.offset<b.outerHeight(C))},_parseCorner:function(a){var b=this.qtip.options.position.my;return a===D||b===D?a=D:a===C?a=new z(b.string()):a.string||(a=new z(a),a.fixed=C),a},_parseWidth:function(a,b,c){var d=this.qtip.elements,e=jb+t(b)+"Width";return(c?v(c,e):v(d.content,e)||v(this._useTitle(a)&&d.titlebar||d.content,e)||v(d.tooltip,e))||0},_parseRadius:function(a){var b=this.qtip.elements,c=jb+t(a.y)+t(a.x)+"Radius";return cb.ie<9?0:v(this._useTitle(a)&&b.titlebar||b.content,c)||v(b.tooltip,c)||0},_invalidColour:function(a,b,c){var d=a.css(b);return!d||c&&d===a.css(c)||pb.test(d)?D:d},_parseColours:function(a){var b=this.qtip.elements,c=this.element.css("cssText",""),e=jb+t(a[a.precedance])+t(kb),f=this._useTitle(a)&&b.titlebar||b.content,g=this._invalidColour,h=[];return h[0]=g(c,lb)||g(f,lb)||g(b.content,lb)||g(b.tooltip,lb)||c.css(lb),h[1]=g(c,e,kb)||g(f,e,kb)||g(b.content,e,kb)||g(b.tooltip,e,kb)||b.tooltip.css(e),d("*",c).add(c).css("cssText",lb+":"+mb+nb+";"+jb+":0"+nb+";"),h},_calculateSize:function(a){var b,c,d,e=a.precedance===G,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=(ob||cb.ie)&&this._parseCorner(this.options.corner);return(this.enabled=!!this.corner&&"c"!==this.corner.abbrev())&&(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===D?r=b:(r=new z(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===F?this._swapDimensions():this._resetDimensions(),e=this.color=this._parseColours(b),e[1]!==mb?(l=this.border=this._parseWidth(b,b[b.precedance]),p.border&&1>l&&!pb.test(e[1])&&(e[0]=e[1]),this.border=l=p.border!==C?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===G?[s(r.x===K?l:r.x===M?k[0]-q[0]-l:(k[0]-q[0])/2),s(r.y===J?k[1]-q[1]:0)]:[s(r.x===K?k[0]-q[0]:0),s(r.y===J?l:r.y===L?k[1]-q[1]-l:(k[1]-q[1])/2)],ob?(g=o[0].getContext("2d"),g.restore(),g.save(),g.clearRect(0,0,6e3,6e3),h=this._calculateTip(r,q,ub),i=this._calculateTip(r,this.size,ub),o.attr(H,k[0]*ub).attr(I,k[1]*ub),o.css(H,k[0]).css(I,k[1]),this._drawCoords(g,i),g.fillStyle=e[1],g.fill(),g.translate(j[0]*ub,j[1]*ub),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===cb.ie?2:1:0,o.css({coordsize:k[0]+l+" "+(k[1]+l),antialias:""+(r.string().indexOf(N)>-1),left:j[0]-j[2]*Number(f===F),top:j[1]-j[2]*Number(f===G),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(vb("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!==D&&this.calculate(b,k)},calculate:function(a,b){if(!this.enabled)return D;var c,e,f=this,g=this.qtip.elements,h=this.element,i=this.options.offset,j=(g.tooltip.hasClass("ui-widget"),{});return a=a||this.corner,c=a.precedance,b=b||this._calculateSize(a),e=[a.x,a.y],c===F&&e.reverse(),d.each(e,function(d,e){var h,k,l;e===N?(h=c===G?K:J,j[h]="50%",j[ib+"-"+h]=-Math.round(b[c===G?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===F?0:1],h.css({margin:"",top:"",bottom:"",left:"",right:""}).css(j),j
4
+ },reposition:function(a,b,d){function e(a,b,c,d,e){a===P&&j.precedance===b&&k[d]&&j[c]!==N?j.precedance=j.precedance===F?G:F:a!==P&&k[d]&&(j[b]=j[b]===N?k[d]>0?d:e:j[b]===d?e:d)}function f(a,b,e){j[a]===N?p[ib+"-"+b]=o[a]=g[ib+"-"+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]=D),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:D,top:D,x:0,y:0},p={};this.corner.fixed!==C&&(e(m,F,G,K,M),e(n,G,F,J,L),j.string()===i.corner.string()||i.cornerTop===k.top&&i.cornerLeft===k.left||this.update(j,D)),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===P&&!!k.left)&&f(F,K,M),(o.top=n===P&&!!k.top)&&f(G,J,L),this.element.css(p).toggle(!(o.x&&o.y||j.x===N&&o.y||j.y===N&&o.x)),d.left-=g.left.charAt?g.user:m!==P||o.top||!o.left&&!o.top?g.left+this.border:0,d.top-=g.top.charAt?g.user:n!==P||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()}}),hb=Q.tip=function(a){return new w(a,a.options.style.tip)},hb.initialize="render",hb.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=C)}},A.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(C,x.defaults,{style:{tip:{corner:C,mimic:D,width:6,height:6,border:C,offset:0}}}),Q.viewport=function(c,d,e,f,g,h,i){function j(a,b,c,e,f,g,h,i,j){var k=d[f],m=v[a],t=w[a],u=c===P,x=m===f?j:m===g?-j:-j/2,y=t===f?i:t===g?-i:-i/2,z=r[f]+s[f]-(o?0:n[f]),A=z-k,B=k+j-(h===H?p:q)-z,C=x-(v.precedance===a||m===v[b]?y:0)-(t===N?i/2:0);return u?(C=(m===f?1:-1)*x,d[f]+=A>0?A:B>0?-B:0,d[f]=Math.max(-n[f]+s[f],k-C,Math.min(Math.max(-n[f]+s[f]+(h===H?p:q),k+C),d[f],"center"===m?k-x:1e9))):(e*=c===O?2:0,A>0&&(m!==f||B>0)?(d[f]-=C+e,l.invert(a,f)):B>0&&(m!==g||A>0)&&(d[f]-=(m===N?-C:C)+e,l.invert(a,g)),d[f]<r&&-d[f]>B&&(d[f]=k,l=v.clone())),d[f]-k}var k,l,m,n,o,p,q,r,s,t=e.target,u=c.elements.tooltip,v=e.my,w=e.at,x=e.adjust,y=x.method.split(" "),z=y[0],A=y[1]||y[0],B=e.viewport,C=e.container,E=c.cache,Q={left:0,top:0};return B.jquery&&t[0]!==a&&t[0]!==b.body&&"none"!==x.method?(n=C.offset()||Q,o="static"===C.css("position"),k="fixed"===u.css("position"),p=B[0]===a?B.width():B.outerWidth(D),q=B[0]===a?B.height():B.outerHeight(D),r={left:k?0:B.scrollLeft(),top:k?0:B.scrollTop()},s=B.offset()||Q,("shift"!==z||"shift"!==A)&&(l=v.clone()),Q={left:"none"!==z?j(F,G,z,x.x,K,M,H,f,h):0,top:"none"!==A?j(G,F,A,x.y,J,L,I,g,i):0},l&&E.lastClass!==(m=R+"-pos-"+l.abbrev())&&u.removeClass(c.cache.lastClass).addClass(c.cache.lastClass=m),Q):Q}})}(window,document);
5
+ //# sourceMappingURL=http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0//var/www/qtip2/build/tmp/tmp-11954ixg744g/jquery.qtip.min.map
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
4
  Tags: plugins, wordpress, admin, column, columns, custom columns, custom fields, image, dashboard, sortable, filters, posts, media, users, pages, posttypes, manage columns, wp-admin
5
  Requires at least: 3.5
6
  Tested up to: 3.9.1
7
- Stable tag: 2.2.3
8
 
9
  Customise columns on the administration screens for post(types), pages, media, comments, links and users with an easy to use drag-and-drop interface.
10
 
@@ -30,6 +30,8 @@ All of the new columns support sorting on all screens, and many of them support
30
  = Third party plugin integration =
31
  Admin Columns works perfectly with just about all external plugins with custom columns. Examples include Yoast SEO (SEO columns), WooCommerce, Advanced Custom Fields, Types and Pods. Not only can you reorganize the custom columns added by these plugins, you can also add custom columns provided by Admin Columns in the overview!
32
 
 
 
33
  = Custom field column =
34
  Admin Columns allows you to display custom fields for posts (post meta) and users (user meta) for all custom fields you have. With many different custom field types supported, such as files, images, numbers and even post and user relations, you can create a beautiful overview of your custom content!
35
 
@@ -246,6 +248,16 @@ You can find a list of the available actions and filters (and examples on how to
246
 
247
  == Changelog ==
248
 
 
 
 
 
 
 
 
 
 
 
249
  = 2.2.3 =
250
  * [Added] Added Path column for post(types). Uses the permalink without the home url.
251
 
4
  Tags: plugins, wordpress, admin, column, columns, custom columns, custom fields, image, dashboard, sortable, filters, posts, media, users, pages, posttypes, manage columns, wp-admin
5
  Requires at least: 3.5
6
  Tested up to: 3.9.1
7
+ Stable tag: 2.2.4
8
 
9
  Customise columns on the administration screens for post(types), pages, media, comments, links and users with an easy to use drag-and-drop interface.
10
 
30
  = Third party plugin integration =
31
  Admin Columns works perfectly with just about all external plugins with custom columns. Examples include Yoast SEO (SEO columns), WooCommerce, Advanced Custom Fields, Types and Pods. Not only can you reorganize the custom columns added by these plugins, you can also add custom columns provided by Admin Columns in the overview!
32
 
33
+ The Developer license of [Admin Columns Pro](http://admincolumns.com/?utm_source=wordpressorg&utm_medium=readme&utm_content=thirdpartyplugins&utm_campaign=cpac-pluginpage) includes [Advanced Custom Fields](http://admincolumns.com/advanced-custom-fields-integration/?utm_source=wordpressorg&utm_medium=readme&utm_content=thirdpartyplugins&utm_campaign=cpac-pluginpage) and [WooCommerce](http://admincolumns.com/woocommerce-integration/?utm_source=wordpressorg&utm_medium=readme&utm_content=thirdpartyplugins&utm_campaign=cpac-pluginpage) add-ons for easy integration and inline editing of data from these plugins.
34
+
35
  = Custom field column =
36
  Admin Columns allows you to display custom fields for posts (post meta) and users (user meta) for all custom fields you have. With many different custom field types supported, such as files, images, numbers and even post and user relations, you can create a beautiful overview of your custom content!
37
 
248
 
249
  == Changelog ==
250
 
251
+ = 2.2.4 =
252
+ * [Added] New filter `cpac/storage_model/columns_default` for filtering the columns that should be loaded if there are no stored columns
253
+ * [Added] Option (column property `hidden`) to hide column types from the dropdown list of column types
254
+ * [Added] Use tooltip library for enhanced column value representation
255
+ * [Added] Box for direct feedback on Admin Columns settings screen
256
+ * [Added] Added method for retrieving current storage model (for overview pages such as the posts and page overviews)
257
+ * [Added] Added WooCommerce add-on to list of add-ons
258
+ * [Updated] Hide ACF5 field group post type from list of post types columns settings
259
+ * [Updated] Updated structure of scripts and styles and way of enqueuing them
260
+
261
  = 2.2.3 =
262
  * [Added] Added Path column for post(types). Uses the permalink without the home url.
263