Smart Custom Fields - Version 4.0.2

Version Description

  • Some updates by @robssanches
Download this release

Release Info

Developer inc2734
Plugin Icon wp plugin Smart Custom Fields
Version 4.0.2
Comparing to
See all releases

Code changes from version 4.0.1 to 4.0.2

Files changed (37) hide show
  1. classes/class.rest-api.php +55 -0
  2. classes/controller/class.settings.php +107 -4
  3. classes/fields/class.field-boolean.php +1 -1
  4. classes/fields/class.field-check.php +1 -1
  5. classes/fields/class.field-colorpicker.php +1 -1
  6. classes/fields/class.field-datepicker.php +1 -1
  7. classes/fields/class.field-file.php +4 -2
  8. classes/fields/class.field-image.php +4 -2
  9. classes/fields/class.field-radio.php +1 -1
  10. classes/fields/class.field-related-posts.php +1 -1
  11. classes/fields/class.field-related-terms.php +1 -1
  12. classes/fields/class.field-select.php +1 -1
  13. classes/fields/class.field-text.php +1 -1
  14. classes/fields/class.field-textarea.php +1 -1
  15. classes/fields/class.field-wysiwyg.php +1 -1
  16. classes/models/class.yoast-seo-analysis.php +34 -0
  17. css/settings.css +71 -3
  18. js/editor.js +5 -3
  19. js/settings.js +121 -10
  20. js/yoast-seo-analysis.js +97 -0
  21. languages/smart-custom-fields-pt_BR.mo +0 -0
  22. languages/smart-custom-fields-pt_BR.po +123 -111
  23. languages/smart-custom-fields.pot +47 -38
  24. libs/iosCheckbox/README.md +44 -0
  25. libs/iosCheckbox/iosCheckbox.css +99 -0
  26. libs/iosCheckbox/iosCheckbox.js +68 -0
  27. libs/iosCheckbox/iosCheckbox.min.css +1 -0
  28. libs/iosCheckbox/iosCheckbox.min.js +1 -0
  29. libs/selectivity-3.1.0/CHANGELOG.md +99 -0
  30. libs/selectivity-3.1.0/LICENSE +23 -0
  31. libs/selectivity-3.1.0/README.md +267 -0
  32. libs/selectivity-3.1.0/selectivity-jquery.css +206 -0
  33. libs/selectivity-3.1.0/selectivity-jquery.js +5497 -0
  34. libs/selectivity-3.1.0/selectivity-jquery.min.css +1 -0
  35. libs/selectivity-3.1.0/selectivity-jquery.min.js +1 -0
  36. readme.txt +5 -2
  37. smart-custom-fields.php +10 -2
classes/class.rest-api.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Rest_API
4
+ * Version : 1.0.0
5
+ * Author : robssanches
6
+ * Created : July 14, 2018
7
+ * Modified : July 14, 2018
8
+ * License : GPLv2 or later
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Rest_API {
12
+
13
+ /**
14
+ * __construct
15
+ */
16
+ public function __construct() {
17
+ add_action( 'rest_api_init', array( $this, 'register_rest_api_routes' ) );
18
+ }
19
+
20
+ /**
21
+ * Register routes
22
+ */
23
+ public function register_rest_api_routes(){
24
+ register_rest_route( SCF_Config::PREFIX.'api', '/search/posts', array(
25
+ 'methods' => 'GET',
26
+ 'callback' => array( $this, 'get_all_posts' ),
27
+ ));
28
+ }
29
+
30
+ /**
31
+ * Get all posts and pages
32
+ */
33
+ public function get_all_posts() {
34
+ $all_posts = get_posts(
35
+ array(
36
+ 'post_type' => array( 'post', 'page' ),
37
+ 'post_status' => 'publish',
38
+ 'orderby' => 'date',
39
+ 'order' => 'ASC',
40
+ 'posts_per_page' => -1 // all posts
41
+ )
42
+ );
43
+
44
+ if ( $all_posts ) {
45
+ $source = array();
46
+
47
+ foreach ( $all_posts as $k => $post ) {
48
+ $source[ $k ]['id'] = $post->ID;
49
+ $source[ $k ]['text'] = $post->ID . ' - ' . $post->post_title;
50
+ }
51
+ }
52
+
53
+ return $source;
54
+ }
55
+ }
classes/controller/class.settings.php CHANGED
@@ -4,7 +4,7 @@
4
  * Version : 1.3.0
5
  * Author : inc2734
6
  * Created : September 23, 2014
7
- * Modified : June 04, 2018
8
  * License : GPLv2 or later
9
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
  */
@@ -21,6 +21,7 @@ class Smart_Custom_Fields_Controller_Settings {
21
  */
22
  public function __construct() {
23
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
 
24
  add_action( 'save_post', array( $this, 'save_post' ) );
25
  add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
26
 
@@ -44,6 +45,45 @@ class Smart_Custom_Fields_Controller_Settings {
44
  );
45
  }
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  /**
48
  * Loading resources
49
  */
@@ -57,6 +97,20 @@ class Smart_Custom_Fields_Controller_Settings {
57
  filemtime( plugin_dir_path( dirname( __FILE__ ) . '/../../css/settings.css' ) )
58
  );
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  wp_enqueue_script(
61
  SCF_Config::PREFIX . 'settings',
62
  plugins_url( SCF_Config::NAME ) . '/js/settings.js',
@@ -65,8 +119,28 @@ class Smart_Custom_Fields_Controller_Settings {
65
  true
66
  );
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  wp_localize_script( SCF_Config::PREFIX . 'settings', 'smart_cf_settings', array(
69
  'duplicate_alert' => esc_html__( 'Same name exists!', 'smart-custom-fields' ),
 
 
 
 
70
  ) );
71
 
72
  wp_enqueue_script( 'jquery-ui-sortable' );
@@ -205,7 +279,7 @@ class Smart_Custom_Fields_Controller_Settings {
205
  </div>
206
  <?php endforeach; ?>
207
  </div>
208
- <div class="button btn-add-group"><?php esc_html_e( 'Add Field', 'smart-custom-fields' ); ?></div>
209
  </div>
210
  <?php wp_nonce_field( SCF_Config::NAME . '-settings', SCF_Config::PREFIX . 'settings-nonce' ) ?>
211
  <?php
@@ -240,9 +314,38 @@ class Smart_Custom_Fields_Controller_Settings {
240
  );
241
 
242
  $condition_post_ids = get_post_meta( get_the_ID(), SCF_Config::PREFIX . 'condition-post-ids', true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  printf(
244
- '<p><b>%s</b><input type="text" name="%s" value="%s" class="widefat" /></p>',
245
- esc_html__( 'Post Ids ( Comma separated )', 'smart-custom-fields' ),
246
  esc_attr( SCF_Config::PREFIX . 'condition-post-ids' ),
247
  $condition_post_ids
248
  );
4
  * Version : 1.3.0
5
  * Author : inc2734
6
  * Created : September 23, 2014
7
+ * Modified : July 14, 2018
8
  * License : GPLv2 or later
9
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
  */
21
  */
22
  public function __construct() {
23
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
24
+ add_action( 'admin_head', array( $this, 'admin_inline_css' ) );
25
  add_action( 'save_post', array( $this, 'save_post' ) );
26
  add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
27
 
45
  );
46
  }
47
 
48
+ /**
49
+ * Get Current Admin Color Scheme
50
+ *
51
+ * @return object
52
+ */
53
+ protected function admin_color_scheme() {
54
+ global $_wp_admin_css_colors;
55
+
56
+ $user_admin_color_scheme = get_user_option( 'admin_color' );
57
+ $colors_obj = $_wp_admin_css_colors[ $user_admin_color_scheme ];
58
+
59
+ return $colors_obj;
60
+ }
61
+
62
+ /**
63
+ * Add Custom Inline CSS on Admin Dashboard
64
+ *
65
+ */
66
+ public function admin_inline_css(){
67
+ $colors = $this->admin_color_scheme()->colors;
68
+ $icon_colors = $this->admin_color_scheme()->icon_colors;
69
+ ?>
70
+ <style>
71
+ #smart-cf-meta-box-condition-post .selectivity-load-more.highlight,
72
+ #smart-cf-meta-box-condition-post .selectivity-result-item.highlight {
73
+ background-color: <?php echo esc_html( $colors[2] ); ?>;
74
+ }
75
+
76
+ .smart-cf-group .smart-cf-group-repeat label .ios-ui-select.checked,
77
+ #smart-cf-meta-box-condition-post .ios-ui-select.checked,
78
+ #smart-cf-meta-box-condition-profile .ios-ui-select.checked,
79
+ #smart-cf-meta-box-condition-taxonomy .ios-ui-select.checked,
80
+ #smart-cf-meta-box-condition-options-page .ios-ui-select.checked {
81
+ box-shadow: inset 0 0 0 36px <?php echo esc_html( $colors[2] ); ?>;
82
+ }
83
+ </style>
84
+ <?php
85
+ }
86
+
87
  /**
88
  * Loading resources
89
  */
97
  filemtime( plugin_dir_path( dirname( __FILE__ ) . '/../../css/settings.css' ) )
98
  );
99
 
100
+ wp_enqueue_style(
101
+ SCF_Config::PREFIX . 'selectivity',
102
+ plugins_url( SCF_Config::NAME ) . '/libs/selectivity-3.1.0/selectivity-jquery.min.css',
103
+ array(),
104
+ filemtime( plugin_dir_path( dirname( __FILE__ ) . '/../../libs/selectivity-3.1.0/selectivity-jquery.min.css' ) )
105
+ );
106
+
107
+ wp_enqueue_style(
108
+ SCF_Config::PREFIX . 'ios-checkbox',
109
+ plugins_url( SCF_Config::NAME ) . '/libs/iosCheckbox/iosCheckbox.min.css',
110
+ array(),
111
+ filemtime( plugin_dir_path( dirname( __FILE__ ) . '/../../libs/iosCheckbox/iosCheckbox.min.css' ) )
112
+ );
113
+
114
  wp_enqueue_script(
115
  SCF_Config::PREFIX . 'settings',
116
  plugins_url( SCF_Config::NAME ) . '/js/settings.js',
119
  true
120
  );
121
 
122
+ wp_enqueue_script(
123
+ SCF_Config::PREFIX . 'selectivity',
124
+ plugins_url( SCF_Config::NAME ) . '/libs/selectivity-3.1.0/selectivity-jquery.min.js',
125
+ array(),
126
+ filemtime( plugin_dir_path( dirname( __FILE__ ) . '/../../libs/selectivity-3.1.0/selectivity-jquery.min.js' ) ),
127
+ true
128
+ );
129
+
130
+ wp_enqueue_script(
131
+ SCF_Config::PREFIX . 'ios-checkbox',
132
+ plugins_url( SCF_Config::NAME ) . '/libs/iosCheckbox/iosCheckbox.min.js',
133
+ array(),
134
+ filemtime( plugin_dir_path( dirname( __FILE__ ) . '/../../libs/iosCheckbox/iosCheckbox.min.js' ) ),
135
+ true
136
+ );
137
+
138
  wp_localize_script( SCF_Config::PREFIX . 'settings', 'smart_cf_settings', array(
139
  'duplicate_alert' => esc_html__( 'Same name exists!', 'smart-custom-fields' ),
140
+ 'autocomplete_placeholder' => esc_html__( 'Type to search a post or page', 'smart-custom-fields' ),
141
+ 'loading' => esc_html__( 'Loading...', 'smart-custom-fields' ),
142
+ 'load_more' => esc_html__( 'Load more', 'smart-custom-fields' ),
143
+ 'rest_api_url' => rest_url( SCF_Config::PREFIX.'api/search/posts' ),
144
  ) );
145
 
146
  wp_enqueue_script( 'jquery-ui-sortable' );
279
  </div>
280
  <?php endforeach; ?>
281
  </div>
282
+ <div class="button button-primary btn-add-group"><?php esc_html_e( 'Add Field', 'smart-custom-fields' ); ?></div>
283
  </div>
284
  <?php wp_nonce_field( SCF_Config::NAME . '-settings', SCF_Config::PREFIX . 'settings-nonce' ) ?>
285
  <?php
314
  );
315
 
316
  $condition_post_ids = get_post_meta( get_the_ID(), SCF_Config::PREFIX . 'condition-post-ids', true );
317
+
318
+ // get all posts saved
319
+ $saved_posts = explode( ',', $condition_post_ids );
320
+
321
+ if ( $saved_posts ) {
322
+ $saved = array();
323
+
324
+ foreach( $saved_posts as $k => $post_id ) {
325
+ if($post_id != ''){
326
+ $saved[ $k ]['id'] = $post_id;
327
+ $saved[ $k ]['text'] = $post_id; //$post_id . ' - ' . get_the_title($post_id);
328
+ }
329
+ }
330
+ }
331
+
332
+ // create variable js with posting IDs to use in post search results
333
+ printf(
334
+ '<script type="text/javascript">smart_cf_saved_posts = %s;</script>',
335
+ json_encode( array_values( $saved ) )
336
+ );
337
+
338
+ // create div to use with jquery plugin "selectivity"
339
+ // https://github.com/arendjr/selectivity
340
+ printf(
341
+ '<p><b>%s</b><div id="%s" class="selectivity-input"></div></p>',
342
+ esc_html__( 'Post or Page Ids', 'smart-custom-fields' ),
343
+ esc_attr( SCF_Config::PREFIX . 'autocomplete-condition-post' )
344
+ );
345
+
346
+ // create input hidden with the IDS of saved posts
347
  printf(
348
+ '<input type="hidden" name="%s" value="%s"/>',
 
349
  esc_attr( SCF_Config::PREFIX . 'condition-post-ids' ),
350
  $condition_post_ids
351
  );
classes/fields/class.field-boolean.php CHANGED
@@ -78,8 +78,8 @@ class Smart_Custom_Fields_Field_Boolean extends Smart_Custom_Fields_Field_Base {
78
  * @param int $field_key
79
  */
80
  public function display_field_options( $group_key, $field_key ) {
81
- $this->display_name_option( $group_key, $field_key );
82
  $this->display_label_option( $group_key, $field_key );
 
83
  ?>
84
  <tr>
85
  <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
78
  * @param int $field_key
79
  */
80
  public function display_field_options( $group_key, $field_key ) {
 
81
  $this->display_label_option( $group_key, $field_key );
82
+ $this->display_name_option( $group_key, $field_key );
83
  ?>
84
  <tr>
85
  <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-check.php CHANGED
@@ -82,8 +82,8 @@ class Smart_Custom_Fields_Field_Check extends Smart_Custom_Fields_Field_Base {
82
  * @param int $field_key
83
  */
84
  public function display_field_options( $group_key, $field_key ) {
85
- $this->display_name_option( $group_key, $field_key );
86
  $this->display_label_option( $group_key, $field_key );
 
87
  ?>
88
  <tr>
89
  <th><?php esc_html_e( 'Choices', 'smart-custom-fields' ); ?></th>
82
  * @param int $field_key
83
  */
84
  public function display_field_options( $group_key, $field_key ) {
 
85
  $this->display_label_option( $group_key, $field_key );
86
+ $this->display_name_option( $group_key, $field_key );
87
  ?>
88
  <tr>
89
  <th><?php esc_html_e( 'Choices', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-colorpicker.php CHANGED
@@ -100,8 +100,8 @@ class Smart_Custom_Fields_Field_Colorpicker extends Smart_Custom_Fields_Field_Ba
100
  * @param int $field_key
101
  */
102
  public function display_field_options( $group_key, $field_key ) {
103
- $this->display_name_option( $group_key, $field_key );
104
  $this->display_label_option( $group_key, $field_key );
 
105
  ?>
106
  <tr>
107
  <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
100
  * @param int $field_key
101
  */
102
  public function display_field_options( $group_key, $field_key ) {
 
103
  $this->display_label_option( $group_key, $field_key );
104
+ $this->display_name_option( $group_key, $field_key );
105
  ?>
106
  <tr>
107
  <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-datepicker.php CHANGED
@@ -123,8 +123,8 @@ class Smart_Custom_Fields_Field_Datepicker extends Smart_Custom_Fields_Field_Bas
123
  * @param int $field_key
124
  */
125
  public function display_field_options( $group_key, $field_key ) {
126
- $this->display_name_option( $group_key, $field_key );
127
  $this->display_label_option( $group_key, $field_key );
 
128
  ?>
129
  <tr>
130
  <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
123
  * @param int $field_key
124
  */
125
  public function display_field_options( $group_key, $field_key ) {
 
126
  $this->display_label_option( $group_key, $field_key );
127
+ $this->display_name_option( $group_key, $field_key );
128
  ?>
129
  <tr>
130
  <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-file.php CHANGED
@@ -59,6 +59,7 @@ class Smart_Custom_Fields_Field_File extends Smart_Custom_Fields_Field_Base {
59
  // Regarded the $value is file URL.
60
  if ( preg_match( '/^\d+$/', $value ) ) {
61
  $image_src = wp_get_attachment_image_src( $value, 'thumbnail', true );
 
62
  if ( is_array( $image_src ) && isset( $image_src[0] ) ) {
63
  $image_src = $image_src[0];
64
  }
@@ -81,9 +82,10 @@ class Smart_Custom_Fields_Field_File extends Smart_Custom_Fields_Field_Base {
81
  $filetype = wp_check_filetype( $attachment_url );
82
  $filename = $attachment_name . '.' . $filetype['ext'];
83
  $image = sprintf(
84
- '<a href="%s" target="_blank"><img src="%s" alt="" />%s</a>%s',
85
  wp_get_attachment_url( $value ),
86
  esc_url( $image_src ),
 
87
  esc_attr( $filename ),
88
  $btn_remove
89
  );
@@ -112,8 +114,8 @@ class Smart_Custom_Fields_Field_File extends Smart_Custom_Fields_Field_Base {
112
  * @param int $field_key
113
  */
114
  public function display_field_options( $group_key, $field_key ) {
115
- $this->display_name_option( $group_key, $field_key );
116
  $this->display_label_option( $group_key, $field_key );
 
117
  ?>
118
  <tr>
119
  <th><?php esc_html_e( 'Instruction', 'smart-custom-fields' ); ?></th>
59
  // Regarded the $value is file URL.
60
  if ( preg_match( '/^\d+$/', $value ) ) {
61
  $image_src = wp_get_attachment_image_src( $value, 'thumbnail', true );
62
+ $image_alt = get_the_title($value);
63
  if ( is_array( $image_src ) && isset( $image_src[0] ) ) {
64
  $image_src = $image_src[0];
65
  }
82
  $filetype = wp_check_filetype( $attachment_url );
83
  $filename = $attachment_name . '.' . $filetype['ext'];
84
  $image = sprintf(
85
+ '<a href="%s" target="_blank"><img src="%s" alt="%s" />%s</a>%s',
86
  wp_get_attachment_url( $value ),
87
  esc_url( $image_src ),
88
+ $image_alt,
89
  esc_attr( $filename ),
90
  $btn_remove
91
  );
114
  * @param int $field_key
115
  */
116
  public function display_field_options( $group_key, $field_key ) {
 
117
  $this->display_label_option( $group_key, $field_key );
118
+ $this->display_name_option( $group_key, $field_key );
119
  ?>
120
  <tr>
121
  <th><?php esc_html_e( 'Instruction', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-image.php CHANGED
@@ -60,6 +60,7 @@ class Smart_Custom_Fields_Field_Image extends Smart_Custom_Fields_Field_Base {
60
  // Regarded the $value is file URL.
61
  if ( preg_match( '/^\d+$/', $value ) ) {
62
  $image_src = wp_get_attachment_image_src( $value, $this->get( 'size' ) );
 
63
  if ( is_array( $image_src ) && isset( $image_src[0] ) ) {
64
  $image_src = $image_src[0];
65
  }
@@ -77,8 +78,9 @@ class Smart_Custom_Fields_Field_Image extends Smart_Custom_Fields_Field_Base {
77
 
78
  if ( $image_src && ! is_array( $image_src ) ) {
79
  $image = sprintf(
80
- '<img src="%s" alt="" />%s',
81
  esc_url( $image_src ),
 
82
  $btn_remove
83
  );
84
  $hide_class = '';
@@ -107,8 +109,8 @@ class Smart_Custom_Fields_Field_Image extends Smart_Custom_Fields_Field_Base {
107
  * @param int $field_key
108
  */
109
  public function display_field_options( $group_key, $field_key ) {
110
- $this->display_name_option( $group_key, $field_key );
111
  $this->display_label_option( $group_key, $field_key );
 
112
  ?>
113
  <tr>
114
  <th><?php esc_html_e( 'Instruction', 'smart-custom-fields' ); ?></th>
60
  // Regarded the $value is file URL.
61
  if ( preg_match( '/^\d+$/', $value ) ) {
62
  $image_src = wp_get_attachment_image_src( $value, $this->get( 'size' ) );
63
+ $image_alt = get_the_title($value);
64
  if ( is_array( $image_src ) && isset( $image_src[0] ) ) {
65
  $image_src = $image_src[0];
66
  }
78
 
79
  if ( $image_src && ! is_array( $image_src ) ) {
80
  $image = sprintf(
81
+ '<img src="%s" alt="%s" />%s',
82
  esc_url( $image_src ),
83
+ $image_alt,
84
  $btn_remove
85
  );
86
  $hide_class = '';
109
  * @param int $field_key
110
  */
111
  public function display_field_options( $group_key, $field_key ) {
 
112
  $this->display_label_option( $group_key, $field_key );
113
+ $this->display_name_option( $group_key, $field_key );
114
  ?>
115
  <tr>
116
  <th><?php esc_html_e( 'Instruction', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-radio.php CHANGED
@@ -81,8 +81,8 @@ class Smart_Custom_Fields_Field_Radio extends Smart_Custom_Fields_Field_Base {
81
  * @param int $field_key
82
  */
83
  public function display_field_options( $group_key, $field_key ) {
84
- $this->display_name_option( $group_key, $field_key );
85
  $this->display_label_option( $group_key, $field_key );
 
86
  ?>
87
  <tr>
88
  <th><?php esc_html_e( 'Choices', 'smart-custom-fields' ); ?></th>
81
  * @param int $field_key
82
  */
83
  public function display_field_options( $group_key, $field_key ) {
 
84
  $this->display_label_option( $group_key, $field_key );
85
+ $this->display_name_option( $group_key, $field_key );
86
  ?>
87
  <tr>
88
  <th><?php esc_html_e( 'Choices', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-related-posts.php CHANGED
@@ -228,8 +228,8 @@ class Smart_Custom_Fields_Field_Related_Posts extends Smart_Custom_Fields_Field_
228
  * @param int $field_key
229
  */
230
  public function display_field_options( $group_key, $field_key ) {
231
- $this->display_name_option( $group_key, $field_key );
232
  $this->display_label_option( $group_key, $field_key );
 
233
  ?>
234
  <tr>
235
  <th><?php esc_html_e( 'Post Types', 'smart-custom-fields' ); ?></th>
228
  * @param int $field_key
229
  */
230
  public function display_field_options( $group_key, $field_key ) {
 
231
  $this->display_label_option( $group_key, $field_key );
232
+ $this->display_name_option( $group_key, $field_key );
233
  ?>
234
  <tr>
235
  <th><?php esc_html_e( 'Post Types', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-related-terms.php CHANGED
@@ -226,8 +226,8 @@ class Smart_Custom_Fields_Field_Related_Terms extends Smart_Custom_Fields_Field_
226
  * @param int $field_key
227
  */
228
  public function display_field_options( $group_key, $field_key ) {
229
- $this->display_name_option( $group_key, $field_key );
230
  $this->display_label_option( $group_key, $field_key );
 
231
  ?>
232
  <tr>
233
  <th><?php esc_html_e( 'Taxonomies', 'smart-custom-fields' ); ?></th>
226
  * @param int $field_key
227
  */
228
  public function display_field_options( $group_key, $field_key ) {
 
229
  $this->display_label_option( $group_key, $field_key );
230
+ $this->display_name_option( $group_key, $field_key );
231
  ?>
232
  <tr>
233
  <th><?php esc_html_e( 'Taxonomies', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-select.php CHANGED
@@ -76,8 +76,8 @@ class Smart_Custom_Fields_Field_Select extends Smart_Custom_Fields_Field_Base {
76
  * @param int $field_key
77
  */
78
  public function display_field_options( $group_key, $field_key ) {
79
- $this->display_name_option( $group_key, $field_key );
80
  $this->display_label_option( $group_key, $field_key );
 
81
  ?>
82
  <tr>
83
  <th><?php esc_html_e( 'Choices', 'smart-custom-fields' ); ?></th>
76
  * @param int $field_key
77
  */
78
  public function display_field_options( $group_key, $field_key ) {
 
79
  $this->display_label_option( $group_key, $field_key );
80
+ $this->display_name_option( $group_key, $field_key );
81
  ?>
82
  <tr>
83
  <th><?php esc_html_e( 'Choices', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-text.php CHANGED
@@ -61,8 +61,8 @@ class Smart_Custom_Fields_Field_Text extends Smart_Custom_Fields_Field_Base {
61
  * @param int $field_key
62
  */
63
  public function display_field_options( $group_key, $field_key ) {
64
- $this->display_name_option( $group_key, $field_key );
65
  $this->display_label_option( $group_key, $field_key );
 
66
  ?>
67
  <tr>
68
  <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
61
  * @param int $field_key
62
  */
63
  public function display_field_options( $group_key, $field_key ) {
 
64
  $this->display_label_option( $group_key, $field_key );
65
+ $this->display_name_option( $group_key, $field_key );
66
  ?>
67
  <tr>
68
  <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-textarea.php CHANGED
@@ -64,8 +64,8 @@ class Smart_Custom_Fields_Field_Textarea extends Smart_Custom_Fields_Field_Base
64
  * @param int $field_key
65
  */
66
  public function display_field_options( $group_key, $field_key ) {
67
- $this->display_name_option( $group_key, $field_key );
68
  $this->display_label_option( $group_key, $field_key );
 
69
  ?>
70
  <tr>
71
  <th><?php esc_html_e( 'Rows', 'smart-custom-fields' ); ?></th>
64
  * @param int $field_key
65
  */
66
  public function display_field_options( $group_key, $field_key ) {
 
67
  $this->display_label_option( $group_key, $field_key );
68
+ $this->display_name_option( $group_key, $field_key );
69
  ?>
70
  <tr>
71
  <th><?php esc_html_e( 'Rows', 'smart-custom-fields' ); ?></th>
classes/fields/class.field-wysiwyg.php CHANGED
@@ -117,8 +117,8 @@ class Smart_Custom_Fields_Field_Wysiwyg extends Smart_Custom_Fields_Field_Base {
117
  * @param int $field_key
118
  */
119
  public function display_field_options( $group_key, $field_key ) {
120
- $this->display_name_option( $group_key, $field_key );
121
  $this->display_label_option( $group_key, $field_key );
 
122
  ?>
123
  <tr>
124
  <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
117
  * @param int $field_key
118
  */
119
  public function display_field_options( $group_key, $field_key ) {
 
120
  $this->display_label_option( $group_key, $field_key );
121
+ $this->display_name_option( $group_key, $field_key );
122
  ?>
123
  <tr>
124
  <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
classes/models/class.yoast-seo-analysis.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Yoast_SEO_Analysis
4
+ * Version : 1.0.0
5
+ * Author : robssanches
6
+ * Created : July 11, 2018
7
+ * Modified : July 11, 2018
8
+ * License : GPLv2 or later
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Yoast_SEO_Analysis {
12
+
13
+ /**
14
+ * __construct
15
+ */
16
+ public function __construct() {
17
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
18
+ }
19
+
20
+ /**
21
+ * Loading resources.
22
+ *
23
+ * @param string $hook
24
+ */
25
+ public function admin_enqueue_scripts( $hook ) {
26
+ wp_enqueue_script(
27
+ SCF_Config::PREFIX . 'yoast-seo-analysis',
28
+ plugins_url( SCF_Config::NAME ) . '/js/yoast-seo-analysis.js',
29
+ null,
30
+ filemtime( plugin_dir_path( dirname( __FILE__ ) . '/../../js/yoast-seo-analysis.js' ) ),
31
+ false
32
+ );
33
+ }
34
+ }
css/settings.css CHANGED
@@ -3,7 +3,7 @@
3
  * Version : 1.1.0
4
  * Author : inc2734
5
  * Created : September 23, 2014
6
- * Modified : May 31, 2016
7
  * License : GPLv2 or later
8
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  */
@@ -27,7 +27,7 @@
27
  */
28
  .smart-cf-group {
29
  background: #f5f5f5;
30
- border: #ddd solid 1px;
31
  margin: 10px 0 0;
32
  padding: 10px;
33
  position: relative;
@@ -75,6 +75,11 @@
75
  position: relative;
76
  top: -2px;
77
  }
 
 
 
 
 
78
 
79
  /**
80
  * .smart-cf-group-names
@@ -109,7 +114,7 @@
109
  */
110
  .smart-cf-group .smart-cf-field {
111
  background: #fff;
112
- border: #ddd solid 1px;
113
  margin: 5px 0 0;
114
  padding: 10px;
115
  overflow: hidden;
@@ -193,6 +198,69 @@
193
  margin: 0 0 5px;
194
  }
195
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  /** ==================================================
197
  * .hide
198
  */
3
  * Version : 1.1.0
4
  * Author : inc2734
5
  * Created : September 23, 2014
6
+ * Modified : July 14, 2018
7
  * License : GPLv2 or later
8
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  */
27
  */
28
  .smart-cf-group {
29
  background: #f5f5f5;
30
+ border: #eee solid 1px;
31
  margin: 10px 0 0;
32
  padding: 10px;
33
  position: relative;
75
  position: relative;
76
  top: -2px;
77
  }
78
+ @media (max-width:750px) {
79
+ .smart-cf-group .smart-cf-group-name {
80
+ max-width:79%;
81
+ }
82
+ }
83
 
84
  /**
85
  * .smart-cf-group-names
114
  */
115
  .smart-cf-group .smart-cf-field {
116
  background: #fff;
117
+ border: #eee solid 1px;
118
  margin: 5px 0 0;
119
  padding: 10px;
120
  overflow: hidden;
198
  margin: 0 0 5px;
199
  }
200
 
201
+ #smart-cf-meta-box-condition-post .selectivity-multiple-input {
202
+ box-shadow: none;
203
+ }
204
+
205
+ #smart-cf-meta-box-condition-post .selectivity-multiple-selected-item {
206
+ margin-right: 5px;
207
+ }
208
+
209
+ #smart-cf-meta-box-condition-post .selectivity-multiple-selected-item-remove {
210
+ font-weight: bold;
211
+ color: #fff;
212
+ }
213
+
214
+ #smart-cf-meta-box-condition-post .selectivity-multiple-input-container {
215
+ border: 1px solid #ddd;
216
+ box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
217
+ background-color: #fff;
218
+ color: #32373c;
219
+ outline: 0;
220
+ transition: 50ms border-color ease-in-out;
221
+ border-radius: 0;
222
+ }
223
+
224
+ #smart-cf-meta-box-condition-post .selectivity-dropdown,
225
+ #smart-cf-meta-box-condition-post .selectivity-result-item:first-child,
226
+ #smart-cf-meta-box-condition-post .selectivity-load-more,
227
+ #smart-cf-meta-box-condition-post .selectivity-result-item:last-child,
228
+ #smart-cf-meta-box-condition-post .selectivity-result-children:last-child .selectivity-result-item:last-child {
229
+ border-radius: 0;
230
+ }
231
+
232
+ .smart-cf-group .smart-cf-group-repeat label .ios-ui-select,
233
+ #smart-cf-meta-box-condition-post .ios-ui-select,
234
+ #smart-cf-meta-box-condition-profile .ios-ui-select,
235
+ #smart-cf-meta-box-condition-taxonomy .ios-ui-select,
236
+ #smart-cf-meta-box-condition-options-page .ios-ui-select {
237
+ height: 18px;
238
+ width: 32px;
239
+ margin-bottom: -5px;
240
+ position: relative;
241
+ background: #ddd;
242
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .07);
243
+
244
+ }
245
+
246
+ .smart-cf-group .smart-cf-group-repeat label .ios-ui-select .inner,
247
+ #smart-cf-meta-box-condition-post .ios-ui-select .inner,
248
+ #smart-cf-meta-box-condition-profile .ios-ui-select .inner,
249
+ #smart-cf-meta-box-condition-taxonomy .ios-ui-select .inner,
250
+ #smart-cf-meta-box-condition-options-page .ios-ui-select .inner {
251
+ width: 12px;
252
+ height: 12px;
253
+ }
254
+
255
+ .smart-cf-group .smart-cf-group-repeat label .ios-ui-select.checked .inner,
256
+ #smart-cf-meta-box-condition-post .ios-ui-select.checked .inner,
257
+ #smart-cf-meta-box-condition-profile .ios-ui-select.checked .inner,
258
+ #smart-cf-meta-box-condition-taxonomy .ios-ui-select.checked .inner,
259
+ #smart-cf-meta-box-condition-options-page .ios-ui-select.checked .inner {
260
+ left: 17px;
261
+ }
262
+
263
+
264
  /** ==================================================
265
  * .hide
266
  */
js/editor.js CHANGED
@@ -3,7 +3,7 @@
3
  * Version : 2.0.0
4
  * Author : inc2734
5
  * Created : September 23, 2014
6
- * Modified : June 4, 2016
7
  * License : GPLv2 or later
8
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  */
@@ -103,9 +103,10 @@ jQuery( function( $ ) {
103
  var image_area = upload_button.parent().find( '.smart-cf-upload-image' );
104
  var sizename = image_area.data('size');
105
  var img = sizes[ sizename ] || sizes.full;
 
106
  image_area.find( 'img' ).remove();
107
  image_area.prepend(
108
- '<img src="' + img.url + '" />'
109
  );
110
  image_area.removeClass( 'hide' );
111
  upload_button.parent().find( 'input[type="hidden"]' ).val( file.toJSON().id );
@@ -156,9 +157,10 @@ jQuery( function( $ ) {
156
  var images = custom_uploader_file.state().get( 'selection' );
157
  images.each( function( file ){
158
  var image_area = upload_button.parent().find( '.smart-cf-upload-file' );
 
159
  image_area.find( 'a' ).remove();
160
  image_area.prepend(
161
- '<a href="' + file.toJSON().url + '" target="_blank"><img src="' + file.toJSON().icon + '" /><span>' + file.toJSON().filename + '</span></a>'
162
  );
163
  image_area.removeClass( 'hide' );
164
  upload_button.parent().find( 'input[type="hidden"]' ).val( file.toJSON().id );
3
  * Version : 2.0.0
4
  * Author : inc2734
5
  * Created : September 23, 2014
6
+ * Modified : July 11, 2018
7
  * License : GPLv2 or later
8
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  */
103
  var image_area = upload_button.parent().find( '.smart-cf-upload-image' );
104
  var sizename = image_area.data('size');
105
  var img = sizes[ sizename ] || sizes.full;
106
+ var alt_attr = file.get('title');
107
  image_area.find( 'img' ).remove();
108
  image_area.prepend(
109
+ '<img src="' + img.url + '" alt="' + alt_attr + '" />'
110
  );
111
  image_area.removeClass( 'hide' );
112
  upload_button.parent().find( 'input[type="hidden"]' ).val( file.toJSON().id );
157
  var images = custom_uploader_file.state().get( 'selection' );
158
  images.each( function( file ){
159
  var image_area = upload_button.parent().find( '.smart-cf-upload-file' );
160
+ var alt_attr = file.get('title');
161
  image_area.find( 'a' ).remove();
162
  image_area.prepend(
163
+ '<a href="' + file.toJSON().url + '" target="_blank"><img src="' + file.toJSON().icon + '" alt="' + alt_attr + '" /><span>' + file.toJSON().filename + '</span></a>'
164
  );
165
  image_area.removeClass( 'hide' );
166
  upload_button.parent().find( 'input[type="hidden"]' ).val( file.toJSON().id );
js/settings.js CHANGED
@@ -3,7 +3,7 @@
3
  * Version : 1.1.0
4
  * Author : inc2734
5
  * Created : September 23, 2014
6
- * Modified : March 10, 2015
7
  * License : GPLv2 or later
8
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  */
@@ -78,11 +78,12 @@ jQuery( function( $ ) {
78
  } );
79
  } );
80
  } else {
81
- var label = table.find( '.smart-cf-field-label' ).val();
82
- var name = $( '<small>' ).text( '[ ' + table.find('.smart-cf-field-name').val() + ' ]' );
 
83
 
84
  if ( !label ) {
85
- label = table.find( '.smart-cf-field-name' ).val();
86
  }
87
  table.fadeOut( 'fast', function() {
88
  $( this ).addClass( 'hide' );
@@ -206,16 +207,126 @@ jQuery( function( $ ) {
206
  }
207
  } );
208
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  /**
210
  * フィールド名入力ボックス
211
  */
212
- wrapper.find( '.smart-cf-field-label' ).focus( function() {
213
- var field = $( this ).parents( '.smart-cf-field' );
214
- var name_val = field.find( '.smart-cf-field-name' ).val();
215
- var label_val = $( this ).val();
216
- if ( name_val && !label_val ) {
217
- $( this ).val( name_val );
218
  }
219
  } );
220
  } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  } );
3
  * Version : 1.1.0
4
  * Author : inc2734
5
  * Created : September 23, 2014
6
+ * Modified : July 14, 2018
7
  * License : GPLv2 or later
8
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  */
78
  } );
79
  } );
80
  } else {
81
+ var field_options = table.find( '.smart-cf-field-options:visible' );
82
+ var label = field_options.find( '.smart-cf-field-label' ).val();
83
+ var name = $( '<small>' ).text( '[ ' + field_options.find('.smart-cf-field-name').val() + ' ]' );
84
 
85
  if ( !label ) {
86
+ label = field_options.find( '.smart-cf-field-name' ).val();
87
  }
88
  table.fadeOut( 'fast', function() {
89
  $( this ).addClass( 'hide' );
207
  }
208
  } );
209
 
210
+ /**
211
+ * Convert string to slug
212
+ * https://gist.github.com/codeguy/6684588
213
+ */
214
+ function string_to_slug(str) {
215
+ str = str.replace(/^\s+|\s+$/g, ""); // trim
216
+ str = str.toLowerCase();
217
+
218
+ // remove accents, swap ñ for n, etc
219
+ var from = "åàáãäâèéëêìíïîòóöôùúüûñç·/-,:;";
220
+ var to = "aaaaaaeeeeiiiioooouuuunc______";
221
+
222
+ for (var i = 0, l = from.length; i < l; i++) {
223
+ str = str.replace(new RegExp(from.charAt(i), "g"), to.charAt(i));
224
+ }
225
+
226
+ str = str
227
+ .replace(/[^a-z0-9 -]/g, "") // remove invalid chars
228
+ .replace(/\s+/g, "_") // collapse whitespace and replace by -
229
+ .replace(/-+/g, "_"); // collapse dashes
230
+
231
+ return str;
232
+ }
233
+
234
  /**
235
  * フィールド名入力ボックス
236
  */
237
+ wrapper.find( '.smart-cf-field-name' ).focus( function() {
238
+ var field = $( this ).parents( '.smart-cf-field-options' );
239
+ var label_val = field.find( '.smart-cf-field-label' ).val();
240
+ var name_val = $( this ).val();
241
+ if ( label_val && !name_val) {
242
+ $( this ).val( string_to_slug(label_val) );
243
  }
244
  } );
245
  } );
246
+
247
+ /**
248
+ * Add autocomplete (selectivity plguin) in posts condition field
249
+ * https://github.com/arendjr/selectivity
250
+ */
251
+ $('#smart-cf-autocomplete-condition-post').selectivity({
252
+ data: smart_cf_saved_posts,
253
+ multiple: true,
254
+ placeholder: smart_cf_settings.autocomplete_placeholder,
255
+ ajax: {
256
+ url: smart_cf_settings.rest_api_url,
257
+ quietMillis:200
258
+ },
259
+ templates: {
260
+ multipleSelectInput: function(options) {
261
+ return (
262
+ '<div class="selectivity-multiple-input-container">' +
263
+ (options.enabled ?
264
+ '<input type="text" autocomplete="off" autocorrect="off" ' +
265
+ 'autocapitalize="off" class="selectivity-multiple-input">' :
266
+ '<div class="selectivity-multiple-input ' + 'selectivity-placeholder"></div>') +
267
+ '<div class="selectivity-clearfix"></div>' +
268
+ '</div>'
269
+ );
270
+ },
271
+ multipleSelectedItem: function(options) {
272
+ var extraClass = options.highlighted ? ' highlighted' : '';
273
+ return (
274
+ '<span class="selectivity-multiple-selected-item button button-primary' +
275
+ extraClass +
276
+ '" ' +
277
+ 'data-item-id="' +
278
+ options.id +
279
+ '">' +
280
+ (options.removable ?
281
+ '<a class="selectivity-multiple-selected-item-remove">' +
282
+ 'x' +
283
+ '</a>' :
284
+ '') +
285
+ options.id +
286
+ '</span>'
287
+ ); //options.text
288
+ },
289
+ dropdown: function(options) {
290
+ var extraClass = options.dropdownCssClass ? ' ' + options.dropdownCssClass : '',
291
+ searchInput = '';
292
+ if (options.showSearchInput) {
293
+ extraClass += ' has-search-input';
294
+ var placeholder = options.searchInputPlaceholder;
295
+ searchInput =
296
+ '<div class="selectivity-search-input-container">' +
297
+ '<input type="text" class="selectivity-search-input"' +
298
+ (placeholder ? ' placeholder="' + escape(placeholder) + '"' : '') +
299
+ '>' +
300
+ '</div>';
301
+ }
302
+
303
+ return (
304
+ '<div class="selectivity-dropdown' +
305
+ extraClass +
306
+ '">' +
307
+ searchInput +
308
+ '<div class="selectivity-results-container"></div>' +
309
+ '</div>'
310
+ );
311
+ },
312
+ loading: function() {
313
+ return '<div class="selectivity-loading">' + smart_cf_settings.loading + '</div>';
314
+ },
315
+ loadMore: function() {
316
+ return '<div class="selectivity-load-more">' + smart_cf_settings.load_more + '</div>';
317
+ },
318
+ }
319
+ });
320
+ $('#smart-cf-autocomplete-condition-post').on('change', function() {
321
+ var data = $(this).selectivity('value');
322
+ $('[name="smart-cf-condition-post-ids"]').val(data);
323
+ });
324
+
325
+ /**
326
+ * Add IOS style for checkboxes
327
+ */
328
+ $('.smart-cf-group .smart-cf-group-repeat label, #smart-cf-meta-box-condition-post, #smart-cf-meta-box-condition-profile, #smart-cf-meta-box-condition-taxonomy, #smart-cf-meta-box-condition-options-page')
329
+ .find('input[type=checkbox]')
330
+ .iosCheckbox();
331
+
332
  } );
js/yoast-seo-analysis.js ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * yoast-seo-analysis.js
3
+ * Version : 1.0.0
4
+ * Author : robssanches
5
+ * Created : July 11, 2018
6
+ * Modified : July 11, 2018
7
+ * License : GPLv2 or later
8
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+ */
10
+ jQuery( function( $ ) {
11
+
12
+ $(document).ready(function(e) {
13
+
14
+ // if is Page or Post continue...
15
+ if( $('body').hasClass('post-php') && typeof YoastSEO !== "undefined" && typeof SCFYoastSEOAnalysis == "undefined" ){
16
+
17
+ /**
18
+ * Set up the SCF Yoast SEO Analysis plugin
19
+ */
20
+ var SCFYoastSEOAnalysis = function() {
21
+
22
+ console.log('SCFYoastSEOAnalysis');
23
+
24
+ YoastSEO.app.registerPlugin('SCFYoastSEOAnalysis', {status: 'ready'});
25
+
26
+ /**
27
+ * @param modification {string} The name of the filter
28
+ * @param callable {function} The callable
29
+ * @param pluginName {string} The plugin that is registering the modification.
30
+ * @param priority {number} (optional) Used to specify the order in which the callables
31
+ * associated with a particular filter are called. Lower numbers
32
+ * correspond with earlier execution.
33
+ */
34
+ YoastSEO.app.registerModification('content', this.addScfFieldsToContent, 'SCFYoastSEOAnalysis', 5);
35
+
36
+ this.analysisTimeout = 0;
37
+ this.bindListeners();
38
+
39
+ // Re-analyse SEO score
40
+ $('.btn-add-repeat-group, .btn-remove-image').on('click', this.bindListeners);
41
+ if (wp.media) wp.media.view.Modal.prototype.on('close', function() {
42
+ window.setTimeout( function() { YoastSEO.app.pluginReloaded('SCFYoastSEOAnalysis'); }, 200 );
43
+ });
44
+
45
+ };
46
+
47
+ /**
48
+ * Bind listeners to text fields (input, textarea and wysiwyg)
49
+ */
50
+ SCFYoastSEOAnalysis.prototype.bindListeners = function() {
51
+
52
+ console.log('bindListeners');
53
+
54
+ SCFYoastSEOAnalysis.analysisTimeout = window.setTimeout( function() { YoastSEO.app.pluginReloaded('SCFYoastSEOAnalysis'); }, 200 );
55
+
56
+ $('#post-body, #edittag').find('input[type="text"][name^="smart-custom-fields"], textarea[name^="smart-custom-fields"], .smart-cf-field-type-wysiwyg iframe body#tinymce').on('keyup paste cut blur focus change', function() {
57
+
58
+ if ( SCFYoastSEOAnalysis.analysisTimeout ) {
59
+ window.clearTimeout(SCFYoastSEOAnalysis.analysisTimeout);
60
+ }
61
+ });
62
+
63
+ };
64
+
65
+ /**
66
+ * Adds some text to the data...
67
+ *
68
+ * @param data The data to modify
69
+ */
70
+ SCFYoastSEOAnalysis.prototype.addScfFieldsToContent = function(data) {
71
+ console.log('addScfFieldsToContent');
72
+
73
+ var scf_content = ' ';
74
+
75
+ $('#post-body, #edittag').find('input[type="text"][name^="smart-custom-fields"], textarea[name^="smart-custom-fields"]').each(function() {
76
+ scf_content += ' ' + $(this).val();
77
+ });
78
+
79
+ $(".smart-cf-field-type-wysiwyg iframe").contents().find("body#tinymce").each(function() {
80
+ scf_content += ' ' + $(this).html();
81
+ });
82
+
83
+ $('#post-body, #edittag').find('.smart-cf-upload-image img').each(function() {
84
+ scf_content += '<img src="' + $(this).attr('src') + '" alt="' + $(this).attr('alt') + '" />';
85
+ });
86
+
87
+ data = data + scf_content;
88
+
89
+ return data.trim();
90
+ };
91
+
92
+ new SCFYoastSEOAnalysis();
93
+ }
94
+
95
+ });
96
+
97
+ });
languages/smart-custom-fields-pt_BR.mo CHANGED
Binary file
languages/smart-custom-fields-pt_BR.po CHANGED
@@ -5,8 +5,8 @@ msgstr ""
5
  "Project-Id-Version: Smart Custom Fields 3.1.7\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/smart-custom-"
7
  "fields\n"
8
- "POT-Creation-Date: 2018-06-02 21:30-0300\n"
9
- "PO-Revision-Date: 2018-06-02 21:30-0300\n"
10
  "Last-Translator: robssanches <robssanches@hotmail.com>\n"
11
  "Language-Team: Português do Brasil\n"
12
  "Language: pt_BR\n"
@@ -14,7 +14,7 @@ msgstr ""
14
  "Content-Type: text/plain; charset=UTF-8\n"
15
  "Content-Transfer-Encoding: 8bit\n"
16
  "Plural-Forms: nplurals=2; plural=n != 1;\n"
17
- "X-Generator: Poedit 2.0.7\n"
18
  "Plural-Forms: nplurals=1; plural=0;\n"
19
  "X-Poedit-KeywordsList: __;_e;esc_html__;esc_html_e;esc_attr__;esc_attr_e\n"
20
  "X-Poedit-Basepath: ..\n"
@@ -33,77 +33,91 @@ msgid "Save settings"
33
  msgstr "Salvar configurações"
34
 
35
  #: classes/controller/class.profile.php:43
36
- #: classes/controller/class.settings.php:76
37
  msgid "Custom Fields"
38
  msgstr "Campos personalizados"
39
 
40
- #: classes/controller/class.settings.php:29
41
  msgid "Basic fields"
42
  msgstr "Campos básicos"
43
 
44
- #: classes/controller/class.settings.php:33
45
  msgid "Select fields"
46
  msgstr "Selecione os campos"
47
 
48
- #: classes/controller/class.settings.php:37
49
  msgid "Content fields"
50
  msgstr "Campos de conteúdo"
51
 
52
- #: classes/controller/class.settings.php:41
53
  msgid "Other fields"
54
  msgstr "Outros campos"
55
 
56
- #: classes/controller/class.settings.php:64
57
  msgid "Same name exists!"
58
  msgstr "O mesmo nome existe!"
59
 
60
- #: classes/controller/class.settings.php:82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  msgid "Display conditions ( Post )"
62
  msgstr "Condições de exibição (Post)"
63
 
64
- #: classes/controller/class.settings.php:89
65
  msgid "Display conditions ( Profile )"
66
  msgstr "Condições de exibição (Perfil)"
67
 
68
- #: classes/controller/class.settings.php:96
69
  msgid "Display conditions ( Taxonomy )"
70
  msgstr "Condições de exibição (Taxonomia)"
71
 
72
- #: classes/controller/class.settings.php:103
73
  msgid "Display conditions ( Options page )"
74
  msgstr "Condições de exibição (Página de Opções)"
75
 
76
- #: classes/controller/class.settings.php:163
77
  msgid "Type"
78
  msgstr "Tipo"
79
 
80
- #: classes/controller/class.settings.php:198
81
  msgid "Add Sub field"
82
  msgstr "Adicionar Campo Secundário"
83
 
84
- #: classes/controller/class.settings.php:202
85
  msgid "Add Field"
86
  msgstr "Adicionar Campo"
87
 
88
- #: classes/controller/class.settings.php:232
89
- #: classes/fields/class.field-related-posts.php:231
90
  msgid "Post Types"
91
  msgstr "Tipos de Post"
92
 
93
- #: classes/controller/class.settings.php:239
94
- msgid "Post Ids ( Comma separated )"
95
- msgstr "IDs de postagem (separados por vírgula)"
96
 
97
- #: classes/controller/class.settings.php:264
98
  msgid "Roles"
99
  msgstr "Funções"
100
 
101
- #: classes/controller/class.settings.php:290
102
- #: classes/fields/class.field-related-terms.php:229
103
  msgid "Taxonomies"
104
  msgstr "Taxonomias"
105
 
106
- #: classes/controller/class.settings.php:314
107
  msgid "Options pages"
108
  msgstr "Páginas de opções"
109
 
@@ -119,57 +133,56 @@ msgstr "Sim"
119
  msgid "No"
120
  msgstr "Não"
121
 
122
- #: classes/fields/class.field-boolean.php:82
123
- #: classes/fields/class.field-check.php:117
124
- #: classes/fields/class.field-colorpicker.php:103
125
- #: classes/fields/class.field-datepicker.php:125
126
- #: classes/fields/class.field-message.php:67
127
- #: classes/fields/class.field-radio.php:116
128
- #: classes/fields/class.field-select.php:91
129
- #: classes/fields/class.field-text.php:66
130
- #: classes/fields/class.field-textarea.php:79
131
- #: classes/fields/class.field-wysiwyg.php:122
132
  msgid "Default"
133
  msgstr "Padrão"
134
 
135
- #: classes/fields/class.field-boolean.php:107
136
  msgid "TRUE Label"
137
  msgstr "Rótulo VERDADEIRO"
138
 
139
- #: classes/fields/class.field-boolean.php:117
140
  msgid "FALSE Label"
141
  msgstr "Rótulo FALSO"
142
 
143
- #: classes/fields/class.field-boolean.php:127
144
- #: classes/fields/class.field-check.php:126
145
- #: classes/fields/class.field-colorpicker.php:112
146
- #: classes/fields/class.field-datepicker.php:189
147
- #: classes/fields/class.field-file.php:117
148
- #: classes/fields/class.field-image.php:112
149
- #: classes/fields/class.field-radio.php:125
150
- #: classes/fields/class.field-related-posts.php:260
151
- #: classes/fields/class.field-related-terms.php:256
152
- #: classes/fields/class.field-select.php:100
153
- #: classes/fields/class.field-text.php:75
154
- #: classes/fields/class.field-textarea.php:88
155
- #: classes/fields/class.field-wysiwyg.php:131
156
  msgid "Instruction"
157
  msgstr "Instrução"
158
 
159
- #: classes/fields/class.field-boolean.php:134
160
- #: classes/fields/class.field-check.php:133
161
- #: classes/fields/class.field-colorpicker.php:119
162
- #: classes/fields/class.field-datepicker.php:196
163
- #: classes/fields/class.field-file.php:124
164
- #: classes/fields/class.field-image.php:119
165
- #: classes/fields/class.field-message.php:76
166
- #: classes/fields/class.field-radio.php:132
167
- #: classes/fields/class.field-related-posts.php:267
168
- #: classes/fields/class.field-related-terms.php:263
169
- #: classes/fields/class.field-select.php:107
170
- #: classes/fields/class.field-text.php:82
171
- #: classes/fields/class.field-textarea.php:95
172
- #: classes/fields/class.field-wysiwyg.php:138
173
  msgid "Notes"
174
  msgstr "Notas"
175
 
@@ -177,33 +190,33 @@ msgstr "Notas"
177
  msgid "Check"
178
  msgstr "Checkbox"
179
 
180
- #: classes/fields/class.field-check.php:87
181
- #: classes/fields/class.field-radio.php:86
182
- #: classes/fields/class.field-select.php:81
183
  msgid "Choices"
184
  msgstr "Opções"
185
 
186
- #: classes/fields/class.field-check.php:93
187
- #: classes/fields/class.field-radio.php:92
188
- #: classes/fields/class.field-select.php:87
189
  msgid ""
190
  "If you want to separate the key and the value, enter as follows: key => value"
191
  msgstr ""
192
  "Se você deseja separar a chave e o valor, insira da seguinte forma: key => "
193
  "value"
194
 
195
- #: classes/fields/class.field-check.php:97
196
- #: classes/fields/class.field-radio.php:96
197
  msgid "Display Direction"
198
  msgstr "Direção de Exibição"
199
 
200
- #: classes/fields/class.field-check.php:101
201
- #: classes/fields/class.field-radio.php:100
202
  msgid "horizontal"
203
  msgstr "horizontal"
204
 
205
- #: classes/fields/class.field-check.php:102
206
- #: classes/fields/class.field-radio.php:101
207
  msgid "vertical"
208
  msgstr "vertical"
209
 
@@ -215,24 +228,24 @@ msgstr "Seletor de cores"
215
  msgid "Date picker"
216
  msgstr "Seletor de data"
217
 
218
- #: classes/fields/class.field-datepicker.php:135
219
  msgid "Date Format"
220
  msgstr "Formato de data"
221
 
222
- #: classes/fields/class.field-datepicker.php:143
223
  msgid "e.g dd/mm/yy"
224
  msgstr "ex. dd/mm/yy"
225
 
226
- #: classes/fields/class.field-datepicker.php:153
227
  msgid "Max Date"
228
  msgstr "Data máxima"
229
 
230
- #: classes/fields/class.field-datepicker.php:161
231
- #: classes/fields/class.field-datepicker.php:179
232
  msgid "e.g +1m +1w"
233
  msgstr "ex. +1m +1w"
234
 
235
- #: classes/fields/class.field-datepicker.php:171
236
  msgid "Min Date"
237
  msgstr "Data mínima"
238
 
@@ -245,7 +258,7 @@ msgstr "Arquivo"
245
  msgid "Delete"
246
  msgstr "Excluir"
247
 
248
- #: classes/fields/class.field-file.php:98
249
  msgid "File Select"
250
  msgstr "Seleção de Arquivo"
251
 
@@ -253,15 +266,16 @@ msgstr "Seleção de Arquivo"
253
  msgid "Image"
254
  msgstr "Imagem"
255
 
256
- #: classes/fields/class.field-image.php:92
257
  msgid "Image Select"
258
  msgstr "Selecionar imagem"
259
 
260
- #: classes/fields/class.field-image.php:129
261
  msgid "Preview Size"
262
  msgstr "Tamanho da pré-visualização"
263
 
264
  #: classes/fields/class.field-message.php:21
 
265
  msgid "Message"
266
  msgstr "Mensagem"
267
 
@@ -273,18 +287,13 @@ msgstr "Radio"
273
  msgid "Related Posts"
274
  msgstr "Posts Relacionados"
275
 
276
- #: classes/fields/class.field-related-posts.php:209
277
- #: classes/fields/class.field-related-terms.php:207
278
  msgid "Search..."
279
  msgstr "Pesquisa..."
280
 
281
- #: classes/fields/class.field-related-posts.php:213
282
- #: classes/fields/class.field-related-terms.php:211
283
- msgid "Load more"
284
- msgstr "Carregar mais"
285
-
286
- #: classes/fields/class.field-related-posts.php:252
287
- #: classes/fields/class.field-related-terms.php:248
288
  msgid "Selectable number"
289
  msgstr "Número selecionável"
290
 
@@ -305,7 +314,7 @@ msgstr "Texto"
305
  msgid "Textarea"
306
  msgstr "Área de Texto"
307
 
308
- #: classes/fields/class.field-textarea.php:69
309
  msgid "Rows"
310
  msgstr "Linhas"
311
 
@@ -317,16 +326,16 @@ msgstr "Wysiwyg"
317
  msgid "Visual"
318
  msgstr "Visual"
319
 
320
- #: classes/fields/class.field-wysiwyg.php:160
321
- #: classes/fields/class.field-wysiwyg.php:161
322
  msgid "Add Media"
323
  msgstr "Adicionar Mídia"
324
 
325
- #: classes/models/class.abstract-field-base.php:106
326
  msgid "Name"
327
  msgstr "Nome"
328
 
329
- #: classes/models/class.abstract-field-base.php:117
330
  msgid "Label"
331
  msgstr "Rótulo"
332
 
@@ -338,48 +347,51 @@ msgstr "Repetir"
338
  msgid "Group name"
339
  msgstr "Nome do grupo"
340
 
341
- #: classes/models/class.revisions.php:128 smart-custom-fields.php:168
342
- #: smart-custom-fields.php:169 smart-custom-fields.php:170
343
  msgid "Smart Custom Fields"
344
  msgstr "Smart Custom Fields"
345
 
346
- #: smart-custom-fields.php:171 smart-custom-fields.php:172
347
- #: smart-custom-fields.php:218 smart-custom-fields.php:219
348
  msgid "Add New"
349
  msgstr "Adicionar Novo"
350
 
351
- #: smart-custom-fields.php:173
352
  msgid "New Field"
353
  msgstr "Novo Campo"
354
 
355
- #: smart-custom-fields.php:174
356
  msgid "Edit Field"
357
  msgstr "Editar campo"
358
 
359
- #: smart-custom-fields.php:175
360
  msgid "View Field"
361
  msgstr "Visualizar campo"
362
 
363
- #: smart-custom-fields.php:176
364
  msgid "All Fields"
365
  msgstr "Todos os Campos"
366
 
367
- #: smart-custom-fields.php:177
368
  msgid "Search Fields"
369
  msgstr "Campos de Pesquisa"
370
 
371
- #: smart-custom-fields.php:178
372
  msgid "Parent Fields:"
373
  msgstr "Campos pai:"
374
 
375
- #: smart-custom-fields.php:179
376
  msgid "No Fields found."
377
  msgstr "Nenhum campo encontrado."
378
 
379
- #: smart-custom-fields.php:180
380
  msgid "No Fields found in Trash."
381
  msgstr "Nenhum campo encontrado na lixeira."
382
 
 
 
 
383
  #~ msgid ""
384
  #~ "Smart Custom Fields is a simple plugin that management custom fields."
385
  #~ msgstr ""
5
  "Project-Id-Version: Smart Custom Fields 3.1.7\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/smart-custom-"
7
  "fields\n"
8
+ "POT-Creation-Date: 2018-07-14 22:36-0300\n"
9
+ "PO-Revision-Date: 2018-07-14 22:37-0300\n"
10
  "Last-Translator: robssanches <robssanches@hotmail.com>\n"
11
  "Language-Team: Português do Brasil\n"
12
  "Language: pt_BR\n"
14
  "Content-Type: text/plain; charset=UTF-8\n"
15
  "Content-Transfer-Encoding: 8bit\n"
16
  "Plural-Forms: nplurals=2; plural=n != 1;\n"
17
+ "X-Generator: Poedit 2.0.9\n"
18
  "Plural-Forms: nplurals=1; plural=0;\n"
19
  "X-Poedit-KeywordsList: __;_e;esc_html__;esc_html_e;esc_attr__;esc_attr_e\n"
20
  "X-Poedit-Basepath: ..\n"
33
  msgstr "Salvar configurações"
34
 
35
  #: classes/controller/class.profile.php:43
36
+ #: classes/controller/class.settings.php:162
37
  msgid "Custom Fields"
38
  msgstr "Campos personalizados"
39
 
40
+ #: classes/controller/class.settings.php:30
41
  msgid "Basic fields"
42
  msgstr "Campos básicos"
43
 
44
+ #: classes/controller/class.settings.php:34
45
  msgid "Select fields"
46
  msgstr "Selecione os campos"
47
 
48
+ #: classes/controller/class.settings.php:38
49
  msgid "Content fields"
50
  msgstr "Campos de conteúdo"
51
 
52
+ #: classes/controller/class.settings.php:42
53
  msgid "Other fields"
54
  msgstr "Outros campos"
55
 
56
+ #: classes/controller/class.settings.php:145
57
  msgid "Same name exists!"
58
  msgstr "O mesmo nome existe!"
59
 
60
+ #: classes/controller/class.settings.php:146
61
+ msgid "Type to search a post or page"
62
+ msgstr "Digite para pesquisar um post ou página"
63
+
64
+ #: classes/controller/class.settings.php:147
65
+ msgid "Loading..."
66
+ msgstr "Carregando..."
67
+
68
+ #: classes/controller/class.settings.php:148
69
+ #: classes/fields/class.field-related-posts.php:215
70
+ #: classes/fields/class.field-related-terms.php:213
71
+ msgid "Load more"
72
+ msgstr "Carregar mais"
73
+
74
+ #: classes/controller/class.settings.php:168
75
  msgid "Display conditions ( Post )"
76
  msgstr "Condições de exibição (Post)"
77
 
78
+ #: classes/controller/class.settings.php:175
79
  msgid "Display conditions ( Profile )"
80
  msgstr "Condições de exibição (Perfil)"
81
 
82
+ #: classes/controller/class.settings.php:182
83
  msgid "Display conditions ( Taxonomy )"
84
  msgstr "Condições de exibição (Taxonomia)"
85
 
86
+ #: classes/controller/class.settings.php:189
87
  msgid "Display conditions ( Options page )"
88
  msgstr "Condições de exibição (Página de Opções)"
89
 
90
+ #: classes/controller/class.settings.php:249
91
  msgid "Type"
92
  msgstr "Tipo"
93
 
94
+ #: classes/controller/class.settings.php:284
95
  msgid "Add Sub field"
96
  msgstr "Adicionar Campo Secundário"
97
 
98
+ #: classes/controller/class.settings.php:288
99
  msgid "Add Field"
100
  msgstr "Adicionar Campo"
101
 
102
+ #: classes/controller/class.settings.php:318
103
+ #: classes/fields/class.field-related-posts.php:235
104
  msgid "Post Types"
105
  msgstr "Tipos de Post"
106
 
107
+ #: classes/controller/class.settings.php:367
108
+ msgid "Post or Page Ids"
109
+ msgstr "IDs de Posts ou Páginas"
110
 
111
+ #: classes/controller/class.settings.php:398
112
  msgid "Roles"
113
  msgstr "Funções"
114
 
115
+ #: classes/controller/class.settings.php:424
116
+ #: classes/fields/class.field-related-terms.php:233
117
  msgid "Taxonomies"
118
  msgstr "Taxonomias"
119
 
120
+ #: classes/controller/class.settings.php:448
121
  msgid "Options pages"
122
  msgstr "Páginas de opções"
123
 
133
  msgid "No"
134
  msgstr "Não"
135
 
136
+ #: classes/fields/class.field-boolean.php:85
137
+ #: classes/fields/class.field-check.php:119
138
+ #: classes/fields/class.field-colorpicker.php:107
139
+ #: classes/fields/class.field-datepicker.php:130
140
+ #: classes/fields/class.field-radio.php:118
141
+ #: classes/fields/class.field-select.php:93
142
+ #: classes/fields/class.field-text.php:68
143
+ #: classes/fields/class.field-textarea.php:81
144
+ #: classes/fields/class.field-wysiwyg.php:124
 
145
  msgid "Default"
146
  msgstr "Padrão"
147
 
148
+ #: classes/fields/class.field-boolean.php:110
149
  msgid "TRUE Label"
150
  msgstr "Rótulo VERDADEIRO"
151
 
152
+ #: classes/fields/class.field-boolean.php:120
153
  msgid "FALSE Label"
154
  msgstr "Rótulo FALSO"
155
 
156
+ #: classes/fields/class.field-boolean.php:130
157
+ #: classes/fields/class.field-check.php:128
158
+ #: classes/fields/class.field-colorpicker.php:116
159
+ #: classes/fields/class.field-datepicker.php:194
160
+ #: classes/fields/class.field-file.php:121
161
+ #: classes/fields/class.field-image.php:116
162
+ #: classes/fields/class.field-radio.php:127
163
+ #: classes/fields/class.field-related-posts.php:264
164
+ #: classes/fields/class.field-related-terms.php:260
165
+ #: classes/fields/class.field-select.php:102
166
+ #: classes/fields/class.field-text.php:77
167
+ #: classes/fields/class.field-textarea.php:90
168
+ #: classes/fields/class.field-wysiwyg.php:133
169
  msgid "Instruction"
170
  msgstr "Instrução"
171
 
172
+ #: classes/fields/class.field-boolean.php:137
173
+ #: classes/fields/class.field-check.php:135
174
+ #: classes/fields/class.field-colorpicker.php:123
175
+ #: classes/fields/class.field-datepicker.php:201
176
+ #: classes/fields/class.field-file.php:128
177
+ #: classes/fields/class.field-image.php:123
178
+ #: classes/fields/class.field-message.php:77
179
+ #: classes/fields/class.field-radio.php:134
180
+ #: classes/fields/class.field-related-posts.php:271
181
+ #: classes/fields/class.field-related-terms.php:267
182
+ #: classes/fields/class.field-select.php:109
183
+ #: classes/fields/class.field-text.php:84
184
+ #: classes/fields/class.field-textarea.php:97
185
+ #: classes/fields/class.field-wysiwyg.php:140
186
  msgid "Notes"
187
  msgstr "Notas"
188
 
190
  msgid "Check"
191
  msgstr "Checkbox"
192
 
193
+ #: classes/fields/class.field-check.php:89
194
+ #: classes/fields/class.field-radio.php:88
195
+ #: classes/fields/class.field-select.php:83
196
  msgid "Choices"
197
  msgstr "Opções"
198
 
199
+ #: classes/fields/class.field-check.php:95
200
+ #: classes/fields/class.field-radio.php:94
201
+ #: classes/fields/class.field-select.php:89
202
  msgid ""
203
  "If you want to separate the key and the value, enter as follows: key => value"
204
  msgstr ""
205
  "Se você deseja separar a chave e o valor, insira da seguinte forma: key => "
206
  "value"
207
 
208
+ #: classes/fields/class.field-check.php:99
209
+ #: classes/fields/class.field-radio.php:98
210
  msgid "Display Direction"
211
  msgstr "Direção de Exibição"
212
 
213
+ #: classes/fields/class.field-check.php:103
214
+ #: classes/fields/class.field-radio.php:102
215
  msgid "horizontal"
216
  msgstr "horizontal"
217
 
218
+ #: classes/fields/class.field-check.php:104
219
+ #: classes/fields/class.field-radio.php:103
220
  msgid "vertical"
221
  msgstr "vertical"
222
 
228
  msgid "Date picker"
229
  msgstr "Seletor de data"
230
 
231
+ #: classes/fields/class.field-datepicker.php:140
232
  msgid "Date Format"
233
  msgstr "Formato de data"
234
 
235
+ #: classes/fields/class.field-datepicker.php:148
236
  msgid "e.g dd/mm/yy"
237
  msgstr "ex. dd/mm/yy"
238
 
239
+ #: classes/fields/class.field-datepicker.php:158
240
  msgid "Max Date"
241
  msgstr "Data máxima"
242
 
243
+ #: classes/fields/class.field-datepicker.php:166
244
+ #: classes/fields/class.field-datepicker.php:184
245
  msgid "e.g +1m +1w"
246
  msgstr "ex. +1m +1w"
247
 
248
+ #: classes/fields/class.field-datepicker.php:176
249
  msgid "Min Date"
250
  msgstr "Data mínima"
251
 
258
  msgid "Delete"
259
  msgstr "Excluir"
260
 
261
+ #: classes/fields/class.field-file.php:100
262
  msgid "File Select"
263
  msgstr "Seleção de Arquivo"
264
 
266
  msgid "Image"
267
  msgstr "Imagem"
268
 
269
+ #: classes/fields/class.field-image.php:94
270
  msgid "Image Select"
271
  msgstr "Selecionar imagem"
272
 
273
+ #: classes/fields/class.field-image.php:133
274
  msgid "Preview Size"
275
  msgstr "Tamanho da pré-visualização"
276
 
277
  #: classes/fields/class.field-message.php:21
278
+ #: classes/fields/class.field-message.php:68
279
  msgid "Message"
280
  msgstr "Mensagem"
281
 
287
  msgid "Related Posts"
288
  msgstr "Posts Relacionados"
289
 
290
+ #: classes/fields/class.field-related-posts.php:211
291
+ #: classes/fields/class.field-related-terms.php:209
292
  msgid "Search..."
293
  msgstr "Pesquisa..."
294
 
295
+ #: classes/fields/class.field-related-posts.php:256
296
+ #: classes/fields/class.field-related-terms.php:252
 
 
 
 
 
297
  msgid "Selectable number"
298
  msgstr "Número selecionável"
299
 
314
  msgid "Textarea"
315
  msgstr "Área de Texto"
316
 
317
+ #: classes/fields/class.field-textarea.php:71
318
  msgid "Rows"
319
  msgstr "Linhas"
320
 
326
  msgid "Visual"
327
  msgstr "Visual"
328
 
329
+ #: classes/fields/class.field-wysiwyg.php:162
330
+ #: classes/fields/class.field-wysiwyg.php:163
331
  msgid "Add Media"
332
  msgstr "Adicionar Mídia"
333
 
334
+ #: classes/models/class.abstract-field-base.php:118
335
  msgid "Name"
336
  msgstr "Nome"
337
 
338
+ #: classes/models/class.abstract-field-base.php:134
339
  msgid "Label"
340
  msgstr "Rótulo"
341
 
347
  msgid "Group name"
348
  msgstr "Nome do grupo"
349
 
350
+ #: classes/models/class.revisions.php:128 smart-custom-fields.php:174
351
+ #: smart-custom-fields.php:175 smart-custom-fields.php:176
352
  msgid "Smart Custom Fields"
353
  msgstr "Smart Custom Fields"
354
 
355
+ #: smart-custom-fields.php:177 smart-custom-fields.php:178
356
+ #: smart-custom-fields.php:224 smart-custom-fields.php:225
357
  msgid "Add New"
358
  msgstr "Adicionar Novo"
359
 
360
+ #: smart-custom-fields.php:179
361
  msgid "New Field"
362
  msgstr "Novo Campo"
363
 
364
+ #: smart-custom-fields.php:180
365
  msgid "Edit Field"
366
  msgstr "Editar campo"
367
 
368
+ #: smart-custom-fields.php:181
369
  msgid "View Field"
370
  msgstr "Visualizar campo"
371
 
372
+ #: smart-custom-fields.php:182
373
  msgid "All Fields"
374
  msgstr "Todos os Campos"
375
 
376
+ #: smart-custom-fields.php:183
377
  msgid "Search Fields"
378
  msgstr "Campos de Pesquisa"
379
 
380
+ #: smart-custom-fields.php:184
381
  msgid "Parent Fields:"
382
  msgstr "Campos pai:"
383
 
384
+ #: smart-custom-fields.php:185
385
  msgid "No Fields found."
386
  msgstr "Nenhum campo encontrado."
387
 
388
+ #: smart-custom-fields.php:186
389
  msgid "No Fields found in Trash."
390
  msgstr "Nenhum campo encontrado na lixeira."
391
 
392
+ #~ msgid "Post Ids ( Comma separated )"
393
+ #~ msgstr "IDs de postagem (separados por vírgula)"
394
+
395
  #~ msgid ""
396
  #~ "Smart Custom Fields is a simple plugin that management custom fields."
397
  #~ msgstr ""
languages/smart-custom-fields.pot CHANGED
@@ -6,14 +6,14 @@ msgstr ""
6
  "Project-Id-Version: Smart Custom Fields 3.1.7\n"
7
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/smart-custom-"
8
  "fields\n"
9
- "POT-Creation-Date: 2018-06-02 21:26-0300\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "PO-Revision-Date: 2018-MO-DA HO:MI+ZONE\n"
14
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
15
  "Language-Team: Smart Custom Fields <LL@li.org>\n"
16
- "X-Generator: Poedit 2.0.7\n"
17
  "X-Poedit-SourceCharset: UTF-8\n"
18
  "X-Poedit-KeywordsList: esc_html__;__;_n;_x;_n_noop;_e\n"
19
  "X-Poedit-Basepath: ..\n"
@@ -28,47 +28,61 @@ msgid "File setting"
28
  msgstr ""
29
 
30
  #: classes/controller/class.profile.php:43
31
- #: classes/controller/class.settings.php:76
32
  msgid "Custom Fields"
33
  msgstr ""
34
 
35
- #: classes/controller/class.settings.php:64
36
  msgid "Same name exists!"
37
  msgstr ""
38
 
39
- #: classes/controller/class.settings.php:82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  msgid "Display conditions ( Post )"
41
  msgstr ""
42
 
43
- #: classes/controller/class.settings.php:89
44
  msgid "Display conditions ( Profile )"
45
  msgstr ""
46
 
47
- #: classes/controller/class.settings.php:96
48
  msgid "Display conditions ( Taxonomy )"
49
  msgstr ""
50
 
51
- #: classes/controller/class.settings.php:103
52
  msgid "Display conditions ( Options page )"
53
  msgstr ""
54
 
55
- #: classes/controller/class.settings.php:232
56
  msgid "Post Types"
57
  msgstr ""
58
 
59
- #: classes/controller/class.settings.php:239
60
- msgid "Post Ids ( Comma separated )"
61
  msgstr ""
62
 
63
- #: classes/controller/class.settings.php:264
64
  msgid "Roles"
65
  msgstr ""
66
 
67
- #: classes/controller/class.settings.php:290
68
  msgid "Taxonomies"
69
  msgstr ""
70
 
71
- #: classes/controller/class.settings.php:314
72
  msgid "Options pages"
73
  msgstr ""
74
 
@@ -88,13 +102,13 @@ msgstr ""
88
  msgid "Check"
89
  msgstr ""
90
 
91
- #: classes/fields/class.field-check.php:101
92
- #: classes/fields/class.field-radio.php:100
93
  msgid "horizontal"
94
  msgstr ""
95
 
96
- #: classes/fields/class.field-check.php:102
97
- #: classes/fields/class.field-radio.php:101
98
  msgid "vertical"
99
  msgstr ""
100
 
@@ -115,7 +129,7 @@ msgstr ""
115
  msgid "Delete"
116
  msgstr ""
117
 
118
- #: classes/fields/class.field-file.php:98
119
  msgid "File Select"
120
  msgstr ""
121
 
@@ -123,7 +137,7 @@ msgstr ""
123
  msgid "Image"
124
  msgstr ""
125
 
126
- #: classes/fields/class.field-image.php:92
127
  msgid "Image Select"
128
  msgstr ""
129
 
@@ -139,11 +153,6 @@ msgstr ""
139
  msgid "Related Posts"
140
  msgstr ""
141
 
142
- #: classes/fields/class.field-related-posts.php:213
143
- #: classes/fields/class.field-related-terms.php:211
144
- msgid "Load more"
145
- msgstr ""
146
-
147
  #: classes/fields/class.field-related-terms.php:24
148
  msgid "Related Terms"
149
  msgstr ""
@@ -169,48 +178,48 @@ msgstr ""
169
  msgid "Visual"
170
  msgstr ""
171
 
172
- #: classes/fields/class.field-wysiwyg.php:161
173
  msgid "Add Media"
174
  msgstr ""
175
 
176
- #: classes/models/class.revisions.php:128 smart-custom-fields.php:168
177
- #: smart-custom-fields.php:169 smart-custom-fields.php:170
178
  msgid "Smart Custom Fields"
179
  msgstr ""
180
 
181
- #: smart-custom-fields.php:171 smart-custom-fields.php:172
182
- #: smart-custom-fields.php:218 smart-custom-fields.php:219
183
  msgid "Add New"
184
  msgstr ""
185
 
186
- #: smart-custom-fields.php:173
187
  msgid "New Field"
188
  msgstr ""
189
 
190
- #: smart-custom-fields.php:174
191
  msgid "Edit Field"
192
  msgstr ""
193
 
194
- #: smart-custom-fields.php:175
195
  msgid "View Field"
196
  msgstr ""
197
 
198
- #: smart-custom-fields.php:176
199
  msgid "All Fields"
200
  msgstr ""
201
 
202
- #: smart-custom-fields.php:177
203
  msgid "Search Fields"
204
  msgstr ""
205
 
206
- #: smart-custom-fields.php:178
207
  msgid "Parent Fields:"
208
  msgstr ""
209
 
210
- #: smart-custom-fields.php:179
211
  msgid "No Fields found."
212
  msgstr ""
213
 
214
- #: smart-custom-fields.php:180
215
  msgid "No Fields found in Trash."
216
  msgstr ""
6
  "Project-Id-Version: Smart Custom Fields 3.1.7\n"
7
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/smart-custom-"
8
  "fields\n"
9
+ "POT-Creation-Date: 2018-07-14 22:36-0300\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "PO-Revision-Date: 2018-MO-DA HO:MI+ZONE\n"
14
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
15
  "Language-Team: Smart Custom Fields <LL@li.org>\n"
16
+ "X-Generator: Poedit 2.0.9\n"
17
  "X-Poedit-SourceCharset: UTF-8\n"
18
  "X-Poedit-KeywordsList: esc_html__;__;_n;_x;_n_noop;_e\n"
19
  "X-Poedit-Basepath: ..\n"
28
  msgstr ""
29
 
30
  #: classes/controller/class.profile.php:43
31
+ #: classes/controller/class.settings.php:162
32
  msgid "Custom Fields"
33
  msgstr ""
34
 
35
+ #: classes/controller/class.settings.php:145
36
  msgid "Same name exists!"
37
  msgstr ""
38
 
39
+ #: classes/controller/class.settings.php:146
40
+ msgid "Type to search a post or page"
41
+ msgstr ""
42
+
43
+ #: classes/controller/class.settings.php:147
44
+ msgid "Loading..."
45
+ msgstr ""
46
+
47
+ #: classes/controller/class.settings.php:148
48
+ #: classes/fields/class.field-related-posts.php:215
49
+ #: classes/fields/class.field-related-terms.php:213
50
+ msgid "Load more"
51
+ msgstr ""
52
+
53
+ #: classes/controller/class.settings.php:168
54
  msgid "Display conditions ( Post )"
55
  msgstr ""
56
 
57
+ #: classes/controller/class.settings.php:175
58
  msgid "Display conditions ( Profile )"
59
  msgstr ""
60
 
61
+ #: classes/controller/class.settings.php:182
62
  msgid "Display conditions ( Taxonomy )"
63
  msgstr ""
64
 
65
+ #: classes/controller/class.settings.php:189
66
  msgid "Display conditions ( Options page )"
67
  msgstr ""
68
 
69
+ #: classes/controller/class.settings.php:318
70
  msgid "Post Types"
71
  msgstr ""
72
 
73
+ #: classes/controller/class.settings.php:367
74
+ msgid "Post or Page Ids"
75
  msgstr ""
76
 
77
+ #: classes/controller/class.settings.php:398
78
  msgid "Roles"
79
  msgstr ""
80
 
81
+ #: classes/controller/class.settings.php:424
82
  msgid "Taxonomies"
83
  msgstr ""
84
 
85
+ #: classes/controller/class.settings.php:448
86
  msgid "Options pages"
87
  msgstr ""
88
 
102
  msgid "Check"
103
  msgstr ""
104
 
105
+ #: classes/fields/class.field-check.php:103
106
+ #: classes/fields/class.field-radio.php:102
107
  msgid "horizontal"
108
  msgstr ""
109
 
110
+ #: classes/fields/class.field-check.php:104
111
+ #: classes/fields/class.field-radio.php:103
112
  msgid "vertical"
113
  msgstr ""
114
 
129
  msgid "Delete"
130
  msgstr ""
131
 
132
+ #: classes/fields/class.field-file.php:100
133
  msgid "File Select"
134
  msgstr ""
135
 
137
  msgid "Image"
138
  msgstr ""
139
 
140
+ #: classes/fields/class.field-image.php:94
141
  msgid "Image Select"
142
  msgstr ""
143
 
153
  msgid "Related Posts"
154
  msgstr ""
155
 
 
 
 
 
 
156
  #: classes/fields/class.field-related-terms.php:24
157
  msgid "Related Terms"
158
  msgstr ""
178
  msgid "Visual"
179
  msgstr ""
180
 
181
+ #: classes/fields/class.field-wysiwyg.php:163
182
  msgid "Add Media"
183
  msgstr ""
184
 
185
+ #: classes/models/class.revisions.php:128 smart-custom-fields.php:174
186
+ #: smart-custom-fields.php:175 smart-custom-fields.php:176
187
  msgid "Smart Custom Fields"
188
  msgstr ""
189
 
190
+ #: smart-custom-fields.php:177 smart-custom-fields.php:178
191
+ #: smart-custom-fields.php:224 smart-custom-fields.php:225
192
  msgid "Add New"
193
  msgstr ""
194
 
195
+ #: smart-custom-fields.php:179
196
  msgid "New Field"
197
  msgstr ""
198
 
199
+ #: smart-custom-fields.php:180
200
  msgid "Edit Field"
201
  msgstr ""
202
 
203
+ #: smart-custom-fields.php:181
204
  msgid "View Field"
205
  msgstr ""
206
 
207
+ #: smart-custom-fields.php:182
208
  msgid "All Fields"
209
  msgstr ""
210
 
211
+ #: smart-custom-fields.php:183
212
  msgid "Search Fields"
213
  msgstr ""
214
 
215
+ #: smart-custom-fields.php:184
216
  msgid "Parent Fields:"
217
  msgstr ""
218
 
219
+ #: smart-custom-fields.php:185
220
  msgid "No Fields found."
221
  msgstr ""
222
 
223
+ #: smart-custom-fields.php:186
224
  msgid "No Fields found in Trash."
225
  msgstr ""
libs/iosCheckbox/README.md ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ iosCheckbox.js
2
+ ==============
3
+
4
+ A jQuery plugin that transform any checkbox element into a beautiful ios style checkbox.
5
+
6
+ ![alt tag](http://s15.postimg.org/gbyj9pzk7/ios_Checbox.png)
7
+
8
+ Demo: http://jsfiddle.net/bttkc3jg/31/
9
+
10
+ Demo Alternative Theme: http://jsfiddle.net/5xzevfq7/9/
11
+
12
+ Usage:
13
+
14
+ Include the css
15
+
16
+ ```html
17
+ <link rel="stylesheet" type="text/css" href="iosCheckbox.css" />
18
+ ```
19
+
20
+ Add some checkboxs to your page
21
+
22
+ ```html
23
+ <input type="checkbox" class="ios" checked />
24
+ <input type="checkbox" class="ios" />
25
+ ```
26
+
27
+ Load jQuery and iosCheckbox
28
+
29
+ ```html
30
+ <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
31
+ <script type="text/javascript" src="iosCheckbox.js"></script>
32
+ ```
33
+
34
+ Transform all checkboxs with the class of `ios`
35
+
36
+ ```html
37
+ <script type="text/javascript">
38
+ jQuery(function ($){
39
+ $(".ios").iosCheckbox();
40
+ });
41
+ </script>
42
+ ```
43
+
44
+ We also have a Zepto based version thanks to [LeoUnglaub](https://github.com/LeoUnglaub) you can find it in [here](https://bitbucket.org/foxship/ioscheckbox.js)
libs/iosCheckbox/iosCheckbox.css ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .ios-ui-select{
2
+ background: #dddddd;
3
+ border: none;
4
+ height: 36px;
5
+ background: #dddddd;
6
+ -webkit-border-radius: 18px;
7
+ border-radius: 18px;
8
+ width: 60px;
9
+ -webkit-transition: all 0.3s ease-in-out;
10
+ -moz-transition: all 0.3s ease-in-out;
11
+ -ms-transition: all 0.3s ease-in-out;
12
+ -o-transition: all 0.3s ease-in-out;
13
+ transition: all 0.3s ease-in-out;
14
+ -webkit-box-shadow: none;
15
+ box-shadow: none;
16
+ cursor: pointer;
17
+ position: relative;
18
+ display: inline-block;
19
+ }
20
+ .ios-ui-select.checked{
21
+ -webkit-box-shadow: inset 0 0 0 36px #6ddc5f;
22
+ box-shadow: inset 0 0 0 36px #6ddc5f;
23
+ }
24
+ .ios-ui-select.checked .inner{
25
+ left: 27px;
26
+ }
27
+ .ios-ui-select .inner{
28
+ width: 30px;
29
+ height: 30px;
30
+ position: absolute;
31
+ top: 3px;
32
+ left: 3px;
33
+ -webkit-border-radius: 100%;
34
+ border-radius: 100%;
35
+ background: white;
36
+ -webkit-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
37
+ -moz-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
38
+ -o-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
39
+ transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
40
+ -webkit-box-shadow: 0 1px 2px 0 rgba(0,0,0,0.2),0 3px 4px 0 rgba(0,0,0,0.1);
41
+ box-shadow: 0 1px 2px 0 rgba(0,0,0,0.2),0 3px 4px 0 rgba(0,0,0,0.1);
42
+ }
43
+
44
+ /* Alternative Theme */
45
+ /* ---------------- */
46
+ /*
47
+ .ios-ui-select{
48
+ border-color: #d1d1d1;
49
+ width: 28px;
50
+ height: 28px;
51
+ -webkit-border-radius: 100%;
52
+ border-radius: 100%;
53
+ opacity: 1;
54
+ -webkit-box-shadow: inset 0 0 0 2px #d6e0e6;
55
+ box-shadow: inset 0 0 0 2px #d6e0e6;
56
+ width: 22px;
57
+ z-index: 2;
58
+ text-align: center;
59
+ display: inline-block;
60
+ cursor: pointer;
61
+ height: 22px;
62
+ -webkit-border-radius: 18px;
63
+ border-radius: 18px;
64
+ -webkit-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
65
+ -moz-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
66
+ -o-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
67
+ transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
68
+ text-indent: -9999px;
69
+ display: inline-block;
70
+ }
71
+ .ios-ui-select.checked {
72
+ -webkit-box-shadow: inset 0 0 0 14px #4ad337;
73
+ box-shadow: inset 0 0 0 14px #4ad337;
74
+ opacity: 1 !important;
75
+ }
76
+ .ios-ui-select.checked .inner{
77
+ -moz-transform: scale(1);
78
+ -webkit-transform: scale(1);
79
+ -o-transform: scale(1);
80
+ -ms-transform: scale(1);
81
+ transform: scale(1);
82
+ }
83
+ .ios-ui-select .inner{
84
+ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAQAAADa613fAAAC70lEQVR42u3bPWgUQRgG4N0kxpjCYJFCFBVRCyFg0PgD/oAiKpGgAUEwhVhoI4I2FoIpxDSmCBZqIYopRMEUWiSIiilEBEEwKCgHRgwqKsIhxngQ89qYkMu9iTuzs7N74Z0rb+bbe/Z2Z+b79i5EMDtaRSCIIIIIIogggggiiCCCCCKIIIIIIogggggyWyE15Q+ZF3QF+WAkeB20GI1Dtl616Md4G0Nr9JHZYlSjD5PbIMJyhFSiB1Pb8qijs3OPhMH1oDXGPZyRbyPEFZS2j6got0urE6y1ldvN3k4Z7SYxssA4RRmdZlHSZxzDGGFcjj7xZgPShj+E0W3KSBuyH6OE0YNK81hpMnajQBi9qLaJlh5jG4YJ4zFq7eKlxdiAPGE8w3zbiOkwGvCdMAawwD5mGoxV+EIYb1AfJ6p/xjIMEcY7LI4X1zdjEXKEMYQVcSObda9CE9ahyvpw9XhFGF+xOv4pMuncjE//Ntd7rA5WhxeEkccaF9919K6Nk5avAvZaZONPCeMnNrq5aKN3vVX0AX5hu9GBavCIMEyjOIHkSs7lJoOiwj3CKKDZ3TQSvetLcnU3Riwq3CaMURxwOR9G79phOd+EuEZGjuGw24ndZM6xWwEu0vzvuOsVyqTzUromD864JndQxmn3S61Z95V0l/R22l3SGco4l8SeIcl96wnK6Epm82M+ZP00mUTdlH5HaFHhqnk2ntymcSvN7fqLcruDNBu/aZONJ7n73UWz7b6JbLuFvn8Xc5LbV9sO3DdD/WMHfpP3HtgVFZLPRw5RSjc20wvviW1RwUdidZTezqzg9rxkKsgUJMBJRGkD8bJxP6nu2f8ycljoI4mOH+LCjIwPWOKnGuDiWdOlaRmf4xcVfFZRQtygjG9o8FefcfU89g5Ju5p8FprcPSHvLWIMY4vfipnL3yw8nGCMYKfvCqbLYHNxHu/xA/ex1n9FOdQfKgURRBBBBBFEEEEEEUQQQQQRRBBBBBFEEEHG21/sNjJ4iVKmQwAAAABJRU5ErkJggg==) center center no-repeat;
85
+ background-size: 100%;
86
+ width: 100%;
87
+ height: 100%;
88
+ content: '';
89
+ -webkit-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
90
+ -moz-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
91
+ -o-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
92
+ transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
93
+ -moz-transform: scale(0);
94
+ -webkit-transform: scale(0);
95
+ -o-transform: scale(0);
96
+ -ms-transform: scale(0);
97
+ transform: scale(0);
98
+ }
99
+ */
libs/iosCheckbox/iosCheckbox.js ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * iosCheckbox.js
3
+ * Version: 1.0.0
4
+ * Author: Ron Masas
5
+ */
6
+ (function($) {
7
+ $.fn.extend({
8
+ iosCheckbox: function() {
9
+ this.destroy = function(){
10
+ $(this).each(function() {
11
+ $(this).next('.ios-ui-select').remove();
12
+ });
13
+ };
14
+
15
+ if ($(this).attr('data-ios-checkbox') === 'true') {
16
+ return;
17
+ }
18
+
19
+ $(this).attr('data-ios-checkbox', 'true');
20
+
21
+ $(this).each(function() {
22
+ /**
23
+ * Original checkbox element
24
+ */
25
+ var org_checkbox = $(this);
26
+ /**
27
+ * iOS checkbox div
28
+ */
29
+ var ios_checkbox = jQuery("<div>", {
30
+ class: 'ios-ui-select'
31
+ }).append(jQuery("<div>", {
32
+ class: 'inner'
33
+ }));
34
+
35
+ // If the original checkbox is checked, add checked class to the ios checkbox.
36
+ if (org_checkbox.is(":checked")) {
37
+ ios_checkbox.addClass("checked");
38
+ }
39
+
40
+ // Hide the original checkbox and print the new one.
41
+ org_checkbox.hide().after(ios_checkbox);
42
+
43
+ if (org_checkbox.is(":disabled")){
44
+ // In case the original checkbox is disabled don't register the click event.
45
+ return ios_checkbox.css('opacity','0.6');
46
+ }
47
+
48
+ // Add click event listener to the ios checkbox
49
+ ios_checkbox.click(function() {
50
+ // Toggel the check state
51
+ ios_checkbox.toggleClass("checked");
52
+ // Check if the ios checkbox is checked
53
+ if (ios_checkbox.hasClass("checked")) {
54
+ // Update state
55
+ org_checkbox.prop('checked', true);
56
+ } else {
57
+ // Update state
58
+ org_checkbox.prop('checked', false);
59
+ }
60
+
61
+ // Run click even in case it was registered to the original checkbox element.
62
+ org_checkbox.click();
63
+ });
64
+ });
65
+ return this;
66
+ }
67
+ });
68
+ })(jQuery);
libs/iosCheckbox/iosCheckbox.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .ios-ui-select{border:none;height:36px;background:#ddd;-webkit-border-radius:18px;border-radius:18px;width:60px;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out;-webkit-box-shadow:none;box-shadow:none;cursor:pointer;position:relative;display:inline-block}.ios-ui-select.checked{-webkit-box-shadow:inset 0 0 0 36px #6ddc5f;box-shadow:inset 0 0 0 36px #6ddc5f}.ios-ui-select.checked .inner{left:27px}.ios-ui-select .inner{width:30px;height:30px;position:absolute;top:3px;left:3px;-webkit-border-radius:100%;border-radius:100%;background:#fff;-webkit-transition:all 350ms cubic-bezier(0,.89,.44,1);-moz-transition:all 350ms cubic-bezier(0,.89,.44,1);-o-transition:all 350ms cubic-bezier(0,.89,.44,1);transition:all 350ms cubic-bezier(0,.89,.44,1);-webkit-box-shadow:0 1px 2px 0 rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.1);box-shadow:0 1px 2px 0 rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.1)}
libs/iosCheckbox/iosCheckbox.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){e.fn.extend({iosCheckbox:function(){if(this.destroy=function(){e(this).each(function(){e(this).next(".ios-ui-select").remove()})},"true"!==e(this).attr("data-ios-checkbox"))return e(this).attr("data-ios-checkbox","true"),e(this).each(function(){var c=e(this),i=jQuery("<div>",{class:"ios-ui-select"}).append(jQuery("<div>",{class:"inner"}));if(c.is(":checked")&&i.addClass("checked"),c.hide().after(i),c.is(":disabled"))return i.css("opacity","0.6");i.click(function(){i.toggleClass("checked"),i.hasClass("checked")?c.prop("checked",!0):c.prop("checked",!1),c.click()})}),this}})}(jQuery);
libs/selectivity-3.1.0/CHANGELOG.md ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CHANGELOG
2
+
3
+ ## 3.1.0
4
+
5
+ - Add `data` property to `change` events.
6
+ - Don't crash when some, but not all, result items have children (#227, thanks to @watsab).
7
+ - Trim template results to avoid runtime errors (#210, thanks to @darekzak).
8
+ - Fix clear button if item text is too long (#211, thanks to @dmarchuk).
9
+ - React: Don't use `componentWillReceiveProps()` for forward compatibility with React 17.
10
+
11
+ ## 3.0.6
12
+
13
+ - Fix updating event listeners after initial render in React API.
14
+ - Rerender single-value inputs when their enabled state changes.
15
+
16
+ ## 3.0.5
17
+
18
+ - Fix issue where dropdown is hard to close on Firefox (#194, thanks to @dmarchuk).
19
+ - Filter selected children from results (#201, thanks to @ne0guille).
20
+ - Move submenu up if otherwise it would fall below the fold of the page.
21
+
22
+ ## 3.0.4
23
+
24
+ - Improved compatibility with React 15.5 (no more deprecation warnings).
25
+ - Improved HTML5 validation support (#188, thanks to @r4z3c).
26
+ - Fix #180: Existing selection highlighted by default on multi-value search results (thanks to
27
+ @ahamid).
28
+ - Fix #177: Don't close dropdown when clicking scrollbar (thanks to @JEkedorff).
29
+
30
+ ## 3.0.3
31
+
32
+ - Fix issue when a single-value Selectivity input is reset to null throught the React API.
33
+
34
+ ## 3.0.2
35
+
36
+ - Fix #161: React API: Value should be re-set when the items change.
37
+
38
+ ## 3.0.1
39
+
40
+ - Fix #156: Don't crash when unsubscribing from non-subscribed event listener.
41
+ - Don't rely on `react-dom-server` in React templates plugin to avoid issues with React 15.4.
42
+ - Fix #158: Expose Selectivity object as `$.Selectivity` in jQuery builds.
43
+ - Yarn compatibility: Get rid of peerDependencies.
44
+
45
+ ## 3.0.0
46
+
47
+ - Made jQuery dependency fully optional.
48
+ - As a result, all callbacks that received jQuery containers as argument(s) now receive plain
49
+ DOM nodes instead.
50
+ - Added optional React API.
51
+ - Fix #128: Added NPM package.
52
+ - Added options:
53
+ - `shouldOpenSubmenu()` - Callback that determines whether a submenu should be opened.
54
+ - `selectable` - Allows to make items unselectable without having to disable them. This is
55
+ mainly useful for items that trigger submenus.
56
+ - Removed Bower and Component support.
57
+ - Moved option validation into its own plugin.
58
+ - Introduced the `"selectivity-change"` event. It's exactly the same as the `"change"` event
59
+ (which is still supported as well) from version 2, but with the added benefit it cannot be
60
+ confused with `"change"` events that bubble from internal `<input>` elements. The React API's
61
+ `onChange` property uses the new event.
62
+ - Rewrote the AJAX plugin:
63
+ - It now relies on the `fetch()` method for performing AJAX requests. This method is only
64
+ available on modern browsers, so you'll need a polyfill if you want to use this with old
65
+ browsers, unless you're using a jQuery build in which case the `jquery/ajax` plugin can
66
+ provide a shim based on `$.ajax()` (requires jQuery 3.0 or higher).
67
+ - Please check the documentation for the new options that can be passed.
68
+ - Renamed the option `suppressMouseWheelSelector` to just `suppressWheelSelector`.
69
+ - Renamed the `Selectivity.InputTypes` map to `Selectivity.Inputs`.
70
+ - Removed dist directory from the repository.
71
+ - Improved submenu positioning by automatically opening them on the left-hand side if there's
72
+ insufficient space on the right side.
73
+ - Improve searching behavior with multiple submenus open.
74
+ - Fix #107: Remove the dropdown after timeout to fix "hover" behavior.
75
+ - Fix #136: Update original `<select>` element on "change" instead of "selectivity-selected".
76
+ - Fix: When a Selectivity instance is clicked but its dropdown should not open, at least it should
77
+ be focused.
78
+ - Fix #144: Properly handle dynamically changing readOnly option.
79
+ - Fix #145: Make sure size detection works outside the DOM (thanks to @Rkokie). Also the
80
+ ".selectivity-width-detector" element is no longer needed.
81
+ - Fix #146: Selectivity created from `<select>` element now uses "s9y\_" prefix for its ID (thanks
82
+ to @dr-itz).
83
+ - Fix: Provide correct offset in pagination when results are filtered.
84
+
85
+ ## 2.1.0
86
+
87
+ - Implemented `disabled` property on items. When an item is disabled it cannot be selected and by
88
+ default is rendered with grey text.
89
+ - PR #63: Fix problem with `closeOnSelect` behavior.
90
+ - PR #80: Added CSS classes for `hover` and `open` states.
91
+ - Fix #66: Respect `removeOnly` option when set after initialization.
92
+ - Fix #67: Pass `queryOptions` to `url` function in AJAX module.
93
+ - Fix #75: Make sure Enter key doesn't submit forms.
94
+ - Fix #93: Make the rerenderSelection() method public and document that `triggerChange: false`
95
+ doesn't automatically update the UI.
96
+ - Fixed issue where the cursor position was constantly reset when using a tokenizer.
97
+ - Miscellaneous smaller fixes and styling tweaks.
98
+
99
+ ## 2.0.0
libs/selectivity-3.1.0/LICENSE ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014-2016 Arend van Beelen jr.
4
+ (c) 2016 Speakap BV
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
23
+
libs/selectivity-3.1.0/README.md ADDED
@@ -0,0 +1,267 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Selectivity.js
2
+
3
+ Modular and light-weight selection library.
4
+
5
+ [![Selectivity on NPM](https://img.shields.io/npm/v/selectivity.svg)](https://www.npmjs.com/package/selectivity)
6
+ [![Build Status](https://travis-ci.org/arendjr/selectivity.svg?branch=master)](https://travis-ci.org/arendjr/selectivity)
7
+ [![Greenkeeper badge](https://badges.greenkeeper.io/arendjr/selectivity.svg)](https://greenkeeper.io/)
8
+
9
+ ## Setup
10
+
11
+ ### Dependencies
12
+
13
+ Selectivity doesn't require any external libraries to be loaded on your page, but it does have some
14
+ optional dependencies:
15
+
16
+ - There's a React build that provides the official Selectivity React API. If you wish to use this,
17
+ [React](https://facebook.github.io/react/) should be loaded on your page.
18
+ - There's a jQuery build that provides the official Selectivity jQuery API. If you wish to use
19
+ this, either [jQuery](http://jquery.com/) or [Zepto.js](http://zeptojs.com/) should be loaded on
20
+ your page.
21
+ - The default templates assume that you have included
22
+ [FontAwesome](http://fortawesome.github.io/Font-Awesome/) in your page to display the icons. If
23
+ you do not want this, please specify custom templates.
24
+
25
+ ### Manual
26
+
27
+ **Warning:** Do you use Browserify or Webpack? Please use Yarn or NPM as described below.
28
+
29
+ Download and unpack the latest release from the project website:
30
+ https://arendjr.github.io/selectivity/
31
+
32
+ Copy the JavaScript and CSS file for your desired build from the archive into your project. See the
33
+ following table to see which files you need:
34
+
35
+ | Build | JavaScript file | CSS file |
36
+ | ------------------------- | ------------------------- | -------------------------- |
37
+ | jQuery (development) | selectivity-jquery.js | selectivity-jquery.css |
38
+ | jQuery (production) | selectivity-jquery.min.js | selectivity-jquery.min.css |
39
+ | React (development) | selectivity-react.js | selectivity-react.css |
40
+ | React (production) | selectivity-react.min.js | selectivity-react.min.css |
41
+ | _VanillaJS_ (development) | selectivity.js | selectivity.css |
42
+ | _VanillaJS_ (production) | selectivity.min.js | selectivity.min.css |
43
+
44
+ Reference the files from your HTML page like this:
45
+
46
+ <head>
47
+ ...
48
+ <link href="font-awesome.css" rel="stylesheet">
49
+ <link href="selectivity.css" rel="stylesheet">
50
+ ...
51
+ <script src="jquery-or-react-or-zepto.js"></script>
52
+ <script src="selectivity.js"></script>
53
+ ...
54
+ </head>
55
+
56
+ Note the first line includes FontAwesome which is required for the default icons. This line is
57
+ optional if you use custom templates.
58
+
59
+ The second line should reference the CSS file from the bundle you chose to use.
60
+
61
+ The third line should reference jQuery, React or Zepto.js as appropriate. This line is optional if
62
+ you use the VanillaJS bundle. _Note: If you want to use the React templates plugin, don't forget to
63
+ also include `react-dom.js`._
64
+
65
+ Finally, the last line should reference the JavaScript file from the bundle you chose to use.
66
+
67
+ You are now ready to start using Selectivity as described on the Selectivity homepage:
68
+ https://arendjr.github.io/selectivity/
69
+
70
+ ### Using Yarn
71
+
72
+ If you have Yarn installed, run:
73
+
74
+ $ yarn add selectivity
75
+
76
+ Note you will need to include the CSS yourself. You can find it in
77
+ `node_modules/selectivity/selectivity.css`.
78
+
79
+ ### Using NPM
80
+
81
+ Make sure you have Node.js installed and run:
82
+
83
+ $ npm install --save selectivity
84
+
85
+ Note you will need to include the CSS yourself. You can find it in
86
+ `node_modules/selectivity/selectivity.css`.
87
+
88
+ #### Which module do I require?
89
+
90
+ You can `require()` Selectivity as follows:
91
+
92
+ var Selectivity = require('selectivity');
93
+
94
+ But, this will only expose the main Selectivity object and will load none of the plugins, nor enable
95
+ any of the specialized APIs. You could say what you're getting is the core of the VanillaJS API.
96
+
97
+ If however, you just want to use the jQuery API with all the relevant plugins loaded, you can do
98
+ this:
99
+
100
+ require('selectivity/jquery');
101
+
102
+ After this you can call the jQuery API as you would expect:
103
+
104
+ $('...').selectivity(/*...*/);
105
+
106
+ Similarly, if you want to use the React API with all its relevant plugins, you can do this:
107
+
108
+ var Selectivity = require('selectivity/react');
109
+
110
+ The Selectivity object you receive is the same one as if you'd required `'selectivity'`, but you get
111
+ the React Component class as `Selectivity.React` so you can use it as follows:
112
+
113
+ <Selectivity.React {...props} />
114
+
115
+ Finally, if you're an expert (\*) you can choose to use the VanillaJS API and enable just the
116
+ plugins you want one by one. For example:
117
+
118
+ var Selectivity = require('selectivity');
119
+ require('selectivity/dropdown');
120
+ require('selectivity/inputs/single');
121
+ require('selectivity/plugins/ajax');
122
+ require('selectivity/plugins/async');
123
+ require('selectivity/plugins/submenu');
124
+
125
+ var singleInput = new Selectivity.Inputs.Single({
126
+ element: document.querySelector('...'),
127
+ /*...*/
128
+ });
129
+
130
+ All the modules listed in the table below under _Creating custom builds_ can be required this way.
131
+
132
+ \*) Using the VanillaJS API isn't really that hard, but all the examples and documentation assume
133
+ you're using either the React or the jQuery API, so be prepared that you'll have to figure out a bit
134
+ more on your own.
135
+
136
+ ### Ruby on Rails
137
+
138
+ Detailed information for `selectivity-rails`, including
139
+ [Installation and usage](https://github.com/msx2/selectivity-rails#installation-and-usage) are
140
+ provided in the [gem's repository](https://github.com/msx2/selectivity-rails).
141
+
142
+ ### Customization
143
+
144
+ Once installed, you may want to customize Selectivity. For example, by specifying custom templates
145
+ or localized strings. While creating a custom build is always an option (see details below), easier
146
+ options exist.
147
+
148
+ To do any basic customization, you'll need a reference to the `Selectivity` object. If you have
149
+ installed through Yarn/NPM, you can get this object through
150
+ `var Selectivity = require('selectivity');`. If you're using a jQuery build, the object is exposed
151
+ as `$.Selectivity`. For non-jQuery builds that you included as a script, the object is exposed as
152
+ global variable.
153
+
154
+ #### Example: Customizing localization in a jQuery build
155
+
156
+ $.Selectivity.Locale.noResultsForTerm = function(term) {
157
+ return 'No results were found for <b>' + escape(term) + '</b>';
158
+ };
159
+
160
+ See [locale.js](https://github.com/arendjr/selectivity/blob/master/src/locale.js) for an overview of
161
+ all localizable messages.
162
+
163
+ #### Example: Specifying a custom template when installed through NPM
164
+
165
+ var Selectivity = require('selectivity');
166
+ Selectivity.Templates.loading = function() {
167
+ return '<div class="selectivity-loading"><div class="my-spinner"></div></div>';
168
+ };
169
+
170
+ See [templates.js](https://github.com/arendjr/selectivity/blob/master/src/templates.js) for an
171
+ overview of all templates that can be customized.
172
+
173
+ ## API
174
+
175
+ For usage instructions, please see the Selectivity homepage: https://arendjr.github.io/selectivity/
176
+
177
+ ## Browser Support
178
+
179
+ - Chrome
180
+ - Firefox
181
+ - Internet Explorer 10+
182
+ - Safari 6+
183
+
184
+ Note that while Internet Explorer versions older than 10 are not supported, you might be able to get
185
+ them to work, possibly with the use of some polyfills. Reports of success or patches to create a
186
+ "legacy" build would be welcomed.
187
+
188
+ ## Build System
189
+
190
+ Selectivity is built modularly and uses Yarn and Gulp as a build system to build its distributable
191
+ files. Make sure you have the `yarn` command globally available and make sure you have the `sass`
192
+ Gem installed. Then, inside the project directory, run:
193
+
194
+ $ yarn
195
+
196
+ Now you can generate new distributable files from the sources, using:
197
+
198
+ $ yarn build
199
+
200
+ ### Creating custom builds
201
+
202
+ If you want to create your own Selectivity library that contains just the modules you need, you can
203
+ use the following command:
204
+
205
+ $ yarn gulp [--api=<react-or-jquery>] --modules=<comma-separated-module-list>
206
+
207
+ The following modules are available:
208
+
209
+ | Module | Description |
210
+ | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
211
+ | **inputs/email** | Implements the 'Email' input type. This is a special case of the 'Multiple' input type with no dropdown and a specialized tokenizer for recognizing email addresses (including pasted content from address books). |
212
+ | **inputs/multiple** | Implements the 'Multiple' input type. If you only want to use Selectivity with single values, you can leave this out. |
213
+ | **inputs/single** | Implements the 'Single' input type. If you only want to use Selectivity with multiple values, you can leave this out. |
214
+ | **plugins/ajax** | Convenience module for performing AJAX requests. Needed if you want to use any `ajax` options. If you use this module, you should also include the 'async' module to correctly handle out-of-order replies. This module relies on the presence of the `[fetch()](https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch)` method which is only available in modern browsers, so you should either provide a polyfill if you want to support older browsers, or -- if you're creating a jQuery build -- you can use the 'jquery/ajax' module to provide a fallback that uses `$.ajax()` instead. |
215
+ | **plugins/async** | Blocks the query function from calling its callback functions if another query has been issued since. This prevents out-of-order replies from remote sources to display incorrect results. This module is only needed if you use the query function and call its callbacks asynchronously. |
216
+ | **plugins/diacritics** | Diacritics support. This will make sure that `"Łódź"` will match when the user searches for `"Lodz"`, for example. However, if you always query a server when searching for results, you may want to solve matching of diacritics server-side, in which case this module can be omitted. |
217
+ | **plugins/keyboard** | Provides keyboard support for navigating through the dropdown. If you don't use a dropdown, or are only targeting mobile, you may want to leave this module out. |
218
+ | **plugins/submenu** | Extends the default dropdown so that multiple levels of submenus can be created. |
219
+ | **plugins/tokenizer** | Default tokenizer implementation. This module adds support for the `tokenSeparators` option which is used by the default tokenizer. Support for tokenizers themselves is already included in the "multiple" module, so you can omit this module if you don't want to use any tokenizers or want to specify your own tokenizer. |
220
+ | **plugins/jquery/ajax** | Provides a fallback to use `$.ajax()` instead of the `fetch()` method for performing AJAX requests. _(Requires jQuery 3.0 or higher)_ |
221
+ | **plugins/jquery/traditional** | This module allows you to convert an HTML5 `<select>` form element into a Selectivity instance. The items will be initialized from the `<option>` and `<optgroup>` elements. _(jQuery only)_ |
222
+ | **plugins/react/templates** | Adds support for React (JSX) templates. Requires `react-dom` to be available. |
223
+ | **dropdown** | Module that implements the dropdown. You will most likely want to include this, unless you only want to use Selectivity without any dropdown or you provide a completely custom implementation instead. |
224
+ | **locale** | Localizable content pulled in by the default templates. You may or may not decide to use these with your own templates. Also used for localizable messages by the ajax module. |
225
+ | **templates** | Default templates to use with Selectivity. If you provide your own templates, you may want to skip this. |
226
+
227
+ Note that the build system automatically resolves dependencies between modules. So for example, if
228
+ you specify you want the submenu plugin, the dropdown module will be automatically included.
229
+
230
+ Example:
231
+
232
+ $ yarn gulp --api=react --modules=inputs/multiple,dropdown
233
+
234
+ This will create a custom build that uses the React API and which has support for selecting multiple
235
+ values with a dropdown. The build will be saved in `build/selectivity-custom.js`. There will be no
236
+ plugins available, you will have to provide your own templates with their localizable content, and
237
+ you cannot use this build for creating a single-select input.
238
+
239
+ To display any other options available for custom builds, run `gulp usage`.
240
+
241
+ ### Development server
242
+
243
+ While developing, you can start a development server like this:
244
+
245
+ $ yarn start [--api=<jquery-or-react>]
246
+
247
+ You may want to pass the `--source-map` parameter to generate a source map for debugging. Check out
248
+ the various files in the `demos/` directory that are set up to with custom builds as they can be
249
+ used for development.
250
+
251
+ ## Unit Tests
252
+
253
+ Unit tests are available and can be ran using the following command:
254
+
255
+ $ yarn unit-tests
256
+
257
+ If you want to run an individual test, just add `--test=<test-name>`. Simply provide an invalid test
258
+ name to get a list of all available test names.
259
+
260
+ ## License
261
+
262
+ Selectivity is made available under the [MIT license](LICENSE).
263
+
264
+ ## Contributing
265
+
266
+ To read more about guidelines for submitting pull requests, please read the
267
+ [Contributing document](CONTRIBUTING.md).
libs/selectivity-3.1.0/selectivity-jquery.css ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * All CSS that comes with Selectivity.js can be used as is, or tweaked to your heart's content :)
3
+ *
4
+ * Please realize though there is no "API contract" regarding styling of CSS classes, meaning that
5
+ * any customized CSS made may need to be updated without warning if you want to upgrade the
6
+ * Selectivity version you use. You can mitigate this problem by using your own templates instead of
7
+ * those defined in src/templates.js, since templates will at the very least continue working across
8
+ * patch versions and any changes necessary to templates will be documented in the changelog.
9
+ */
10
+ .selectivity-clearfix {
11
+ clear: both; }
12
+
13
+ .selectivity-input {
14
+ display: inline-block;
15
+ width: 250px; }
16
+ .selectivity-input select {
17
+ display: none; }
18
+
19
+ .selectivity-input:focus {
20
+ outline: none; }
21
+
22
+ .selectivity-placeholder {
23
+ color: #999; }
24
+
25
+ /**
26
+ * Dropdown
27
+ */
28
+ .selectivity-dropdown {
29
+ background: #fff;
30
+ border-radius: 4px;
31
+ -webkit-box-shadow: 0 1px 5px 1px rgba(0, 0, 0, 0.15), 0 10px 16px 0 rgba(0, 0, 0, 0.2);
32
+ box-shadow: 0 1px 5px 1px rgba(0, 0, 0, 0.15), 0 10px 16px 0 rgba(0, 0, 0, 0.2);
33
+ position: fixed;
34
+ z-index: 1046; }
35
+
36
+ .selectivity-search-input-container {
37
+ border-bottom: 1px solid #eee; }
38
+
39
+ .selectivity-search-input {
40
+ background: transparent;
41
+ border: 0;
42
+ outline: 0;
43
+ width: 100%; }
44
+
45
+ .selectivity-results-container {
46
+ max-height: 28em;
47
+ overflow: auto;
48
+ position: relative; }
49
+
50
+ .selectivity-load-more,
51
+ .selectivity-result-item {
52
+ cursor: pointer;
53
+ padding: 7px; }
54
+
55
+ .selectivity-result-children .selectivity-result-item {
56
+ padding-left: 17px; }
57
+
58
+ .selectivity-load-more.highlight,
59
+ .selectivity-result-item.highlight {
60
+ background: #4484c7;
61
+ color: #fff; }
62
+
63
+ .selectivity-result-item.disabled {
64
+ cursor: default;
65
+ color: #999; }
66
+
67
+ .selectivity-result-item:first-child {
68
+ border-radius: 4px 4px 0 0; }
69
+
70
+ .selectivity-dropdown.has-search-input .selectivity-result-item:first-child {
71
+ border-radius: 0; }
72
+
73
+ .selectivity-result-label {
74
+ font-weight: bold; }
75
+
76
+ .selectivity-load-more,
77
+ .selectivity-result-item:last-child,
78
+ .selectivity-result-children:last-child .selectivity-result-item:last-child {
79
+ border-radius: 0 0 4px 4px; }
80
+
81
+ .selectivity-result-children .selectivity-result-item:last-child {
82
+ border-radius: 0; }
83
+
84
+ .selectivity-error,
85
+ .selectivity-loading,
86
+ .selectivity-search-input-container,
87
+ .selectivity-result-label {
88
+ padding: 7px; }
89
+
90
+ /**
91
+ * Multi-selection input
92
+ */
93
+ .selectivity-multiple-input-container {
94
+ background: #eee;
95
+ border-radius: 2px;
96
+ cursor: text;
97
+ max-height: 10em;
98
+ min-height: calc(2em + 4px);
99
+ overflow: auto;
100
+ padding: 5px; }
101
+
102
+ .selectivity-multiple-input-container .selectivity-placeholder {
103
+ height: calc(2em + 4px);
104
+ line-height: calc(2em + 4px); }
105
+
106
+ .selectivity-multiple-input,
107
+ input[type='text'].selectivity-multiple-input {
108
+ background-color: transparent;
109
+ border: none;
110
+ float: left;
111
+ font: inherit;
112
+ height: calc(2em + 4px);
113
+ max-width: 100%;
114
+ outline: 0;
115
+ padding: 0; }
116
+ .selectivity-multiple-input:focus,
117
+ input[type='text'].selectivity-multiple-input:focus {
118
+ background-color: transparent;
119
+ -webkit-box-shadow: none;
120
+ box-shadow: none;
121
+ outline: none; }
122
+
123
+ .selectivity-multiple-input::-ms-clear {
124
+ display: none; }
125
+
126
+ .selectivity-multiple-selected-item {
127
+ background: #4484c7;
128
+ border-radius: 3px;
129
+ color: #fff;
130
+ cursor: default;
131
+ float: left;
132
+ line-height: 2em;
133
+ margin: 2px;
134
+ padding: 0 5px;
135
+ position: relative;
136
+ -moz-user-select: none;
137
+ -ms-user-select: none;
138
+ -webkit-user-select: none;
139
+ user-select: none;
140
+ white-space: nowrap; }
141
+ .selectivity-multiple-selected-item.highlighted {
142
+ background-color: #ccc; }
143
+
144
+ .selectivity-multiple-selected-item-remove {
145
+ color: #fff;
146
+ cursor: pointer;
147
+ margin-left: -5px;
148
+ padding: 5px; }
149
+
150
+ /**
151
+ * Single-selection input
152
+ */
153
+ .selectivity-single-select {
154
+ background: #eee;
155
+ border-radius: 2px;
156
+ cursor: pointer;
157
+ min-height: 2em;
158
+ padding: 5px;
159
+ position: relative;
160
+ -webkit-box-sizing: content-box;
161
+ box-sizing: content-box; }
162
+
163
+ .selectivity-single-select-input {
164
+ opacity: 0; }
165
+
166
+ .selectivity-single-result-container {
167
+ position: absolute;
168
+ top: 0.8em;
169
+ right: 15px;
170
+ left: 5px;
171
+ overflow: hidden;
172
+ -o-text-overflow: ellipsis;
173
+ text-overflow: ellipsis;
174
+ white-space: nowrap; }
175
+
176
+ .selectivity-single-selected-item {
177
+ color: #000; }
178
+
179
+ .selectivity-single-selected-item-remove {
180
+ color: #000;
181
+ float: right;
182
+ padding: 0 5px;
183
+ position: relative;
184
+ z-index: 1; }
185
+
186
+ .selectivity-caret {
187
+ position: absolute;
188
+ right: 5px;
189
+ top: 0.7em; }
190
+
191
+ @media only screen and (max-device-width: 480px) {
192
+ .selectivity-single-select {
193
+ background: #eee;
194
+ border-radius: 2px; }
195
+
196
+ .selectivity-single-result-container {
197
+ right: 5px; }
198
+
199
+ .selectivity-caret {
200
+ display: none; } }
201
+ /**
202
+ * Submenu
203
+ */
204
+ .selectivity-submenu-icon {
205
+ position: absolute;
206
+ right: 4px; }
libs/selectivity-3.1.0/selectivity-jquery.js ADDED
@@ -0,0 +1,5497 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @license
3
+ * Selectivity.js 3.1.0 <https://arendjr.github.io/selectivity/>
4
+ * Copyright (c) 2014-2016 Arend van Beelen jr.
5
+ * (c) 2016 Speakap BV
6
+ * Available under MIT license <https://github.com/arendjr/selectivity/blob/master/LICENSE>
7
+ */
8
+ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.selectivity = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
9
+ var root = _dereq_(10);
10
+
11
+ /** Built-in value references. */
12
+ var Symbol = root.Symbol;
13
+
14
+ module.exports = Symbol;
15
+
16
+ },{"10":10}],2:[function(_dereq_,module,exports){
17
+ /**
18
+ * A specialized version of `_.map` for arrays without support for iteratee
19
+ * shorthands.
20
+ *
21
+ * @private
22
+ * @param {Array} [array] The array to iterate over.
23
+ * @param {Function} iteratee The function invoked per iteration.
24
+ * @returns {Array} Returns the new mapped array.
25
+ */
26
+ function arrayMap(array, iteratee) {
27
+ var index = -1,
28
+ length = array == null ? 0 : array.length,
29
+ result = Array(length);
30
+
31
+ while (++index < length) {
32
+ result[index] = iteratee(array[index], index, array);
33
+ }
34
+ return result;
35
+ }
36
+
37
+ module.exports = arrayMap;
38
+
39
+ },{}],3:[function(_dereq_,module,exports){
40
+ var Symbol = _dereq_(1),
41
+ getRawTag = _dereq_(8),
42
+ objectToString = _dereq_(9);
43
+
44
+ /** `Object#toString` result references. */
45
+ var nullTag = '[object Null]',
46
+ undefinedTag = '[object Undefined]';
47
+
48
+ /** Built-in value references. */
49
+ var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
50
+
51
+ /**
52
+ * The base implementation of `getTag` without fallbacks for buggy environments.
53
+ *
54
+ * @private
55
+ * @param {*} value The value to query.
56
+ * @returns {string} Returns the `toStringTag`.
57
+ */
58
+ function baseGetTag(value) {
59
+ if (value == null) {
60
+ return value === undefined ? undefinedTag : nullTag;
61
+ }
62
+ return (symToStringTag && symToStringTag in Object(value))
63
+ ? getRawTag(value)
64
+ : objectToString(value);
65
+ }
66
+
67
+ module.exports = baseGetTag;
68
+
69
+ },{"1":1,"8":8,"9":9}],4:[function(_dereq_,module,exports){
70
+ /**
71
+ * The base implementation of `_.propertyOf` without support for deep paths.
72
+ *
73
+ * @private
74
+ * @param {Object} object The object to query.
75
+ * @returns {Function} Returns the new accessor function.
76
+ */
77
+ function basePropertyOf(object) {
78
+ return function(key) {
79
+ return object == null ? undefined : object[key];
80
+ };
81
+ }
82
+
83
+ module.exports = basePropertyOf;
84
+
85
+ },{}],5:[function(_dereq_,module,exports){
86
+ var Symbol = _dereq_(1),
87
+ arrayMap = _dereq_(2),
88
+ isArray = _dereq_(13),
89
+ isSymbol = _dereq_(17);
90
+
91
+ /** Used as references for various `Number` constants. */
92
+ var INFINITY = 1 / 0;
93
+
94
+ /** Used to convert symbols to primitives and strings. */
95
+ var symbolProto = Symbol ? Symbol.prototype : undefined,
96
+ symbolToString = symbolProto ? symbolProto.toString : undefined;
97
+
98
+ /**
99
+ * The base implementation of `_.toString` which doesn't convert nullish
100
+ * values to empty strings.
101
+ *
102
+ * @private
103
+ * @param {*} value The value to process.
104
+ * @returns {string} Returns the string.
105
+ */
106
+ function baseToString(value) {
107
+ // Exit early for strings to avoid a performance hit in some environments.
108
+ if (typeof value == 'string') {
109
+ return value;
110
+ }
111
+ if (isArray(value)) {
112
+ // Recursively convert values (susceptible to call stack limits).
113
+ return arrayMap(value, baseToString) + '';
114
+ }
115
+ if (isSymbol(value)) {
116
+ return symbolToString ? symbolToString.call(value) : '';
117
+ }
118
+ var result = (value + '');
119
+ return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
120
+ }
121
+
122
+ module.exports = baseToString;
123
+
124
+ },{"1":1,"13":13,"17":17,"2":2}],6:[function(_dereq_,module,exports){
125
+ var basePropertyOf = _dereq_(4);
126
+
127
+ /** Used to map characters to HTML entities. */
128
+ var htmlEscapes = {
129
+ '&': '&amp;',
130
+ '<': '&lt;',
131
+ '>': '&gt;',
132
+ '"': '&quot;',
133
+ "'": '&#39;'
134
+ };
135
+
136
+ /**
137
+ * Used by `_.escape` to convert characters to HTML entities.
138
+ *
139
+ * @private
140
+ * @param {string} chr The matched character to escape.
141
+ * @returns {string} Returns the escaped character.
142
+ */
143
+ var escapeHtmlChar = basePropertyOf(htmlEscapes);
144
+
145
+ module.exports = escapeHtmlChar;
146
+
147
+ },{"4":4}],7:[function(_dereq_,module,exports){
148
+ (function (global){
149
+ /** Detect free variable `global` from Node.js. */
150
+ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
151
+
152
+ module.exports = freeGlobal;
153
+
154
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
155
+ },{}],8:[function(_dereq_,module,exports){
156
+ var Symbol = _dereq_(1);
157
+
158
+ /** Used for built-in method references. */
159
+ var objectProto = Object.prototype;
160
+
161
+ /** Used to check objects for own properties. */
162
+ var hasOwnProperty = objectProto.hasOwnProperty;
163
+
164
+ /**
165
+ * Used to resolve the
166
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
167
+ * of values.
168
+ */
169
+ var nativeObjectToString = objectProto.toString;
170
+
171
+ /** Built-in value references. */
172
+ var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
173
+
174
+ /**
175
+ * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
176
+ *
177
+ * @private
178
+ * @param {*} value The value to query.
179
+ * @returns {string} Returns the raw `toStringTag`.
180
+ */
181
+ function getRawTag(value) {
182
+ var isOwn = hasOwnProperty.call(value, symToStringTag),
183
+ tag = value[symToStringTag];
184
+
185
+ try {
186
+ value[symToStringTag] = undefined;
187
+ var unmasked = true;
188
+ } catch (e) {}
189
+
190
+ var result = nativeObjectToString.call(value);
191
+ if (unmasked) {
192
+ if (isOwn) {
193
+ value[symToStringTag] = tag;
194
+ } else {
195
+ delete value[symToStringTag];
196
+ }
197
+ }
198
+ return result;
199
+ }
200
+
201
+ module.exports = getRawTag;
202
+
203
+ },{"1":1}],9:[function(_dereq_,module,exports){
204
+ /** Used for built-in method references. */
205
+ var objectProto = Object.prototype;
206
+
207
+ /**
208
+ * Used to resolve the
209
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
210
+ * of values.
211
+ */
212
+ var nativeObjectToString = objectProto.toString;
213
+
214
+ /**
215
+ * Converts `value` to a string using `Object.prototype.toString`.
216
+ *
217
+ * @private
218
+ * @param {*} value The value to convert.
219
+ * @returns {string} Returns the converted string.
220
+ */
221
+ function objectToString(value) {
222
+ return nativeObjectToString.call(value);
223
+ }
224
+
225
+ module.exports = objectToString;
226
+
227
+ },{}],10:[function(_dereq_,module,exports){
228
+ var freeGlobal = _dereq_(7);
229
+
230
+ /** Detect free variable `self`. */
231
+ var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
232
+
233
+ /** Used as a reference to the global object. */
234
+ var root = freeGlobal || freeSelf || Function('return this')();
235
+
236
+ module.exports = root;
237
+
238
+ },{"7":7}],11:[function(_dereq_,module,exports){
239
+ var isObject = _dereq_(14),
240
+ now = _dereq_(18),
241
+ toNumber = _dereq_(19);
242
+
243
+ /** Error message constants. */
244
+ var FUNC_ERROR_TEXT = 'Expected a function';
245
+
246
+ /* Built-in method references for those with the same name as other `lodash` methods. */
247
+ var nativeMax = Math.max,
248
+ nativeMin = Math.min;
249
+
250
+ /**
251
+ * Creates a debounced function that delays invoking `func` until after `wait`
252
+ * milliseconds have elapsed since the last time the debounced function was
253
+ * invoked. The debounced function comes with a `cancel` method to cancel
254
+ * delayed `func` invocations and a `flush` method to immediately invoke them.
255
+ * Provide `options` to indicate whether `func` should be invoked on the
256
+ * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
257
+ * with the last arguments provided to the debounced function. Subsequent
258
+ * calls to the debounced function return the result of the last `func`
259
+ * invocation.
260
+ *
261
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is
262
+ * invoked on the trailing edge of the timeout only if the debounced function
263
+ * is invoked more than once during the `wait` timeout.
264
+ *
265
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
266
+ * until to the next tick, similar to `setTimeout` with a timeout of `0`.
267
+ *
268
+ * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
269
+ * for details over the differences between `_.debounce` and `_.throttle`.
270
+ *
271
+ * @static
272
+ * @memberOf _
273
+ * @since 0.1.0
274
+ * @category Function
275
+ * @param {Function} func The function to debounce.
276
+ * @param {number} [wait=0] The number of milliseconds to delay.
277
+ * @param {Object} [options={}] The options object.
278
+ * @param {boolean} [options.leading=false]
279
+ * Specify invoking on the leading edge of the timeout.
280
+ * @param {number} [options.maxWait]
281
+ * The maximum time `func` is allowed to be delayed before it's invoked.
282
+ * @param {boolean} [options.trailing=true]
283
+ * Specify invoking on the trailing edge of the timeout.
284
+ * @returns {Function} Returns the new debounced function.
285
+ * @example
286
+ *
287
+ * // Avoid costly calculations while the window size is in flux.
288
+ * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
289
+ *
290
+ * // Invoke `sendMail` when clicked, debouncing subsequent calls.
291
+ * jQuery(element).on('click', _.debounce(sendMail, 300, {
292
+ * 'leading': true,
293
+ * 'trailing': false
294
+ * }));
295
+ *
296
+ * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
297
+ * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
298
+ * var source = new EventSource('/stream');
299
+ * jQuery(source).on('message', debounced);
300
+ *
301
+ * // Cancel the trailing debounced invocation.
302
+ * jQuery(window).on('popstate', debounced.cancel);
303
+ */
304
+ function debounce(func, wait, options) {
305
+ var lastArgs,
306
+ lastThis,
307
+ maxWait,
308
+ result,
309
+ timerId,
310
+ lastCallTime,
311
+ lastInvokeTime = 0,
312
+ leading = false,
313
+ maxing = false,
314
+ trailing = true;
315
+
316
+ if (typeof func != 'function') {
317
+ throw new TypeError(FUNC_ERROR_TEXT);
318
+ }
319
+ wait = toNumber(wait) || 0;
320
+ if (isObject(options)) {
321
+ leading = !!options.leading;
322
+ maxing = 'maxWait' in options;
323
+ maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
324
+ trailing = 'trailing' in options ? !!options.trailing : trailing;
325
+ }
326
+
327
+ function invokeFunc(time) {
328
+ var args = lastArgs,
329
+ thisArg = lastThis;
330
+
331
+ lastArgs = lastThis = undefined;
332
+ lastInvokeTime = time;
333
+ result = func.apply(thisArg, args);
334
+ return result;
335
+ }
336
+
337
+ function leadingEdge(time) {
338
+ // Reset any `maxWait` timer.
339
+ lastInvokeTime = time;
340
+ // Start the timer for the trailing edge.
341
+ timerId = setTimeout(timerExpired, wait);
342
+ // Invoke the leading edge.
343
+ return leading ? invokeFunc(time) : result;
344
+ }
345
+
346
+ function remainingWait(time) {
347
+ var timeSinceLastCall = time - lastCallTime,
348
+ timeSinceLastInvoke = time - lastInvokeTime,
349
+ result = wait - timeSinceLastCall;
350
+
351
+ return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
352
+ }
353
+
354
+ function shouldInvoke(time) {
355
+ var timeSinceLastCall = time - lastCallTime,
356
+ timeSinceLastInvoke = time - lastInvokeTime;
357
+
358
+ // Either this is the first call, activity has stopped and we're at the
359
+ // trailing edge, the system time has gone backwards and we're treating
360
+ // it as the trailing edge, or we've hit the `maxWait` limit.
361
+ return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
362
+ (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
363
+ }
364
+
365
+ function timerExpired() {
366
+ var time = now();
367
+ if (shouldInvoke(time)) {
368
+ return trailingEdge(time);
369
+ }
370
+ // Restart the timer.
371
+ timerId = setTimeout(timerExpired, remainingWait(time));
372
+ }
373
+
374
+ function trailingEdge(time) {
375
+ timerId = undefined;
376
+
377
+ // Only invoke if we have `lastArgs` which means `func` has been
378
+ // debounced at least once.
379
+ if (trailing && lastArgs) {
380
+ return invokeFunc(time);
381
+ }
382
+ lastArgs = lastThis = undefined;
383
+ return result;
384
+ }
385
+
386
+ function cancel() {
387
+ if (timerId !== undefined) {
388
+ clearTimeout(timerId);
389
+ }
390
+ lastInvokeTime = 0;
391
+ lastArgs = lastCallTime = lastThis = timerId = undefined;
392
+ }
393
+
394
+ function flush() {
395
+ return timerId === undefined ? result : trailingEdge(now());
396
+ }
397
+
398
+ function debounced() {
399
+ var time = now(),
400
+ isInvoking = shouldInvoke(time);
401
+
402
+ lastArgs = arguments;
403
+ lastThis = this;
404
+ lastCallTime = time;
405
+
406
+ if (isInvoking) {
407
+ if (timerId === undefined) {
408
+ return leadingEdge(lastCallTime);
409
+ }
410
+ if (maxing) {
411
+ // Handle invocations in a tight loop.
412
+ timerId = setTimeout(timerExpired, wait);
413
+ return invokeFunc(lastCallTime);
414
+ }
415
+ }
416
+ if (timerId === undefined) {
417
+ timerId = setTimeout(timerExpired, wait);
418
+ }
419
+ return result;
420
+ }
421
+ debounced.cancel = cancel;
422
+ debounced.flush = flush;
423
+ return debounced;
424
+ }
425
+
426
+ module.exports = debounce;
427
+
428
+ },{"14":14,"18":18,"19":19}],12:[function(_dereq_,module,exports){
429
+ var escapeHtmlChar = _dereq_(6),
430
+ toString = _dereq_(20);
431
+
432
+ /** Used to match HTML entities and HTML characters. */
433
+ var reUnescapedHtml = /[&<>"']/g,
434
+ reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
435
+
436
+ /**
437
+ * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
438
+ * corresponding HTML entities.
439
+ *
440
+ * **Note:** No other characters are escaped. To escape additional
441
+ * characters use a third-party library like [_he_](https://mths.be/he).
442
+ *
443
+ * Though the ">" character is escaped for symmetry, characters like
444
+ * ">" and "/" don't need escaping in HTML and have no special meaning
445
+ * unless they're part of a tag or unquoted attribute value. See
446
+ * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
447
+ * (under "semi-related fun fact") for more details.
448
+ *
449
+ * When working with HTML you should always
450
+ * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
451
+ * XSS vectors.
452
+ *
453
+ * @static
454
+ * @since 0.1.0
455
+ * @memberOf _
456
+ * @category String
457
+ * @param {string} [string=''] The string to escape.
458
+ * @returns {string} Returns the escaped string.
459
+ * @example
460
+ *
461
+ * _.escape('fred, barney, & pebbles');
462
+ * // => 'fred, barney, &amp; pebbles'
463
+ */
464
+ function escape(string) {
465
+ string = toString(string);
466
+ return (string && reHasUnescapedHtml.test(string))
467
+ ? string.replace(reUnescapedHtml, escapeHtmlChar)
468
+ : string;
469
+ }
470
+
471
+ module.exports = escape;
472
+
473
+ },{"20":20,"6":6}],13:[function(_dereq_,module,exports){
474
+ /**
475
+ * Checks if `value` is classified as an `Array` object.
476
+ *
477
+ * @static
478
+ * @memberOf _
479
+ * @since 0.1.0
480
+ * @category Lang
481
+ * @param {*} value The value to check.
482
+ * @returns {boolean} Returns `true` if `value` is an array, else `false`.
483
+ * @example
484
+ *
485
+ * _.isArray([1, 2, 3]);
486
+ * // => true
487
+ *
488
+ * _.isArray(document.body.children);
489
+ * // => false
490
+ *
491
+ * _.isArray('abc');
492
+ * // => false
493
+ *
494
+ * _.isArray(_.noop);
495
+ * // => false
496
+ */
497
+ var isArray = Array.isArray;
498
+
499
+ module.exports = isArray;
500
+
501
+ },{}],14:[function(_dereq_,module,exports){
502
+ /**
503
+ * Checks if `value` is the
504
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
505
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
506
+ *
507
+ * @static
508
+ * @memberOf _
509
+ * @since 0.1.0
510
+ * @category Lang
511
+ * @param {*} value The value to check.
512
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
513
+ * @example
514
+ *
515
+ * _.isObject({});
516
+ * // => true
517
+ *
518
+ * _.isObject([1, 2, 3]);
519
+ * // => true
520
+ *
521
+ * _.isObject(_.noop);
522
+ * // => true
523
+ *
524
+ * _.isObject(null);
525
+ * // => false
526
+ */
527
+ function isObject(value) {
528
+ var type = typeof value;
529
+ return value != null && (type == 'object' || type == 'function');
530
+ }
531
+
532
+ module.exports = isObject;
533
+
534
+ },{}],15:[function(_dereq_,module,exports){
535
+ /**
536
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
537
+ * and has a `typeof` result of "object".
538
+ *
539
+ * @static
540
+ * @memberOf _
541
+ * @since 4.0.0
542
+ * @category Lang
543
+ * @param {*} value The value to check.
544
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
545
+ * @example
546
+ *
547
+ * _.isObjectLike({});
548
+ * // => true
549
+ *
550
+ * _.isObjectLike([1, 2, 3]);
551
+ * // => true
552
+ *
553
+ * _.isObjectLike(_.noop);
554
+ * // => false
555
+ *
556
+ * _.isObjectLike(null);
557
+ * // => false
558
+ */
559
+ function isObjectLike(value) {
560
+ return value != null && typeof value == 'object';
561
+ }
562
+
563
+ module.exports = isObjectLike;
564
+
565
+ },{}],16:[function(_dereq_,module,exports){
566
+ var baseGetTag = _dereq_(3),
567
+ isArray = _dereq_(13),
568
+ isObjectLike = _dereq_(15);
569
+
570
+ /** `Object#toString` result references. */
571
+ var stringTag = '[object String]';
572
+
573
+ /**
574
+ * Checks if `value` is classified as a `String` primitive or object.
575
+ *
576
+ * @static
577
+ * @since 0.1.0
578
+ * @memberOf _
579
+ * @category Lang
580
+ * @param {*} value The value to check.
581
+ * @returns {boolean} Returns `true` if `value` is a string, else `false`.
582
+ * @example
583
+ *
584
+ * _.isString('abc');
585
+ * // => true
586
+ *
587
+ * _.isString(1);
588
+ * // => false
589
+ */
590
+ function isString(value) {
591
+ return typeof value == 'string' ||
592
+ (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
593
+ }
594
+
595
+ module.exports = isString;
596
+
597
+ },{"13":13,"15":15,"3":3}],17:[function(_dereq_,module,exports){
598
+ var baseGetTag = _dereq_(3),
599
+ isObjectLike = _dereq_(15);
600
+
601
+ /** `Object#toString` result references. */
602
+ var symbolTag = '[object Symbol]';
603
+
604
+ /**
605
+ * Checks if `value` is classified as a `Symbol` primitive or object.
606
+ *
607
+ * @static
608
+ * @memberOf _
609
+ * @since 4.0.0
610
+ * @category Lang
611
+ * @param {*} value The value to check.
612
+ * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
613
+ * @example
614
+ *
615
+ * _.isSymbol(Symbol.iterator);
616
+ * // => true
617
+ *
618
+ * _.isSymbol('abc');
619
+ * // => false
620
+ */
621
+ function isSymbol(value) {
622
+ return typeof value == 'symbol' ||
623
+ (isObjectLike(value) && baseGetTag(value) == symbolTag);
624
+ }
625
+
626
+ module.exports = isSymbol;
627
+
628
+ },{"15":15,"3":3}],18:[function(_dereq_,module,exports){
629
+ var root = _dereq_(10);
630
+
631
+ /**
632
+ * Gets the timestamp of the number of milliseconds that have elapsed since
633
+ * the Unix epoch (1 January 1970 00:00:00 UTC).
634
+ *
635
+ * @static
636
+ * @memberOf _
637
+ * @since 2.4.0
638
+ * @category Date
639
+ * @returns {number} Returns the timestamp.
640
+ * @example
641
+ *
642
+ * _.defer(function(stamp) {
643
+ * console.log(_.now() - stamp);
644
+ * }, _.now());
645
+ * // => Logs the number of milliseconds it took for the deferred invocation.
646
+ */
647
+ var now = function() {
648
+ return root.Date.now();
649
+ };
650
+
651
+ module.exports = now;
652
+
653
+ },{"10":10}],19:[function(_dereq_,module,exports){
654
+ var isObject = _dereq_(14),
655
+ isSymbol = _dereq_(17);
656
+
657
+ /** Used as references for various `Number` constants. */
658
+ var NAN = 0 / 0;
659
+
660
+ /** Used to match leading and trailing whitespace. */
661
+ var reTrim = /^\s+|\s+$/g;
662
+
663
+ /** Used to detect bad signed hexadecimal string values. */
664
+ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
665
+
666
+ /** Used to detect binary string values. */
667
+ var reIsBinary = /^0b[01]+$/i;
668
+
669
+ /** Used to detect octal string values. */
670
+ var reIsOctal = /^0o[0-7]+$/i;
671
+
672
+ /** Built-in method references without a dependency on `root`. */
673
+ var freeParseInt = parseInt;
674
+
675
+ /**
676
+ * Converts `value` to a number.
677
+ *
678
+ * @static
679
+ * @memberOf _
680
+ * @since 4.0.0
681
+ * @category Lang
682
+ * @param {*} value The value to process.
683
+ * @returns {number} Returns the number.
684
+ * @example
685
+ *
686
+ * _.toNumber(3.2);
687
+ * // => 3.2
688
+ *
689
+ * _.toNumber(Number.MIN_VALUE);
690
+ * // => 5e-324
691
+ *
692
+ * _.toNumber(Infinity);
693
+ * // => Infinity
694
+ *
695
+ * _.toNumber('3.2');
696
+ * // => 3.2
697
+ */
698
+ function toNumber(value) {
699
+ if (typeof value == 'number') {
700
+ return value;
701
+ }
702
+ if (isSymbol(value)) {
703
+ return NAN;
704
+ }
705
+ if (isObject(value)) {
706
+ var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
707
+ value = isObject(other) ? (other + '') : other;
708
+ }
709
+ if (typeof value != 'string') {
710
+ return value === 0 ? value : +value;
711
+ }
712
+ value = value.replace(reTrim, '');
713
+ var isBinary = reIsBinary.test(value);
714
+ return (isBinary || reIsOctal.test(value))
715
+ ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
716
+ : (reIsBadHex.test(value) ? NAN : +value);
717
+ }
718
+
719
+ module.exports = toNumber;
720
+
721
+ },{"14":14,"17":17}],20:[function(_dereq_,module,exports){
722
+ var baseToString = _dereq_(5);
723
+
724
+ /**
725
+ * Converts `value` to a string. An empty string is returned for `null`
726
+ * and `undefined` values. The sign of `-0` is preserved.
727
+ *
728
+ * @static
729
+ * @memberOf _
730
+ * @since 4.0.0
731
+ * @category Lang
732
+ * @param {*} value The value to convert.
733
+ * @returns {string} Returns the converted string.
734
+ * @example
735
+ *
736
+ * _.toString(null);
737
+ * // => ''
738
+ *
739
+ * _.toString(-0);
740
+ * // => '-0'
741
+ *
742
+ * _.toString([1, 2, 3]);
743
+ * // => '1,2,3'
744
+ */
745
+ function toString(value) {
746
+ return value == null ? '' : baseToString(value);
747
+ }
748
+
749
+ module.exports = toString;
750
+
751
+ },{"5":5}],21:[function(_dereq_,module,exports){
752
+ 'use strict';
753
+
754
+ var $ = (window.jQuery || window.Zepto);
755
+ var isString = _dereq_(16);
756
+
757
+ var Selectivity = _dereq_(38);
758
+
759
+ var EVENT_PROPERTIES = {
760
+ change: ['added', 'removed', 'value'],
761
+ 'selectivity-change': ['added', 'removed', 'value'],
762
+ 'selectivity-highlight': ['id', 'item'],
763
+ 'selectivity-selected': ['id', 'item'],
764
+ 'selectivity-selecting': ['id', 'item']
765
+ };
766
+
767
+ // create event listeners that will copy the custom properties from the native events
768
+ // to the jQuery events, so jQuery users can use them seamlessly
769
+ function patchEvents($el) {
770
+ $.each(EVENT_PROPERTIES, function(eventName, properties) {
771
+ $el.on(eventName, function(event) {
772
+ if (event.originalEvent) {
773
+ properties.forEach(function(propertyName) {
774
+ event[propertyName] = event.originalEvent[propertyName];
775
+ });
776
+ }
777
+ });
778
+ });
779
+ }
780
+
781
+ /**
782
+ * Create a new Selectivity instance or invoke a method on an instance.
783
+ *
784
+ * @param methodName Optional name of a method to call. If omitted, a Selectivity instance is
785
+ * created for each element in the set of matched elements. If an element in the
786
+ * set already has a Selectivity instance, the result is the same as if the
787
+ * setOptions() method is called. If a method name is given, the options
788
+ * parameter is ignored and any additional parameters are passed to the given
789
+ * method.
790
+ * @param options Options object to pass to the constructor or the setOptions() method. In case
791
+ * a new instance is being created, the following properties are used:
792
+ * inputType - The input type to use. Default inputs include 'Multiple' and 'Single',
793
+ * but you can add custom inputs to the Selectivity.Inputs map or just
794
+ * specify one here as a function. The default value is 'Multiple' if
795
+ * `multiple` is true and 'Single' otherwise.
796
+ * multiple - Boolean determining whether multiple items may be selected
797
+ * (default: false). If true, the default `inputType` is set to
798
+ * 'Multiple'.
799
+ *
800
+ * @return If the given method returns a value, this method returns the value of that method
801
+ * executed on the first element in the set of matched elements.
802
+ */
803
+ $.fn.selectivity = function selectivity(methodName, options) {
804
+ var methodArgs = Array.prototype.slice.call(arguments, 1);
805
+ var result;
806
+
807
+ this.each(function() {
808
+ var instance = this.selectivity;
809
+
810
+ if (instance) {
811
+ if (methodName === 'data') {
812
+ methodName = methodArgs.length ? 'setData' : 'getData';
813
+ } else if (methodName === 'val' || methodName === 'value') {
814
+ methodName = methodArgs.length ? 'setValue' : 'getValue';
815
+ } else if (!isString(methodName)) {
816
+ methodArgs = [methodName];
817
+ methodName = 'setOptions';
818
+ }
819
+
820
+ if ($.isFunction(instance[methodName])) {
821
+ if (result === undefined) {
822
+ result = instance[methodName].apply(instance, methodArgs);
823
+ }
824
+ } else {
825
+ throw new Error('Unknown method: ' + methodName);
826
+ }
827
+ } else if (isString(methodName)) {
828
+ if (methodName !== 'destroy') {
829
+ throw new Error('Cannot call method on element without Selectivity instance');
830
+ }
831
+ } else {
832
+ options = $.extend({}, methodName, { element: this });
833
+
834
+ // this is a one-time hack to facilitate the "traditional" plugin, because
835
+ // the plugin is not able to hook this early into creation of the instance
836
+ var $this = $(this);
837
+ if ($this.is('select') && $this.prop('multiple')) {
838
+ options.multiple = true;
839
+ }
840
+
841
+ var Inputs = Selectivity.Inputs;
842
+ var InputType = options.inputType || (options.multiple ? 'Multiple' : 'Single');
843
+ if (!$.isFunction(InputType)) {
844
+ if (Inputs[InputType]) {
845
+ InputType = Inputs[InputType];
846
+ } else {
847
+ throw new Error('Unknown Selectivity input type: ' + InputType);
848
+ }
849
+ }
850
+
851
+ this.selectivity = new InputType(options);
852
+ $this = $(this.selectivity.el);
853
+
854
+ patchEvents($this);
855
+
856
+ if (result === undefined) {
857
+ result = $this;
858
+ }
859
+ }
860
+ });
861
+
862
+ return result === undefined ? this : result;
863
+ };
864
+
865
+ Selectivity.patchEvents = patchEvents;
866
+
867
+ $.Selectivity = Selectivity;
868
+
869
+ },{"16":16,"38":38,"jquery":"jquery"}],22:[function(_dereq_,module,exports){
870
+ 'use strict';
871
+
872
+ var assign = (window.jQuery || window.Zepto).extend;
873
+
874
+ var EventListener = _dereq_(23);
875
+ var getItemSelector = _dereq_(41);
876
+ var matchesSelector = _dereq_(43);
877
+ var parseElement = _dereq_(44);
878
+ var removeElement = _dereq_(45);
879
+ var stopPropagation = _dereq_(46);
880
+ var toggleClass = _dereq_(47);
881
+
882
+ var Selectivity = _dereq_(38);
883
+
884
+ var HIGHLIGHT_CLASS = 'highlight';
885
+ var HIGHLIGHT_SELECTOR = '.' + HIGHLIGHT_CLASS;
886
+ var LOAD_MORE_SELECTOR = '.selectivity-load-more';
887
+ var RESULT_ITEM_SELECTOR = '.selectivity-result-item';
888
+
889
+ var SCROLL_EVENTS = ['scroll', 'touchend', 'touchmove'];
890
+
891
+ function findClosestElementMatchingSelector(el, selector) {
892
+ while (el && !matchesSelector(el, selector)) {
893
+ el = el.parentElement;
894
+ }
895
+ return el || null;
896
+ }
897
+
898
+ /**
899
+ * Selectivity Dropdown Constructor.
900
+ *
901
+ * @param selectivity Selectivity instance to which the dropdown belongs.
902
+ * @param options Options object. Should have the following properties:
903
+ * highlightFirstItem - Set to false if you don't want the first item to be
904
+ * automatically highlighted (optional).
905
+ * items - Array of items to display.
906
+ * position - Callback for positioning the dropdown.
907
+ * query - Callback to fetch the items to display.
908
+ * showSearchInput - Boolean whether a search input should be shown.
909
+ */
910
+ function SelectivityDropdown(selectivity, options) {
911
+ this.el = parseElement(
912
+ selectivity.template('dropdown', {
913
+ dropdownCssClass: selectivity.options.dropdownCssClass,
914
+ searchInputPlaceholder: selectivity.options.searchInputPlaceholder,
915
+ showSearchInput: options.showSearchInput
916
+ })
917
+ );
918
+
919
+ /**
920
+ * DOM element to add the results to.
921
+ */
922
+ this.resultsContainer = this.$('.selectivity-results-container');
923
+
924
+ /**
925
+ * Boolean indicating whether more results are available than currently displayed in the
926
+ * dropdown.
927
+ */
928
+ this.hasMore = false;
929
+
930
+ /**
931
+ * The currently highlighted result item.
932
+ */
933
+ this.highlightedResult = null;
934
+
935
+ /**
936
+ * Boolean whether the load more link is currently highlighted.
937
+ */
938
+ this.loadMoreHighlighted = false;
939
+
940
+ /**
941
+ * Options passed to the dropdown constructor.
942
+ */
943
+ this.options = options;
944
+
945
+ /**
946
+ * The results displayed in the dropdown.
947
+ */
948
+ this.results = [];
949
+
950
+ /**
951
+ * Selectivity instance.
952
+ */
953
+ this.selectivity = selectivity;
954
+
955
+ this._closed = false;
956
+ this._lastMousePosition = {};
957
+
958
+ this.close = this.close.bind(this);
959
+ this.position = this.position.bind(this);
960
+
961
+ if (selectivity.options.closeOnSelect !== false) {
962
+ selectivity.events.on('selectivity-selecting', this.close);
963
+ }
964
+
965
+ this.addToDom();
966
+ this.showLoading();
967
+
968
+ if (options.showSearchInput) {
969
+ selectivity.initInput(this.$('.selectivity-search-input'));
970
+ selectivity.focus();
971
+ }
972
+
973
+ var events = {};
974
+ events['click ' + LOAD_MORE_SELECTOR] = this._loadMoreClicked;
975
+ events['click ' + RESULT_ITEM_SELECTOR] = this._resultClicked;
976
+ events['mouseenter ' + LOAD_MORE_SELECTOR] = this._loadMoreHovered;
977
+ events['mouseenter ' + RESULT_ITEM_SELECTOR] = this._resultHovered;
978
+
979
+ this.events = new EventListener(this.el, this);
980
+ this.events.on(events);
981
+
982
+ this._attachScrollListeners();
983
+ this._suppressWheel();
984
+
985
+ setTimeout(this.triggerOpen.bind(this), 1);
986
+ }
987
+
988
+ /**
989
+ * Methods.
990
+ */
991
+ assign(SelectivityDropdown.prototype, {
992
+ /**
993
+ * Convenience shortcut for this.el.querySelector(selector).
994
+ */
995
+ $: function(selector) {
996
+ return this.el.querySelector(selector);
997
+ },
998
+
999
+ /**
1000
+ * Adds the dropdown to the DOM.
1001
+ */
1002
+ addToDom: function() {
1003
+ this.selectivity.el.appendChild(this.el);
1004
+ },
1005
+
1006
+ /**
1007
+ * Closes the dropdown.
1008
+ */
1009
+ close: function() {
1010
+ if (!this._closed) {
1011
+ this._closed = true;
1012
+
1013
+ removeElement(this.el);
1014
+
1015
+ this.selectivity.events.off('selectivity-selecting', this.close);
1016
+
1017
+ this.triggerClose();
1018
+
1019
+ this._removeScrollListeners();
1020
+ }
1021
+ },
1022
+
1023
+ /**
1024
+ * Highlights a result item.
1025
+ *
1026
+ * @param item The item to highlight.
1027
+ * @param options Optional options object that may contain the following property:
1028
+ * reason - The reason why the result item is being highlighted. Possible
1029
+ * values: 'current_value', 'first_result', 'hovered'.
1030
+ */
1031
+ highlight: function(item, options) {
1032
+ toggleClass(this.$(HIGHLIGHT_SELECTOR), HIGHLIGHT_CLASS, false);
1033
+ toggleClass(this.$(getItemSelector(RESULT_ITEM_SELECTOR, item.id)), HIGHLIGHT_CLASS, true);
1034
+
1035
+ this.highlightedResult = item;
1036
+ this.loadMoreHighlighted = false;
1037
+
1038
+ this.selectivity.triggerEvent('selectivity-highlight', {
1039
+ item: item,
1040
+ id: item.id,
1041
+ reason: (options && options.reason) || 'unspecified'
1042
+ });
1043
+ },
1044
+
1045
+ /**
1046
+ * Highlights the load more link.
1047
+ *
1048
+ * @param item The item to highlight.
1049
+ */
1050
+ highlightLoadMore: function() {
1051
+ toggleClass(this.$(HIGHLIGHT_SELECTOR), HIGHLIGHT_CLASS, false);
1052
+ toggleClass(this.$(LOAD_MORE_SELECTOR), HIGHLIGHT_CLASS, true);
1053
+
1054
+ this.highlightedResult = null;
1055
+ this.loadMoreHighlighted = true;
1056
+ },
1057
+
1058
+ /**
1059
+ * Loads a follow-up page with results after a search.
1060
+ *
1061
+ * This method should only be called after a call to search() when the callback has indicated
1062
+ * more results are available.
1063
+ */
1064
+ loadMore: function() {
1065
+ removeElement(this.$(LOAD_MORE_SELECTOR));
1066
+ this.resultsContainer.innerHTML += this.selectivity.template('loading');
1067
+
1068
+ this.options.query({
1069
+ callback: function(response) {
1070
+ if (response && response.results) {
1071
+ this._showResults(Selectivity.processItems(response.results), {
1072
+ add: true,
1073
+ hasMore: !!response.more
1074
+ });
1075
+ } else {
1076
+ throw new Error('callback must be passed a response object');
1077
+ }
1078
+ }.bind(this),
1079
+ error: this._showResults.bind(this, [], { add: true }),
1080
+ offset: this.results.length,
1081
+ selectivity: this.selectivity,
1082
+ term: this.term
1083
+ });
1084
+ },
1085
+
1086
+ /**
1087
+ * Positions the dropdown inside the DOM.
1088
+ */
1089
+ position: function() {
1090
+ var position = this.options.position;
1091
+ if (position) {
1092
+ position(this.el, this.selectivity.el);
1093
+ }
1094
+
1095
+ this._scrolled();
1096
+ },
1097
+
1098
+ /**
1099
+ * Renders an array of result items.
1100
+ *
1101
+ * @param items Array of result items.
1102
+ *
1103
+ * @return HTML-formatted string to display the result items.
1104
+ */
1105
+ renderItems: function(items) {
1106
+ var selectivity = this.selectivity;
1107
+ return items
1108
+ .map(function(item) {
1109
+ var result = selectivity.template(item.id ? 'resultItem' : 'resultLabel', item);
1110
+ if (item.children) {
1111
+ result += selectivity.template('resultChildren', {
1112
+ childrenHtml: this.renderItems(item.children)
1113
+ });
1114
+ }
1115
+ return result;
1116
+ }, this)
1117
+ .join('');
1118
+ },
1119
+
1120
+ /**
1121
+ * Searches for results based on the term given.
1122
+ *
1123
+ * If an items array has been passed with the options to the Selectivity instance, a local
1124
+ * search will be performed among those items. Otherwise, the query function specified in the
1125
+ * options will be used to perform the search. If neither is defined, nothing happens.
1126
+ *
1127
+ * @param term Term to search for.
1128
+ */
1129
+ search: function(term) {
1130
+ this.term = term;
1131
+
1132
+ if (this.options.items) {
1133
+ term = Selectivity.transformText(term);
1134
+ var matcher = this.selectivity.options.matcher || Selectivity.matcher;
1135
+ this._showResults(
1136
+ this.options.items
1137
+ .map(function(item) {
1138
+ return matcher(item, term);
1139
+ })
1140
+ .filter(function(item) {
1141
+ return !!item;
1142
+ }),
1143
+ { term: term }
1144
+ );
1145
+ } else if (this.options.query) {
1146
+ this.options.query({
1147
+ callback: function(response) {
1148
+ if (response && response.results) {
1149
+ this._showResults(Selectivity.processItems(response.results), {
1150
+ hasMore: !!response.more,
1151
+ term: term
1152
+ });
1153
+ } else {
1154
+ throw new Error('callback must be passed a response object');
1155
+ }
1156
+ }.bind(this),
1157
+ error: this.showError.bind(this),
1158
+ offset: 0,
1159
+ selectivity: this.selectivity,
1160
+ term: term
1161
+ });
1162
+ }
1163
+ },
1164
+
1165
+ /**
1166
+ * Selects the highlighted item.
1167
+ */
1168
+ selectHighlight: function() {
1169
+ if (this.highlightedResult) {
1170
+ this.selectItem(this.highlightedResult.id);
1171
+ } else if (this.loadMoreHighlighted) {
1172
+ this.loadMore();
1173
+ }
1174
+ },
1175
+
1176
+ /**
1177
+ * Selects the item with the given ID.
1178
+ *
1179
+ * @param id ID of the item to select.
1180
+ */
1181
+ selectItem: function(id) {
1182
+ var item = Selectivity.findNestedById(this.results, id);
1183
+ if (item && !item.disabled && item.selectable !== false) {
1184
+ var options = { id: id, item: item };
1185
+ if (this.selectivity.triggerEvent('selectivity-selecting', options)) {
1186
+ this.selectivity.triggerEvent('selectivity-selected', options);
1187
+ }
1188
+ }
1189
+ },
1190
+
1191
+ /**
1192
+ * Shows an error message.
1193
+ *
1194
+ * @param message Error message to display.
1195
+ * @param options Options object. May contain the following property:
1196
+ * escape - Set to false to disable HTML-escaping of the message. Useful if you
1197
+ * want to set raw HTML as the message, but may open you up to XSS
1198
+ * attacks if you're not careful with escaping user input.
1199
+ */
1200
+ showError: function(message, options) {
1201
+ this.resultsContainer.innerHTML = this.selectivity.template('error', {
1202
+ escape: !options || options.escape !== false,
1203
+ message: message
1204
+ });
1205
+
1206
+ this.hasMore = false;
1207
+ this.results = [];
1208
+
1209
+ this.highlightedResult = null;
1210
+ this.loadMoreHighlighted = false;
1211
+
1212
+ this.position();
1213
+ },
1214
+
1215
+ /**
1216
+ * Shows a loading indicator in the dropdown.
1217
+ */
1218
+ showLoading: function() {
1219
+ this.resultsContainer.innerHTML = this.selectivity.template('loading');
1220
+
1221
+ this.hasMore = false;
1222
+ this.results = [];
1223
+
1224
+ this.highlightedResult = null;
1225
+ this.loadMoreHighlighted = false;
1226
+
1227
+ this.position();
1228
+ },
1229
+
1230
+ /**
1231
+ * Shows the results from a search query.
1232
+ *
1233
+ * @param results Array of result items.
1234
+ * @param options Options object. May contain the following properties:
1235
+ * add - True if the results should be added to any already shown results.
1236
+ * dropdown - The dropdown instance for which the results are meant.
1237
+ * hasMore - Boolean whether more results can be fetched using the query()
1238
+ * function.
1239
+ * term - The search term for which the results are displayed.
1240
+ */
1241
+ showResults: function(results, options) {
1242
+ if (options.add) {
1243
+ removeElement(this.$('.selectivity-loading'));
1244
+ } else {
1245
+ this.resultsContainer.innerHTML = '';
1246
+ }
1247
+
1248
+ var filteredResults = this.selectivity.filterResults(results);
1249
+ var resultsHtml = this.renderItems(filteredResults);
1250
+ if (options.hasMore) {
1251
+ resultsHtml += this.selectivity.template('loadMore');
1252
+ } else if (!resultsHtml && !options.add) {
1253
+ resultsHtml = this.selectivity.template('noResults', { term: options.term });
1254
+ }
1255
+ this.resultsContainer.innerHTML += resultsHtml;
1256
+
1257
+ this.results = options.add ? this.results.concat(results) : results;
1258
+
1259
+ this.hasMore = options.hasMore;
1260
+
1261
+ var value = this.selectivity.getValue();
1262
+ if (value && !Array.isArray(value)) {
1263
+ var item = Selectivity.findNestedById(results, value);
1264
+ if (item) {
1265
+ this.highlight(item, { reason: 'current_value' });
1266
+ }
1267
+ } else if (
1268
+ this.options.highlightFirstItem !== false &&
1269
+ (!options.add || this.loadMoreHighlighted)
1270
+ ) {
1271
+ this._highlightFirstItem(filteredResults);
1272
+ }
1273
+
1274
+ this.position();
1275
+ },
1276
+
1277
+ /**
1278
+ * Triggers the 'selectivity-close' event.
1279
+ */
1280
+ triggerClose: function() {
1281
+ this.selectivity.triggerEvent('selectivity-close');
1282
+ },
1283
+
1284
+ /**
1285
+ * Triggers the 'selectivity-open' event.
1286
+ */
1287
+ triggerOpen: function() {
1288
+ this.selectivity.triggerEvent('selectivity-open');
1289
+ },
1290
+
1291
+ /**
1292
+ * @private
1293
+ */
1294
+ _attachScrollListeners: function() {
1295
+ for (var i = 0; i < SCROLL_EVENTS.length; i++) {
1296
+ window.addEventListener(SCROLL_EVENTS[i], this.position, true);
1297
+ }
1298
+ window.addEventListener('resize', this.position);
1299
+ },
1300
+
1301
+ /**
1302
+ * @private
1303
+ */
1304
+ _highlightFirstItem: function(results) {
1305
+ function findFirstItem(results) {
1306
+ for (var i = 0, length = results.length; i < length; i++) {
1307
+ var result = results[i];
1308
+ if (result.id) {
1309
+ return result;
1310
+ } else if (result.children) {
1311
+ var item = findFirstItem(result.children);
1312
+ if (item) {
1313
+ return item;
1314
+ }
1315
+ }
1316
+ }
1317
+ }
1318
+
1319
+ var firstItem = findFirstItem(results);
1320
+ if (firstItem) {
1321
+ this.highlight(firstItem, { reason: 'first_result' });
1322
+ } else {
1323
+ this.highlightedResult = null;
1324
+ this.loadMoreHighlighted = false;
1325
+ }
1326
+ },
1327
+
1328
+ /**
1329
+ * @private
1330
+ */
1331
+ _loadMoreClicked: function(event) {
1332
+ this.loadMore();
1333
+
1334
+ stopPropagation(event);
1335
+ },
1336
+
1337
+ /**
1338
+ * @private
1339
+ */
1340
+ _loadMoreHovered: function(event) {
1341
+ if (
1342
+ event.screenX === undefined ||
1343
+ event.screenX !== this._lastMousePosition.x ||
1344
+ event.screenY === undefined ||
1345
+ event.screenY !== this._lastMousePosition.y
1346
+ ) {
1347
+ this.highlightLoadMore();
1348
+
1349
+ this._recordMousePosition(event);
1350
+ }
1351
+ },
1352
+
1353
+ /**
1354
+ * @private
1355
+ */
1356
+ _recordMousePosition: function(event) {
1357
+ this._lastMousePosition = { x: event.screenX, y: event.screenY };
1358
+ },
1359
+
1360
+ /**
1361
+ * @private
1362
+ */
1363
+ _removeScrollListeners: function() {
1364
+ for (var i = 0; i < SCROLL_EVENTS.length; i++) {
1365
+ window.removeEventListener(SCROLL_EVENTS[i], this.position, true);
1366
+ }
1367
+ window.removeEventListener('resize', this.position);
1368
+ },
1369
+
1370
+ /**
1371
+ * @private
1372
+ */
1373
+ _resultClicked: function(event) {
1374
+ this.selectItem(this.selectivity.getRelatedItemId(event));
1375
+
1376
+ stopPropagation(event);
1377
+ },
1378
+
1379
+ /**
1380
+ * @private
1381
+ */
1382
+ _resultHovered: function(event) {
1383
+ if (
1384
+ !event.screenX ||
1385
+ event.screenX !== this._lastMousePosition.x ||
1386
+ !event.screenY ||
1387
+ event.screenY !== this._lastMousePosition.y
1388
+ ) {
1389
+ var id = this.selectivity.getRelatedItemId(event);
1390
+ var item = Selectivity.findNestedById(this.results, id);
1391
+ if (item && !item.disabled) {
1392
+ this.highlight(item, { reason: 'hovered' });
1393
+ }
1394
+
1395
+ this._recordMousePosition(event);
1396
+ }
1397
+ },
1398
+
1399
+ /**
1400
+ * @private
1401
+ */
1402
+ _scrolled: function() {
1403
+ var el = this.$(LOAD_MORE_SELECTOR);
1404
+ if (el && el.offsetTop - this.resultsContainer.scrollTop < this.el.clientHeight) {
1405
+ this.loadMore();
1406
+ }
1407
+ },
1408
+
1409
+ /**
1410
+ * @private
1411
+ */
1412
+ _showResults: function(results, options) {
1413
+ this.showResults(results, assign({ dropdown: this }, options));
1414
+ },
1415
+
1416
+ /**
1417
+ * @private
1418
+ */
1419
+ _suppressWheel: function() {
1420
+ var suppressWheelSelector = this.selectivity.options.suppressWheelSelector;
1421
+ if (suppressWheelSelector === null) {
1422
+ return;
1423
+ }
1424
+
1425
+ var selector = suppressWheelSelector || '.selectivity-results-container';
1426
+ this.events.on('wheel', selector, function(event) {
1427
+ // Thanks to Troy Alford:
1428
+ // http://stackoverflow.com/questions/5802467/prevent-scrolling-of-parent-element
1429
+
1430
+ var delta = event.deltaMode === 0 ? event.deltaY : event.deltaY * 40;
1431
+ var el = findClosestElementMatchingSelector(event.target, selector);
1432
+ var height = el.clientHeight;
1433
+ var scrollHeight = el.scrollHeight;
1434
+ var scrollTop = el.scrollTop;
1435
+
1436
+ function prevent() {
1437
+ stopPropagation(event);
1438
+ event.preventDefault();
1439
+ }
1440
+
1441
+ if (scrollHeight > height) {
1442
+ if (delta < -scrollTop) {
1443
+ // Scrolling up, but this will take us past the top.
1444
+ el.scrollTop = 0;
1445
+ prevent();
1446
+ } else if (delta > scrollHeight - height - scrollTop) {
1447
+ // Scrolling down, but this will take us past the bottom.
1448
+ el.scrollTop = scrollHeight;
1449
+ prevent();
1450
+ }
1451
+ }
1452
+ });
1453
+ }
1454
+ });
1455
+
1456
+ module.exports = Selectivity.Dropdown = SelectivityDropdown;
1457
+
1458
+ },{"23":23,"38":38,"41":41,"43":43,"44":44,"45":45,"46":46,"47":47,"lodash/assign":"lodash/assign"}],23:[function(_dereq_,module,exports){
1459
+ 'use strict';
1460
+
1461
+ var assign = (window.jQuery || window.Zepto).extend;
1462
+ var isString = _dereq_(16);
1463
+
1464
+ var matchesSelector = _dereq_(43);
1465
+
1466
+ var CAPTURED_EVENTS = ['blur', 'focus', 'mouseenter', 'mouseleave', 'scroll'];
1467
+
1468
+ /**
1469
+ * Listens to events dispatched to an element or its children.
1470
+ *
1471
+ * @param el The element to listen to.
1472
+ * @param context Optional context in which to execute the callbacks.
1473
+ */
1474
+ function EventListener(el, context) {
1475
+ this.context = context || null;
1476
+
1477
+ this.el = el;
1478
+
1479
+ this.events = {};
1480
+
1481
+ this._onEvent = this._onEvent.bind(this);
1482
+ }
1483
+
1484
+ assign(EventListener.prototype, {
1485
+ /**
1486
+ * Destructor.
1487
+ *
1488
+ * Removes all event listeners and cleans up all references.
1489
+ */
1490
+ destruct: function() {
1491
+ Object.keys(this.events).forEach(function(eventName) {
1492
+ var useCapture = CAPTURED_EVENTS.indexOf(eventName) > -1;
1493
+ this.el.removeEventListener(eventName, this._onEvent, useCapture);
1494
+ }, this);
1495
+
1496
+ this.context = null;
1497
+ this.el = null;
1498
+ this.events = null;
1499
+ },
1500
+
1501
+ /**
1502
+ * Stops listening to an event.
1503
+ *
1504
+ * The arguments are the same as for on(), but when no callback is given, all callbacks for the
1505
+ * given event and class are discarded.
1506
+ */
1507
+ off: function(eventName, selector, callback) {
1508
+ if (!isString(selector)) {
1509
+ callback = selector;
1510
+ selector = '';
1511
+ }
1512
+
1513
+ if (callback) {
1514
+ var events = this.events[eventName];
1515
+ if (events) {
1516
+ events = events[selector];
1517
+ if (events) {
1518
+ for (var i = 0; i < events.length; i++) {
1519
+ if (events[i] === callback) {
1520
+ events.splice(i, 1);
1521
+ i--;
1522
+ }
1523
+ }
1524
+ }
1525
+ }
1526
+ } else {
1527
+ this.events[eventName][selector] = [];
1528
+ }
1529
+ },
1530
+
1531
+ /**
1532
+ * Starts listening to an event.
1533
+ *
1534
+ * @param eventName Name of the event to listen to, in lower-case.
1535
+ * @param selector Optional CSS selector. If given, only events inside a child element matching
1536
+ * the selector are caught.
1537
+ * @param callback Callback to invoke when the event is caught.
1538
+ *
1539
+ * Alternatively, the arguments may be provided using a map to start listening to multiple
1540
+ * events at once. Here, the keys of the map are eventNames and the values are callbacks.
1541
+ * Selectors may be specified by separating them from the event name with a space. For example:
1542
+ *
1543
+ * .on({
1544
+ * 'blur': this._blurred,
1545
+ * 'click .some-input': this._inputClicked,
1546
+ * })
1547
+ */
1548
+ on: function(eventName, selector, callback) {
1549
+ if (!isString(eventName)) {
1550
+ var eventsMap = eventName;
1551
+ for (var key in eventsMap) {
1552
+ if (eventsMap.hasOwnProperty(key)) {
1553
+ var split = key.split(' ');
1554
+ if (split.length > 1) {
1555
+ this.on(split[0], split[1], eventsMap[key]);
1556
+ } else {
1557
+ this.on(split[0], eventsMap[key]);
1558
+ }
1559
+ }
1560
+ }
1561
+ return;
1562
+ }
1563
+
1564
+ if (!isString(selector)) {
1565
+ callback = selector;
1566
+ selector = '';
1567
+ }
1568
+
1569
+ if (!this.events.hasOwnProperty(eventName)) {
1570
+ var useCapture = CAPTURED_EVENTS.indexOf(eventName) > -1;
1571
+ this.el.addEventListener(eventName, this._onEvent, useCapture);
1572
+
1573
+ this.events[eventName] = {};
1574
+ }
1575
+
1576
+ if (!this.events[eventName].hasOwnProperty(selector)) {
1577
+ this.events[eventName][selector] = [];
1578
+ }
1579
+
1580
+ if (this.events[eventName][selector].indexOf(callback) < 0) {
1581
+ this.events[eventName][selector].push(callback);
1582
+ }
1583
+ },
1584
+
1585
+ _onEvent: function(event) {
1586
+ var isPropagationStopped = false;
1587
+ var stopPropagation = event.stopPropagation;
1588
+ event.stopPropagation = function() {
1589
+ stopPropagation.call(event);
1590
+ isPropagationStopped = true;
1591
+ };
1592
+
1593
+ var context = this.context;
1594
+ function callAll(callbacks) {
1595
+ for (var i = 0; i < callbacks.length; i++) {
1596
+ callbacks[i].call(context, event);
1597
+ }
1598
+ }
1599
+
1600
+ var target = event.target;
1601
+ var events = this.events[event.type.toLowerCase()];
1602
+ while (target && target !== this.el && !isPropagationStopped) {
1603
+ for (var selector in events) {
1604
+ if (
1605
+ selector &&
1606
+ events.hasOwnProperty(selector) &&
1607
+ matchesSelector(target, selector)
1608
+ ) {
1609
+ callAll(events[selector]);
1610
+ }
1611
+ }
1612
+ target = target.parentElement;
1613
+ }
1614
+
1615
+ if (!isPropagationStopped && events.hasOwnProperty('')) {
1616
+ callAll(events['']);
1617
+ }
1618
+ }
1619
+ });
1620
+
1621
+ module.exports = EventListener;
1622
+
1623
+ },{"16":16,"43":43,"lodash/assign":"lodash/assign"}],24:[function(_dereq_,module,exports){
1624
+ 'use strict';
1625
+
1626
+ var assign = (window.jQuery || window.Zepto).extend;
1627
+
1628
+ var MultipleInput = _dereq_(25);
1629
+ var Selectivity = _dereq_(38);
1630
+
1631
+ function isValidEmail(email) {
1632
+ var atIndex = email.indexOf('@');
1633
+ if (atIndex === -1 || email.indexOf(' ') > -1) {
1634
+ return false; // email needs to have an '@', and may not contain any spaces
1635
+ }
1636
+
1637
+ var dotIndex = email.lastIndexOf('.');
1638
+ if (dotIndex === -1) {
1639
+ // no dot is fine, as long as the '@' is followed by at least two more characters
1640
+ return atIndex < email.length - 2;
1641
+ }
1642
+
1643
+ // but if there is a dot after the '@', it must be followed by at least two more characters
1644
+ return dotIndex > atIndex ? dotIndex < email.length - 2 : true;
1645
+ }
1646
+
1647
+ function lastWord(token, length) {
1648
+ length = length === undefined ? token.length : length;
1649
+ for (var i = length - 1; i >= 0; i--) {
1650
+ if (/\s/.test(token[i])) {
1651
+ return token.slice(i + 1, length);
1652
+ }
1653
+ }
1654
+ return token.slice(0, length);
1655
+ }
1656
+
1657
+ function stripEnclosure(token, enclosure) {
1658
+ if (token.charAt(0) === enclosure[0] && token.slice(-1) === enclosure[1]) {
1659
+ return token.slice(1, -1).trim();
1660
+ } else {
1661
+ return token.trim();
1662
+ }
1663
+ }
1664
+
1665
+ function createEmailItem(token) {
1666
+ var email = lastWord(token);
1667
+ var name = token.slice(0, -email.length).trim();
1668
+ if (isValidEmail(email)) {
1669
+ email = stripEnclosure(stripEnclosure(email, '()'), '<>');
1670
+ name = stripEnclosure(name, '""').trim() || email;
1671
+ return { id: email, text: name };
1672
+ } else {
1673
+ return token.trim() ? { id: token, text: token } : null;
1674
+ }
1675
+ }
1676
+
1677
+ function emailTokenizer(input, selection, createToken) {
1678
+ function hasToken(input) {
1679
+ if (input) {
1680
+ for (var i = 0, length = input.length; i < length; i++) {
1681
+ switch (input[i]) {
1682
+ case ';':
1683
+ case ',':
1684
+ case '\n':
1685
+ return true;
1686
+ case ' ':
1687
+ case '\t':
1688
+ if (isValidEmail(lastWord(input, i))) {
1689
+ return true;
1690
+ }
1691
+ break;
1692
+ case '"':
1693
+ do {
1694
+ i++;
1695
+ } while (i < length && input[i] !== '"');
1696
+ break;
1697
+ default:
1698
+ continue;
1699
+ }
1700
+ }
1701
+ }
1702
+ return false;
1703
+ }
1704
+
1705
+ function takeToken(input) {
1706
+ for (var i = 0, length = input.length; i < length; i++) {
1707
+ switch (input[i]) {
1708
+ case ';':
1709
+ case ',':
1710
+ case '\n':
1711
+ return { term: input.slice(0, i), input: input.slice(i + 1) };
1712
+ case ' ':
1713
+ case '\t':
1714
+ if (isValidEmail(lastWord(input, i))) {
1715
+ return { term: input.slice(0, i), input: input.slice(i + 1) };
1716
+ }
1717
+ break;
1718
+ case '"':
1719
+ do {
1720
+ i++;
1721
+ } while (i < length && input[i] !== '"');
1722
+ break;
1723
+ default:
1724
+ continue;
1725
+ }
1726
+ }
1727
+ return {};
1728
+ }
1729
+
1730
+ while (hasToken(input)) {
1731
+ var token = takeToken(input);
1732
+ if (token.term) {
1733
+ var item = createEmailItem(token.term);
1734
+ if (item && !(item.id && Selectivity.findById(selection, item.id))) {
1735
+ createToken(item);
1736
+ }
1737
+ }
1738
+ input = token.input;
1739
+ }
1740
+
1741
+ return input;
1742
+ }
1743
+
1744
+ /**
1745
+ * EmailInput Constructor.
1746
+ *
1747
+ * @param options Options object. Accepts all options from the MultipleInput Constructor.
1748
+ */
1749
+ function EmailInput(options) {
1750
+ MultipleInput.call(
1751
+ this,
1752
+ assign(
1753
+ {
1754
+ createTokenItem: createEmailItem,
1755
+ showDropdown: false,
1756
+ tokenizer: emailTokenizer
1757
+ },
1758
+ options
1759
+ )
1760
+ );
1761
+
1762
+ this.events.on('blur', function() {
1763
+ var input = this.input;
1764
+ if (input && isValidEmail(lastWord(input.value))) {
1765
+ this.add(createEmailItem(input.value));
1766
+ }
1767
+ });
1768
+ }
1769
+
1770
+ Selectivity.inherits(EmailInput, MultipleInput);
1771
+
1772
+ module.exports = Selectivity.Inputs.Email = EmailInput;
1773
+
1774
+ },{"25":25,"38":38,"lodash/assign":"lodash/assign"}],25:[function(_dereq_,module,exports){
1775
+ 'use strict';
1776
+
1777
+ var assign = (window.jQuery || window.Zepto).extend;
1778
+ var isString = _dereq_(16);
1779
+
1780
+ var Selectivity = _dereq_(38);
1781
+ var getItemSelector = _dereq_(41);
1782
+ var getKeyCode = _dereq_(42);
1783
+ var parseElement = _dereq_(44);
1784
+ var removeElement = _dereq_(45);
1785
+ var stopPropagation = _dereq_(46);
1786
+ var toggleClass = _dereq_(47);
1787
+
1788
+ var KEY_BACKSPACE = 8;
1789
+ var KEY_DELETE = 46;
1790
+ var KEY_ENTER = 13;
1791
+
1792
+ var INPUT_SELECTOR = '.selectivity-multiple-input';
1793
+ var SELECTED_ITEM_SELECTOR = '.selectivity-multiple-selected-item';
1794
+
1795
+ var hasTouch = 'ontouchstart' in window;
1796
+
1797
+ /**
1798
+ * MultipleInput Constructor.
1799
+ */
1800
+ function MultipleInput(options) {
1801
+ Selectivity.call(
1802
+ this,
1803
+ assign(
1804
+ {
1805
+ // dropdowns for multiple-value inputs should open below the select box,
1806
+ // unless there is not enough space below, but there is space enough above, then it should
1807
+ // open upwards
1808
+ positionDropdown: function(el, selectEl) {
1809
+ var rect = selectEl.getBoundingClientRect();
1810
+ var dropdownHeight = el.clientHeight;
1811
+ var openUpwards =
1812
+ rect.bottom + dropdownHeight > window.innerHeight &&
1813
+ rect.top - dropdownHeight > 0;
1814
+
1815
+ assign(el.style, {
1816
+ left: rect.left + 'px',
1817
+ top: (openUpwards ? rect.top - dropdownHeight : rect.bottom) + 'px',
1818
+ width: rect.width + 'px'
1819
+ });
1820
+ },
1821
+
1822
+ showSearchInputInDropdown: false
1823
+ },
1824
+ options
1825
+ )
1826
+ );
1827
+
1828
+ this._reset();
1829
+
1830
+ var events = {
1831
+ change: this.rerenderSelection,
1832
+ click: this._clicked,
1833
+ 'selectivity-selected': this._resultSelected
1834
+ };
1835
+ events['change ' + INPUT_SELECTOR] = stopPropagation;
1836
+ events['click ' + SELECTED_ITEM_SELECTOR] = this._itemClicked;
1837
+ events['click ' + SELECTED_ITEM_SELECTOR + '-remove'] = this._itemRemoveClicked;
1838
+ events['keydown ' + INPUT_SELECTOR] = this._keyHeld;
1839
+ events['keyup ' + INPUT_SELECTOR] = this._keyReleased;
1840
+ events['paste ' + INPUT_SELECTOR] = this._onPaste;
1841
+
1842
+ this.events.on(events);
1843
+ }
1844
+
1845
+ /**
1846
+ * Methods.
1847
+ */
1848
+ var callSuper = Selectivity.inherits(MultipleInput, Selectivity, {
1849
+ /**
1850
+ * Adds an item to the selection, if it's not selected yet.
1851
+ *
1852
+ * @param item The item to add. May be an item with 'id' and 'text' properties or just an ID.
1853
+ */
1854
+ add: function(item) {
1855
+ var itemIsId = Selectivity.isValidId(item);
1856
+ var id = itemIsId ? item : this.validateItem(item) && item.id;
1857
+
1858
+ if (this._value.indexOf(id) === -1) {
1859
+ this._value.push(id);
1860
+
1861
+ if (itemIsId && this.options.initSelection) {
1862
+ this.options.initSelection(
1863
+ [id],
1864
+ function(data) {
1865
+ if (this._value.indexOf(id) > -1) {
1866
+ item = this.validateItem(data[0]);
1867
+ this._data.push(item);
1868
+
1869
+ this.triggerChange({ added: item });
1870
+ }
1871
+ }.bind(this)
1872
+ );
1873
+ } else {
1874
+ if (itemIsId) {
1875
+ item = this.getItemForId(id);
1876
+ }
1877
+ this._data.push(item);
1878
+
1879
+ this.triggerChange({ added: item });
1880
+ }
1881
+ }
1882
+
1883
+ this.input.value = '';
1884
+ this._updateInputWidth();
1885
+ },
1886
+
1887
+ /**
1888
+ * Clears the data and value.
1889
+ */
1890
+ clear: function() {
1891
+ this.setData([]);
1892
+ },
1893
+
1894
+ /**
1895
+ * @inherit
1896
+ */
1897
+ filterResults: function(results) {
1898
+ results = results.map(function(item) {
1899
+ var result = {
1900
+ id: item.id,
1901
+ text: item.text
1902
+ };
1903
+ if (item.children) {
1904
+ result['children'] = this.filterResults(item.children);
1905
+ }
1906
+ return result;
1907
+ }, this);
1908
+
1909
+ return results.filter(function(item) {
1910
+ return !Selectivity.findById(this._data, item.id);
1911
+ }, this);
1912
+ },
1913
+
1914
+ /**
1915
+ * Returns the correct data for a given value.
1916
+ *
1917
+ * @param value The value to get the data for. Should be an array of IDs.
1918
+ *
1919
+ * @return The corresponding data. Will be an array of objects with 'id' and 'text' properties.
1920
+ * Note that if no items are defined, this method assumes the text labels will be equal
1921
+ * to the IDs.
1922
+ */
1923
+ getDataForValue: function(value) {
1924
+ return value.map(this.getItemForId, this).filter(function(item) {
1925
+ return !!item;
1926
+ });
1927
+ },
1928
+
1929
+ /**
1930
+ * Returns the correct value for the given data.
1931
+ *
1932
+ * @param data The data to get the value for. Should be an array of objects with 'id' and 'text'
1933
+ * properties.
1934
+ *
1935
+ * @return The corresponding value. Will be an array of IDs.
1936
+ */
1937
+ getValueForData: function(data) {
1938
+ return data.map(function(item) {
1939
+ return item.id;
1940
+ });
1941
+ },
1942
+
1943
+ /**
1944
+ * Removes an item from the selection, if it is selected.
1945
+ *
1946
+ * @param item The item to remove. May be an item with 'id' and 'text' properties or just an ID.
1947
+ */
1948
+ remove: function(item) {
1949
+ var id = item.id || item;
1950
+
1951
+ var removedItem;
1952
+ var index = Selectivity.findIndexById(this._data, id);
1953
+ if (index > -1) {
1954
+ removedItem = this._data[index];
1955
+ this._data.splice(index, 1);
1956
+ }
1957
+
1958
+ if (this._value[index] !== id) {
1959
+ index = this._value.indexOf(id);
1960
+ }
1961
+ if (index > -1) {
1962
+ this._value.splice(index, 1);
1963
+ }
1964
+
1965
+ if (removedItem) {
1966
+ this.triggerChange({ removed: removedItem });
1967
+ }
1968
+
1969
+ if (id === this._highlightedItemId) {
1970
+ this._highlightedItemId = null;
1971
+ }
1972
+
1973
+ this._updateInputWidth();
1974
+ },
1975
+
1976
+ /**
1977
+ * Re-renders the selection.
1978
+ *
1979
+ * Normally the UI is automatically updated whenever the selection changes, but you may want to
1980
+ * call this method explicitly if you've updated the selection with the triggerChange option set
1981
+ * to false.
1982
+ */
1983
+ rerenderSelection: function(event) {
1984
+ event = event || {};
1985
+
1986
+ if (event.added) {
1987
+ this._renderSelectedItem(event.added);
1988
+
1989
+ this._scrollToBottom();
1990
+ } else if (event.removed) {
1991
+ removeElement(this.$(getItemSelector(SELECTED_ITEM_SELECTOR, event.removed.id)));
1992
+ } else {
1993
+ this._forEachSelectedItem(removeElement);
1994
+
1995
+ this._data.forEach(this._renderSelectedItem, this);
1996
+
1997
+ this._updateInputWidth();
1998
+ }
1999
+
2000
+ if (event.added || event.removed) {
2001
+ if (this.dropdown) {
2002
+ this.dropdown.showResults(this.filterResults(this.dropdown.results), {
2003
+ hasMore: this.dropdown.hasMore
2004
+ });
2005
+ }
2006
+
2007
+ if (!hasTouch) {
2008
+ this.focus();
2009
+ }
2010
+ }
2011
+
2012
+ this.positionDropdown();
2013
+
2014
+ this._updatePlaceholder();
2015
+ },
2016
+
2017
+ /**
2018
+ * @inherit
2019
+ */
2020
+ search: function(term) {
2021
+ if (this.options.tokenizer) {
2022
+ term = this.options.tokenizer(term, this._data, this.add.bind(this), this.options);
2023
+
2024
+ if (isString(term) && term !== this.input.value) {
2025
+ this.input.value = term;
2026
+ }
2027
+ }
2028
+
2029
+ this._updateInputWidth();
2030
+
2031
+ if (this.dropdown) {
2032
+ callSuper(this, 'search', term);
2033
+ }
2034
+ },
2035
+
2036
+ /**
2037
+ * @inherit
2038
+ */
2039
+ setOptions: function(options) {
2040
+ var wasEnabled = this.enabled;
2041
+
2042
+ callSuper(this, 'setOptions', options);
2043
+
2044
+ if (wasEnabled !== this.enabled) {
2045
+ this._reset();
2046
+ }
2047
+ },
2048
+
2049
+ /**
2050
+ * Validates data to set. Throws an exception if the data is invalid.
2051
+ *
2052
+ * @param data The data to validate. Should be an array of objects with 'id' and 'text'
2053
+ * properties.
2054
+ *
2055
+ * @return The validated data. This may differ from the input data.
2056
+ */
2057
+ validateData: function(data) {
2058
+ if (data === null) {
2059
+ return [];
2060
+ } else if (Array.isArray(data)) {
2061
+ return data.map(this.validateItem, this);
2062
+ } else {
2063
+ throw new Error('Data for MultiSelectivity instance should be an array');
2064
+ }
2065
+ },
2066
+
2067
+ /**
2068
+ * Validates a value to set. Throws an exception if the value is invalid.
2069
+ *
2070
+ * @param value The value to validate. Should be an array of IDs.
2071
+ *
2072
+ * @return The validated value. This may differ from the input value.
2073
+ */
2074
+ validateValue: function(value) {
2075
+ if (value === null) {
2076
+ return [];
2077
+ } else if (Array.isArray(value)) {
2078
+ if (value.every(Selectivity.isValidId)) {
2079
+ return value;
2080
+ } else {
2081
+ throw new Error('Value contains invalid IDs');
2082
+ }
2083
+ } else {
2084
+ throw new Error('Value for MultiSelectivity instance should be an array');
2085
+ }
2086
+ },
2087
+
2088
+ /**
2089
+ * @private
2090
+ */
2091
+ _backspacePressed: function() {
2092
+ if (this.options.backspaceHighlightsBeforeDelete) {
2093
+ if (this._highlightedItemId) {
2094
+ this._deletePressed();
2095
+ } else if (this._value.length) {
2096
+ this._highlightItem(this._value.slice(-1)[0]);
2097
+ }
2098
+ } else if (this._value.length) {
2099
+ this.remove(this._value.slice(-1)[0]);
2100
+ }
2101
+ },
2102
+
2103
+ /**
2104
+ * @private
2105
+ */
2106
+ _clicked: function(event) {
2107
+ if (this.enabled) {
2108
+ if (this.options.showDropdown !== false) {
2109
+ this.open();
2110
+ } else {
2111
+ this.focus();
2112
+ }
2113
+
2114
+ stopPropagation(event);
2115
+ }
2116
+ },
2117
+
2118
+ /**
2119
+ * @private
2120
+ */
2121
+ _createToken: function() {
2122
+ var term = this.input.value;
2123
+ var createTokenItem = this.options.createTokenItem;
2124
+
2125
+ if (term && createTokenItem) {
2126
+ var item = createTokenItem(term);
2127
+ if (item) {
2128
+ this.add(item);
2129
+ }
2130
+ }
2131
+ },
2132
+
2133
+ /**
2134
+ * @private
2135
+ */
2136
+ _deletePressed: function() {
2137
+ if (this._highlightedItemId) {
2138
+ this.remove(this._highlightedItemId);
2139
+ }
2140
+ },
2141
+
2142
+ /**
2143
+ * @private
2144
+ */
2145
+ _forEachSelectedItem: function(callback) {
2146
+ Array.prototype.forEach.call(this.el.querySelectorAll(SELECTED_ITEM_SELECTOR), callback);
2147
+ },
2148
+
2149
+ /**
2150
+ * @private
2151
+ */
2152
+ _highlightItem: function(id) {
2153
+ this._highlightedItemId = id;
2154
+
2155
+ this._forEachSelectedItem(function(el) {
2156
+ toggleClass(el, 'highlighted', el.getAttribute('data-item-id') === id);
2157
+ });
2158
+
2159
+ if (!hasTouch) {
2160
+ this.focus();
2161
+ }
2162
+ },
2163
+
2164
+ /**
2165
+ * @private
2166
+ */
2167
+ _itemClicked: function(event) {
2168
+ if (this.enabled) {
2169
+ this._highlightItem(this.getRelatedItemId(event));
2170
+ }
2171
+ },
2172
+
2173
+ /**
2174
+ * @private
2175
+ */
2176
+ _itemRemoveClicked: function(event) {
2177
+ this.remove(this.getRelatedItemId(event));
2178
+
2179
+ stopPropagation(event);
2180
+ },
2181
+
2182
+ /**
2183
+ * @private
2184
+ */
2185
+ _keyHeld: function(event) {
2186
+ this._originalValue = this.input.value;
2187
+
2188
+ if (getKeyCode(event) === KEY_ENTER && !event.ctrlKey) {
2189
+ event.preventDefault();
2190
+ }
2191
+ },
2192
+
2193
+ /**
2194
+ * @private
2195
+ */
2196
+ _keyReleased: function(event) {
2197
+ var inputHadText = !!this._originalValue;
2198
+ var keyCode = getKeyCode(event);
2199
+
2200
+ if (keyCode === KEY_ENTER && !event.ctrlKey) {
2201
+ this._createToken();
2202
+ } else if (keyCode === KEY_BACKSPACE && !inputHadText) {
2203
+ this._backspacePressed();
2204
+ } else if (keyCode === KEY_DELETE && !inputHadText) {
2205
+ this._deletePressed();
2206
+ }
2207
+ },
2208
+
2209
+ /**
2210
+ * @private
2211
+ */
2212
+ _onPaste: function() {
2213
+ setTimeout(
2214
+ function() {
2215
+ this.search(this.input.value);
2216
+
2217
+ this._createToken();
2218
+ }.bind(this),
2219
+ 10
2220
+ );
2221
+ },
2222
+
2223
+ /**
2224
+ * @private
2225
+ */
2226
+ _renderSelectedItem: function(item) {
2227
+ var el = parseElement(
2228
+ this.template(
2229
+ 'multipleSelectedItem',
2230
+ assign(
2231
+ {
2232
+ highlighted: item.id === this._highlightedItemId,
2233
+ removable: !this.options.readOnly
2234
+ },
2235
+ item
2236
+ )
2237
+ )
2238
+ );
2239
+
2240
+ this.input.parentNode.insertBefore(el, this.input);
2241
+ },
2242
+
2243
+ /**
2244
+ * @private
2245
+ */
2246
+ _reset: function() {
2247
+ this.el.innerHTML = this.template('multipleSelectInput', { enabled: this.enabled });
2248
+
2249
+ this._highlightedItemId = null;
2250
+
2251
+ this.initInput(this.$(INPUT_SELECTOR));
2252
+
2253
+ this.rerenderSelection();
2254
+ },
2255
+
2256
+ /**
2257
+ * @private
2258
+ */
2259
+ _resultSelected: function(event) {
2260
+ if (this._value.indexOf(event.id) === -1) {
2261
+ this.add(event.item);
2262
+ } else {
2263
+ this.remove(event.item);
2264
+ }
2265
+ },
2266
+
2267
+ /**
2268
+ * @private
2269
+ */
2270
+ _scrollToBottom: function() {
2271
+ var inputContainer = this.$(INPUT_SELECTOR + '-container');
2272
+ inputContainer.scrollTop = inputContainer.clientHeight;
2273
+ },
2274
+
2275
+ /**
2276
+ * @private
2277
+ */
2278
+ _updateInputWidth: function() {
2279
+ if (this.enabled) {
2280
+ var inputContent =
2281
+ this.input.value || (!this._data.length && this.options.placeholder) || '';
2282
+ this.input.setAttribute('size', inputContent.length + 2);
2283
+
2284
+ this.positionDropdown();
2285
+ }
2286
+ },
2287
+
2288
+ /**
2289
+ * @private
2290
+ */
2291
+ _updatePlaceholder: function() {
2292
+ var placeholder = (!this._data.length && this.options.placeholder) || '';
2293
+ if (this.enabled) {
2294
+ this.input.setAttribute('placeholder', placeholder);
2295
+ } else {
2296
+ this.$('.selectivity-placeholder').textContent = placeholder;
2297
+ }
2298
+ }
2299
+ });
2300
+
2301
+ module.exports = Selectivity.Inputs.Multiple = MultipleInput;
2302
+
2303
+ },{"16":16,"38":38,"41":41,"42":42,"44":44,"45":45,"46":46,"47":47,"lodash/assign":"lodash/assign"}],26:[function(_dereq_,module,exports){
2304
+ 'use strict';
2305
+
2306
+ var assign = (window.jQuery || window.Zepto).extend;
2307
+
2308
+ var Selectivity = _dereq_(38);
2309
+ var stopPropagation = _dereq_(46);
2310
+
2311
+ /**
2312
+ * SingleInput Constructor.
2313
+ */
2314
+ function SingleInput(options) {
2315
+ Selectivity.call(
2316
+ this,
2317
+ assign(
2318
+ {
2319
+ // Dropdowns for single-value inputs should open below the select box, unless there
2320
+ // is not enough space below, in which case the dropdown should be moved up just
2321
+ // enough so it fits in the window, but never so much that it reaches above the top.
2322
+ positionDropdown: function(el, selectEl) {
2323
+ var rect = selectEl.getBoundingClientRect();
2324
+ var dropdownTop = rect.bottom;
2325
+
2326
+ var deltaUp = Math.min(
2327
+ Math.max(dropdownTop + el.clientHeight - window.innerHeight, 0),
2328
+ rect.top + rect.height
2329
+ );
2330
+
2331
+ assign(el.style, {
2332
+ left: rect.left + 'px',
2333
+ top: dropdownTop - deltaUp + 'px',
2334
+ width: rect.width + 'px'
2335
+ });
2336
+ }
2337
+ },
2338
+ options
2339
+ )
2340
+ );
2341
+
2342
+ this.rerender();
2343
+
2344
+ if (options.showSearchInputInDropdown === false) {
2345
+ this.initInput(this.$('.selectivity-single-select-input'), { search: false });
2346
+ }
2347
+
2348
+ this.events.on({
2349
+ change: this.rerenderSelection,
2350
+ click: this._clicked,
2351
+ 'click .selectivity-search-input': stopPropagation,
2352
+ 'click .selectivity-single-selected-item-remove': this._itemRemoveClicked,
2353
+ 'focus .selectivity-single-select-input': this._focused,
2354
+ 'selectivity-selected': this._resultSelected
2355
+ });
2356
+ }
2357
+
2358
+ /**
2359
+ * Methods.
2360
+ */
2361
+ var callSuper = Selectivity.inherits(SingleInput, Selectivity, {
2362
+ /**
2363
+ * Clears the data and value.
2364
+ */
2365
+ clear: function() {
2366
+ this.setData(null);
2367
+ },
2368
+
2369
+ /**
2370
+ * @inherit
2371
+ *
2372
+ * @param options Optional options object. May contain the following property:
2373
+ * keepFocus - If true, the focus will remain on the input.
2374
+ */
2375
+ close: function(options) {
2376
+ this._closing = true;
2377
+
2378
+ callSuper(this, 'close');
2379
+
2380
+ if (options && options.keepFocus && this.input) {
2381
+ this.input.focus();
2382
+ }
2383
+
2384
+ this._closing = false;
2385
+ },
2386
+
2387
+ /**
2388
+ * Returns the correct data for a given value.
2389
+ *
2390
+ * @param value The value to get the data for. Should be an ID.
2391
+ *
2392
+ * @return The corresponding data. Will be an object with 'id' and 'text' properties. Note that
2393
+ * if no items are defined, this method assumes the text label will be equal to the ID.
2394
+ */
2395
+ getDataForValue: function(value) {
2396
+ return this.getItemForId(value);
2397
+ },
2398
+
2399
+ /**
2400
+ * Returns the correct value for the given data.
2401
+ *
2402
+ * @param data The data to get the value for. Should be an object with 'id' and 'text'
2403
+ * properties or null.
2404
+ *
2405
+ * @return The corresponding value. Will be an ID or null.
2406
+ */
2407
+ getValueForData: function(data) {
2408
+ return data ? data.id : null;
2409
+ },
2410
+
2411
+ /**
2412
+ * Rerenders the entire component.
2413
+ */
2414
+ rerender: function() {
2415
+ this.el.innerHTML = this.template('singleSelectInput', this.options);
2416
+
2417
+ this.rerenderSelection();
2418
+ },
2419
+
2420
+ /**
2421
+ * Re-renders the selection.
2422
+ *
2423
+ * Normally the UI is automatically updated whenever the selection changes, but you may want to
2424
+ * call this method explicitly if you've updated the selection with the triggerChange option set
2425
+ * to false.
2426
+ */
2427
+ rerenderSelection: function() {
2428
+ var template = this._data ? 'singleSelectedItem' : 'singleSelectPlaceholder';
2429
+ var options = this._data
2430
+ ? assign(
2431
+ {
2432
+ removable: this.options.allowClear && !this.options.readOnly
2433
+ },
2434
+ this._data
2435
+ )
2436
+ : { placeholder: this.options.placeholder };
2437
+
2438
+ this.el.querySelector('input').value = this._value;
2439
+ this.$('.selectivity-single-result-container').innerHTML = this.template(template, options);
2440
+ },
2441
+
2442
+ /**
2443
+ * @inherit
2444
+ */
2445
+ setOptions: function(options) {
2446
+ var wasEnabled = this.enabled;
2447
+
2448
+ callSuper(this, 'setOptions', options);
2449
+
2450
+ if (wasEnabled !== this.enabled) {
2451
+ this.rerender();
2452
+ }
2453
+ },
2454
+
2455
+ /**
2456
+ * Validates data to set. Throws an exception if the data is invalid.
2457
+ *
2458
+ * @param data The data to validate. Should be an object with 'id' and 'text' properties or null
2459
+ * to indicate no item is selected.
2460
+ *
2461
+ * @return The validated data. This may differ from the input data.
2462
+ */
2463
+ validateData: function(data) {
2464
+ return data === null ? data : this.validateItem(data);
2465
+ },
2466
+
2467
+ /**
2468
+ * Validates a value to set. Throws an exception if the value is invalid.
2469
+ *
2470
+ * @param value The value to validate. Should be null or a valid ID.
2471
+ *
2472
+ * @return The validated value. This may differ from the input value.
2473
+ */
2474
+ validateValue: function(value) {
2475
+ if (value === null || Selectivity.isValidId(value)) {
2476
+ return value;
2477
+ } else {
2478
+ throw new Error('Value for SingleSelectivity instance should be a valid ID or null');
2479
+ }
2480
+ },
2481
+
2482
+ /**
2483
+ * @private
2484
+ */
2485
+ _clicked: function() {
2486
+ if (this.enabled) {
2487
+ if (this.dropdown) {
2488
+ this.close({ keepFocus: true });
2489
+ } else if (this.options.showDropdown !== false) {
2490
+ this.open();
2491
+ }
2492
+ }
2493
+ },
2494
+
2495
+ /**
2496
+ * @private
2497
+ */
2498
+ _focused: function() {
2499
+ if (
2500
+ this.enabled &&
2501
+ !this._closing &&
2502
+ !this._opening &&
2503
+ this.options.showDropdown !== false
2504
+ ) {
2505
+ this.open();
2506
+ }
2507
+ },
2508
+
2509
+ /**
2510
+ * @private
2511
+ */
2512
+ _itemRemoveClicked: function(event) {
2513
+ this.setData(null);
2514
+
2515
+ stopPropagation(event);
2516
+ },
2517
+
2518
+ /**
2519
+ * @private
2520
+ */
2521
+ _resultSelected: function(event) {
2522
+ this.setData(event.item);
2523
+
2524
+ this.close({ keepFocus: true });
2525
+ }
2526
+ });
2527
+
2528
+ module.exports = Selectivity.Inputs.Single = SingleInput;
2529
+
2530
+ },{"38":38,"46":46,"lodash/assign":"lodash/assign"}],27:[function(_dereq_,module,exports){
2531
+ 'use strict';
2532
+
2533
+ var escape = _dereq_(12);
2534
+
2535
+ var Selectivity = _dereq_(38);
2536
+
2537
+ /**
2538
+ * Localizable elements of the Selectivity Templates.
2539
+ *
2540
+ * Be aware that these strings are added straight to the HTML output of the templates, so any
2541
+ * non-safe strings should be escaped.
2542
+ */
2543
+ module.exports = Selectivity.Locale = {
2544
+ loading: 'Loading...',
2545
+ loadMore: 'Load more...',
2546
+ noResults: 'No results found',
2547
+
2548
+ ajaxError: function(term) {
2549
+ if (term) {
2550
+ return 'Failed to fetch results for <b>' + escape(term) + '</b>';
2551
+ } else {
2552
+ return 'Failed to fetch results';
2553
+ }
2554
+ },
2555
+
2556
+ needMoreCharacters: function(numCharacters) {
2557
+ return 'Enter ' + numCharacters + ' more characters to search';
2558
+ },
2559
+
2560
+ noResultsForTerm: function(term) {
2561
+ return 'No results for <b>' + escape(term) + '</b>';
2562
+ }
2563
+ };
2564
+
2565
+ },{"12":12,"38":38}],28:[function(_dereq_,module,exports){
2566
+ 'use strict';
2567
+
2568
+ var debounce = _dereq_(11);
2569
+
2570
+ var Selectivity = _dereq_(38);
2571
+ var Locale = _dereq_(27);
2572
+
2573
+ function addUrlParam(url, key, value) {
2574
+ return url + (url.indexOf('?') > -1 ? '&' : '?') + key + '=' + encodeURIComponent(value);
2575
+ }
2576
+
2577
+ function pick(object, keys) {
2578
+ var result = {};
2579
+ keys.forEach(function(key) {
2580
+ if (object[key] !== undefined) {
2581
+ result[key] = object[key];
2582
+ }
2583
+ });
2584
+ return result;
2585
+ }
2586
+
2587
+ function doFetch(ajax, queryOptions) {
2588
+ var fetch = ajax.fetch || window.fetch;
2589
+ var term = queryOptions.term;
2590
+
2591
+ var url = typeof ajax.url === 'function' ? ajax.url(queryOptions) : ajax.url;
2592
+ if (ajax.params) {
2593
+ var params = ajax.params(term, queryOptions.offset || 0);
2594
+ for (var key in params) {
2595
+ if (params.hasOwnProperty(key)) {
2596
+ url = addUrlParam(url, key, params[key]);
2597
+ }
2598
+ }
2599
+ }
2600
+
2601
+ var init = pick(ajax, [
2602
+ 'body',
2603
+ 'cache',
2604
+ 'credentials',
2605
+ 'headers',
2606
+ 'integrity',
2607
+ 'method',
2608
+ 'mode',
2609
+ 'redirect',
2610
+ 'referrer',
2611
+ 'referrerPolicy'
2612
+ ]);
2613
+
2614
+ fetch(url, init, queryOptions)
2615
+ .then(function(response) {
2616
+ if (response.ok) {
2617
+ return response.json();
2618
+ } else if (Array.isArray(response) || response.results) {
2619
+ return response;
2620
+ } else {
2621
+ throw new Error('Unexpected AJAX response');
2622
+ }
2623
+ })
2624
+ .then(function(response) {
2625
+ if (Array.isArray(response)) {
2626
+ queryOptions.callback({ results: response, more: false });
2627
+ } else {
2628
+ queryOptions.callback({ results: response.results, more: !!response.more });
2629
+ }
2630
+ })
2631
+ .catch(function(error) {
2632
+ var formatError = ajax.formatError || Locale.ajaxError;
2633
+ queryOptions.error(formatError(term, error), { escape: false });
2634
+ });
2635
+ }
2636
+
2637
+ /**
2638
+ * Option listener that implements a convenience query function for performing AJAX requests.
2639
+ */
2640
+ Selectivity.OptionListeners.unshift(function(selectivity, options) {
2641
+ var ajax = options.ajax;
2642
+ if (ajax && ajax.url) {
2643
+ var fetch = ajax.quietMillis ? debounce(doFetch, ajax.quietMillis) : doFetch;
2644
+
2645
+ options.query = function(queryOptions) {
2646
+ var numCharsNeeded = ajax.minimumInputLength - queryOptions.term.length;
2647
+ if (numCharsNeeded > 0) {
2648
+ queryOptions.error(Locale.needMoreCharacters(numCharsNeeded));
2649
+ return;
2650
+ }
2651
+
2652
+ fetch(ajax, queryOptions);
2653
+ };
2654
+ }
2655
+ });
2656
+
2657
+ },{"11":11,"27":27,"38":38}],29:[function(_dereq_,module,exports){
2658
+ 'use strict';
2659
+
2660
+ var Selectivity = _dereq_(38);
2661
+
2662
+ var latestQueryNum = 0;
2663
+
2664
+ /**
2665
+ * Option listener that will discard any callbacks from the query function if another query has
2666
+ * been called afterwards. This prevents responses from remote sources arriving out-of-order.
2667
+ */
2668
+ Selectivity.OptionListeners.push(function(selectivity, options) {
2669
+ var query = options.query;
2670
+ if (query && !query._async) {
2671
+ options.query = function(queryOptions) {
2672
+ latestQueryNum++;
2673
+ var queryNum = latestQueryNum;
2674
+
2675
+ var callback = queryOptions.callback;
2676
+ var error = queryOptions.error;
2677
+ queryOptions.callback = function() {
2678
+ if (queryNum === latestQueryNum) {
2679
+ callback.apply(null, arguments);
2680
+ }
2681
+ };
2682
+ queryOptions.error = function() {
2683
+ if (queryNum === latestQueryNum) {
2684
+ error.apply(null, arguments);
2685
+ }
2686
+ };
2687
+ query(queryOptions);
2688
+ };
2689
+ options.query._async = true;
2690
+ }
2691
+ });
2692
+
2693
+ },{"38":38}],30:[function(_dereq_,module,exports){
2694
+ 'use strict';
2695
+
2696
+ var DIACRITICS = {
2697
+ '\u24B6': 'A',
2698
+ A: 'A',
2699
+ À: 'A',
2700
+ Á: 'A',
2701
+ Â: 'A',
2702
+ Ầ: 'A',
2703
+ Ấ: 'A',
2704
+ Ẫ: 'A',
2705
+ Ẩ: 'A',
2706
+ Ã: 'A',
2707
+ Ā: 'A',
2708
+ Ă: 'A',
2709
+ Ằ: 'A',
2710
+ Ắ: 'A',
2711
+ Ẵ: 'A',
2712
+ Ẳ: 'A',
2713
+ Ȧ: 'A',
2714
+ Ǡ: 'A',
2715
+ Ä: 'A',
2716
+ Ǟ: 'A',
2717
+ Ả: 'A',
2718
+ Å: 'A',
2719
+ Ǻ: 'A',
2720
+ Ǎ: 'A',
2721
+ Ȁ: 'A',
2722
+ Ȃ: 'A',
2723
+ Ạ: 'A',
2724
+ Ậ: 'A',
2725
+ Ặ: 'A',
2726
+ Ḁ: 'A',
2727
+ Ą: 'A',
2728
+ Ⱥ: 'A',
2729
+ Ɐ: 'A',
2730
+ Ꜳ: 'AA',
2731
+ Æ: 'AE',
2732
+ Ǽ: 'AE',
2733
+ Ǣ: 'AE',
2734
+ Ꜵ: 'AO',
2735
+ Ꜷ: 'AU',
2736
+ Ꜹ: 'AV',
2737
+ Ꜻ: 'AV',
2738
+ Ꜽ: 'AY',
2739
+ '\u24B7': 'B',
2740
+ B: 'B',
2741
+ Ḃ: 'B',
2742
+ Ḅ: 'B',
2743
+ Ḇ: 'B',
2744
+ Ƀ: 'B',
2745
+ Ƃ: 'B',
2746
+ Ɓ: 'B',
2747
+ '\u24B8': 'C',
2748
+ C: 'C',
2749
+ Ć: 'C',
2750
+ Ĉ: 'C',
2751
+ Ċ: 'C',
2752
+ Č: 'C',
2753
+ Ç: 'C',
2754
+ Ḉ: 'C',
2755
+ Ƈ: 'C',
2756
+ Ȼ: 'C',
2757
+ Ꜿ: 'C',
2758
+ '\u24B9': 'D',
2759
+ D: 'D',
2760
+ Ḋ: 'D',
2761
+ Ď: 'D',
2762
+ Ḍ: 'D',
2763
+ Ḑ: 'D',
2764
+ Ḓ: 'D',
2765
+ Ḏ: 'D',
2766
+ Đ: 'D',
2767
+ Ƌ: 'D',
2768
+ Ɗ: 'D',
2769
+ Ɖ: 'D',
2770
+ Ꝺ: 'D',
2771
+ DZ: 'DZ',
2772
+ DŽ: 'DZ',
2773
+ Dz: 'Dz',
2774
+ Dž: 'Dz',
2775
+ '\u24BA': 'E',
2776
+ E: 'E',
2777
+ È: 'E',
2778
+ É: 'E',
2779
+ Ê: 'E',
2780
+ Ề: 'E',
2781
+ Ế: 'E',
2782
+ Ễ: 'E',
2783
+ Ể: 'E',
2784
+ Ẽ: 'E',
2785
+ Ē: 'E',
2786
+ Ḕ: 'E',
2787
+ Ḗ: 'E',
2788
+ Ĕ: 'E',
2789
+ Ė: 'E',
2790
+ Ë: 'E',
2791
+ Ẻ: 'E',
2792
+ Ě: 'E',
2793
+ Ȅ: 'E',
2794
+ Ȇ: 'E',
2795
+ Ẹ: 'E',
2796
+ Ệ: 'E',
2797
+ Ȩ: 'E',
2798
+ Ḝ: 'E',
2799
+ Ę: 'E',
2800
+ Ḙ: 'E',
2801
+ Ḛ: 'E',
2802
+ Ɛ: 'E',
2803
+ Ǝ: 'E',
2804
+ '\u24BB': 'F',
2805
+ F: 'F',
2806
+ Ḟ: 'F',
2807
+ Ƒ: 'F',
2808
+ Ꝼ: 'F',
2809
+ '\u24BC': 'G',
2810
+ G: 'G',
2811
+ Ǵ: 'G',
2812
+ Ĝ: 'G',
2813
+ Ḡ: 'G',
2814
+ Ğ: 'G',
2815
+ Ġ: 'G',
2816
+ Ǧ: 'G',
2817
+ Ģ: 'G',
2818
+ Ǥ: 'G',
2819
+ Ɠ: 'G',
2820
+ Ꞡ: 'G',
2821
+ Ᵹ: 'G',
2822
+ Ꝿ: 'G',
2823
+ '\u24BD': 'H',
2824
+ H: 'H',
2825
+ Ĥ: 'H',
2826
+ Ḣ: 'H',
2827
+ Ḧ: 'H',
2828
+ Ȟ: 'H',
2829
+ Ḥ: 'H',
2830
+ Ḩ: 'H',
2831
+ Ḫ: 'H',
2832
+ Ħ: 'H',
2833
+ Ⱨ: 'H',
2834
+ Ⱶ: 'H',
2835
+ Ɥ: 'H',
2836
+ '\u24BE': 'I',
2837
+ I: 'I',
2838
+ Ì: 'I',
2839
+ Í: 'I',
2840
+ Î: 'I',
2841
+ Ĩ: 'I',
2842
+ Ī: 'I',
2843
+ Ĭ: 'I',
2844
+ İ: 'I',
2845
+ Ï: 'I',
2846
+ Ḯ: 'I',
2847
+ Ỉ: 'I',
2848
+ Ǐ: 'I',
2849
+ Ȉ: 'I',
2850
+ Ȋ: 'I',
2851
+ Ị: 'I',
2852
+ Į: 'I',
2853
+ Ḭ: 'I',
2854
+ Ɨ: 'I',
2855
+ '\u24BF': 'J',
2856
+ J: 'J',
2857
+ Ĵ: 'J',
2858
+ Ɉ: 'J',
2859
+ '\u24C0': 'K',
2860
+ K: 'K',
2861
+ Ḱ: 'K',
2862
+ Ǩ: 'K',
2863
+ Ḳ: 'K',
2864
+ Ķ: 'K',
2865
+ Ḵ: 'K',
2866
+ Ƙ: 'K',
2867
+ Ⱪ: 'K',
2868
+ Ꝁ: 'K',
2869
+ Ꝃ: 'K',
2870
+ Ꝅ: 'K',
2871
+ Ꞣ: 'K',
2872
+ '\u24C1': 'L',
2873
+ L: 'L',
2874
+ Ŀ: 'L',
2875
+ Ĺ: 'L',
2876
+ Ľ: 'L',
2877
+ Ḷ: 'L',
2878
+ Ḹ: 'L',
2879
+ Ļ: 'L',
2880
+ Ḽ: 'L',
2881
+ Ḻ: 'L',
2882
+ Ł: 'L',
2883
+ Ƚ: 'L',
2884
+ Ɫ: 'L',
2885
+ Ⱡ: 'L',
2886
+ Ꝉ: 'L',
2887
+ Ꝇ: 'L',
2888
+ Ꞁ: 'L',
2889
+ LJ: 'LJ',
2890
+ Lj: 'Lj',
2891
+ '\u24C2': 'M',
2892
+ M: 'M',
2893
+ Ḿ: 'M',
2894
+ Ṁ: 'M',
2895
+ Ṃ: 'M',
2896
+ Ɱ: 'M',
2897
+ Ɯ: 'M',
2898
+ '\u24C3': 'N',
2899
+ N: 'N',
2900
+ Ǹ: 'N',
2901
+ Ń: 'N',
2902
+ Ñ: 'N',
2903
+ Ṅ: 'N',
2904
+ Ň: 'N',
2905
+ Ṇ: 'N',
2906
+ Ņ: 'N',
2907
+ Ṋ: 'N',
2908
+ Ṉ: 'N',
2909
+ Ƞ: 'N',
2910
+ Ɲ: 'N',
2911
+ Ꞑ: 'N',
2912
+ Ꞥ: 'N',
2913
+ NJ: 'NJ',
2914
+ Nj: 'Nj',
2915
+ '\u24C4': 'O',
2916
+ O: 'O',
2917
+ Ò: 'O',
2918
+ Ó: 'O',
2919
+ Ô: 'O',
2920
+ Ồ: 'O',
2921
+ Ố: 'O',
2922
+ Ỗ: 'O',
2923
+ Ổ: 'O',
2924
+ Õ: 'O',
2925
+ Ṍ: 'O',
2926
+ Ȭ: 'O',
2927
+ Ṏ: 'O',
2928
+ Ō: 'O',
2929
+ Ṑ: 'O',
2930
+ Ṓ: 'O',
2931
+ Ŏ: 'O',
2932
+ Ȯ: 'O',
2933
+ Ȱ: 'O',
2934
+ Ö: 'O',
2935
+ Ȫ: 'O',
2936
+ Ỏ: 'O',
2937
+ Ő: 'O',
2938
+ Ǒ: 'O',
2939
+ Ȍ: 'O',
2940
+ Ȏ: 'O',
2941
+ Ơ: 'O',
2942
+ Ờ: 'O',
2943
+ Ớ: 'O',
2944
+ Ỡ: 'O',
2945
+ Ở: 'O',
2946
+ Ợ: 'O',
2947
+ Ọ: 'O',
2948
+ Ộ: 'O',
2949
+ Ǫ: 'O',
2950
+ Ǭ: 'O',
2951
+ Ø: 'O',
2952
+ Ǿ: 'O',
2953
+ Ɔ: 'O',
2954
+ Ɵ: 'O',
2955
+ Ꝋ: 'O',
2956
+ Ꝍ: 'O',
2957
+ Ƣ: 'OI',
2958
+ Ꝏ: 'OO',
2959
+ Ȣ: 'OU',
2960
+ '\u24C5': 'P',
2961
+ P: 'P',
2962
+ Ṕ: 'P',
2963
+ Ṗ: 'P',
2964
+ Ƥ: 'P',
2965
+ Ᵽ: 'P',
2966
+ Ꝑ: 'P',
2967
+ Ꝓ: 'P',
2968
+ Ꝕ: 'P',
2969
+ '\u24C6': 'Q',
2970
+ Q: 'Q',
2971
+ Ꝗ: 'Q',
2972
+ Ꝙ: 'Q',
2973
+ Ɋ: 'Q',
2974
+ '\u24C7': 'R',
2975
+ R: 'R',
2976
+ Ŕ: 'R',
2977
+ Ṙ: 'R',
2978
+ Ř: 'R',
2979
+ Ȑ: 'R',
2980
+ Ȓ: 'R',
2981
+ Ṛ: 'R',
2982
+ Ṝ: 'R',
2983
+ Ŗ: 'R',
2984
+ Ṟ: 'R',
2985
+ Ɍ: 'R',
2986
+ Ɽ: 'R',
2987
+ Ꝛ: 'R',
2988
+ Ꞧ: 'R',
2989
+ Ꞃ: 'R',
2990
+ '\u24C8': 'S',
2991
+ S: 'S',
2992
+ ẞ: 'S',
2993
+ Ś: 'S',
2994
+ Ṥ: 'S',
2995
+ Ŝ: 'S',
2996
+ Ṡ: 'S',
2997
+ Š: 'S',
2998
+ Ṧ: 'S',
2999
+ Ṣ: 'S',
3000
+ Ṩ: 'S',
3001
+ Ș: 'S',
3002
+ Ş: 'S',
3003
+ Ȿ: 'S',
3004
+ Ꞩ: 'S',
3005
+ Ꞅ: 'S',
3006
+ '\u24C9': 'T',
3007
+ T: 'T',
3008
+ Ṫ: 'T',
3009
+ Ť: 'T',
3010
+ Ṭ: 'T',
3011
+ Ț: 'T',
3012
+ Ţ: 'T',
3013
+ Ṱ: 'T',
3014
+ Ṯ: 'T',
3015
+ Ŧ: 'T',
3016
+ Ƭ: 'T',
3017
+ Ʈ: 'T',
3018
+ Ⱦ: 'T',
3019
+ Ꞇ: 'T',
3020
+ Ꜩ: 'TZ',
3021
+ '\u24CA': 'U',
3022
+ U: 'U',
3023
+ Ù: 'U',
3024
+ Ú: 'U',
3025
+ Û: 'U',
3026
+ Ũ: 'U',
3027
+ Ṹ: 'U',
3028
+ Ū: 'U',
3029
+ Ṻ: 'U',
3030
+ Ŭ: 'U',
3031
+ Ü: 'U',
3032
+ Ǜ: 'U',
3033
+ Ǘ: 'U',
3034
+ Ǖ: 'U',
3035
+ Ǚ: 'U',
3036
+ Ủ: 'U',
3037
+ Ů: 'U',
3038
+ Ű: 'U',
3039
+ Ǔ: 'U',
3040
+ Ȕ: 'U',
3041
+ Ȗ: 'U',
3042
+ Ư: 'U',
3043
+ Ừ: 'U',
3044
+ Ứ: 'U',
3045
+ Ữ: 'U',
3046
+ Ử: 'U',
3047
+ Ự: 'U',
3048
+ Ụ: 'U',
3049
+ Ṳ: 'U',
3050
+ Ų: 'U',
3051
+ Ṷ: 'U',
3052
+ Ṵ: 'U',
3053
+ Ʉ: 'U',
3054
+ '\u24CB': 'V',
3055
+ V: 'V',
3056
+ Ṽ: 'V',
3057
+ Ṿ: 'V',
3058
+ Ʋ: 'V',
3059
+ Ꝟ: 'V',
3060
+ Ʌ: 'V',
3061
+ Ꝡ: 'VY',
3062
+ '\u24CC': 'W',
3063
+ W: 'W',
3064
+ Ẁ: 'W',
3065
+ Ẃ: 'W',
3066
+ Ŵ: 'W',
3067
+ Ẇ: 'W',
3068
+ Ẅ: 'W',
3069
+ Ẉ: 'W',
3070
+ Ⱳ: 'W',
3071
+ '\u24CD': 'X',
3072
+ X: 'X',
3073
+ Ẋ: 'X',
3074
+ Ẍ: 'X',
3075
+ '\u24CE': 'Y',
3076
+ Y: 'Y',
3077
+ Ỳ: 'Y',
3078
+ Ý: 'Y',
3079
+ Ŷ: 'Y',
3080
+ Ỹ: 'Y',
3081
+ Ȳ: 'Y',
3082
+ Ẏ: 'Y',
3083
+ Ÿ: 'Y',
3084
+ Ỷ: 'Y',
3085
+ Ỵ: 'Y',
3086
+ Ƴ: 'Y',
3087
+ Ɏ: 'Y',
3088
+ Ỿ: 'Y',
3089
+ '\u24CF': 'Z',
3090
+ Z: 'Z',
3091
+ Ź: 'Z',
3092
+ Ẑ: 'Z',
3093
+ Ż: 'Z',
3094
+ Ž: 'Z',
3095
+ Ẓ: 'Z',
3096
+ Ẕ: 'Z',
3097
+ Ƶ: 'Z',
3098
+ Ȥ: 'Z',
3099
+ Ɀ: 'Z',
3100
+ Ⱬ: 'Z',
3101
+ Ꝣ: 'Z',
3102
+ '\u24D0': 'a',
3103
+ a: 'a',
3104
+ ẚ: 'a',
3105
+ à: 'a',
3106
+ á: 'a',
3107
+ â: 'a',
3108
+ ầ: 'a',
3109
+ ấ: 'a',
3110
+ ẫ: 'a',
3111
+ ẩ: 'a',
3112
+ ã: 'a',
3113
+ ā: 'a',
3114
+ ă: 'a',
3115
+ ằ: 'a',
3116
+ ắ: 'a',
3117
+ ẵ: 'a',
3118
+ ẳ: 'a',
3119
+ ȧ: 'a',
3120
+ ǡ: 'a',
3121
+ ä: 'a',
3122
+ ǟ: 'a',
3123
+ ả: 'a',
3124
+ å: 'a',
3125
+ ǻ: 'a',
3126
+ ǎ: 'a',
3127
+ ȁ: 'a',
3128
+ ȃ: 'a',
3129
+ ạ: 'a',
3130
+ ậ: 'a',
3131
+ ặ: 'a',
3132
+ ḁ: 'a',
3133
+ ą: 'a',
3134
+ ⱥ: 'a',
3135
+ ɐ: 'a',
3136
+ ꜳ: 'aa',
3137
+ æ: 'ae',
3138
+ ǽ: 'ae',
3139
+ ǣ: 'ae',
3140
+ ꜵ: 'ao',
3141
+ ꜷ: 'au',
3142
+ ꜹ: 'av',
3143
+ ꜻ: 'av',
3144
+ ꜽ: 'ay',
3145
+ '\u24D1': 'b',
3146
+ b: 'b',
3147
+ ḃ: 'b',
3148
+ ḅ: 'b',
3149
+ ḇ: 'b',
3150
+ ƀ: 'b',
3151
+ ƃ: 'b',
3152
+ ɓ: 'b',
3153
+ '\u24D2': 'c',
3154
+ c: 'c',
3155
+ ć: 'c',
3156
+ ĉ: 'c',
3157
+ ċ: 'c',
3158
+ č: 'c',
3159
+ ç: 'c',
3160
+ ḉ: 'c',
3161
+ ƈ: 'c',
3162
+ ȼ: 'c',
3163
+ ꜿ: 'c',
3164
+ ↄ: 'c',
3165
+ '\u24D3': 'd',
3166
+ d: 'd',
3167
+ ḋ: 'd',
3168
+ ď: 'd',
3169
+ ḍ: 'd',
3170
+ ḑ: 'd',
3171
+ ḓ: 'd',
3172
+ ḏ: 'd',
3173
+ đ: 'd',
3174
+ ƌ: 'd',
3175
+ ɖ: 'd',
3176
+ ɗ: 'd',
3177
+ ꝺ: 'd',
3178
+ dz: 'dz',
3179
+ dž: 'dz',
3180
+ '\u24D4': 'e',
3181
+ e: 'e',
3182
+ è: 'e',
3183
+ é: 'e',
3184
+ ê: 'e',
3185
+ ề: 'e',
3186
+ ế: 'e',
3187
+ ễ: 'e',
3188
+ ể: 'e',
3189
+ ẽ: 'e',
3190
+ ē: 'e',
3191
+ ḕ: 'e',
3192
+ ḗ: 'e',
3193
+ ĕ: 'e',
3194
+ ė: 'e',
3195
+ ë: 'e',
3196
+ ẻ: 'e',
3197
+ ě: 'e',
3198
+ ȅ: 'e',
3199
+ ȇ: 'e',
3200
+ ẹ: 'e',
3201
+ ệ: 'e',
3202
+ ȩ: 'e',
3203
+ ḝ: 'e',
3204
+ ę: 'e',
3205
+ ḙ: 'e',
3206
+ ḛ: 'e',
3207
+ ɇ: 'e',
3208
+ ɛ: 'e',
3209
+ ǝ: 'e',
3210
+ '\u24D5': 'f',
3211
+ f: 'f',
3212
+ ḟ: 'f',
3213
+ ƒ: 'f',
3214
+ ꝼ: 'f',
3215
+ '\u24D6': 'g',
3216
+ g: 'g',
3217
+ ǵ: 'g',
3218
+ ĝ: 'g',
3219
+ ḡ: 'g',
3220
+ ğ: 'g',
3221
+ ġ: 'g',
3222
+ ǧ: 'g',
3223
+ ģ: 'g',
3224
+ ǥ: 'g',
3225
+ ɠ: 'g',
3226
+ ꞡ: 'g',
3227
+ ᵹ: 'g',
3228
+ ꝿ: 'g',
3229
+ '\u24D7': 'h',
3230
+ h: 'h',
3231
+ ĥ: 'h',
3232
+ ḣ: 'h',
3233
+ ḧ: 'h',
3234
+ ȟ: 'h',
3235
+ ḥ: 'h',
3236
+ ḩ: 'h',
3237
+ ḫ: 'h',
3238
+ ẖ: 'h',
3239
+ ħ: 'h',
3240
+ ⱨ: 'h',
3241
+ ⱶ: 'h',
3242
+ ɥ: 'h',
3243
+ ƕ: 'hv',
3244
+ '\u24D8': 'i',
3245
+ i: 'i',
3246
+ ì: 'i',
3247
+ í: 'i',
3248
+ î: 'i',
3249
+ ĩ: 'i',
3250
+ ī: 'i',
3251
+ ĭ: 'i',
3252
+ ï: 'i',
3253
+ ḯ: 'i',
3254
+ ỉ: 'i',
3255
+ ǐ: 'i',
3256
+ ȉ: 'i',
3257
+ ȋ: 'i',
3258
+ ị: 'i',
3259
+ į: 'i',
3260
+ ḭ: 'i',
3261
+ ɨ: 'i',
3262
+ ı: 'i',
3263
+ '\u24D9': 'j',
3264
+ j: 'j',
3265
+ ĵ: 'j',
3266
+ ǰ: 'j',
3267
+ ɉ: 'j',
3268
+ '\u24DA': 'k',
3269
+ k: 'k',
3270
+ ḱ: 'k',
3271
+ ǩ: 'k',
3272
+ ḳ: 'k',
3273
+ ķ: 'k',
3274
+ ḵ: 'k',
3275
+ ƙ: 'k',
3276
+ ⱪ: 'k',
3277
+ ꝁ: 'k',
3278
+ ꝃ: 'k',
3279
+ ꝅ: 'k',
3280
+ ꞣ: 'k',
3281
+ '\u24DB': 'l',
3282
+ l: 'l',
3283
+ ŀ: 'l',
3284
+ ĺ: 'l',
3285
+ ľ: 'l',
3286
+ ḷ: 'l',
3287
+ ḹ: 'l',
3288
+ ļ: 'l',
3289
+ ḽ: 'l',
3290
+ ḻ: 'l',
3291
+ ſ: 'l',
3292
+ ł: 'l',
3293
+ ƚ: 'l',
3294
+ ɫ: 'l',
3295
+ ⱡ: 'l',
3296
+ ꝉ: 'l',
3297
+ ꞁ: 'l',
3298
+ ꝇ: 'l',
3299
+ lj: 'lj',
3300
+ '\u24DC': 'm',
3301
+ m: 'm',
3302
+ ḿ: 'm',
3303
+ ṁ: 'm',
3304
+ ṃ: 'm',
3305
+ ɱ: 'm',
3306
+ ɯ: 'm',
3307
+ '\u24DD': 'n',
3308
+ n: 'n',
3309
+ ǹ: 'n',
3310
+ ń: 'n',
3311
+ ñ: 'n',
3312
+ ṅ: 'n',
3313
+ ň: 'n',
3314
+ ṇ: 'n',
3315
+ ņ: 'n',
3316
+ ṋ: 'n',
3317
+ ṉ: 'n',
3318
+ ƞ: 'n',
3319
+ ɲ: 'n',
3320
+ ʼn: 'n',
3321
+ ꞑ: 'n',
3322
+ ꞥ: 'n',
3323
+ nj: 'nj',
3324
+ '\u24DE': 'o',
3325
+ o: 'o',
3326
+ ò: 'o',
3327
+ ó: 'o',
3328
+ ô: 'o',
3329
+ ồ: 'o',
3330
+ ố: 'o',
3331
+ ỗ: 'o',
3332
+ ổ: 'o',
3333
+ õ: 'o',
3334
+ ṍ: 'o',
3335
+ ȭ: 'o',
3336
+ ṏ: 'o',
3337
+ ō: 'o',
3338
+ ṑ: 'o',
3339
+ ṓ: 'o',
3340
+ ŏ: 'o',
3341
+ ȯ: 'o',
3342
+ ȱ: 'o',
3343
+ ö: 'o',
3344
+ ȫ: 'o',
3345
+ ỏ: 'o',
3346
+ ő: 'o',
3347
+ ǒ: 'o',
3348
+ ȍ: 'o',
3349
+ ȏ: 'o',
3350
+ ơ: 'o',
3351
+ ờ: 'o',
3352
+ ớ: 'o',
3353
+ ỡ: 'o',
3354
+ ở: 'o',
3355
+ ợ: 'o',
3356
+ ọ: 'o',
3357
+ ộ: 'o',
3358
+ ǫ: 'o',
3359
+ ǭ: 'o',
3360
+ ø: 'o',
3361
+ ǿ: 'o',
3362
+ ɔ: 'o',
3363
+ ꝋ: 'o',
3364
+ ꝍ: 'o',
3365
+ ɵ: 'o',
3366
+ ƣ: 'oi',
3367
+ ȣ: 'ou',
3368
+ ꝏ: 'oo',
3369
+ '\u24DF': 'p',
3370
+ p: 'p',
3371
+ ṕ: 'p',
3372
+ ṗ: 'p',
3373
+ ƥ: 'p',
3374
+ ᵽ: 'p',
3375
+ ꝑ: 'p',
3376
+ ꝓ: 'p',
3377
+ ꝕ: 'p',
3378
+ '\u24E0': 'q',
3379
+ q: 'q',
3380
+ ɋ: 'q',
3381
+ ꝗ: 'q',
3382
+ ꝙ: 'q',
3383
+ '\u24E1': 'r',
3384
+ r: 'r',
3385
+ ŕ: 'r',
3386
+ ṙ: 'r',
3387
+ ř: 'r',
3388
+ ȑ: 'r',
3389
+ ȓ: 'r',
3390
+ ṛ: 'r',
3391
+ ṝ: 'r',
3392
+ ŗ: 'r',
3393
+ ṟ: 'r',
3394
+ ɍ: 'r',
3395
+ ɽ: 'r',
3396
+ ꝛ: 'r',
3397
+ ꞧ: 'r',
3398
+ ꞃ: 'r',
3399
+ '\u24E2': 's',
3400
+ s: 's',
3401
+ ß: 's',
3402
+ ś: 's',
3403
+ ṥ: 's',
3404
+ ŝ: 's',
3405
+ ṡ: 's',
3406
+ š: 's',
3407
+ ṧ: 's',
3408
+ ṣ: 's',
3409
+ ṩ: 's',
3410
+ ș: 's',
3411
+ ş: 's',
3412
+ ȿ: 's',
3413
+ ꞩ: 's',
3414
+ ꞅ: 's',
3415
+ ẛ: 's',
3416
+ '\u24E3': 't',
3417
+ t: 't',
3418
+ ṫ: 't',
3419
+ ẗ: 't',
3420
+ ť: 't',
3421
+ ṭ: 't',
3422
+ ț: 't',
3423
+ ţ: 't',
3424
+ ṱ: 't',
3425
+ ṯ: 't',
3426
+ ŧ: 't',
3427
+ ƭ: 't',
3428
+ ʈ: 't',
3429
+ ⱦ: 't',
3430
+ ꞇ: 't',
3431
+ ꜩ: 'tz',
3432
+ '\u24E4': 'u',
3433
+ u: 'u',
3434
+ ù: 'u',
3435
+ ú: 'u',
3436
+ û: 'u',
3437
+ ũ: 'u',
3438
+ ṹ: 'u',
3439
+ ū: 'u',
3440
+ ṻ: 'u',
3441
+ ŭ: 'u',
3442
+ ü: 'u',
3443
+ ǜ: 'u',
3444
+ ǘ: 'u',
3445
+ ǖ: 'u',
3446
+ ǚ: 'u',
3447
+ ủ: 'u',
3448
+ ů: 'u',
3449
+ ű: 'u',
3450
+ ǔ: 'u',
3451
+ ȕ: 'u',
3452
+ ȗ: 'u',
3453
+ ư: 'u',
3454
+ ừ: 'u',
3455
+ ứ: 'u',
3456
+ ữ: 'u',
3457
+ ử: 'u',
3458
+ ự: 'u',
3459
+ ụ: 'u',
3460
+ ṳ: 'u',
3461
+ ų: 'u',
3462
+ ṷ: 'u',
3463
+ ṵ: 'u',
3464
+ ʉ: 'u',
3465
+ '\u24E5': 'v',
3466
+ v: 'v',
3467
+ ṽ: 'v',
3468
+ ṿ: 'v',
3469
+ ʋ: 'v',
3470
+ ꝟ: 'v',
3471
+ ʌ: 'v',
3472
+ ꝡ: 'vy',
3473
+ '\u24E6': 'w',
3474
+ w: 'w',
3475
+ ẁ: 'w',
3476
+ ẃ: 'w',
3477
+ ŵ: 'w',
3478
+ ẇ: 'w',
3479
+ ẅ: 'w',
3480
+ ẘ: 'w',
3481
+ ẉ: 'w',
3482
+ ⱳ: 'w',
3483
+ '\u24E7': 'x',
3484
+ x: 'x',
3485
+ ẋ: 'x',
3486
+ ẍ: 'x',
3487
+ '\u24E8': 'y',
3488
+ y: 'y',
3489
+ ỳ: 'y',
3490
+ ý: 'y',
3491
+ ŷ: 'y',
3492
+ ỹ: 'y',
3493
+ ȳ: 'y',
3494
+ ẏ: 'y',
3495
+ ÿ: 'y',
3496
+ ỷ: 'y',
3497
+ ẙ: 'y',
3498
+ ỵ: 'y',
3499
+ ƴ: 'y',
3500
+ ɏ: 'y',
3501
+ ỿ: 'y',
3502
+ '\u24E9': 'z',
3503
+ z: 'z',
3504
+ ź: 'z',
3505
+ ẑ: 'z',
3506
+ ż: 'z',
3507
+ ž: 'z',
3508
+ ẓ: 'z',
3509
+ ẕ: 'z',
3510
+ ƶ: 'z',
3511
+ ȥ: 'z',
3512
+ ɀ: 'z',
3513
+ ⱬ: 'z',
3514
+ ꝣ: 'z',
3515
+ Ά: '\u0391',
3516
+ Έ: '\u0395',
3517
+ Ή: '\u0397',
3518
+ Ί: '\u0399',
3519
+ Ϊ: '\u0399',
3520
+ Ό: '\u039F',
3521
+ Ύ: '\u03A5',
3522
+ Ϋ: '\u03A5',
3523
+ Ώ: '\u03A9',
3524
+ ά: '\u03B1',
3525
+ έ: '\u03B5',
3526
+ ή: '\u03B7',
3527
+ ί: '\u03B9',
3528
+ ϊ: '\u03B9',
3529
+ ΐ: '\u03B9',
3530
+ ό: '\u03BF',
3531
+ ύ: '\u03C5',
3532
+ ϋ: '\u03C5',
3533
+ ΰ: '\u03C5',
3534
+ ω: '\u03C9',
3535
+ ς: '\u03C3'
3536
+ };
3537
+
3538
+ var Selectivity = _dereq_(38);
3539
+ var previousTransform = Selectivity.transformText;
3540
+
3541
+ /**
3542
+ * Extended version of the transformText() function that simplifies diacritics to their latin1
3543
+ * counterparts.
3544
+ *
3545
+ * Note that if all query functions fetch their results from a remote server, you may not need this
3546
+ * function, because it makes sense to remove diacritics server-side in such cases.
3547
+ */
3548
+ Selectivity.transformText = function(string) {
3549
+ var result = '';
3550
+ for (var i = 0, length = string.length; i < length; i++) {
3551
+ var character = string[i];
3552
+ result += DIACRITICS[character] || character;
3553
+ }
3554
+ return previousTransform(result);
3555
+ };
3556
+
3557
+ },{"38":38}],31:[function(_dereq_,module,exports){
3558
+ 'use strict';
3559
+
3560
+ var $ = (window.jQuery || window.Zepto);
3561
+
3562
+ var Selectivity = _dereq_(38);
3563
+
3564
+ /**
3565
+ * Option listener that implements a convenience query function for performing AJAX requests.
3566
+ */
3567
+ Selectivity.OptionListeners.unshift(function(selectivity, options) {
3568
+ var ajax = options.ajax;
3569
+ if (ajax && ajax.url && !ajax.fetch && $.Deferred) {
3570
+ ajax.fetch = function(url, init) {
3571
+ return $.ajax(url, {
3572
+ cache: init.cache !== 'no-cache',
3573
+ headers: init.headers || null,
3574
+ method: init.method || 'GET',
3575
+ xhrFields: init.credentials === 'include' ? { withCredentials: true } : null
3576
+ }).then(
3577
+ function(data) {
3578
+ return {
3579
+ results: $.map(data, function(result) {
3580
+ return result;
3581
+ }),
3582
+ more: false
3583
+ };
3584
+ },
3585
+ function(jqXHR, textStatus, errorThrown) {
3586
+ throw new Error(
3587
+ 'AJAX request returned: ' +
3588
+ textStatus +
3589
+ (errorThrown ? ', ' + errorThrown : '')
3590
+ );
3591
+ }
3592
+ );
3593
+ };
3594
+ }
3595
+ });
3596
+
3597
+ },{"38":38,"jquery":"jquery"}],32:[function(_dereq_,module,exports){
3598
+ 'use strict';
3599
+
3600
+ var $ = (window.jQuery || window.Zepto);
3601
+
3602
+ var Selectivity = _dereq_(38);
3603
+
3604
+ function createSelectivityNextToSelectElement($el, options) {
3605
+ var data = options.multiple ? [] : null;
3606
+
3607
+ var mapOptions = function() {
3608
+ var $this = $(this);
3609
+ if ($this.is('option')) {
3610
+ var text = $this.text();
3611
+ var id = $this.attr('value');
3612
+ if (id === undefined) {
3613
+ id = text;
3614
+ }
3615
+ if ($this.prop('selected')) {
3616
+ var item = { id: id, text: text };
3617
+ if (options.multiple) {
3618
+ data.push(item);
3619
+ } else {
3620
+ data = item;
3621
+ }
3622
+ }
3623
+
3624
+ return {
3625
+ id: id,
3626
+ text: $this.attr('label') || text
3627
+ };
3628
+ } else {
3629
+ return {
3630
+ text: $this.attr('label'),
3631
+ children: $this
3632
+ .children('option,optgroup')
3633
+ .map(mapOptions)
3634
+ .get()
3635
+ };
3636
+ }
3637
+ };
3638
+
3639
+ options.allowClear = 'allowClear' in options ? options.allowClear : !$el.prop('required');
3640
+
3641
+ var items = $el
3642
+ .children('option,optgroup')
3643
+ .map(mapOptions)
3644
+ .get();
3645
+ options.data = data;
3646
+
3647
+ options.items = options.query ? null : items;
3648
+
3649
+ options.placeholder = options.placeholder || $el.data('placeholder') || '';
3650
+
3651
+ options.tabIndex =
3652
+ options.tabIndex === undefined ? $el.attr('tabindex') || 0 : options.tabIndex;
3653
+
3654
+ var classes = ($el.attr('class') || 'selectivity-input').split(' ');
3655
+ if (classes.indexOf('selectivity-input') < 0) {
3656
+ classes.push('selectivity-input');
3657
+ }
3658
+
3659
+ var $div = $('<div>').attr({
3660
+ id: 's9y_' + $el.attr('id'),
3661
+ class: classes.join(' '),
3662
+ style: $el.attr('style'),
3663
+ 'data-name': $el.attr('name')
3664
+ });
3665
+ $div.insertAfter($el);
3666
+ $el.hide();
3667
+ return $div[0];
3668
+ }
3669
+
3670
+ function bindTraditionalSelectEvents(selectivity) {
3671
+ var $el = $(selectivity.el);
3672
+ $el.on('change', function(event) {
3673
+ var value = event.originalEvent.value;
3674
+ $el
3675
+ .prev('select')
3676
+ .val($.type(value) === 'array' ? value.slice(0) : value)
3677
+ .trigger(event);
3678
+ });
3679
+ }
3680
+
3681
+ /**
3682
+ * Option listener providing support for converting traditional <select> boxes into Selectivity
3683
+ * instances.
3684
+ */
3685
+ Selectivity.OptionListeners.push(function(selectivity, options) {
3686
+ var $el = $(selectivity.el);
3687
+ if ($el.is('select')) {
3688
+ if ($el.attr('autofocus')) {
3689
+ setTimeout(function() {
3690
+ selectivity.focus();
3691
+ }, 1);
3692
+ }
3693
+
3694
+ selectivity.el = createSelectivityNextToSelectElement($el, options);
3695
+ selectivity.el.selectivity = selectivity;
3696
+
3697
+ Selectivity.patchEvents($el);
3698
+
3699
+ bindTraditionalSelectEvents(selectivity);
3700
+ }
3701
+ });
3702
+
3703
+ },{"38":38,"jquery":"jquery"}],33:[function(_dereq_,module,exports){
3704
+ 'use strict';
3705
+
3706
+ var Selectivity = _dereq_(38);
3707
+ var findResultItem = _dereq_(40);
3708
+ var getKeyCode = _dereq_(42);
3709
+
3710
+ var KEY_BACKSPACE = 8;
3711
+ var KEY_DOWN_ARROW = 40;
3712
+ var KEY_ENTER = 13;
3713
+ var KEY_ESCAPE = 27;
3714
+ var KEY_TAB = 9;
3715
+ var KEY_UP_ARROW = 38;
3716
+
3717
+ /**
3718
+ * Search input listener providing keyboard support for navigating the dropdown.
3719
+ */
3720
+ function listener(selectivity, input) {
3721
+ var keydownCanceled = false;
3722
+ var closeSubmenu = null;
3723
+
3724
+ /**
3725
+ * Moves a dropdown's highlight to the next or previous result item.
3726
+ *
3727
+ * @param delta Either 1 to move to the next item, or -1 to move to the previous item.
3728
+ */
3729
+ function moveHighlight(dropdown, delta) {
3730
+ var results = dropdown.results;
3731
+ if (!results.length) {
3732
+ return;
3733
+ }
3734
+
3735
+ var resultItems = [].slice.call(dropdown.el.querySelectorAll('.selectivity-result-item'));
3736
+
3737
+ function scrollToHighlight() {
3738
+ var el;
3739
+ if (dropdown.highlightedResult) {
3740
+ el = findResultItem(resultItems, dropdown.highlightedResult.id);
3741
+ } else if (dropdown.loadMoreHighlighted) {
3742
+ el = dropdown.$('.selectivity-load-more');
3743
+ }
3744
+
3745
+ if (el && el.scrollIntoView) {
3746
+ el.scrollIntoView(delta < 0);
3747
+ }
3748
+ }
3749
+
3750
+ if (dropdown.submenu) {
3751
+ moveHighlight(dropdown.submenu, delta);
3752
+ return;
3753
+ }
3754
+
3755
+ var defaultIndex = delta > 0 ? 0 : resultItems.length - 1;
3756
+ var index = defaultIndex;
3757
+ var highlightedResult = dropdown.highlightedResult;
3758
+ if (highlightedResult) {
3759
+ var highlightedResultItem = findResultItem(resultItems, highlightedResult.id);
3760
+ index = resultItems.indexOf(highlightedResultItem) + delta;
3761
+ if (delta > 0 ? index >= resultItems.length : index < 0) {
3762
+ if (dropdown.hasMore) {
3763
+ dropdown.highlightLoadMore();
3764
+ scrollToHighlight();
3765
+ return;
3766
+ } else {
3767
+ index = defaultIndex;
3768
+ }
3769
+ }
3770
+ }
3771
+
3772
+ var resultItem = resultItems[index];
3773
+ var result = Selectivity.findNestedById(results, selectivity.getRelatedItemId(resultItem));
3774
+ if (result) {
3775
+ dropdown.highlight(result, { delay: !!result.submenu });
3776
+ scrollToHighlight();
3777
+ }
3778
+ }
3779
+
3780
+ function keyHeld(event) {
3781
+ var dropdown = selectivity.dropdown;
3782
+ if (dropdown) {
3783
+ var keyCode = getKeyCode(event);
3784
+ if (keyCode === KEY_BACKSPACE) {
3785
+ if (!input.value) {
3786
+ if (dropdown.submenu) {
3787
+ var submenu = dropdown.submenu;
3788
+ while (submenu.submenu) {
3789
+ submenu = submenu.submenu;
3790
+ }
3791
+ closeSubmenu = submenu;
3792
+ }
3793
+
3794
+ event.preventDefault();
3795
+ keydownCanceled = true;
3796
+ }
3797
+ } else if (keyCode === KEY_DOWN_ARROW) {
3798
+ moveHighlight(dropdown, 1);
3799
+ } else if (keyCode === KEY_UP_ARROW) {
3800
+ moveHighlight(dropdown, -1);
3801
+ } else if (keyCode === KEY_TAB) {
3802
+ setTimeout(function() {
3803
+ selectivity.close();
3804
+ }, 1);
3805
+ } else if (keyCode === KEY_ENTER) {
3806
+ event.preventDefault(); // don't submit forms on keydown
3807
+ }
3808
+ }
3809
+ }
3810
+
3811
+ function keyReleased(event) {
3812
+ function open() {
3813
+ if (selectivity.options.showDropdown !== false) {
3814
+ selectivity.open();
3815
+ }
3816
+ }
3817
+
3818
+ var dropdown = selectivity.dropdown;
3819
+ var keyCode = getKeyCode(event);
3820
+ if (keydownCanceled) {
3821
+ event.preventDefault();
3822
+ keydownCanceled = false;
3823
+
3824
+ if (closeSubmenu) {
3825
+ closeSubmenu.close();
3826
+ selectivity.focus();
3827
+ closeSubmenu = null;
3828
+ }
3829
+ } else if (keyCode === KEY_BACKSPACE) {
3830
+ if (!dropdown && selectivity.options.allowClear) {
3831
+ selectivity.clear();
3832
+ }
3833
+ } else if (keyCode === KEY_ENTER && !event.ctrlKey) {
3834
+ if (dropdown) {
3835
+ dropdown.selectHighlight();
3836
+ } else if (selectivity.options.showDropdown !== false) {
3837
+ open();
3838
+ }
3839
+
3840
+ event.preventDefault();
3841
+ } else if (keyCode === KEY_ESCAPE) {
3842
+ selectivity.close();
3843
+
3844
+ event.preventDefault();
3845
+ } else if (keyCode === KEY_DOWN_ARROW || keyCode === KEY_UP_ARROW) {
3846
+ // handled in keyHeld() because the response feels faster and it works with repeated
3847
+ // events if the user holds the key for a longer period
3848
+ // still, we issue an open() call here in case the dropdown was not yet open...
3849
+ open();
3850
+
3851
+ event.preventDefault();
3852
+ } else {
3853
+ open();
3854
+ }
3855
+ }
3856
+
3857
+ input.addEventListener('keydown', keyHeld);
3858
+ input.addEventListener('keyup', keyReleased);
3859
+ }
3860
+
3861
+ Selectivity.InputListeners.push(listener);
3862
+
3863
+ },{"38":38,"40":40,"42":42}],34:[function(_dereq_,module,exports){
3864
+ 'use strict';
3865
+
3866
+ var Selectivity = _dereq_(38);
3867
+
3868
+ var allowedOptions = {
3869
+ allowClear: 'boolean',
3870
+ backspaceHighlightsBeforeDelete: 'boolean',
3871
+ closeOnSelect: 'boolean',
3872
+ createTokenItem: 'function',
3873
+ dropdown: 'function|null',
3874
+ initSelection: 'function|null',
3875
+ inputListeners: 'array',
3876
+ items: 'array|null',
3877
+ matcher: 'function|null',
3878
+ placeholder: 'string',
3879
+ positionDropdown: 'function|null',
3880
+ query: 'function|null',
3881
+ readOnly: 'boolean',
3882
+ removeOnly: 'boolean',
3883
+ shouldOpenSubmenu: 'function',
3884
+ showSearchInputInDropdown: 'boolean',
3885
+ suppressWheelSelector: 'string|null',
3886
+ tabIndex: 'number',
3887
+ templates: 'object',
3888
+ tokenizer: 'function'
3889
+ };
3890
+
3891
+ /**
3892
+ * Option listener that validates the options being set. This is useful during debugging to quickly
3893
+ * get notified if you're passing invalid options.
3894
+ */
3895
+ Selectivity.OptionListeners.unshift(function(selectivity, options) {
3896
+ for (var key in options) {
3897
+ if (!options.hasOwnProperty(key)) {
3898
+ continue;
3899
+ }
3900
+
3901
+ var value = options[key];
3902
+ var type = allowedOptions[key];
3903
+ if (
3904
+ type &&
3905
+ !type.split('|').some(function(type) {
3906
+ if (type === 'null') {
3907
+ return value === null;
3908
+ } else if (type === 'array') {
3909
+ return Array.isArray(value);
3910
+ } else {
3911
+ return value !== null && value !== undefined && typeof value === type;
3912
+ }
3913
+ })
3914
+ ) {
3915
+ throw new Error(key + ' must be of type ' + type);
3916
+ }
3917
+ }
3918
+ });
3919
+
3920
+ },{"38":38}],35:[function(_dereq_,module,exports){
3921
+ 'use strict';
3922
+
3923
+ var Dropdown = _dereq_(22);
3924
+ var Selectivity = _dereq_(38);
3925
+
3926
+ var findResultItem = _dereq_(40);
3927
+
3928
+ /**
3929
+ * Extended dropdown that supports submenus.
3930
+ */
3931
+ function SubmenuPlugin(selectivity, options) {
3932
+ /**
3933
+ * Optional parent dropdown menu from which this dropdown was opened.
3934
+ */
3935
+ this.parentMenu = options.parentMenu;
3936
+
3937
+ Dropdown.call(this, selectivity, options);
3938
+
3939
+ this._closeSubmenuTimeout = 0;
3940
+
3941
+ this._openSubmenuTimeout = 0;
3942
+ }
3943
+
3944
+ var callSuper = Selectivity.inherits(SubmenuPlugin, Dropdown, {
3945
+ /**
3946
+ * @inherit
3947
+ */
3948
+ close: function() {
3949
+ if (this.submenu) {
3950
+ this.submenu.close();
3951
+ }
3952
+
3953
+ callSuper(this, 'close');
3954
+
3955
+ if (this.parentMenu) {
3956
+ this.parentMenu.submenu = null;
3957
+ this.parentMenu = null;
3958
+ }
3959
+
3960
+ clearTimeout(this._closeSubmenuTimeout);
3961
+ clearTimeout(this._openSubmenuTimeout);
3962
+ },
3963
+
3964
+ /**
3965
+ * @inherit
3966
+ *
3967
+ * @param options Optional options object. May contain the following properties:
3968
+ * delay - If true, indicates any submenu should not be opened until after some
3969
+ * delay.
3970
+ * openSubmenu - If false, no submenu will be automatically opened for the
3971
+ * highlighted item.
3972
+ * reason - The reason why the result item is being highlighted. See
3973
+ * Dropdown#highlight().
3974
+ */
3975
+ highlight: function(item, options) {
3976
+ options = options || {};
3977
+ var reason = options.reason || 'unspecified';
3978
+
3979
+ if (options.delay) {
3980
+ callSuper(this, 'highlight', item);
3981
+
3982
+ clearTimeout(this._openSubmenuTimeout);
3983
+ this._openSubmenuTimeout = setTimeout(this._doHighlight.bind(this, item, reason), 300);
3984
+ } else if (this.submenu) {
3985
+ if (this.highlightedResult && this.highlightedResult.id === item.id) {
3986
+ this._doHighlight(item, reason);
3987
+ } else {
3988
+ clearTimeout(this._closeSubmenuTimeout);
3989
+ this._closeSubmenuTimeout = setTimeout(
3990
+ this._closeSubmenuAndHighlight.bind(this, item, reason),
3991
+ 100
3992
+ );
3993
+ }
3994
+ } else {
3995
+ if (this.parentMenu && this.parentMenu._closeSubmenuTimeout) {
3996
+ clearTimeout(this.parentMenu._closeSubmenuTimeout);
3997
+ this.parentMenu._closeSubmenuTimeout = 0;
3998
+ }
3999
+
4000
+ if (options.openSubmenu === false) {
4001
+ callSuper(this, 'highlight', item);
4002
+ } else {
4003
+ this._doHighlight(item, reason);
4004
+ }
4005
+ }
4006
+ },
4007
+
4008
+ /**
4009
+ * @inherit
4010
+ */
4011
+ search: function(term) {
4012
+ if (this.submenu) {
4013
+ var searchInput = this.$('.selectivity-search-input');
4014
+ if (searchInput && searchInput === document.activeElement) {
4015
+ this.submenu.close();
4016
+ } else {
4017
+ this.submenu.search(term);
4018
+ return;
4019
+ }
4020
+ }
4021
+
4022
+ callSuper(this, 'search', term);
4023
+ },
4024
+
4025
+ /**
4026
+ * @inherit
4027
+ */
4028
+ selectHighlight: function() {
4029
+ if (this.submenu) {
4030
+ this.submenu.selectHighlight();
4031
+ } else {
4032
+ callSuper(this, 'selectHighlight');
4033
+ }
4034
+ },
4035
+
4036
+ /**
4037
+ * @inherit
4038
+ */
4039
+ showResults: function(results, options) {
4040
+ // makes sure any result item with a submenu that's not explicitly
4041
+ // set as selectable becomes unselectable
4042
+ function setSelectable(item) {
4043
+ if (item.children) {
4044
+ item.children.forEach(setSelectable);
4045
+ }
4046
+ if (item.submenu) {
4047
+ item.selectable = !!item.selectable;
4048
+ }
4049
+ }
4050
+
4051
+ if (this.submenu && options.dropdown !== this) {
4052
+ this.submenu.showResults(results, options);
4053
+ } else {
4054
+ results.forEach(setSelectable);
4055
+ callSuper(this, 'showResults', results, options);
4056
+ }
4057
+ },
4058
+
4059
+ /**
4060
+ * @inherit
4061
+ */
4062
+ triggerClose: function() {
4063
+ if (this.parentMenu) {
4064
+ this.selectivity.triggerEvent('selectivity-close-submenu');
4065
+ } else {
4066
+ callSuper(this, 'triggerClose');
4067
+ }
4068
+ },
4069
+
4070
+ /**
4071
+ * @inherit
4072
+ */
4073
+ triggerOpen: function() {
4074
+ if (this.parentMenu) {
4075
+ this.selectivity.triggerEvent('selectivity-open-submenu');
4076
+ } else {
4077
+ callSuper(this, 'triggerOpen');
4078
+ }
4079
+ },
4080
+
4081
+ /**
4082
+ * @private
4083
+ */
4084
+ _closeSubmenuAndHighlight: function(item, reason) {
4085
+ if (this.submenu) {
4086
+ this.submenu.close();
4087
+ }
4088
+
4089
+ this._doHighlight(item, reason);
4090
+ },
4091
+
4092
+ /**
4093
+ * @private
4094
+ */
4095
+ _doHighlight: function(item, reason) {
4096
+ callSuper(this, 'highlight', item);
4097
+
4098
+ var options = this.selectivity.options;
4099
+ if (
4100
+ !item.submenu ||
4101
+ this.submenu ||
4102
+ (options.shouldOpenSubmenu && options.shouldOpenSubmenu(item, reason) === false)
4103
+ ) {
4104
+ return;
4105
+ }
4106
+
4107
+ var Dropdown = options.dropdown || Selectivity.Dropdown;
4108
+ if (Dropdown) {
4109
+ var resultItems = this.el.querySelectorAll('.selectivity-result-item');
4110
+ var resultItem = findResultItem(resultItems, item.id);
4111
+ var dropdownEl = this.el;
4112
+
4113
+ this.submenu = new Dropdown(this.selectivity, {
4114
+ highlightFirstItem: !item.selectable,
4115
+ items: item.submenu.items || null,
4116
+ parentMenu: this,
4117
+ position: function(el, selectEl) {
4118
+ if (item.submenu.positionDropdown) {
4119
+ item.submenu.positionDropdown(el, selectEl, resultItem, dropdownEl);
4120
+ } else {
4121
+ var rect = dropdownEl.getBoundingClientRect();
4122
+ var left = rect.right;
4123
+ var width = rect.width;
4124
+ if (left + width > document.body.clientWidth && rect.left - width > 0) {
4125
+ // Open the submenu on the left-hand side if there's no sufficient
4126
+ // space on the right side.
4127
+ // Use a little margin to prevent awkward-looking overlaps.
4128
+ left = rect.left - width + 10;
4129
+ }
4130
+
4131
+ // Move the submenu up so it fits in the window, if necessary and possible.
4132
+ var submenuTop = resultItem.getBoundingClientRect().top;
4133
+ var deltaUp = Math.min(
4134
+ Math.max(submenuTop + el.clientHeight - window.innerHeight, 0),
4135
+ rect.top + rect.height
4136
+ );
4137
+
4138
+ el.style.left = left + 'px';
4139
+ el.style.top = submenuTop - deltaUp + 'px';
4140
+ el.style.width = width + 'px';
4141
+ }
4142
+ },
4143
+ query: item.submenu.query || null,
4144
+ showSearchInput: item.submenu.showSearchInput
4145
+ });
4146
+
4147
+ this.submenu.search('');
4148
+ }
4149
+ }
4150
+ });
4151
+
4152
+ Selectivity.Dropdown = SubmenuPlugin;
4153
+
4154
+ module.exports = SubmenuPlugin;
4155
+
4156
+ },{"22":22,"38":38,"40":40}],36:[function(_dereq_,module,exports){
4157
+ 'use strict';
4158
+
4159
+ var assign = (window.jQuery || window.Zepto).extend;
4160
+
4161
+ var Selectivity = _dereq_(38);
4162
+
4163
+ function defaultTokenizer(input, selection, createToken, options) {
4164
+ var createTokenItem =
4165
+ options.createTokenItem ||
4166
+ function(token) {
4167
+ return token ? { id: token, text: token } : null;
4168
+ };
4169
+
4170
+ var separators = options.tokenSeparators;
4171
+
4172
+ function hasToken(input) {
4173
+ return input
4174
+ ? separators.some(function(separator) {
4175
+ return input.indexOf(separator) > -1;
4176
+ })
4177
+ : false;
4178
+ }
4179
+
4180
+ function takeToken(input) {
4181
+ for (var i = 0, length = input.length; i < length; i++) {
4182
+ if (separators.indexOf(input[i]) > -1) {
4183
+ return { term: input.slice(0, i), input: input.slice(i + 1) };
4184
+ }
4185
+ }
4186
+ return {};
4187
+ }
4188
+
4189
+ while (hasToken(input)) {
4190
+ var token = takeToken(input);
4191
+ if (token.term) {
4192
+ var item = createTokenItem(token.term);
4193
+ if (item && !Selectivity.findById(selection, item.id)) {
4194
+ createToken(item);
4195
+ }
4196
+ }
4197
+ input = token.input;
4198
+ }
4199
+
4200
+ return input;
4201
+ }
4202
+
4203
+ /**
4204
+ * Option listener that provides a default tokenizer which is used when the tokenSeparators option
4205
+ * is specified.
4206
+ *
4207
+ * @param options Options object. In addition to the options supported in the multi-input
4208
+ * implementation, this may contain the following property:
4209
+ * tokenSeparators - Array of string separators which are used to separate the search
4210
+ * string into tokens. If specified and the tokenizer property is
4211
+ * not set, the tokenizer property will be set to a function which
4212
+ * splits the search term into tokens separated by any of the given
4213
+ * separators. The tokens will be converted into selectable items
4214
+ * using the 'createTokenItem' function. The default tokenizer also
4215
+ * filters out already selected items.
4216
+ */
4217
+ Selectivity.OptionListeners.push(function(selectivity, options) {
4218
+ if (options.tokenSeparators) {
4219
+ options.allowedTypes = assign({ tokenSeparators: 'array' }, options.allowedTypes);
4220
+
4221
+ options.tokenizer = options.tokenizer || defaultTokenizer;
4222
+ }
4223
+ });
4224
+
4225
+ },{"38":38,"lodash/assign":"lodash/assign"}],37:[function(_dereq_,module,exports){
4226
+ _dereq_(22);_dereq_(24);_dereq_(25);_dereq_(26);_dereq_(27);_dereq_(28);_dereq_(29);_dereq_(30);_dereq_(31);_dereq_(32);_dereq_(33);_dereq_(34);_dereq_(35);_dereq_(36);_dereq_(39);_dereq_(21);
4227
+ },{"21":21,"22":22,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"36":36,"39":39}],38:[function(_dereq_,module,exports){
4228
+ 'use strict';
4229
+
4230
+ var assign = (window.jQuery || window.Zepto).extend;
4231
+ var isString = _dereq_(16);
4232
+
4233
+ var EventListener = _dereq_(23);
4234
+ var toggleClass = _dereq_(47);
4235
+
4236
+ /**
4237
+ * Selectivity Base Constructor.
4238
+ *
4239
+ * You will never use this constructor directly. Instead, you use $(selector).selectivity(options)
4240
+ * to create an instance of either MultipleSelectivity or SingleSelectivity. This class defines all
4241
+ * functionality that is common between both.
4242
+ *
4243
+ * @param options Options object. Accepts the same options as the setOptions method(), in addition
4244
+ * to the following ones:
4245
+ * data - Initial selection data to set. This should be an array of objects with 'id'
4246
+ * and 'text' properties. This option is mutually exclusive with 'value'.
4247
+ * element - The DOM element to which to attach the Selectivity instance. This
4248
+ * property is set by the API wrapper.
4249
+ * value - Initial value to set. This should be an array of IDs. This property is
4250
+ * mutually exclusive with 'data'.
4251
+ */
4252
+ function Selectivity(options) {
4253
+ /**
4254
+ * Reference to the currently open dropdown.
4255
+ */
4256
+ this.dropdown = null;
4257
+
4258
+ /**
4259
+ * DOM element to which this instance is attached.
4260
+ */
4261
+ this.el = options.element;
4262
+
4263
+ /**
4264
+ * Whether the input is enabled.
4265
+ *
4266
+ * This is false when the option readOnly is false or the option removeOnly is false.
4267
+ */
4268
+ this.enabled = !options.readOnly && !options.removeOnly;
4269
+
4270
+ /**
4271
+ * DOM element for the input.
4272
+ *
4273
+ * May be null as long as there is no visible input. It is set by initInput().
4274
+ */
4275
+ this.input = null;
4276
+
4277
+ /**
4278
+ * Array of items from which to select. If set, this will be an array of objects with 'id' and
4279
+ * 'text' properties.
4280
+ *
4281
+ * If given, all items are expected to be available locally and all selection operations operate
4282
+ * on this local array only. If null, items are not available locally, and a query function
4283
+ * should be provided to fetch remote data.
4284
+ */
4285
+ this.items = null;
4286
+
4287
+ /**
4288
+ * Options passed to the Selectivity instance or set through setOptions().
4289
+ */
4290
+ this.options = {};
4291
+
4292
+ /**
4293
+ * Mapping of templates.
4294
+ *
4295
+ * Custom templates can be specified in the options object.
4296
+ */
4297
+ this.templates = assign({}, Selectivity.Templates);
4298
+
4299
+ /**
4300
+ * The last used search term.
4301
+ */
4302
+ this.term = '';
4303
+
4304
+ this.setOptions(options);
4305
+
4306
+ if (options.value) {
4307
+ this.setValue(options.value, { triggerChange: false });
4308
+ } else {
4309
+ this.setData(options.data || null, { triggerChange: false });
4310
+ }
4311
+
4312
+ this.el.setAttribute('tabindex', options.tabIndex || 0);
4313
+
4314
+ this.events = new EventListener(this.el, this);
4315
+ this.events.on({
4316
+ blur: this._blur,
4317
+ mouseenter: this._mouseenter,
4318
+ mouseleave: this._mouseleave,
4319
+ 'selectivity-close': this._closed
4320
+ });
4321
+ }
4322
+
4323
+ /**
4324
+ * Methods.
4325
+ */
4326
+ assign(Selectivity.prototype, {
4327
+ /**
4328
+ * Convenience shortcut for this.el.querySelector(selector).
4329
+ */
4330
+ $: function(selector) {
4331
+ return this.el.querySelector(selector);
4332
+ },
4333
+
4334
+ /**
4335
+ * Closes the dropdown.
4336
+ */
4337
+ close: function() {
4338
+ this._clearCloseTimeout();
4339
+
4340
+ if (this.dropdown) {
4341
+ this.dropdown.close();
4342
+ this.dropdown = null;
4343
+ }
4344
+ },
4345
+
4346
+ /**
4347
+ * Destroys the Selectivity instance.
4348
+ */
4349
+ destroy: function() {
4350
+ this.events.destruct();
4351
+
4352
+ var el = this.el;
4353
+ while (el.firstChild) {
4354
+ el.removeChild(el.firstChild);
4355
+ }
4356
+ el.selectivity = null;
4357
+ },
4358
+
4359
+ /**
4360
+ * Filters the results to be displayed in the dropdown.
4361
+ *
4362
+ * The default implementation simply returns the results unfiltered, but the MultipleSelectivity
4363
+ * class overrides this method to filter out any items that have already been selected.
4364
+ *
4365
+ * @param results Array of items with 'id' and 'text' properties.
4366
+ *
4367
+ * @return The filtered array.
4368
+ */
4369
+ filterResults: function(results) {
4370
+ return results;
4371
+ },
4372
+
4373
+ /**
4374
+ * Applies focus to the input.
4375
+ */
4376
+ focus: function() {
4377
+ this._clearCloseTimeout();
4378
+
4379
+ this._focusing = true;
4380
+
4381
+ if (this.input) {
4382
+ this.input.focus();
4383
+ }
4384
+
4385
+ this._focusing = false;
4386
+ },
4387
+
4388
+ /**
4389
+ * Returns the selection data.
4390
+ */
4391
+ getData: function() {
4392
+ return this._data;
4393
+ },
4394
+
4395
+ /**
4396
+ * Returns the correct item for a given ID.
4397
+ *
4398
+ * @param id The ID to get the item for.
4399
+ *
4400
+ * @return The corresponding item. Will be an object with 'id' and 'text' properties or null if
4401
+ * the item cannot be found. Note that if no items are defined, this method assumes the
4402
+ * text labels will be equal to the IDs.
4403
+ */
4404
+ getItemForId: function(id) {
4405
+ var items = this.items;
4406
+ if (items) {
4407
+ return Selectivity.findNestedById(items, id);
4408
+ } else if (id === null) {
4409
+ return null;
4410
+ } else {
4411
+ return { id: id, text: '' + id };
4412
+ }
4413
+ },
4414
+
4415
+ /**
4416
+ * Returns the item ID related to an element or event target.
4417
+ *
4418
+ * @param elementOrEvent The DOM element or event to get the item ID for.
4419
+ *
4420
+ * @return Item ID or null if no ID could be found.
4421
+ */
4422
+ getRelatedItemId: function(elementOrEvent) {
4423
+ var el = elementOrEvent.target || elementOrEvent;
4424
+ while (el) {
4425
+ if (el.hasAttribute('data-item-id')) {
4426
+ break;
4427
+ }
4428
+ el = el.parentNode;
4429
+ }
4430
+
4431
+ if (!el) {
4432
+ return null;
4433
+ }
4434
+
4435
+ var id = el.getAttribute('data-item-id');
4436
+
4437
+ // IDs can be either numbers or strings, but attribute values are always strings, so we
4438
+ // will have to find out whether the item ID ought to be a number or string ourselves.
4439
+ if (Selectivity.findById(this._data || [], id)) {
4440
+ return id;
4441
+ } else {
4442
+ var dropdown = this.dropdown;
4443
+ while (dropdown) {
4444
+ if (Selectivity.findNestedById(dropdown.results, id)) {
4445
+ return id;
4446
+ }
4447
+ // FIXME: reference to submenu plugin doesn't belong in base
4448
+ dropdown = dropdown.submenu;
4449
+ }
4450
+ var number = parseInt(id, 10);
4451
+ return '' + number === id ? number : id;
4452
+ }
4453
+ },
4454
+
4455
+ /**
4456
+ * Returns the value of the selection.
4457
+ */
4458
+ getValue: function() {
4459
+ return this._value;
4460
+ },
4461
+
4462
+ /**
4463
+ * Initializes the input element.
4464
+ *
4465
+ * Sets the input property, invokes all input listeners and (by default) attaches the action of
4466
+ * searching when something is typed.
4467
+ *
4468
+ * @param input Input element.
4469
+ * @param options Optional options object. May contain the following property:
4470
+ * search - If false, no event handlers are setup to initiate searching when the
4471
+ * user types in the input field. This is useful if you want to use the
4472
+ * input only to handle keyboard support.
4473
+ */
4474
+ initInput: function(input, options) {
4475
+ this.input = input;
4476
+
4477
+ var selectivity = this;
4478
+ var inputListeners = this.options.inputListeners || Selectivity.InputListeners;
4479
+ inputListeners.forEach(function(listener) {
4480
+ listener(selectivity, input, options);
4481
+ });
4482
+
4483
+ if (!options || options.search !== false) {
4484
+ input.addEventListener('keyup', function(event) {
4485
+ if (!event.defaultPrevented) {
4486
+ selectivity.search(event.target.value);
4487
+ }
4488
+ });
4489
+ }
4490
+ },
4491
+
4492
+ /**
4493
+ * Opens the dropdown.
4494
+ */
4495
+ open: function() {
4496
+ if (this._opening || this.dropdown || !this.triggerEvent('selectivity-opening')) {
4497
+ return;
4498
+ }
4499
+
4500
+ this._opening = true;
4501
+
4502
+ var Dropdown = this.options.dropdown || Selectivity.Dropdown;
4503
+ if (Dropdown) {
4504
+ this.dropdown = new Dropdown(this, {
4505
+ items: this.items,
4506
+ position: this.options.positionDropdown,
4507
+ query: this.options.query,
4508
+ showSearchInput: this.options.showSearchInputInDropdown !== false
4509
+ });
4510
+ }
4511
+
4512
+ this.search('');
4513
+
4514
+ this.focus();
4515
+
4516
+ toggleClass(this.el, 'open', true);
4517
+
4518
+ this._opening = false;
4519
+ },
4520
+
4521
+ /**
4522
+ * (Re-)positions the dropdown.
4523
+ */
4524
+ positionDropdown: function() {
4525
+ if (this.dropdown) {
4526
+ this.dropdown.position();
4527
+ }
4528
+ },
4529
+
4530
+ /**
4531
+ * Searches for results based on the term given.
4532
+ *
4533
+ * If an items array has been passed with the options to the Selectivity instance, a local
4534
+ * search will be performed among those items. Otherwise, the query function specified in the
4535
+ * options will be used to perform the search. If neither is defined, nothing happens.
4536
+ *
4537
+ * @param term Term to search for.
4538
+ */
4539
+ search: function(term) {
4540
+ this.open();
4541
+
4542
+ if (this.dropdown) {
4543
+ this.dropdown.search(term);
4544
+ }
4545
+ },
4546
+
4547
+ /**
4548
+ * Sets the selection data.
4549
+ *
4550
+ * The selection data contains both IDs and text labels. If you only want to set or get the IDs,
4551
+ * you should use the value() method.
4552
+ *
4553
+ * @param newData New data to set. For a MultipleSelectivity instance the data must be an array
4554
+ * of objects with 'id' and 'text' properties, for a SingleSelectivity instance
4555
+ * the data must be a single such object or null to indicate no item is selected.
4556
+ * @param options Optional options object. May contain the following property:
4557
+ * triggerChange - Set to false to suppress the "change" event being triggered.
4558
+ * Note this will also cause the UI to not update automatically;
4559
+ * so you may want to call rerenderSelection() manually when
4560
+ * using this option.
4561
+ */
4562
+ setData: function(newData, options) {
4563
+ options = options || {};
4564
+
4565
+ newData = this.validateData(newData);
4566
+
4567
+ this._data = newData;
4568
+ this._value = this.getValueForData(newData);
4569
+
4570
+ if (options.triggerChange !== false) {
4571
+ this.triggerChange();
4572
+ }
4573
+ },
4574
+
4575
+ /**
4576
+ * Sets one or more options on this Selectivity instance.
4577
+ *
4578
+ * @param options Options object. May contain one or more of the following properties:
4579
+ * closeOnSelect - Set to false to keep the dropdown open after the user has
4580
+ * selected an item. This is useful if you want to allow the user
4581
+ * to quickly select multiple items. The default value is true.
4582
+ * dropdown - Custom dropdown implementation to use for this instance.
4583
+ * initSelection - Function to map values by ID to selection data. This function
4584
+ * receives two arguments, 'value' and 'callback'. The value is
4585
+ * the current value of the selection, which is an ID or an array
4586
+ * of IDs depending on the input type. The callback should be
4587
+ * invoked with an object or array of objects, respectively,
4588
+ * containing 'id' and 'text' properties.
4589
+ * inputListeners - Array of search input listeners. By default, the global
4590
+ * array Selectivity.InputListeners is used.
4591
+ * items - Array of items from which to select. Should be an array of objects
4592
+ * with 'id' and 'text' properties. As convenience, you may also pass an
4593
+ * array of strings, in which case the same string is used for both the
4594
+ * 'id' and 'text' properties. If items are given, all items are expected
4595
+ * to be available locally and all selection operations operate on this
4596
+ * local array only. If null, items are not available locally, and a
4597
+ * query function should be provided to fetch remote data.
4598
+ * matcher - Function to determine whether text matches a given search term. Note
4599
+ * this function is only used if you have specified an array of items.
4600
+ * Receives two arguments:
4601
+ * item - The item that should match the search term.
4602
+ * term - The search term. Note that for performance reasons, the term
4603
+ * has always been already processed using
4604
+ * Selectivity.transformText().
4605
+ * The method should return the item if it matches, and null otherwise.
4606
+ * If the item has a children array, the matcher is expected to filter
4607
+ * those itself (be sure to only return the filtered array of children
4608
+ * in the returned item and not to modify the children of the item
4609
+ * argument).
4610
+ * placeholder - Placeholder text to display when the element has no focus and
4611
+ * no selected items.
4612
+ * positionDropdown - Function to position the dropdown. Receives two arguments:
4613
+ * dropdownEl - The element to be positioned.
4614
+ * selectEl - The element of the Selectivity instance, that
4615
+ * you can position the dropdown to.
4616
+ * The default implementation positions the dropdown element
4617
+ * under the Selectivity's element and gives it the same
4618
+ * width.
4619
+ * query - Function to use for querying items. Receives a single object as
4620
+ * argument with the following properties:
4621
+ * callback - Callback to invoke when the results are available. This
4622
+ * callback should be passed a single object as argument with
4623
+ * the following properties:
4624
+ * more - Boolean that can be set to true to indicate there
4625
+ * are more results available. Additional results may
4626
+ * be fetched by the user through pagination.
4627
+ * results - Array of result items. The format for the result
4628
+ * items is the same as for passing local items.
4629
+ * offset - This property is only used for pagination and indicates how
4630
+ * many results should be skipped when returning more results.
4631
+ * selectivity - The Selectivity instance the query function is used on.
4632
+ * term - The search term the user is searching for. Unlike with the
4633
+ * matcher function, the term has not been processed using
4634
+ * Selectivity.transformText().
4635
+ * readOnly - If true, disables any modification of the input.
4636
+ * removeOnly - If true, disables any modification of the input except removing
4637
+ * of selected items.
4638
+ * shouldOpenSubmenu - Function to call that will decide whether a submenu should
4639
+ * be opened. Receives two parameters:
4640
+ * item - The currently highlighted result item.
4641
+ * reason - The reason why the item is being highlighted.
4642
+ * See Dropdown#highlight() for possible values.
4643
+ * showDropdown - Set to false if you don't want to use any dropdown (you can
4644
+ * still open it programmatically using open()).
4645
+ * showSearchInputInDropdown - Set to false to remove the search input used in
4646
+ * dropdowns. The default is true for single-value
4647
+ * inputs.
4648
+ * templates - Object with instance-specific templates to override the global
4649
+ * templates assigned to Selectivity.Templates.
4650
+ */
4651
+ setOptions: function(options) {
4652
+ options = options || {};
4653
+
4654
+ var selectivity = this;
4655
+ Selectivity.OptionListeners.forEach(function(listener) {
4656
+ listener(selectivity, options);
4657
+ });
4658
+
4659
+ if ('items' in options) {
4660
+ this.items = options.items ? Selectivity.processItems(options.items) : null;
4661
+ }
4662
+ if ('templates' in options) {
4663
+ assign(this.templates, options.templates);
4664
+ }
4665
+
4666
+ assign(this.options, options);
4667
+
4668
+ this.enabled = !this.options.readOnly && !this.options.removeOnly;
4669
+ },
4670
+
4671
+ /**
4672
+ * Sets the value of the selection.
4673
+ *
4674
+ * The value of the selection only concerns the IDs of the selection items. If you are
4675
+ * interested in the IDs and the text labels, you should use the data() method.
4676
+ *
4677
+ * Note that if neither the items option nor the initSelection option have been set, Selectivity
4678
+ * will have no way to determine what text labels should be used with the given IDs in which
4679
+ * case it will assume the text is equal to the ID. This is useful if you're working with tags,
4680
+ * or selecting e-mail addresses for instance, but may not always be what you want.
4681
+ *
4682
+ * @param newValue New value to set. For a MultipleSelectivity instance the value must be an
4683
+ * array of IDs, for a SingleSelectivity instance the value must be a single ID
4684
+ * (a string or a number) or null to indicate no item is selected.
4685
+ * @param options Optional options object. May contain the following property:
4686
+ * triggerChange - Set to false to suppress the "change" event being triggered.
4687
+ * Note this will also cause the UI to not update automatically;
4688
+ * so you may want to call rerenderSelection() manually when
4689
+ * using this option.
4690
+ */
4691
+ setValue: function(newValue, options) {
4692
+ options = options || {};
4693
+
4694
+ newValue = this.validateValue(newValue);
4695
+
4696
+ this._value = newValue;
4697
+
4698
+ if (this.options.initSelection) {
4699
+ this.options.initSelection(
4700
+ newValue,
4701
+ function(data) {
4702
+ if (this._value === newValue) {
4703
+ this._data = this.validateData(data);
4704
+
4705
+ if (options.triggerChange !== false) {
4706
+ this.triggerChange();
4707
+ }
4708
+ }
4709
+ }.bind(this)
4710
+ );
4711
+ } else {
4712
+ this._data = this.getDataForValue(newValue);
4713
+
4714
+ if (options.triggerChange !== false) {
4715
+ this.triggerChange();
4716
+ }
4717
+ }
4718
+ },
4719
+
4720
+ /**
4721
+ * Returns the result of the given template.
4722
+ *
4723
+ * @param templateName Name of the template to process.
4724
+ * @param options Options to pass to the template.
4725
+ *
4726
+ * @return String containing HTML or ReactElement if template is a function returning
4727
+ * ReactElement.
4728
+ */
4729
+ template: function(templateName, options) {
4730
+ var template = this.templates[templateName];
4731
+ if (!template) {
4732
+ throw new Error('Unknown template: ' + templateName);
4733
+ }
4734
+
4735
+ if (typeof template === 'function') {
4736
+ var templateResult = template(options);
4737
+ return typeof templateResult === 'string' ? templateResult.trim() : templateResult;
4738
+ } else if (template.render) {
4739
+ return template.render(options).trim();
4740
+ } else {
4741
+ return template.toString().trim();
4742
+ }
4743
+ },
4744
+
4745
+ /**
4746
+ * Triggers the change event.
4747
+ *
4748
+ * The event object at least contains the following properties:
4749
+ * data - The new data of the Selectivity instance.
4750
+ * value - The new value of the Selectivity instance.
4751
+ *
4752
+ * @param Optional additional options added to the event object.
4753
+ *
4754
+ * @see getData()
4755
+ * @see getValue()
4756
+ */
4757
+ triggerChange: function(options) {
4758
+ var data = assign({ data: this._data, value: this._value }, options);
4759
+ this.triggerEvent('change', data);
4760
+ this.triggerEvent('selectivity-change', data);
4761
+ },
4762
+
4763
+ /**
4764
+ * Triggers an event on the instance's element.
4765
+ *
4766
+ * @param eventName Name of the event to trigger.
4767
+ * @param data Optional event data to be added to the event object.
4768
+ *
4769
+ * @return Whether the default action of the event may be executed, ie. returns false if
4770
+ * preventDefault() has been called.
4771
+ */
4772
+ triggerEvent: function(eventName, data) {
4773
+ var event = document.createEvent('Event');
4774
+ event.initEvent(eventName, /* bubbles: */ false, /* cancelable: */ true);
4775
+ assign(event, data);
4776
+ this.el.dispatchEvent(event);
4777
+ return !event.defaultPrevented;
4778
+ },
4779
+
4780
+ /**
4781
+ * Validates a single item. Throws an exception if the item is invalid.
4782
+ *
4783
+ * @param item The item to validate.
4784
+ *
4785
+ * @return The validated item. May differ from the input item.
4786
+ */
4787
+ validateItem: function(item) {
4788
+ if (item && Selectivity.isValidId(item.id) && isString(item.text)) {
4789
+ return item;
4790
+ } else {
4791
+ throw new Error('Item should have id (number or string) and text (string) properties');
4792
+ }
4793
+ },
4794
+
4795
+ /**
4796
+ * @private
4797
+ */
4798
+ _blur: function() {
4799
+ if (!this._focusing && !this.el.classList.contains('hover')) {
4800
+ // Without the timeout it appears clicks on result items are not always properly
4801
+ // handled, especially when the user doesn't click exactly on the text of the result
4802
+ // item. I don't understand really why that happens, or why the timeout has to be so
4803
+ // large, but after trial and error, this now seems to work reliably...
4804
+ this._clearCloseTimeout();
4805
+ this._closeTimeout = setTimeout(this.close.bind(this), 166);
4806
+ }
4807
+ },
4808
+
4809
+ /**
4810
+ * @private
4811
+ */
4812
+ _clearCloseTimeout: function() {
4813
+ if (this._closeTimeout) {
4814
+ clearTimeout(this._closeTimeout);
4815
+ this._closeTimeout = 0;
4816
+ }
4817
+ },
4818
+
4819
+ /**
4820
+ * @private
4821
+ */
4822
+ _closed: function() {
4823
+ this.dropdown = null;
4824
+
4825
+ toggleClass(this.el, 'open', false);
4826
+ },
4827
+
4828
+ /**
4829
+ * @private
4830
+ */
4831
+ _mouseleave: function(event) {
4832
+ // If mouseleave happens on any selectivity related element, remove hover class
4833
+ if (!this.el.contains(event.relatedTarget)) {
4834
+ toggleClass(this.el, 'hover', false);
4835
+ }
4836
+ },
4837
+
4838
+ /**
4839
+ * @private
4840
+ */
4841
+ _mouseenter: function() {
4842
+ toggleClass(this.el, 'hover', true);
4843
+ }
4844
+ });
4845
+
4846
+ /**
4847
+ * Dropdown class to use for displaying dropdowns.
4848
+ *
4849
+ * The default implementation of a dropdown is defined in the selectivity-dropdown module.
4850
+ */
4851
+ Selectivity.Dropdown = null;
4852
+
4853
+ /**
4854
+ * Array of input listeners.
4855
+ *
4856
+ * Input listeners are invoked when initInput() is called (typically right after the input is
4857
+ * created). Every listener receives three arguments:
4858
+ *
4859
+ * selectivity - The Selectivity instance.
4860
+ * input - DOM element of the input.
4861
+ * options - Options that were passed to initInput().
4862
+ *
4863
+ * An example of a search input listener is the selectivity-keyboard module.
4864
+ */
4865
+ Selectivity.InputListeners = [];
4866
+
4867
+ /**
4868
+ * Mapping of input types.
4869
+ */
4870
+ Selectivity.Inputs = {};
4871
+
4872
+ /**
4873
+ * Array of option listeners.
4874
+ *
4875
+ * Option listeners are invoked when setOptions() is called. Every listener receives two arguments:
4876
+ *
4877
+ * selectivity - The Selectivity instance.
4878
+ * options - The options that are about to be set. The listener may modify this options object.
4879
+ *
4880
+ * An example of an option listener is the selectivity-traditional module.
4881
+ */
4882
+ Selectivity.OptionListeners = [];
4883
+
4884
+ /**
4885
+ * Mapping with templates to use for rendering select boxes and dropdowns. See
4886
+ * selectivity-templates.js for a useful set of default templates, as well as for documentation of
4887
+ * the individual templates.
4888
+ */
4889
+ Selectivity.Templates = {};
4890
+
4891
+ /**
4892
+ * Finds an item in the given array with the specified ID.
4893
+ *
4894
+ * @param array Array to search in.
4895
+ * @param id ID to search for.
4896
+ *
4897
+ * @return The item in the array with the given ID, or null if the item was not found.
4898
+ */
4899
+ Selectivity.findById = function(array, id) {
4900
+ var index = Selectivity.findIndexById(array, id);
4901
+ return index > -1 ? array[index] : null;
4902
+ };
4903
+
4904
+ /**
4905
+ * Finds the index of an item in the given array with the specified ID.
4906
+ *
4907
+ * @param array Array to search in.
4908
+ * @param id ID to search for.
4909
+ *
4910
+ * @return The index of the item in the array with the given ID, or -1 if the item was not found.
4911
+ */
4912
+ Selectivity.findIndexById = function(array, id) {
4913
+ for (var i = 0, length = array.length; i < length; i++) {
4914
+ if (array[i].id === id) {
4915
+ return i;
4916
+ }
4917
+ }
4918
+ return -1;
4919
+ };
4920
+
4921
+ /**
4922
+ * Finds an item in the given array with the specified ID. Items in the array may contain 'children'
4923
+ * properties which in turn will be searched for the item.
4924
+ *
4925
+ * @param array Array to search in.
4926
+ * @param id ID to search for.
4927
+ *
4928
+ * @return The item in the array with the given ID, or null if the item was not found.
4929
+ */
4930
+ Selectivity.findNestedById = function(array, id) {
4931
+ for (var i = 0, length = array.length; i < length; i++) {
4932
+ var item = array[i],
4933
+ result;
4934
+ if (item.id === id) {
4935
+ result = item;
4936
+ } else if (item.children) {
4937
+ result = Selectivity.findNestedById(item.children, id);
4938
+ } else if (item.submenu && item.submenu.items) {
4939
+ // FIXME: reference to submenu plugin doesn't belong in base
4940
+ result = Selectivity.findNestedById(item.submenu.items, id);
4941
+ }
4942
+ if (result) {
4943
+ return result;
4944
+ }
4945
+ }
4946
+ return null;
4947
+ };
4948
+
4949
+ /**
4950
+ * Utility method for inheriting another class.
4951
+ *
4952
+ * @param SubClass Constructor function of the subclass.
4953
+ * @param SuperClass Constructor function of the superclass.
4954
+ * @param prototype Object with methods you want to add to the subclass prototype.
4955
+ *
4956
+ * @return A utility function for calling the methods of the superclass. This function receives two
4957
+ * arguments: The this object on which you want to execute the method and the name of the
4958
+ * method. Any arguments past those are passed to the superclass method.
4959
+ */
4960
+ Selectivity.inherits = function(SubClass, SuperClass, prototype) {
4961
+ SubClass.prototype = assign(
4962
+ Object.create(SuperClass.prototype),
4963
+ { constructor: SubClass },
4964
+ prototype
4965
+ );
4966
+
4967
+ return function(self, methodName) {
4968
+ SuperClass.prototype[methodName].apply(self, Array.prototype.slice.call(arguments, 2));
4969
+ };
4970
+ };
4971
+
4972
+ /**
4973
+ * Checks whether a value can be used as a valid ID for selection items. Only numbers and strings
4974
+ * are accepted to be used as IDs.
4975
+ *
4976
+ * @param id The value to check whether it is a valid ID.
4977
+ *
4978
+ * @return true if the value is a valid ID, false otherwise.
4979
+ */
4980
+ Selectivity.isValidId = function(id) {
4981
+ return typeof id === 'number' || isString(id);
4982
+ };
4983
+
4984
+ /**
4985
+ * Decides whether a given item matches a search term. The default implementation simply
4986
+ * checks whether the term is contained within the item's text, after transforming them using
4987
+ * transformText().
4988
+ *
4989
+ * @param item The item that should match the search term.
4990
+ * @param term The search term. Note that for performance reasons, the term has always been already
4991
+ * processed using transformText().
4992
+ *
4993
+ * @return true if the text matches the term, false otherwise.
4994
+ */
4995
+ Selectivity.matcher = function(item, term) {
4996
+ var result = null;
4997
+ if (Selectivity.transformText(item.text).indexOf(term) > -1) {
4998
+ result = item;
4999
+ } else if (item.children) {
5000
+ var matchingChildren = item.children
5001
+ .map(function(child) {
5002
+ return Selectivity.matcher(child, term);
5003
+ })
5004
+ .filter(function(child) {
5005
+ return !!child;
5006
+ });
5007
+ if (matchingChildren.length) {
5008
+ result = { id: item.id, text: item.text, children: matchingChildren };
5009
+ }
5010
+ }
5011
+ return result;
5012
+ };
5013
+
5014
+ /**
5015
+ * Helper function for processing items.
5016
+ *
5017
+ * @param item The item to process, either as object containing 'id' and 'text' properties or just
5018
+ * as ID. The 'id' property of an item is optional if it has a 'children' property
5019
+ * containing an array of items.
5020
+ *
5021
+ * @return Object containing 'id' and 'text' properties.
5022
+ */
5023
+ Selectivity.processItem = function(item) {
5024
+ if (Selectivity.isValidId(item)) {
5025
+ return { id: item, text: '' + item };
5026
+ } else if (item && (Selectivity.isValidId(item.id) || item.children) && isString(item.text)) {
5027
+ if (item.children) {
5028
+ item.children = Selectivity.processItems(item.children);
5029
+ }
5030
+
5031
+ return item;
5032
+ } else {
5033
+ throw new Error('invalid item');
5034
+ }
5035
+ };
5036
+
5037
+ /**
5038
+ * Helper function for processing an array of items.
5039
+ *
5040
+ * @param items Array of items to process. See processItem() for details about a single item.
5041
+ *
5042
+ * @return Array with items.
5043
+ */
5044
+ Selectivity.processItems = function(items) {
5045
+ if (Array.isArray(items)) {
5046
+ return items.map(Selectivity.processItem);
5047
+ } else {
5048
+ throw new Error('invalid items');
5049
+ }
5050
+ };
5051
+
5052
+ /**
5053
+ * Transforms text in order to find matches. The default implementation casts all strings to
5054
+ * lower-case so that any matches found will be case-insensitive.
5055
+ *
5056
+ * @param string The string to transform.
5057
+ *
5058
+ * @return The transformed string.
5059
+ */
5060
+ Selectivity.transformText = function(string) {
5061
+ return string.toLowerCase();
5062
+ };
5063
+
5064
+ module.exports = Selectivity;
5065
+
5066
+ },{"16":16,"23":23,"47":47,"lodash/assign":"lodash/assign"}],39:[function(_dereq_,module,exports){
5067
+ 'use strict';
5068
+
5069
+ var escape = _dereq_(12);
5070
+
5071
+ var Selectivity = _dereq_(38);
5072
+ var Locale = _dereq_(27);
5073
+
5074
+ /**
5075
+ * Default set of templates to use with Selectivity.js.
5076
+ *
5077
+ * Template can be defined as either a string, a function returning a string (like Handlebars
5078
+ * templates, for instance), an object containing a render function (like Hogan.js templates, fo
5079
+ * instance) or as a function returning a DOM element.
5080
+ *
5081
+ * Every template must return a single root element.
5082
+ */
5083
+ Selectivity.Templates = {
5084
+ /**
5085
+ * Renders the dropdown.
5086
+ *
5087
+ * The template is expected to have at least one element with the class
5088
+ * 'selectivity-results-container', which is where all results will be added to.
5089
+ *
5090
+ * @param options Options object containing the following properties:
5091
+ * dropdownCssClass - Optional CSS class to add to the top-level element.
5092
+ * searchInputPlaceholder - Optional placeholder text to display in the search
5093
+ * input in the dropdown.
5094
+ * showSearchInput - Boolean whether a search input should be shown. If true,
5095
+ * an input element with the 'selectivity-search-input' is
5096
+ * expected.
5097
+ */
5098
+ dropdown: function(options) {
5099
+ var extraClass = options.dropdownCssClass ? ' ' + options.dropdownCssClass : '',
5100
+ searchInput = '';
5101
+ if (options.showSearchInput) {
5102
+ extraClass += ' has-search-input';
5103
+
5104
+ var placeholder = options.searchInputPlaceholder;
5105
+ searchInput =
5106
+ '<div class="selectivity-search-input-container">' +
5107
+ '<input type="text" class="selectivity-search-input"' +
5108
+ (placeholder ? ' placeholder="' + escape(placeholder) + '"' : '') +
5109
+ '>' +
5110
+ '</div>';
5111
+ }
5112
+ return (
5113
+ '<div class="selectivity-dropdown' +
5114
+ extraClass +
5115
+ '">' +
5116
+ searchInput +
5117
+ '<div class="selectivity-results-container"></div>' +
5118
+ '</div>'
5119
+ );
5120
+ },
5121
+
5122
+ /**
5123
+ * Renders an error message in the dropdown.
5124
+ *
5125
+ * @param options Options object containing the following properties:
5126
+ * escape - Boolean whether the message should be HTML-escaped.
5127
+ * message - The message to display.
5128
+ */
5129
+ error: function(options) {
5130
+ return (
5131
+ '<div class="selectivity-error">' +
5132
+ (options.escape ? escape(options.message) : options.message) +
5133
+ '</div>'
5134
+ );
5135
+ },
5136
+
5137
+ /**
5138
+ * Renders a loading indicator in the dropdown.
5139
+ *
5140
+ * This template is expected to have an element with a 'selectivity-loading' class which may be
5141
+ * replaced with actual results.
5142
+ */
5143
+ loading: function() {
5144
+ return '<div class="selectivity-loading">' + Locale.loading + '</div>';
5145
+ },
5146
+
5147
+ /**
5148
+ * Load more indicator.
5149
+ *
5150
+ * This template is expected to have an element with a 'selectivity-load-more' class which, when
5151
+ * clicked, will load more results.
5152
+ */
5153
+ loadMore: function() {
5154
+ return '<div class="selectivity-load-more">' + Locale.loadMore + '</div>';
5155
+ },
5156
+
5157
+ /**
5158
+ * Renders multi-selection input boxes.
5159
+ *
5160
+ * The template is expected to have at least have elements with the following classes:
5161
+ * 'selectivity-multiple-input-container' - The element containing all the selected items and
5162
+ * the input for selecting additional items.
5163
+ * 'selectivity-multiple-input' - The actual input element that allows the user to type to
5164
+ * search for more items. When selected items are added, they are
5165
+ * inserted right before this element.
5166
+ *
5167
+ * @param options Options object containing the following property:
5168
+ * enabled - Boolean whether the input is enabled.
5169
+ */
5170
+ multipleSelectInput: function(options) {
5171
+ return (
5172
+ '<div class="selectivity-multiple-input-container">' +
5173
+ (options.enabled
5174
+ ? '<input type="text" autocomplete="off" autocorrect="off" ' +
5175
+ 'autocapitalize="off" class="selectivity-multiple-input">'
5176
+ : '<div class="selectivity-multiple-input ' + 'selectivity-placeholder"></div>') +
5177
+ '<div class="selectivity-clearfix"></div>' +
5178
+ '</div>'
5179
+ );
5180
+ },
5181
+
5182
+ /**
5183
+ * Renders a selected item in multi-selection input boxes.
5184
+ *
5185
+ * The template is expected to have a top-level element with the class
5186
+ * 'selectivity-multiple-selected-item'. This element is also required to have a 'data-item-id'
5187
+ * attribute with the ID set to that passed through the options object.
5188
+ *
5189
+ * An element with the class 'selectivity-multiple-selected-item-remove' should be present
5190
+ * which, when clicked, will cause the element to be removed.
5191
+ *
5192
+ * @param options Options object containing the following properties:
5193
+ * highlighted - Boolean whether this item is currently highlighted.
5194
+ * id - Identifier for the item.
5195
+ * removable - Boolean whether a remove icon should be displayed.
5196
+ * text - Text label which the user sees.
5197
+ */
5198
+ multipleSelectedItem: function(options) {
5199
+ var extraClass = options.highlighted ? ' highlighted' : '';
5200
+ return (
5201
+ '<span class="selectivity-multiple-selected-item' +
5202
+ extraClass +
5203
+ '" ' +
5204
+ 'data-item-id="' +
5205
+ escape(options.id) +
5206
+ '">' +
5207
+ (options.removable
5208
+ ? '<a class="selectivity-multiple-selected-item-remove">' +
5209
+ '<i class="fa fa-remove"></i>' +
5210
+ '</a>'
5211
+ : '') +
5212
+ escape(options.text) +
5213
+ '</span>'
5214
+ );
5215
+ },
5216
+
5217
+ /**
5218
+ * Renders a message there are no results for the given query.
5219
+ *
5220
+ * @param options Options object containing the following property:
5221
+ * term - Search term the user is searching for.
5222
+ */
5223
+ noResults: function(options) {
5224
+ return (
5225
+ '<div class="selectivity-error">' +
5226
+ (options.term ? Locale.noResultsForTerm(options.term) : Locale.noResults) +
5227
+ '</div>'
5228
+ );
5229
+ },
5230
+
5231
+ /**
5232
+ * Renders a container for item children.
5233
+ *
5234
+ * The template is expected to have an element with the class 'selectivity-result-children'.
5235
+ *
5236
+ * @param options Options object containing the following property:
5237
+ * childrenHtml - Rendered HTML for the children.
5238
+ */
5239
+ resultChildren: function(options) {
5240
+ return '<div class="selectivity-result-children">' + options.childrenHtml + '</div>';
5241
+ },
5242
+
5243
+ /**
5244
+ * Render a result item in the dropdown.
5245
+ *
5246
+ * The template is expected to have a top-level element with the class
5247
+ * 'selectivity-result-item'. This element is also required to have a 'data-item-id' attribute
5248
+ * with the ID set to that passed through the options object.
5249
+ *
5250
+ * @param options Options object containing the following properties:
5251
+ * id - Identifier for the item.
5252
+ * text - Text label which the user sees.
5253
+ * disabled - Truthy if the item should be disabled.
5254
+ * submenu - Truthy if the result item has a menu with subresults.
5255
+ */
5256
+ resultItem: function(options) {
5257
+ return (
5258
+ '<div class="selectivity-result-item' +
5259
+ (options.disabled ? ' disabled' : '') +
5260
+ '"' +
5261
+ ' data-item-id="' +
5262
+ escape(options.id) +
5263
+ '">' +
5264
+ escape(options.text) +
5265
+ (options.submenu
5266
+ ? '<i class="selectivity-submenu-icon fa fa-chevron-right"></i>'
5267
+ : '') +
5268
+ '</div>'
5269
+ );
5270
+ },
5271
+
5272
+ /**
5273
+ * Render a result label in the dropdown.
5274
+ *
5275
+ * The template is expected to have a top-level element with the class
5276
+ * 'selectivity-result-label'.
5277
+ *
5278
+ * @param options Options object containing the following properties:
5279
+ * text - Text label.
5280
+ */
5281
+ resultLabel: function(options) {
5282
+ return '<div class="selectivity-result-label">' + escape(options.text) + '</div>';
5283
+ },
5284
+
5285
+ /**
5286
+ * Renders single-select input boxes.
5287
+ *
5288
+ * The template is expected to have at least one element with the class
5289
+ * 'selectivity-single-result-container' which is the element containing the selected item or
5290
+ * the placeholder.
5291
+ */
5292
+ singleSelectInput: function(options) {
5293
+ return (
5294
+ '<div class="selectivity-single-select">' +
5295
+ '<input type="text" class="selectivity-single-select-input"' +
5296
+ (options.required ? ' required' : '') +
5297
+ '>' +
5298
+ '<div class="selectivity-single-result-container"></div>' +
5299
+ '<i class="fa fa-sort-desc selectivity-caret"></i>' +
5300
+ '</div>'
5301
+ );
5302
+ },
5303
+
5304
+ /**
5305
+ * Renders the placeholder for single-select input boxes.
5306
+ *
5307
+ * The template is expected to have a top-level element with the class
5308
+ * 'selectivity-placeholder'.
5309
+ *
5310
+ * @param options Options object containing the following property:
5311
+ * placeholder - The placeholder text.
5312
+ */
5313
+ singleSelectPlaceholder: function(options) {
5314
+ return '<div class="selectivity-placeholder">' + escape(options.placeholder) + '</div>';
5315
+ },
5316
+
5317
+ /**
5318
+ * Renders the selected item in single-select input boxes.
5319
+ *
5320
+ * The template is expected to have a top-level element with the class
5321
+ * 'selectivity-single-selected-item'. This element is also required to have a 'data-item-id'
5322
+ * attribute with the ID set to that passed through the options object.
5323
+ *
5324
+ * @param options Options object containing the following properties:
5325
+ * id - Identifier for the item.
5326
+ * removable - Boolean whether a remove icon should be displayed.
5327
+ * text - Text label which the user sees.
5328
+ */
5329
+ singleSelectedItem: function(options) {
5330
+ return (
5331
+ '<span class="selectivity-single-selected-item" ' +
5332
+ 'data-item-id="' +
5333
+ escape(options.id) +
5334
+ '">' +
5335
+ (options.removable
5336
+ ? '<a class="selectivity-single-selected-item-remove">' +
5337
+ '<i class="fa fa-remove"></i>' +
5338
+ '</a>'
5339
+ : '') +
5340
+ escape(options.text) +
5341
+ '</span>'
5342
+ );
5343
+ },
5344
+
5345
+ /**
5346
+ * Renders select-box inside single-select input that was initialized on
5347
+ * traditional <select> element.
5348
+ *
5349
+ * @param options Options object containing the following properties:
5350
+ * name - Name of the <select> element.
5351
+ * mode - Mode in which select exists, single or multiple.
5352
+ */
5353
+ selectCompliance: function(options) {
5354
+ var mode = options.mode;
5355
+ var name = options.name;
5356
+ if (mode === 'multiple' && name.slice(-2) !== '[]') {
5357
+ name += '[]';
5358
+ }
5359
+ return (
5360
+ '<select name="' + name + '"' + (mode === 'multiple' ? ' multiple' : '') + '></select>'
5361
+ );
5362
+ },
5363
+
5364
+ /**
5365
+ * Renders the selected item in compliance <select> element as <option>.
5366
+ *
5367
+ * @param options Options object containing the following properties
5368
+ * id - Identifier for the item.
5369
+ * text - Text label which the user sees.
5370
+ */
5371
+ selectOptionCompliance: function(options) {
5372
+ return (
5373
+ '<option value="' +
5374
+ escape(options.id) +
5375
+ '" selected>' +
5376
+ escape(options.text) +
5377
+ '</option>'
5378
+ );
5379
+ }
5380
+ };
5381
+
5382
+ },{"12":12,"27":27,"38":38}],40:[function(_dereq_,module,exports){
5383
+ 'use strict';
5384
+
5385
+ /**
5386
+ * Returns a result item with a given item ID.
5387
+ *
5388
+ * @param resultItems Array of DOM elements representing result items.
5389
+ * @param itemId ID of the item to return.
5390
+ *
5391
+ * @param DOM element of the result item with the given item ID, or null if not found.
5392
+ */
5393
+ module.exports = function(resultItems, itemId) {
5394
+ for (var i = 0, length = resultItems.length; i < length; i++) {
5395
+ var resultItem = resultItems[i];
5396
+ var resultId = resultItem.getAttribute('data-item-id');
5397
+ if ((typeof itemId === 'number' ? parseInt(resultId, 10) : resultId) === itemId) {
5398
+ return resultItem;
5399
+ }
5400
+ }
5401
+ return null;
5402
+ };
5403
+
5404
+ },{}],41:[function(_dereq_,module,exports){
5405
+ 'use strict';
5406
+
5407
+ /**
5408
+ * Returns the CSS selector for selecting a specific item by ID.
5409
+ *
5410
+ * @param selector Generic CSS selector to identify items.
5411
+ * @param id ID of the item to select.
5412
+ */
5413
+ module.exports = function(selector, id) {
5414
+ var quotedId = '"' + ('' + id).replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
5415
+ return selector + '[data-item-id=' + quotedId + ']';
5416
+ };
5417
+
5418
+ },{}],42:[function(_dereq_,module,exports){
5419
+ 'use strict';
5420
+
5421
+ /**
5422
+ * Returns the keyCode value of the given event.
5423
+ */
5424
+ module.exports = function(event) {
5425
+ return event.which || event.keyCode || 0;
5426
+ };
5427
+
5428
+ },{}],43:[function(_dereq_,module,exports){
5429
+ 'use strict';
5430
+
5431
+ /**
5432
+ * Returns whether the given element matches the given selector.
5433
+ */
5434
+ module.exports = function(el, selector) {
5435
+ var method =
5436
+ el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
5437
+ return method.call(el, selector);
5438
+ };
5439
+
5440
+ },{}],44:[function(_dereq_,module,exports){
5441
+ 'use strict';
5442
+
5443
+ /**
5444
+ * Parses an HTML string and returns the resulting DOM element.
5445
+ *
5446
+ * @param html HTML representation of the element to parse.
5447
+ */
5448
+ module.exports = function(html) {
5449
+ var div = document.createElement('div');
5450
+ div.innerHTML = html;
5451
+ return div.firstChild;
5452
+ };
5453
+
5454
+ },{}],45:[function(_dereq_,module,exports){
5455
+ 'use strict';
5456
+
5457
+ /**
5458
+ * Removes a DOM element.
5459
+ *
5460
+ * @param el The element to remove.
5461
+ */
5462
+ module.exports = function(el) {
5463
+ if (el && el.parentNode) {
5464
+ el.parentNode.removeChild(el);
5465
+ }
5466
+ };
5467
+
5468
+ },{}],46:[function(_dereq_,module,exports){
5469
+ 'use strict';
5470
+
5471
+ /**
5472
+ * Stops event propagation.
5473
+ *
5474
+ * @param event The event to stop from propagating.
5475
+ */
5476
+ module.exports = function(event) {
5477
+ event.stopPropagation();
5478
+ };
5479
+
5480
+ },{}],47:[function(_dereq_,module,exports){
5481
+ 'use strict';
5482
+
5483
+ /**
5484
+ * Toggles a CSS class on an element.
5485
+ *
5486
+ * @param el The element on which to toggle the CSS class.
5487
+ * @param className The CSS class to toggle.
5488
+ * @param force If true, the class is added. If false, the class is removed.
5489
+ */
5490
+ module.exports = function(el, className, force) {
5491
+ if (el) {
5492
+ el.classList[force ? 'add' : 'remove'](className);
5493
+ }
5494
+ };
5495
+
5496
+ },{}]},{},[37])(37)
5497
+ });
libs/selectivity-3.1.0/selectivity-jquery.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .selectivity-clearfix{clear:both}.selectivity-input{display:inline-block;width:250px}.selectivity-input select{display:none}.selectivity-input:focus{outline:0}.selectivity-placeholder{color:#999}.selectivity-dropdown{background:#fff;border-radius:4px;-webkit-box-shadow:0 1px 5px 1px rgba(0,0,0,.15),0 10px 16px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px 1px rgba(0,0,0,.15),0 10px 16px 0 rgba(0,0,0,.2);position:fixed;z-index:1046}.selectivity-search-input-container{border-bottom:1px solid #eee}.selectivity-search-input{background:0 0;border:0;outline:0;width:100%}.selectivity-results-container{max-height:28em;overflow:auto;position:relative}.selectivity-load-more,.selectivity-result-item{cursor:pointer;padding:7px}.selectivity-result-children .selectivity-result-item{padding-left:17px}.selectivity-load-more.highlight,.selectivity-result-item.highlight{background:#4484c7;color:#fff}.selectivity-result-item.disabled{cursor:default;color:#999}.selectivity-result-item:first-child{border-radius:4px 4px 0 0}.selectivity-dropdown.has-search-input .selectivity-result-item:first-child{border-radius:0}.selectivity-result-label{font-weight:700}.selectivity-load-more,.selectivity-result-children:last-child .selectivity-result-item:last-child,.selectivity-result-item:last-child{border-radius:0 0 4px 4px}.selectivity-result-children .selectivity-result-item:last-child{border-radius:0}.selectivity-error,.selectivity-loading,.selectivity-result-label,.selectivity-search-input-container{padding:7px}.selectivity-multiple-input-container{background:#eee;border-radius:2px;cursor:text;max-height:10em;min-height:calc(2em + 4px);overflow:auto;padding:5px}.selectivity-multiple-input-container .selectivity-placeholder{height:calc(2em + 4px);line-height:calc(2em + 4px)}.selectivity-multiple-input,input[type=text].selectivity-multiple-input{background-color:transparent;border:0;float:left;font:inherit;height:calc(2em + 4px);max-width:100%;outline:0;padding:0}.selectivity-multiple-input:focus,input[type=text].selectivity-multiple-input:focus{background-color:transparent;-webkit-box-shadow:none;box-shadow:none;outline:0}.selectivity-multiple-input::-ms-clear{display:none}.selectivity-multiple-selected-item{background:#4484c7;border-radius:3px;color:#fff;cursor:default;float:left;line-height:2em;margin:2px;padding:0 5px;position:relative;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none;white-space:nowrap}.selectivity-multiple-selected-item.highlighted{background-color:#ccc}.selectivity-multiple-selected-item-remove{color:#fff;cursor:pointer;margin-left:-5px;padding:5px}.selectivity-single-select{background:#eee;border-radius:2px;cursor:pointer;min-height:2em;padding:5px;position:relative;-webkit-box-sizing:content-box;box-sizing:content-box}.selectivity-single-select-input{opacity:0}.selectivity-single-result-container{position:absolute;top:.8em;right:15px;left:5px;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap}.selectivity-single-selected-item{color:#000}.selectivity-single-selected-item-remove{color:#000;float:right;padding:0 5px;position:relative;z-index:1}.selectivity-caret{position:absolute;right:5px;top:.7em}@media only screen and (max-device-width:480px){.selectivity-single-select{background:#eee;border-radius:2px}.selectivity-single-result-container{right:5px}.selectivity-caret{display:none}}.selectivity-submenu-icon{position:absolute;right:4px}
libs/selectivity-3.1.0/selectivity-jquery.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).selectivity=t()}}(function(){return function t(e,i,n){function s(o,l){if(!i[o]){if(!e[o]){var u="function"==typeof require&&require;if(!l&&u)return u(o,!0);if(r)return r(o,!0);var a=new Error("Cannot find module '"+o+"'");throw a.code="MODULE_NOT_FOUND",a}var h=i[o]={exports:{}};e[o][0].call(h.exports,function(t){var i=e[o][1][t];return s(i||t)},h,h.exports,t,e,i,n)}return i[o].exports}for(var r="function"==typeof require&&require,o=0;o<n.length;o++)s(n[o]);return s}({1:[function(t,e,i){var n=t(10).Symbol;e.exports=n},{10:10}],2:[function(t,e,i){e.exports=function(t,e){for(var i=-1,n=null==t?0:t.length,s=Array(n);++i<n;)s[i]=e(t[i],i,t);return s}},{}],3:[function(t,e,i){var n=t(1),s=t(8),r=t(9),o="[object Null]",l="[object Undefined]",u=n?n.toStringTag:void 0;e.exports=function(t){return null==t?void 0===t?l:o:u&&u in Object(t)?s(t):r(t)}},{1:1,8:8,9:9}],4:[function(t,e,i){e.exports=function(t){return function(e){return null==t?void 0:t[e]}}},{}],5:[function(t,e,i){function n(t){if("string"==typeof t)return t;if(o(t))return r(t,n)+"";if(l(t))return h?h.call(t):"";var e=t+"";return"0"==e&&1/t==-u?"-0":e}var s=t(1),r=t(2),o=t(13),l=t(17),u=1/0,a=s?s.prototype:void 0,h=a?a.toString:void 0;e.exports=n},{1:1,13:13,17:17,2:2}],6:[function(t,e,i){var n=t(4)({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"});e.exports=n},{4:4}],7:[function(t,e,i){(function(t){var i="object"==typeof t&&t&&t.Object===Object&&t;e.exports=i}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],8:[function(t,e,i){var n=t(1),s=Object.prototype,r=s.hasOwnProperty,o=s.toString,l=n?n.toStringTag:void 0;e.exports=function(t){var e=r.call(t,l),i=t[l];try{t[l]=void 0;var n=!0}catch(t){}var s=o.call(t);return n&&(e?t[l]=i:delete t[l]),s}},{1:1}],9:[function(t,e,i){var n=Object.prototype.toString;e.exports=function(t){return n.call(t)}},{}],10:[function(t,e,i){var n=t(7),s="object"==typeof self&&self&&self.Object===Object&&self,r=n||s||Function("return this")();e.exports=r},{7:7}],11:[function(t,e,i){var n=t(14),s=t(18),r=t(19),o="Expected a function",l=Math.max,u=Math.min;e.exports=function(t,e,i){function a(e){var i=g,n=m;return g=m=void 0,I=e,w=t.apply(n,i)}function h(t){return I=t,b=setTimeout(f,e),x?a(t):w}function c(t){var i=t-I,n=e-(t-_);return O?u(n,y-i):n}function d(t){var i=t-_,n=t-I;return void 0===_||i>=e||i<0||O&&n>=y}function f(){var t=s();if(d(t))return p(t);b=setTimeout(f,c(t))}function p(t){return b=void 0,E&&g?a(t):(g=m=void 0,w)}function v(){var t=s(),i=d(t);if(g=arguments,m=this,_=t,i){if(void 0===b)return h(_);if(O)return b=setTimeout(f,e),a(_)}return void 0===b&&(b=setTimeout(f,e)),w}var g,m,y,w,b,_,I=0,x=!1,O=!1,E=!0;if("function"!=typeof t)throw new TypeError(o);return e=r(e)||0,n(i)&&(x=!!i.leading,y=(O="maxWait"in i)?l(r(i.maxWait)||0,e):y,E="trailing"in i?!!i.trailing:E),v.cancel=function(){void 0!==b&&clearTimeout(b),I=0,g=_=m=b=void 0},v.flush=function(){return void 0===b?w:p(s())},v}},{14:14,18:18,19:19}],12:[function(t,e,i){var n=t(6),s=t(20),r=/[&<>"']/g,o=RegExp(r.source);e.exports=function(t){return(t=s(t))&&o.test(t)?t.replace(r,n):t}},{20:20,6:6}],13:[function(t,e,i){var n=Array.isArray;e.exports=n},{}],14:[function(t,e,i){e.exports=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},{}],15:[function(t,e,i){e.exports=function(t){return null!=t&&"object"==typeof t}},{}],16:[function(t,e,i){var n=t(3),s=t(13),r=t(15),o="[object String]";e.exports=function(t){return"string"==typeof t||!s(t)&&r(t)&&n(t)==o}},{13:13,15:15,3:3}],17:[function(t,e,i){var n=t(3),s=t(15),r="[object Symbol]";e.exports=function(t){return"symbol"==typeof t||s(t)&&n(t)==r}},{15:15,3:3}],18:[function(t,e,i){var n=t(10);e.exports=function(){return n.Date.now()}},{10:10}],19:[function(t,e,i){var n=t(14),s=t(17),r=NaN,o=/^\s+|\s+$/g,l=/^[-+]0x[0-9a-f]+$/i,u=/^0b[01]+$/i,a=/^0o[0-7]+$/i,h=parseInt;e.exports=function(t){if("number"==typeof t)return t;if(s(t))return r;if(n(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=n(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(o,"");var i=u.test(t);return i||a.test(t)?h(t.slice(2),i?2:8):l.test(t)?r:+t}},{14:14,17:17}],20:[function(t,e,i){var n=t(5);e.exports=function(t){return null==t?"":n(t)}},{5:5}],21:[function(t,e,i){"use strict";function n(t){s.each(l,function(e,i){t.on(e,function(t){t.originalEvent&&i.forEach(function(e){t[e]=t.originalEvent[e]})})})}var s=window.jQuery||window.Zepto,r=t(16),o=t(37),l={change:["added","removed","value"],"selectivity-change":["added","removed","value"],"selectivity-highlight":["id","item"],"selectivity-selected":["id","item"],"selectivity-selecting":["id","item"]};s.fn.selectivity=function(t,e){var i,l=Array.prototype.slice.call(arguments,1);return this.each(function(){var u=this.selectivity;if(u){if("data"===t?t=l.length?"setData":"getData":"val"===t||"value"===t?t=l.length?"setValue":"getValue":r(t)||(l=[t],t="setOptions"),!s.isFunction(u[t]))throw new Error("Unknown method: "+t);void 0===i&&(i=u[t].apply(u,l))}else if(r(t)){if("destroy"!==t)throw new Error("Cannot call method on element without Selectivity instance")}else{e=s.extend({},t,{element:this});var a=s(this);a.is("select")&&a.prop("multiple")&&(e.multiple=!0);var h=o.Inputs,c=e.inputType||(e.multiple?"Multiple":"Single");if(!s.isFunction(c)){if(!h[c])throw new Error("Unknown Selectivity input type: "+c);c=h[c]}this.selectivity=new c(e),n(a=s(this.selectivity.el)),void 0===i&&(i=a)}}),void 0===i?this:i},o.patchEvents=n,s.Selectivity=o},{16:16,37:37,jquery:"jquery"}],22:[function(t,e,i){"use strict";function n(t,e){for(;t&&!u(t,e);)t=t.parentElement;return t||null}function s(t,e){this.el=a(t.template("dropdown",{dropdownCssClass:t.options.dropdownCssClass,searchInputPlaceholder:t.options.searchInputPlaceholder,showSearchInput:e.showSearchInput})),this.resultsContainer=this.$(".selectivity-results-container"),this.hasMore=!1,this.highlightedResult=null,this.loadMoreHighlighted=!1,this.options=e,this.results=[],this.selectivity=t,this._closed=!1,this._lastMousePosition={},this.close=this.close.bind(this),this.position=this.position.bind(this),!1!==t.options.closeOnSelect&&t.events.on("selectivity-selecting",this.close),this.addToDom(),this.showLoading(),e.showSearchInput&&(t.initInput(this.$(".selectivity-search-input")),t.focus());var i={};i["click "+p]=this._loadMoreClicked,i["click "+v]=this._resultClicked,i["mouseenter "+p]=this._loadMoreHovered,i["mouseenter "+v]=this._resultHovered,this.events=new o(this.el,this),this.events.on(i),this._attachScrollListeners(),this._suppressWheel(),setTimeout(this.triggerOpen.bind(this),1)}var r=(window.jQuery||window.Zepto).extend,o=t(23),l=t(40),u=t(42),a=t(43),h=t(44),c=t(45),d=t(46),f=t(37),p=".selectivity-load-more",v=".selectivity-result-item",g=["scroll","touchend","touchmove"];r(s.prototype,{$:function(t){return this.el.querySelector(t)},addToDom:function(){this.selectivity.el.appendChild(this.el)},close:function(){this._closed||(this._closed=!0,h(this.el),this.selectivity.events.off("selectivity-selecting",this.close),this.triggerClose(),this._removeScrollListeners())},highlight:function(t,e){d(this.$(".highlight"),"highlight",!1),d(this.$(l(v,t.id)),"highlight",!0),this.highlightedResult=t,this.loadMoreHighlighted=!1,this.selectivity.triggerEvent("selectivity-highlight",{item:t,id:t.id,reason:e&&e.reason||"unspecified"})},highlightLoadMore:function(){d(this.$(".highlight"),"highlight",!1),d(this.$(p),"highlight",!0),this.highlightedResult=null,this.loadMoreHighlighted=!0},loadMore:function(){h(this.$(p)),this.resultsContainer.innerHTML+=this.selectivity.template("loading"),this.options.query({callback:function(t){if(!t||!t.results)throw new Error("callback must be passed a response object");this._showResults(f.processItems(t.results),{add:!0,hasMore:!!t.more})}.bind(this),error:this._showResults.bind(this,[],{add:!0}),offset:this.results.length,selectivity:this.selectivity,term:this.term})},position:function(){var t=this.options.position;t&&t(this.el,this.selectivity.el),this._scrolled()},renderItems:function(t){var e=this.selectivity;return t.map(function(t){var i=e.template(t.id?"resultItem":"resultLabel",t);return t.children&&(i+=e.template("resultChildren",{childrenHtml:this.renderItems(t.children)})),i},this).join("")},search:function(t){if(this.term=t,this.options.items){t=f.transformText(t);var e=this.selectivity.options.matcher||f.matcher;this._showResults(this.options.items.map(function(i){return e(i,t)}).filter(function(t){return!!t}),{term:t})}else this.options.query&&this.options.query({callback:function(e){if(!e||!e.results)throw new Error("callback must be passed a response object");this._showResults(f.processItems(e.results),{hasMore:!!e.more,term:t})}.bind(this),error:this.showError.bind(this),offset:0,selectivity:this.selectivity,term:t})},selectHighlight:function(){this.highlightedResult?this.selectItem(this.highlightedResult.id):this.loadMoreHighlighted&&this.loadMore()},selectItem:function(t){var e=f.findNestedById(this.results,t);if(e&&!e.disabled&&!1!==e.selectable){var i={id:t,item:e};this.selectivity.triggerEvent("selectivity-selecting",i)&&this.selectivity.triggerEvent("selectivity-selected",i)}},showError:function(t,e){this.resultsContainer.innerHTML=this.selectivity.template("error",{escape:!e||!1!==e.escape,message:t}),this.hasMore=!1,this.results=[],this.highlightedResult=null,this.loadMoreHighlighted=!1,this.position()},showLoading:function(){this.resultsContainer.innerHTML=this.selectivity.template("loading"),this.hasMore=!1,this.results=[],this.highlightedResult=null,this.loadMoreHighlighted=!1,this.position()},showResults:function(t,e){e.add?h(this.$(".selectivity-loading")):this.resultsContainer.innerHTML="";var i=this.selectivity.filterResults(t),n=this.renderItems(i);e.hasMore?n+=this.selectivity.template("loadMore"):n||e.add||(n=this.selectivity.template("noResults",{term:e.term})),this.resultsContainer.innerHTML+=n,this.results=e.add?this.results.concat(t):t,this.hasMore=e.hasMore;var s=this.selectivity.getValue();if(s&&!Array.isArray(s)){var r=f.findNestedById(t,s);r&&this.highlight(r,{reason:"current_value"})}else!1===this.options.highlightFirstItem||e.add&&!this.loadMoreHighlighted||this._highlightFirstItem(i);this.position()},triggerClose:function(){this.selectivity.triggerEvent("selectivity-close")},triggerOpen:function(){this.selectivity.triggerEvent("selectivity-open")},_attachScrollListeners:function(){for(var t=0;t<g.length;t++)window.addEventListener(g[t],this.position,!0);window.addEventListener("resize",this.position)},_highlightFirstItem:function(t){function e(t){for(var i=0,n=t.length;i<n;i++){var s=t[i];if(s.id)return s;if(s.children){var r=e(s.children);if(r)return r}}}var i=e(t);i?this.highlight(i,{reason:"first_result"}):(this.highlightedResult=null,this.loadMoreHighlighted=!1)},_loadMoreClicked:function(t){this.loadMore(),c(t)},_loadMoreHovered:function(t){void 0!==t.screenX&&t.screenX===this._lastMousePosition.x&&void 0!==t.screenY&&t.screenY===this._lastMousePosition.y||(this.highlightLoadMore(),this._recordMousePosition(t))},_recordMousePosition:function(t){this._lastMousePosition={x:t.screenX,y:t.screenY}},_removeScrollListeners:function(){for(var t=0;t<g.length;t++)window.removeEventListener(g[t],this.position,!0);window.removeEventListener("resize",this.position)},_resultClicked:function(t){this.selectItem(this.selectivity.getRelatedItemId(t)),c(t)},_resultHovered:function(t){if(!t.screenX||t.screenX!==this._lastMousePosition.x||!t.screenY||t.screenY!==this._lastMousePosition.y){var e=this.selectivity.getRelatedItemId(t),i=f.findNestedById(this.results,e);i&&!i.disabled&&this.highlight(i,{reason:"hovered"}),this._recordMousePosition(t)}},_scrolled:function(){var t=this.$(p);t&&t.offsetTop-this.resultsContainer.scrollTop<this.el.clientHeight&&this.loadMore()},_showResults:function(t,e){this.showResults(t,r({dropdown:this},e))},_suppressWheel:function(){var t=this.selectivity.options.suppressWheelSelector;if(null!==t){var e=t||".selectivity-results-container";this.events.on("wheel",e,function(t){function i(){c(t),t.preventDefault()}var s=0===t.deltaMode?t.deltaY:40*t.deltaY,r=n(t.target,e),o=r.clientHeight,l=r.scrollHeight,u=r.scrollTop;l>o&&(s<-u?(r.scrollTop=0,i()):s>l-o-u&&(r.scrollTop=l,i()))})}}}),e.exports=f.Dropdown=s},{23:23,37:37,40:40,42:42,43:43,44:44,45:45,46:46,"lodash/assign":"lodash/assign"}],23:[function(t,e,i){"use strict";function n(t,e){this.context=e||null,this.el=t,this.events={},this._onEvent=this._onEvent.bind(this)}var s=(window.jQuery||window.Zepto).extend,r=t(16),o=t(42),l=["blur","focus","mouseenter","mouseleave","scroll"];s(n.prototype,{destruct:function(){Object.keys(this.events).forEach(function(t){var e=l.indexOf(t)>-1;this.el.removeEventListener(t,this._onEvent,e)},this),this.context=null,this.el=null,this.events=null},off:function(t,e,i){if(r(e)||(i=e,e=""),i){var n=this.events[t];if(n&&(n=n[e]))for(var s=0;s<n.length;s++)n[s]===i&&(n.splice(s,1),s--)}else this.events[t][e]=[]},on:function(t,e,i){if(r(t)){if(r(e)||(i=e,e=""),!this.events.hasOwnProperty(t)){var n=l.indexOf(t)>-1;this.el.addEventListener(t,this._onEvent,n),this.events[t]={}}this.events[t].hasOwnProperty(e)||(this.events[t][e]=[]),this.events[t][e].indexOf(i)<0&&this.events[t][e].push(i)}else{var s=t;for(var o in s)if(s.hasOwnProperty(o)){var u=o.split(" ");u.length>1?this.on(u[0],u[1],s[o]):this.on(u[0],s[o])}}},_onEvent:function(t){function e(e){for(var i=0;i<e.length;i++)e[i].call(s,t)}var i=!1,n=t.stopPropagation;t.stopPropagation=function(){n.call(t),i=!0};for(var s=this.context,r=t.target,l=this.events[t.type.toLowerCase()];r&&r!==this.el&&!i;){for(var u in l)u&&l.hasOwnProperty(u)&&o(r,u)&&e(l[u]);r=r.parentElement}!i&&l.hasOwnProperty("")&&e(l[""])}}),e.exports=n},{16:16,42:42,"lodash/assign":"lodash/assign"}],24:[function(t,e,i){"use strict";function n(t){var e=t.indexOf("@");if(-1===e||t.indexOf(" ")>-1)return!1;var i=t.lastIndexOf(".");return-1===i?e<t.length-2:!(i>e)||i<t.length-2}function s(t,e){for(var i=(e=void 0===e?t.length:e)-1;i>=0;i--)if(/\s/.test(t[i]))return t.slice(i+1,e);return t.slice(0,e)}function r(t,e){return t.charAt(0)===e[0]&&t.slice(-1)===e[1]?t.slice(1,-1).trim():t.trim()}function o(t){var e=s(t),i=t.slice(0,-e.length).trim();return n(e)?(e=r(r(e,"()"),"<>"),i=r(i,'""').trim()||e,{id:e,text:i}):t.trim()?{id:t,text:t}:null}function l(t,e,i){for(;function(t){if(t)for(var e=0,i=t.length;e<i;e++)switch(t[e]){case";":case",":case"\n":return!0;case" ":case"\t":if(n(s(t,e)))return!0;break;case'"':do{e++}while(e<i&&'"'!==t[e]);break;default:continue}return!1}(t);){var r=function(t){for(var e=0,i=t.length;e<i;e++)switch(t[e]){case";":case",":case"\n":return{term:t.slice(0,e),input:t.slice(e+1)};case" ":case"\t":if(n(s(t,e)))return{term:t.slice(0,e),input:t.slice(e+1)};break;case'"':do{e++}while(e<i&&'"'!==t[e]);break;default:continue}return{}}(t);if(r.term){var l=o(r.term);!l||l.id&&c.findById(e,l.id)||i(l)}t=r.input}return t}function u(t){h.call(this,a({createTokenItem:o,showDropdown:!1,tokenizer:l},t)),this.events.on("blur",function(){var t=this.input;t&&n(s(t.value))&&this.add(o(t.value))})}var a=(window.jQuery||window.Zepto).extend,h=t(25),c=t(37);c.inherits(u,h),e.exports=c.Inputs.Email=u},{25:25,37:37,"lodash/assign":"lodash/assign"}],25:[function(t,e,i){"use strict";function n(t){o.call(this,s({positionDropdown:function(t,e){var i=e.getBoundingClientRect(),n=t.clientHeight,r=i.bottom+n>window.innerHeight&&i.top-n>0;s(t.style,{left:i.left+"px",top:(r?i.top-n:i.bottom)+"px",width:i.width+"px"})},showSearchInputInDropdown:!1},t)),this._reset();var e={change:this.rerenderSelection,click:this._clicked,"selectivity-selected":this._resultSelected};e["change "+f]=c,e["click "+p]=this._itemClicked,e["click "+p+"-remove"]=this._itemRemoveClicked,e["keydown "+f]=this._keyHeld,e["keyup "+f]=this._keyReleased,e["paste "+f]=this._onPaste,this.events.on(e)}var s=(window.jQuery||window.Zepto).extend,r=t(16),o=t(37),l=t(40),u=t(41),a=t(43),h=t(44),c=t(45),d=t(46),f=".selectivity-multiple-input",p=".selectivity-multiple-selected-item",v="ontouchstart"in window,g=o.inherits(n,o,{add:function(t){var e=o.isValidId(t),i=e?t:this.validateItem(t)&&t.id;-1===this._value.indexOf(i)&&(this._value.push(i),e&&this.options.initSelection?this.options.initSelection([i],function(e){this._value.indexOf(i)>-1&&(t=this.validateItem(e[0]),this._data.push(t),this.triggerChange({added:t}))}.bind(this)):(e&&(t=this.getItemForId(i)),this._data.push(t),this.triggerChange({added:t}))),this.input.value="",this._updateInputWidth()},clear:function(){this.setData([])},filterResults:function(t){return(t=t.map(function(t){var e={id:t.id,text:t.text};return t.children&&(e.children=this.filterResults(t.children)),e},this)).filter(function(t){return!o.findById(this._data,t.id)},this)},getDataForValue:function(t){return t.map(this.getItemForId,this).filter(function(t){return!!t})},getValueForData:function(t){return t.map(function(t){return t.id})},remove:function(t){var e,i=t.id||t,n=o.findIndexById(this._data,i);n>-1&&(e=this._data[n],this._data.splice(n,1)),this._value[n]!==i&&(n=this._value.indexOf(i)),n>-1&&this._value.splice(n,1),e&&this.triggerChange({removed:e}),i===this._highlightedItemId&&(this._highlightedItemId=null),this._updateInputWidth()},rerenderSelection:function(t){(t=t||{}).added?(this._renderSelectedItem(t.added),this._scrollToBottom()):t.removed?h(this.$(l(p,t.removed.id))):(this._forEachSelectedItem(h),this._data.forEach(this._renderSelectedItem,this),this._updateInputWidth()),(t.added||t.removed)&&(this.dropdown&&this.dropdown.showResults(this.filterResults(this.dropdown.results),{hasMore:this.dropdown.hasMore}),v||this.focus()),this.positionDropdown(),this._updatePlaceholder()},search:function(t){this.options.tokenizer&&(t=this.options.tokenizer(t,this._data,this.add.bind(this),this.options),r(t)&&t!==this.input.value&&(this.input.value=t)),this._updateInputWidth(),this.dropdown&&g(this,"search",t)},setOptions:function(t){var e=this.enabled;g(this,"setOptions",t),e!==this.enabled&&this._reset()},validateData:function(t){if(null===t)return[];if(Array.isArray(t))return t.map(this.validateItem,this);throw new Error("Data for MultiSelectivity instance should be an array")},validateValue:function(t){if(null===t)return[];if(Array.isArray(t)){if(t.every(o.isValidId))return t;throw new Error("Value contains invalid IDs")}throw new Error("Value for MultiSelectivity instance should be an array")},_backspacePressed:function(){this.options.backspaceHighlightsBeforeDelete?this._highlightedItemId?this._deletePressed():this._value.length&&this._highlightItem(this._value.slice(-1)[0]):this._value.length&&this.remove(this._value.slice(-1)[0])},_clicked:function(t){this.enabled&&(!1!==this.options.showDropdown?this.open():this.focus(),c(t))},_createToken:function(){var t=this.input.value,e=this.options.createTokenItem;if(t&&e){var i=e(t);i&&this.add(i)}},_deletePressed:function(){this._highlightedItemId&&this.remove(this._highlightedItemId)},_forEachSelectedItem:function(t){Array.prototype.forEach.call(this.el.querySelectorAll(p),t)},_highlightItem:function(t){this._highlightedItemId=t,this._forEachSelectedItem(function(e){d(e,"highlighted",e.getAttribute("data-item-id")===t)}),v||this.focus()},_itemClicked:function(t){this.enabled&&this._highlightItem(this.getRelatedItemId(t))},_itemRemoveClicked:function(t){this.remove(this.getRelatedItemId(t)),c(t)},_keyHeld:function(t){this._originalValue=this.input.value,13!==u(t)||t.ctrlKey||t.preventDefault()},_keyReleased:function(t){var e=!!this._originalValue,i=u(t);13!==i||t.ctrlKey?8!==i||e?46!==i||e||this._deletePressed():this._backspacePressed():this._createToken()},_onPaste:function(){setTimeout(function(){this.search(this.input.value),this._createToken()}.bind(this),10)},_renderSelectedItem:function(t){var e=a(this.template("multipleSelectedItem",s({highlighted:t.id===this._highlightedItemId,removable:!this.options.readOnly},t)));this.input.parentNode.insertBefore(e,this.input)},_reset:function(){this.el.innerHTML=this.template("multipleSelectInput",{enabled:this.enabled}),this._highlightedItemId=null,this.initInput(this.$(f)),this.rerenderSelection()},_resultSelected:function(t){-1===this._value.indexOf(t.id)?this.add(t.item):this.remove(t.item)},_scrollToBottom:function(){var t=this.$(f+"-container");t.scrollTop=t.clientHeight},_updateInputWidth:function(){if(this.enabled){var t=this.input.value||!this._data.length&&this.options.placeholder||"";this.input.setAttribute("size",t.length+2),this.positionDropdown()}},_updatePlaceholder:function(){var t=!this._data.length&&this.options.placeholder||"";this.enabled?this.input.setAttribute("placeholder",t):this.$(".selectivity-placeholder").textContent=t}});e.exports=o.Inputs.Multiple=n},{16:16,37:37,40:40,41:41,43:43,44:44,45:45,46:46,"lodash/assign":"lodash/assign"}],26:[function(t,e,i){"use strict";function n(t){r.call(this,s({positionDropdown:function(t,e){var i=e.getBoundingClientRect(),n=i.bottom,r=Math.min(Math.max(n+t.clientHeight-window.innerHeight,0),i.top+i.height);s(t.style,{left:i.left+"px",top:n-r+"px",width:i.width+"px"})}},t)),this.rerender(),!1===t.showSearchInputInDropdown&&this.initInput(this.$(".selectivity-single-select-input"),{search:!1}),this.events.on({change:this.rerenderSelection,click:this._clicked,"click .selectivity-search-input":o,"click .selectivity-single-selected-item-remove":this._itemRemoveClicked,"focus .selectivity-single-select-input":this._focused,"selectivity-selected":this._resultSelected})}var s=(window.jQuery||window.Zepto).extend,r=t(37),o=t(45),l=r.inherits(n,r,{clear:function(){this.setData(null)},close:function(t){this._closing=!0,l(this,"close"),t&&t.keepFocus&&this.input&&this.input.focus(),this._closing=!1},getDataForValue:function(t){return this.getItemForId(t)},getValueForData:function(t){return t?t.id:null},rerender:function(){this.el.innerHTML=this.template("singleSelectInput",this.options),this.rerenderSelection()},rerenderSelection:function(){var t=this._data?"singleSelectedItem":"singleSelectPlaceholder",e=this._data?s({removable:this.options.allowClear&&!this.options.readOnly},this._data):{placeholder:this.options.placeholder};this.el.querySelector("input").value=this._value,this.$(".selectivity-single-result-container").innerHTML=this.template(t,e)},setOptions:function(t){var e=this.enabled;l(this,"setOptions",t),e!==this.enabled&&this.rerender()},validateData:function(t){return null===t?t:this.validateItem(t)},validateValue:function(t){if(null===t||r.isValidId(t))return t;throw new Error("Value for SingleSelectivity instance should be a valid ID or null")},_clicked:function(){this.enabled&&(this.dropdown?this.close({keepFocus:!0}):!1!==this.options.showDropdown&&this.open())},_focused:function(){!this.enabled||this._closing||this._opening||!1===this.options.showDropdown||this.open()},_itemRemoveClicked:function(t){this.setData(null),o(t)},_resultSelected:function(t){this.setData(t.item),this.close({keepFocus:!0})}});e.exports=r.Inputs.Single=n},{37:37,45:45,"lodash/assign":"lodash/assign"}],27:[function(t,e,i){"use strict";var n=t(12),s=t(37);e.exports=s.Locale={loading:"Loading...",loadMore:"Load more...",noResults:"No results found",ajaxError:function(t){return t?"Failed to fetch results for <b>"+n(t)+"</b>":"Failed to fetch results"},needMoreCharacters:function(t){return"Enter "+t+" more characters to search"},noResultsForTerm:function(t){return"No results for <b>"+n(t)+"</b>"}}},{12:12,37:37}],28:[function(t,e,i){"use strict";function n(t,e,i){return t+(t.indexOf("?")>-1?"&":"?")+e+"="+encodeURIComponent(i)}function s(t,e){var i={};return e.forEach(function(e){void 0!==t[e]&&(i[e]=t[e])}),i}function r(t,e){var i=t.fetch||window.fetch,r=e.term,o="function"==typeof t.url?t.url(e):t.url;if(t.params){var l=t.params(r,e.offset||0);for(var a in l)l.hasOwnProperty(a)&&(o=n(o,a,l[a]))}i(o,s(t,["body","cache","credentials","headers","integrity","method","mode","redirect","referrer","referrerPolicy"]),e).then(function(t){if(t.ok)return t.json();if(Array.isArray(t)||t.results)return t;throw new Error("Unexpected AJAX response")}).then(function(t){Array.isArray(t)?e.callback({results:t,more:!1}):e.callback({results:t.results,more:!!t.more})}).catch(function(i){var n=t.formatError||u.ajaxError;e.error(n(r,i),{escape:!1})})}var o=t(11),l=t(37),u=t(27);l.OptionListeners.unshift(function(t,e){var i=e.ajax;if(i&&i.url){var n=i.quietMillis?o(r,i.quietMillis):r;e.query=function(t){var e=i.minimumInputLength-t.term.length;e>0?t.error(u.needMoreCharacters(e)):n(i,t)}}})},{11:11,27:27,37:37}],29:[function(t,e,i){"use strict";var n=0;t(37).OptionListeners.push(function(t,e){var i=e.query;i&&!i._async&&(e.query=function(t){var e=++n,s=t.callback,r=t.error;t.callback=function(){e===n&&s.apply(null,arguments)},t.error=function(){e===n&&r.apply(null,arguments)},i(t)},e.query._async=!0)})},{37:37}],30:[function(t,e,i){"use strict";var n={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"},s=t(37),r=s.transformText;s.transformText=function(t){for(var e="",i=0,s=t.length;i<s;i++){var o=t[i];e+=n[o]||o}return r(e)}},{37:37}],31:[function(t,e,i){"use strict";var n=window.jQuery||window.Zepto;t(37).OptionListeners.unshift(function(t,e){var i=e.ajax;i&&i.url&&!i.fetch&&n.Deferred&&(i.fetch=function(t,e){return n.ajax(t,{cache:"no-cache"!==e.cache,headers:e.headers||null,method:e.method||"GET",xhrFields:"include"===e.credentials?{withCredentials:!0}:null}).then(function(t){return{results:n.map(t,function(t){return t}),more:!1}},function(t,e,i){throw new Error("AJAX request returned: "+e+(i?", "+i:""))})})})},{37:37,jquery:"jquery"}],32:[function(t,e,i){"use strict";function n(t,e){var i=e.multiple?[]:null,n=function(){var t=r(this);if(t.is("option")){var s=t.text(),o=t.attr("value");if(void 0===o&&(o=s),t.prop("selected")){var l={id:o,text:s};e.multiple?i.push(l):i=l}return{id:o,text:t.attr("label")||s}}return{text:t.attr("label"),children:t.children("option,optgroup").map(n).get()}};e.allowClear="allowClear"in e?e.allowClear:!t.prop("required");var s=t.children("option,optgroup").map(n).get();e.data=i,e.items=e.query?null:s,e.placeholder=e.placeholder||t.data("placeholder")||"",e.tabIndex=void 0===e.tabIndex?t.attr("tabindex")||0:e.tabIndex;var o=(t.attr("class")||"selectivity-input").split(" ");o.indexOf("selectivity-input")<0&&o.push("selectivity-input");var l=r("<div>").attr({id:"s9y_"+t.attr("id"),class:o.join(" "),style:t.attr("style"),"data-name":t.attr("name")});return l.insertAfter(t),t.hide(),l[0]}function s(t){var e=r(t.el);e.on("change",function(t){var i=t.originalEvent.value;e.prev("select").val("array"===r.type(i)?i.slice(0):i).trigger(t)})}var r=window.jQuery||window.Zepto,o=t(37);o.OptionListeners.push(function(t,e){var i=r(t.el);i.is("select")&&(i.attr("autofocus")&&setTimeout(function(){t.focus()},1),t.el=n(i,e),t.el.selectivity=t,o.patchEvents(i),s(t))})},{37:37,jquery:"jquery"}],33:[function(t,e,i){"use strict";var n=t(37),s=t(39),r=t(41),o=8,l=40,u=13,a=27,h=9,c=38;n.InputListeners.push(function(t,e){function i(e,r){function o(){var t;e.highlightedResult?t=s(u,e.highlightedResult.id):e.loadMoreHighlighted&&(t=e.$(".selectivity-load-more")),t&&t.scrollIntoView&&t.scrollIntoView(r<0)}var l=e.results;if(l.length){var u=[].slice.call(e.el.querySelectorAll(".selectivity-result-item"));if(e.submenu)i(e.submenu,r);else{var a=r>0?0:u.length-1,h=a,c=e.highlightedResult;if(c){var d=s(u,c.id);if(h=u.indexOf(d)+r,r>0?h>=u.length:h<0){if(e.hasMore)return e.highlightLoadMore(),void o();h=a}}var f=u[h],p=n.findNestedById(l,t.getRelatedItemId(f));p&&(e.highlight(p,{delay:!!p.submenu}),o())}}}var d=!1,f=null;e.addEventListener("keydown",function(n){var s=t.dropdown;if(s){var a=r(n);if(a===o){if(!e.value){if(s.submenu){for(var p=s.submenu;p.submenu;)p=p.submenu;f=p}n.preventDefault(),d=!0}}else a===l?i(s,1):a===c?i(s,-1):a===h?setTimeout(function(){t.close()},1):a===u&&n.preventDefault()}}),e.addEventListener("keyup",function(e){function i(){!1!==t.options.showDropdown&&t.open()}var n=t.dropdown,s=r(e);d?(e.preventDefault(),d=!1,f&&(f.close(),t.focus(),f=null)):s===o?!n&&t.options.allowClear&&t.clear():s!==u||e.ctrlKey?s===a?(t.close(),e.preventDefault()):s===l||s===c?(i(),e.preventDefault()):i():(n?n.selectHighlight():!1!==t.options.showDropdown&&i(),e.preventDefault())})})},{37:37,39:39,41:41}],34:[function(t,e,i){"use strict";function n(t,e){this.parentMenu=e.parentMenu,s.call(this,t,e),this._closeSubmenuTimeout=0,this._openSubmenuTimeout=0}var s=t(22),r=t(37),o=t(39),l=r.inherits(n,s,{close:function(){this.submenu&&this.submenu.close(),l(this,"close"),this.parentMenu&&(this.parentMenu.submenu=null,this.parentMenu=null),clearTimeout(this._closeSubmenuTimeout),clearTimeout(this._openSubmenuTimeout)},highlight:function(t,e){var i=(e=e||{}).reason||"unspecified";e.delay?(l(this,"highlight",t),clearTimeout(this._openSubmenuTimeout),this._openSubmenuTimeout=setTimeout(this._doHighlight.bind(this,t,i),300)):this.submenu?this.highlightedResult&&this.highlightedResult.id===t.id?this._doHighlight(t,i):(clearTimeout(this._closeSubmenuTimeout),this._closeSubmenuTimeout=setTimeout(this._closeSubmenuAndHighlight.bind(this,t,i),100)):(this.parentMenu&&this.parentMenu._closeSubmenuTimeout&&(clearTimeout(this.parentMenu._closeSubmenuTimeout),this.parentMenu._closeSubmenuTimeout=0),!1===e.openSubmenu?l(this,"highlight",t):this._doHighlight(t,i))},search:function(t){if(this.submenu){var e=this.$(".selectivity-search-input");if(!e||e!==document.activeElement)return void this.submenu.search(t);this.submenu.close()}l(this,"search",t)},selectHighlight:function(){this.submenu?this.submenu.selectHighlight():l(this,"selectHighlight")},showResults:function(t,e){function i(t){t.children&&t.children.forEach(i),t.submenu&&(t.selectable=!!t.selectable)}this.submenu&&e.dropdown!==this?this.submenu.showResults(t,e):(t.forEach(i),l(this,"showResults",t,e))},triggerClose:function(){this.parentMenu?this.selectivity.triggerEvent("selectivity-close-submenu"):l(this,"triggerClose")},triggerOpen:function(){this.parentMenu?this.selectivity.triggerEvent("selectivity-open-submenu"):l(this,"triggerOpen")},_closeSubmenuAndHighlight:function(t,e){this.submenu&&this.submenu.close(),this._doHighlight(t,e)},_doHighlight:function(t,e){l(this,"highlight",t);var i=this.selectivity.options;if(!(!t.submenu||this.submenu||i.shouldOpenSubmenu&&!1===i.shouldOpenSubmenu(t,e))){var n=i.dropdown||r.Dropdown;if(n){var s=this.el.querySelectorAll(".selectivity-result-item"),u=o(s,t.id),a=this.el;this.submenu=new n(this.selectivity,{highlightFirstItem:!t.selectable,items:t.submenu.items||null,parentMenu:this,position:function(e,i){if(t.submenu.positionDropdown)t.submenu.positionDropdown(e,i,u,a);else{var n=a.getBoundingClientRect(),s=n.right,r=n.width;s+r>document.body.clientWidth&&n.left-r>0&&(s=n.left-r+10);var o=u.getBoundingClientRect().top,l=Math.min(Math.max(o+e.clientHeight-window.innerHeight,0),n.top+n.height);e.style.left=s+"px",e.style.top=o-l+"px",e.style.width=r+"px"}},query:t.submenu.query||null,showSearchInput:t.submenu.showSearchInput}),this.submenu.search("")}}}});r.Dropdown=n,e.exports=n},{22:22,37:37,39:39}],35:[function(t,e,i){"use strict";function n(t,e,i,n){for(var s=n.createTokenItem||function(t){return t?{id:t,text:t}:null},o=n.tokenSeparators;function(t){return!!t&&o.some(function(e){return t.indexOf(e)>-1})}(t);){var l=function(t){for(var e=0,i=t.length;e<i;e++)if(o.indexOf(t[e])>-1)return{term:t.slice(0,e),input:t.slice(e+1)};return{}}(t);if(l.term){var u=s(l.term);u&&!r.findById(e,u.id)&&i(u)}t=l.input}return t}var s=(window.jQuery||window.Zepto).extend,r=t(37);r.OptionListeners.push(function(t,e){e.tokenSeparators&&(e.allowedTypes=s({tokenSeparators:"array"},e.allowedTypes),e.tokenizer=e.tokenizer||n)})},{37:37,"lodash/assign":"lodash/assign"}],36:[function(t,e,i){t(22),t(24),t(25),t(26),t(27),t(28),t(29),t(30),t(31),t(32),t(33),t(34),t(35),t(38),t(21)},{21:21,22:22,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,38:38}],37:[function(t,e,i){"use strict";function n(t){this.dropdown=null,this.el=t.element,this.enabled=!t.readOnly&&!t.removeOnly,this.input=null,this.items=null,this.options={},this.templates=s({},n.Templates),this.term="",this.setOptions(t),t.value?this.setValue(t.value,{triggerChange:!1}):this.setData(t.data||null,{triggerChange:!1}),this.el.setAttribute("tabindex",t.tabIndex||0),this.events=new o(this.el,this),this.events.on({blur:this._blur,mouseenter:this._mouseenter,mouseleave:this._mouseleave,"selectivity-close":this._closed})}var s=(window.jQuery||window.Zepto).extend,r=t(16),o=t(23),l=t(46);s(n.prototype,{$:function(t){return this.el.querySelector(t)},close:function(){this._clearCloseTimeout(),this.dropdown&&(this.dropdown.close(),this.dropdown=null)},destroy:function(){this.events.destruct();for(var t=this.el;t.firstChild;)t.removeChild(t.firstChild);t.selectivity=null},filterResults:function(t){return t},focus:function(){this._clearCloseTimeout(),this._focusing=!0,this.input&&this.input.focus(),this._focusing=!1},getData:function(){return this._data},getItemForId:function(t){var e=this.items;return e?n.findNestedById(e,t):null===t?null:{id:t,text:""+t}},getRelatedItemId:function(t){for(var e=t.target||t;e&&!e.hasAttribute("data-item-id");)e=e.parentNode;if(!e)return null;var i=e.getAttribute("data-item-id");if(n.findById(this._data||[],i))return i;for(var s=this.dropdown;s;){if(n.findNestedById(s.results,i))return i;s=s.submenu}var r=parseInt(i,10);return""+r===i?r:i},getValue:function(){return this._value},initInput:function(t,e){this.input=t;var i=this;(this.options.inputListeners||n.InputListeners).forEach(function(n){n(i,t,e)}),e&&!1===e.search||t.addEventListener("keyup",function(t){t.defaultPrevented||i.search(t.target.value)})},open:function(){if(!this._opening&&!this.dropdown&&this.triggerEvent("selectivity-opening")){this._opening=!0;var t=this.options.dropdown||n.Dropdown;t&&(this.dropdown=new t(this,{items:this.items,position:this.options.positionDropdown,query:this.options.query,showSearchInput:!1!==this.options.showSearchInputInDropdown})),this.search(""),this.focus(),l(this.el,"open",!0),this._opening=!1}},positionDropdown:function(){this.dropdown&&this.dropdown.position()},search:function(t){this.open(),this.dropdown&&this.dropdown.search(t)},setData:function(t,e){e=e||{},t=this.validateData(t),this._data=t,this._value=this.getValueForData(t),!1!==e.triggerChange&&this.triggerChange()},setOptions:function(t){t=t||{};var e=this;n.OptionListeners.forEach(function(i){i(e,t)}),"items"in t&&(this.items=t.items?n.processItems(t.items):null),"templates"in t&&s(this.templates,t.templates),s(this.options,t),this.enabled=!this.options.readOnly&&!this.options.removeOnly},setValue:function(t,e){e=e||{},t=this.validateValue(t),this._value=t,this.options.initSelection?this.options.initSelection(t,function(i){this._value===t&&(this._data=this.validateData(i),!1!==e.triggerChange&&this.triggerChange())}.bind(this)):(this._data=this.getDataForValue(t),!1!==e.triggerChange&&this.triggerChange())},template:function(t,e){var i=this.templates[t];if(!i)throw new Error("Unknown template: "+t);if("function"==typeof i){var n=i(e);return"string"==typeof n?n.trim():n}return i.render?i.render(e).trim():i.toString().trim()},triggerChange:function(t){var e=s({data:this._data,value:this._value},t);this.triggerEvent("change",e),this.triggerEvent("selectivity-change",e)},triggerEvent:function(t,e){var i=document.createEvent("Event");return i.initEvent(t,!1,!0),s(i,e),this.el.dispatchEvent(i),!i.defaultPrevented},validateItem:function(t){if(t&&n.isValidId(t.id)&&r(t.text))return t;throw new Error("Item should have id (number or string) and text (string) properties")},_blur:function(){this._focusing||this.el.classList.contains("hover")||(this._clearCloseTimeout(),this._closeTimeout=setTimeout(this.close.bind(this),166))},_clearCloseTimeout:function(){this._closeTimeout&&(clearTimeout(this._closeTimeout),this._closeTimeout=0)},_closed:function(){this.dropdown=null,l(this.el,"open",!1)},_mouseleave:function(t){this.el.contains(t.relatedTarget)||l(this.el,"hover",!1)},_mouseenter:function(){l(this.el,"hover",!0)}}),n.Dropdown=null,n.InputListeners=[],n.Inputs={},n.OptionListeners=[],n.Templates={},n.findById=function(t,e){var i=n.findIndexById(t,e);return i>-1?t[i]:null},n.findIndexById=function(t,e){for(var i=0,n=t.length;i<n;i++)if(t[i].id===e)return i;return-1},n.findNestedById=function(t,e){for(var i=0,s=t.length;i<s;i++){var r,o=t[i];if(o.id===e?r=o:o.children?r=n.findNestedById(o.children,e):o.submenu&&o.submenu.items&&(r=n.findNestedById(o.submenu.items,e)),r)return r}return null},n.inherits=function(t,e,i){return t.prototype=s(Object.create(e.prototype),{constructor:t},i),function(t,i){e.prototype[i].apply(t,Array.prototype.slice.call(arguments,2))}},n.isValidId=function(t){return"number"==typeof t||r(t)},n.matcher=function(t,e){var i=null;if(n.transformText(t.text).indexOf(e)>-1)i=t;else if(t.children){var s=t.children.map(function(t){return n.matcher(t,e)}).filter(function(t){return!!t});s.length&&(i={id:t.id,text:t.text,children:s})}return i},n.processItem=function(t){if(n.isValidId(t))return{id:t,text:""+t};if(t&&(n.isValidId(t.id)||t.children)&&r(t.text))return t.children&&(t.children=n.processItems(t.children)),t;throw new Error("invalid item")},n.processItems=function(t){if(Array.isArray(t))return t.map(n.processItem);throw new Error("invalid items")},n.transformText=function(t){return t.toLowerCase()},e.exports=n},{16:16,23:23,46:46,"lodash/assign":"lodash/assign"}],38:[function(t,e,i){"use strict";var n=t(12),s=t(37),r=t(27);s.Templates={dropdown:function(t){var e=t.dropdownCssClass?" "+t.dropdownCssClass:"",i="";if(t.showSearchInput){e+=" has-search-input";var s=t.searchInputPlaceholder;i='<div class="selectivity-search-input-container"><input type="text" class="selectivity-search-input"'+(s?' placeholder="'+n(s)+'"':"")+"></div>"}return'<div class="selectivity-dropdown'+e+'">'+i+'<div class="selectivity-results-container"></div></div>'},error:function(t){return'<div class="selectivity-error">'+(t.escape?n(t.message):t.message)+"</div>"},loading:function(){return'<div class="selectivity-loading">'+r.loading+"</div>"},loadMore:function(){return'<div class="selectivity-load-more">'+r.loadMore+"</div>"},multipleSelectInput:function(t){return'<div class="selectivity-multiple-input-container">'+(t.enabled?'<input type="text" autocomplete="off" autocorrect="off" autocapitalize="off" class="selectivity-multiple-input">':'<div class="selectivity-multiple-input selectivity-placeholder"></div>')+'<div class="selectivity-clearfix"></div></div>'},multipleSelectedItem:function(t){return'<span class="selectivity-multiple-selected-item'+(t.highlighted?" highlighted":"")+'" data-item-id="'+n(t.id)+'">'+(t.removable?'<a class="selectivity-multiple-selected-item-remove"><i class="fa fa-remove"></i></a>':"")+n(t.text)+"</span>"},noResults:function(t){return'<div class="selectivity-error">'+(t.term?r.noResultsForTerm(t.term):r.noResults)+"</div>"},resultChildren:function(t){return'<div class="selectivity-result-children">'+t.childrenHtml+"</div>"},resultItem:function(t){return'<div class="selectivity-result-item'+(t.disabled?" disabled":"")+'" data-item-id="'+n(t.id)+'">'+n(t.text)+(t.submenu?'<i class="selectivity-submenu-icon fa fa-chevron-right"></i>':"")+"</div>"},resultLabel:function(t){return'<div class="selectivity-result-label">'+n(t.text)+"</div>"},singleSelectInput:function(t){return'<div class="selectivity-single-select"><input type="text" class="selectivity-single-select-input"'+(t.required?" required":"")+'><div class="selectivity-single-result-container"></div><i class="fa fa-sort-desc selectivity-caret"></i></div>'},singleSelectPlaceholder:function(t){return'<div class="selectivity-placeholder">'+n(t.placeholder)+"</div>"},singleSelectedItem:function(t){return'<span class="selectivity-single-selected-item" data-item-id="'+n(t.id)+'">'+(t.removable?'<a class="selectivity-single-selected-item-remove"><i class="fa fa-remove"></i></a>':"")+n(t.text)+"</span>"},selectCompliance:function(t){var e=t.mode,i=t.name;return"multiple"===e&&"[]"!==i.slice(-2)&&(i+="[]"),'<select name="'+i+'"'+("multiple"===e?" multiple":"")+"></select>"},selectOptionCompliance:function(t){return'<option value="'+n(t.id)+'" selected>'+n(t.text)+"</option>"}}},{12:12,27:27,37:37}],39:[function(t,e,i){"use strict";e.exports=function(t,e){for(var i=0,n=t.length;i<n;i++){var s=t[i],r=s.getAttribute("data-item-id");if(("number"==typeof e?parseInt(r,10):r)===e)return s}return null}},{}],40:[function(t,e,i){"use strict";e.exports=function(t,e){return t+"[data-item-id="+('"'+(""+e).replace(/\\/g,"\\\\").replace(/"/g,'\\"')+'"')+"]"}},{}],41:[function(t,e,i){"use strict";e.exports=function(t){return t.which||t.keyCode||0}},{}],42:[function(t,e,i){"use strict";e.exports=function(t,e){return(t.matches||t.webkitMatchesSelector||t.mozMatchesSelector||t.msMatchesSelector).call(t,e)}},{}],43:[function(t,e,i){"use strict";e.exports=function(t){var e=document.createElement("div");return e.innerHTML=t,e.firstChild}},{}],44:[function(t,e,i){"use strict";e.exports=function(t){t&&t.parentNode&&t.parentNode.removeChild(t)}},{}],45:[function(t,e,i){"use strict";e.exports=function(t){t.stopPropagation()}},{}],46:[function(t,e,i){"use strict";e.exports=function(t,e,i){t&&t.classList[i?"add":"remove"](e)}},{}]},{},[36])(36)});
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: inc2734, toro_unit, mimosafa, hideokamoto, hisako-isaka, kurudrive
3
  Donate link: http://www.amazon.co.jp/registry/wishlist/39ANKRNSTNW40
4
  Tags: plugin, custom field, custom, field, meta, meta field, repeat, repeatable
5
  Requires at least: 3.9
6
- Tested up to: 4.9.6
7
- Stable tag: 4.0.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -128,6 +128,9 @@ You can translate this plugin into your language by using [GlotPress](https://tr
128
 
129
  == Changelog ==
130
 
 
 
 
131
  = 4.0.0 =
132
  * Add message field. #64 (by [@robssanches](https://github.com/robssanches))
133
  * Fix boolean field bug with `smart-cf-register-fields` filter hook.
3
  Donate link: http://www.amazon.co.jp/registry/wishlist/39ANKRNSTNW40
4
  Tags: plugin, custom field, custom, field, meta, meta field, repeat, repeatable
5
  Requires at least: 3.9
6
+ Tested up to: 4.9.8
7
+ Stable tag: 4.0.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
128
 
129
  == Changelog ==
130
 
131
+ = 4.0.2 =
132
+ * Some updates by [@robssanches](https://github.com/robssanches)
133
+
134
  = 4.0.0 =
135
  * Add message field. #64 (by [@robssanches](https://github.com/robssanches))
136
  * Fix boolean field bug with `smart-cf-register-fields` filter hook.
smart-custom-fields.php CHANGED
@@ -3,11 +3,11 @@
3
  * Plugin name: Smart Custom Fields
4
  * Plugin URI: https://github.com/inc2734/smart-custom-fields/
5
  * Description: Smart Custom Fields is a simple plugin that management custom fields.
6
- * Version: 4.0.1
7
  * Author: inc2734
8
  * Author URI: https://2inc.org
9
  * Created: October 9, 2014
10
- * Modified: June 26, 2018
11
  * Text Domain: smart-custom-fields
12
  * Domain Path: /languages
13
  * License: GPLv2 or later
@@ -20,8 +20,11 @@ class Smart_Custom_Fields {
20
  */
21
  public function __construct() {
22
  require_once plugin_dir_path( __FILE__ ) . 'classes/class.config.php';
 
23
  add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
24
  register_uninstall_hook( __FILE__, array( __CLASS__, 'uninstall' ) );
 
 
25
  }
26
 
27
  /**
@@ -46,6 +49,11 @@ class Smart_Custom_Fields {
46
  require_once plugin_dir_path( __FILE__ ) . 'classes/class.scf.php';
47
  new Smart_Custom_Fields_Revisions();
48
 
 
 
 
 
 
49
  foreach ( glob( plugin_dir_path( __FILE__ ) . 'classes/fields/*.php' ) as $form_item ) {
50
  include_once $form_item;
51
  $basename = basename( $form_item, '.php' );
3
  * Plugin name: Smart Custom Fields
4
  * Plugin URI: https://github.com/inc2734/smart-custom-fields/
5
  * Description: Smart Custom Fields is a simple plugin that management custom fields.
6
+ * Version: 4.0.2
7
  * Author: inc2734
8
  * Author URI: https://2inc.org
9
  * Created: October 9, 2014
10
+ * Modified: August 12, 2018
11
  * Text Domain: smart-custom-fields
12
  * Domain Path: /languages
13
  * License: GPLv2 or later
20
  */
21
  public function __construct() {
22
  require_once plugin_dir_path( __FILE__ ) . 'classes/class.config.php';
23
+ require_once plugin_dir_path( __FILE__ ) . 'classes/class.rest-api.php';
24
  add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
25
  register_uninstall_hook( __FILE__, array( __CLASS__, 'uninstall' ) );
26
+
27
+ new Smart_Custom_Fields_Rest_API();
28
  }
29
 
30
  /**
49
  require_once plugin_dir_path( __FILE__ ) . 'classes/class.scf.php';
50
  new Smart_Custom_Fields_Revisions();
51
 
52
+ if ( function_exists( 'wpseo_init' ) ) {
53
+ require_once plugin_dir_path( __FILE__ ) . 'classes/models/class.yoast-seo-analysis.php';
54
+ new Smart_Custom_Fields_Yoast_SEO_Analysis();
55
+ }
56
+
57
  foreach ( glob( plugin_dir_path( __FILE__ ) . 'classes/fields/*.php' ) as $form_item ) {
58
  include_once $form_item;
59
  $basename = basename( $form_item, '.php' );