ui_bibz 3.0.13 → 4.0.0.beta4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3 -3
  3. data/.github/workflows/linter.yml +13 -12
  4. data/.overcommit.yml +6 -0
  5. data/.rubocop.yml +6 -0
  6. data/.ruby-version +1 -1
  7. data/Gemfile +19 -12
  8. data/Gemfile.lock +219 -148
  9. data/app/assets/config/ui_bibz.js +14 -0
  10. data/app/assets/javascripts/controllers/combobox_controller.js +37 -0
  11. data/app/assets/javascripts/forms/formula.js +82 -0
  12. data/app/assets/javascripts/forms/input-connected.js +132 -0
  13. data/app/assets/javascripts/forms/jquery.multi-select-extend.js +52 -0
  14. data/app/assets/javascripts/forms.js +160 -0
  15. data/app/assets/javascripts/interfaces.js +56 -0
  16. data/app/assets/javascripts/tables.js +49 -0
  17. data/app/assets/javascripts/ui_bibz_js.js +37 -0
  18. data/app/assets/stylesheets/navigations/_nav.sass +2 -0
  19. data/app/assets/stylesheets/navigations/_navbar.sass +12 -0
  20. data/app/assets/stylesheets/navigations/_progress_bar.sass +2 -0
  21. data/app/assets/stylesheets/navigations/_toolbar.sass +3 -0
  22. data/app/assets/stylesheets/sass/_boxes.sass +1 -0
  23. data/app/assets/stylesheets/sass/_containers.sass +2 -0
  24. data/app/assets/stylesheets/sass/_fixes.sass +2 -0
  25. data/app/assets/stylesheets/sass/_forms.sass +9 -0
  26. data/app/assets/stylesheets/sass/_navigations.sass +4 -0
  27. data/app/assets/stylesheets/sass/_notifications.sass +4 -0
  28. data/app/assets/stylesheets/sass/_tables.sass +2 -0
  29. data/app/assets/stylesheets/sass/_variables_mixins_functions.sass +3 -0
  30. data/app/assets/stylesheets/sass/boxes/_card.sass +4 -0
  31. data/app/assets/stylesheets/sass/containers/_panel.scss +330 -0
  32. data/app/assets/stylesheets/sass/forms/_bootstrap_select.sass +5 -0
  33. data/app/assets/stylesheets/sass/forms/_button.sass +3 -0
  34. data/app/assets/stylesheets/sass/forms/_combobox.sass +32 -0
  35. data/app/assets/stylesheets/sass/forms/_date_picker.sass +3 -0
  36. data/app/assets/stylesheets/sass/forms/_form_check.sass +10 -0
  37. data/app/assets/stylesheets/sass/forms/_formula_field.sass +17 -0
  38. data/app/assets/stylesheets/sass/forms/_multiselect.sass +44 -0
  39. data/app/assets/stylesheets/sass/forms/_range.sass +44 -0
  40. data/app/assets/stylesheets/sass/forms/_slider.sass +136 -0
  41. data/app/assets/stylesheets/sass/forms/_surround_field.sass +25 -0
  42. data/app/assets/stylesheets/sass/notifications/_badge.sass +5 -0
  43. data/app/assets/stylesheets/sass/notifications/_glyph.sass +3 -0
  44. data/app/assets/stylesheets/sass/notifications/_star.sass +2 -0
  45. data/app/assets/stylesheets/sass/notifications/_toast.sass +3 -0
  46. data/app/assets/stylesheets/sass/tables/_table.sass +39 -0
  47. data/app/assets/stylesheets/sass/tables/_table_card.sass +39 -0
  48. data/app/assets/stylesheets/ui_bibz.sass +26 -0
  49. data/bin/test +3 -5
  50. data/config/importmap.rb +21 -0
  51. data/config/initializers/assets.rb +5 -0
  52. data/config/initializers/will_paginate.rb +1 -3
  53. data/lib/ui_bibz/builders/data_html_options_builder.rb +118 -0
  54. data/lib/ui_bibz/builders/html_classes_builder.rb +89 -0
  55. data/lib/ui_bibz/builders/html_options_builder.rb +22 -0
  56. data/lib/ui_bibz/factory_methods/component_initialize_factory_method.rb +33 -0
  57. data/lib/ui_bibz/helpers/ui/core/boxes_helper.rb +12 -12
  58. data/lib/ui_bibz/helpers/ui/core/forms_helper.rb +58 -50
  59. data/lib/ui_bibz/helpers/ui/core/icons_helper.rb +6 -6
  60. data/lib/ui_bibz/helpers/ui/core/layouts_helper.rb +2 -2
  61. data/lib/ui_bibz/helpers/ui/core/lists_helper.rb +2 -2
  62. data/lib/ui_bibz/helpers/ui/core/navigations_helper.rb +12 -12
  63. data/lib/ui_bibz/helpers/ui/core/notifications_helper.rb +4 -4
  64. data/lib/ui_bibz/helpers/ui/core/windows_helper.rb +10 -2
  65. data/lib/ui_bibz/helpers/ui/ux_helper.rb +2 -2
  66. data/lib/ui_bibz/helpers/utils_helper.rb +2 -2
  67. data/lib/ui_bibz/infos.rb +3 -3
  68. data/lib/ui_bibz/inputs/ui_bibz_form/ui_bibz_form_builder.rb +12 -12
  69. data/lib/ui_bibz/inputs/ui_bibz_inputs/collection_input.rb +1 -1
  70. data/lib/ui_bibz/inputs/ui_bibz_inputs/ui_combobox_field_input.rb +15 -0
  71. data/lib/ui_bibz/rails/engine.rb +21 -4
  72. data/lib/ui_bibz/strategies/component_initialize_abstract_strategy.rb +27 -0
  73. data/lib/ui_bibz/strategies/component_initialize_block_strategy.rb +31 -0
  74. data/lib/ui_bibz/strategies/component_initialize_hash_strategy.rb +18 -0
  75. data/lib/ui_bibz/strategies/component_initialize_standard_strategy.rb +18 -0
  76. data/lib/ui_bibz/ui/concerns/card_itemable_concern.rb +4 -4
  77. data/lib/ui_bibz/ui/concerns/notification_concern.rb +1 -1
  78. data/lib/ui_bibz/ui/core/boxes/card.rb +1 -1
  79. data/lib/ui_bibz/ui/core/boxes/card_accordion.rb +4 -4
  80. data/lib/ui_bibz/ui/core/boxes/card_column.rb +1 -1
  81. data/lib/ui_bibz/ui/core/boxes/card_deck.rb +1 -1
  82. data/lib/ui_bibz/ui/core/boxes/card_grid.rb +0 -3
  83. data/lib/ui_bibz/ui/core/boxes/card_group.rb +1 -1
  84. data/lib/ui_bibz/ui/core/boxes/components/card_body.rb +9 -9
  85. data/lib/ui_bibz/ui/core/boxes/components/card_col.rb +2 -2
  86. data/lib/ui_bibz/ui/core/boxes/components/card_list_group.rb +1 -1
  87. data/lib/ui_bibz/ui/core/boxes/components/card_row.rb +1 -1
  88. data/lib/ui_bibz/ui/core/component.rb +13 -62
  89. data/lib/ui_bibz/ui/core/forms/buttons/button.rb +3 -1
  90. data/lib/ui_bibz/ui/core/forms/buttons/button_group.rb +11 -11
  91. data/lib/ui_bibz/ui/core/forms/choices/box_switch_field.rb +7 -7
  92. data/lib/ui_bibz/ui/core/forms/choices/checkbox_field.rb +2 -2
  93. data/lib/ui_bibz/ui/core/forms/choices/choice_group.rb +5 -6
  94. data/lib/ui_bibz/ui/core/forms/choices/components/choice.rb +1 -1
  95. data/lib/ui_bibz/ui/core/forms/dates/date_picker_field.rb +15 -15
  96. data/lib/ui_bibz/ui/core/forms/dropdowns/components/dropdown_link.rb +1 -1
  97. data/lib/ui_bibz/ui/core/forms/dropdowns/dropdown.rb +5 -5
  98. data/lib/ui_bibz/ui/core/forms/numbers/slider_field.rb +1 -1
  99. data/lib/ui_bibz/ui/core/forms/selects/dropdown_select_field.rb +10 -10
  100. data/lib/ui_bibz/ui/core/forms/selects/multi_column_field.rb +2 -2
  101. data/lib/ui_bibz/ui/core/forms/surrounds/surround_field.rb +32 -32
  102. data/lib/ui_bibz/ui/core/forms/textareas/markdown_editor_field.rb +7 -8
  103. data/lib/ui_bibz/ui/core/forms/texts/combobox_field.rb +96 -0
  104. data/lib/ui_bibz/ui/core/icons/components/glyph_text.rb +1 -1
  105. data/lib/ui_bibz/ui/core/icons/glyph.rb +4 -3
  106. data/lib/ui_bibz/ui/core/layouts/row.rb +2 -2
  107. data/lib/ui_bibz/ui/core/lists/components/list.rb +4 -4
  108. data/lib/ui_bibz/ui/core/lists/list_group.rb +1 -1
  109. data/lib/ui_bibz/ui/core/navigations/breadcrumb.rb +6 -4
  110. data/lib/ui_bibz/ui/core/navigations/components/nav_link_span.rb +1 -2
  111. data/lib/ui_bibz/ui/core/navigations/components/navbar_form.rb +6 -5
  112. data/lib/ui_bibz/ui/core/navigations/components/toolbar_form.rb +2 -2
  113. data/lib/ui_bibz/ui/core/navigations/nav.rb +10 -6
  114. data/lib/ui_bibz/ui/core/navigations/navbar.rb +21 -19
  115. data/lib/ui_bibz/ui/core/navigations/pagination.rb +3 -3
  116. data/lib/ui_bibz/ui/core/navigations/toolbar.rb +5 -5
  117. data/lib/ui_bibz/ui/core/notifications/alert.rb +4 -5
  118. data/lib/ui_bibz/ui/core/notifications/badge.rb +6 -2
  119. data/lib/ui_bibz/ui/core/notifications/components/toast_header.rb +1 -1
  120. data/lib/ui_bibz/ui/core/notifications/progress_bar.rb +3 -3
  121. data/lib/ui_bibz/ui/core/notifications/toast.rb +8 -9
  122. data/lib/ui_bibz/ui/core/windows/components/offcanvas_body.rb +47 -0
  123. data/lib/ui_bibz/ui/core/windows/components/offcanvas_header.rb +54 -0
  124. data/lib/ui_bibz/ui/core/windows/modal.rb +9 -9
  125. data/lib/ui_bibz/ui/core/windows/offcanvas.rb +84 -0
  126. data/lib/ui_bibz/ui/extensions/core/component/glyph_extension.rb +4 -20
  127. data/lib/ui_bibz/ui/extensions/core/component/klass_extension.rb +11 -19
  128. data/lib/ui_bibz/ui/extensions/core/forms/connect_extension.rb +1 -1
  129. data/lib/ui_bibz/ui/ux/containers/components/panel_column.rb +3 -3
  130. data/lib/ui_bibz/ui/ux/containers/components/panel_deck.rb +3 -3
  131. data/lib/ui_bibz/ui/ux/containers/components/panel_group.rb +3 -3
  132. data/lib/ui_bibz/ui/ux/containers/components/panel_header.rb +4 -4
  133. data/lib/ui_bibz/ui/ux/containers/panel.rb +13 -13
  134. data/lib/ui_bibz/ui/ux/tables/components/actions.rb +4 -4
  135. data/lib/ui_bibz/ui/ux/tables/components/column.rb +1 -1
  136. data/lib/ui_bibz/ui/ux/tables/components/columns.rb +2 -2
  137. data/lib/ui_bibz/ui/ux/tables/extensions/sortable.rb +1 -1
  138. data/lib/ui_bibz/ui/ux/tables/table.rb +5 -5
  139. data/lib/ui_bibz/ui/ux/tables/table_card.rb +6 -6
  140. data/lib/ui_bibz/ui/ux/tables/table_search_field.rb +1 -1
  141. data/lib/ui_bibz/utils/breakdown_class_name_generator.rb +3 -3
  142. data/lib/ui_bibz/utils/screwdriver.rb +1 -1
  143. data/lib/ui_bibz/view_objects/glyph_component_view_object.rb +38 -0
  144. data/lib/ui_bibz.rb +26 -0
  145. data/test/builders/data_html_classes_builder_test.rb +37 -0
  146. data/test/builders/html_classes_builder_test.rb +76 -0
  147. data/test/dummy/Rakefile +1 -1
  148. data/test/dummy/app/assets/stylesheets/application.css +1 -15
  149. data/test/dummy/app/channels/application_cable/channel.rb +6 -0
  150. data/test/dummy/app/channels/application_cable/connection.rb +6 -0
  151. data/test/dummy/app/jobs/application_job.rb +9 -0
  152. data/test/dummy/app/mailers/application_mailer.rb +6 -0
  153. data/test/dummy/app/views/layouts/application.html.erb +10 -12
  154. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  155. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  156. data/test/dummy/bin/rails +3 -3
  157. data/test/dummy/bin/rake +2 -2
  158. data/test/dummy/bin/setup +12 -12
  159. data/test/dummy/config/application.rb +13 -17
  160. data/test/dummy/config/boot.rb +3 -3
  161. data/test/dummy/config/database.yml +2 -2
  162. data/test/dummy/config/environment.rb +1 -1
  163. data/test/dummy/config/environments/development.rb +21 -16
  164. data/test/dummy/config/environments/production.rb +16 -41
  165. data/test/dummy/config/environments/test.rb +19 -8
  166. data/test/dummy/config/importmap.rb +11 -0
  167. data/test/dummy/config/initializers/content_security_policy.rb +21 -24
  168. data/test/dummy/config/initializers/filter_parameter_logging.rb +6 -2
  169. data/test/dummy/config/initializers/inflections.rb +4 -4
  170. data/test/dummy/config/initializers/permissions_policy.rb +12 -0
  171. data/test/dummy/config/locales/en.yml +13 -3
  172. data/test/dummy/config/puma.rb +7 -2
  173. data/test/dummy/config/storage.yml +5 -5
  174. data/test/dummy/config.ru +2 -1
  175. data/test/simple_form_test.rb +24 -24
  176. data/test/ui/core/boxes/card_test.rb +2 -1
  177. data/test/ui/core/component_test.rb +2 -2
  178. data/test/ui/core/forms/buttons/button_group_test.rb +1 -1
  179. data/test/ui/core/forms/buttons/button_link_test.rb +1 -1
  180. data/test/ui/core/forms/buttons/button_refresh_test.rb +1 -1
  181. data/test/ui/core/forms/buttons/button_test.rb +2 -2
  182. data/test/ui/core/forms/choices/box_switch_field_test.rb +10 -10
  183. data/test/ui/core/forms/choices/checkbox_field_test.rb +1 -1
  184. data/test/ui/core/forms/choices/choice_group_test.rb +1 -1
  185. data/test/ui/core/forms/dropdowns/dropdown_test.rb +1 -1
  186. data/test/ui/core/forms/numbers/formula_field_test.rb +1 -1
  187. data/test/ui/core/forms/selects/dropdown_select_field_test.rb +2 -2
  188. data/test/ui/core/forms/selects/select_field_test.rb +1 -1
  189. data/test/ui/core/forms/surrounds/surround_field_test.rb +4 -4
  190. data/test/ui/core/forms/texts/auto_complete_field_test.rb +2 -2
  191. data/test/ui/core/forms/texts/combobox_field_test.rb +19 -0
  192. data/test/ui/core/icons/glyph_test.rb +8 -4
  193. data/test/ui/core/icons/star_test.rb +12 -6
  194. data/test/ui/core/navigations/breadcrumb_test.rb +1 -1
  195. data/test/ui/core/navigations/link_test.rb +1 -1
  196. data/test/ui/core/navigations/nav_test.rb +11 -0
  197. data/test/ui/core/notifications/alert_test.rb +1 -1
  198. data/test/ui/core/notifications/badge_test.rb +3 -3
  199. data/test/ui/core/notifications/popover_test.rb +4 -4
  200. data/test/ui/core/notifications/spinner_test.rb +1 -1
  201. data/test/ui/core/notifications/toast_test.rb +1 -1
  202. data/test/ui/core/notifications/tooltip_test.rb +4 -4
  203. data/test/ui/core/windows/offcanvas_test.rb +27 -0
  204. data/test/ui/ux/containers/panel_test.rb +1 -1
  205. data/test/ui/ux/tables/table_test.rb +3 -3
  206. data/test/view_objects/glyph_component_view_object_test.rb +17 -0
  207. data/ui_bibz.gemspec +6 -20
  208. data/vendor/assets/fonts/fontawesome/fa-brands-400.ttf +0 -0
  209. data/vendor/assets/fonts/fontawesome/fa-brands-400.woff2 +0 -0
  210. data/vendor/assets/fonts/fontawesome/fa-regular-400.ttf +0 -0
  211. data/vendor/assets/fonts/fontawesome/fa-regular-400.woff2 +0 -0
  212. data/vendor/assets/fonts/fontawesome/fa-solid-900.ttf +0 -0
  213. data/vendor/assets/fonts/fontawesome/fa-solid-900.woff2 +0 -0
  214. data/vendor/assets/fonts/fontawesome/fa-v4compatibility.ttf +0 -0
  215. data/vendor/assets/fonts/fontawesome/fa-v4compatibility.woff2 +0 -0
  216. data/vendor/assets/javascripts/bootstrap-markdown.js +1 -1555
  217. data/vendor/assets/javascripts/bootstrap-multiselect.min.js +40 -1176
  218. data/vendor/assets/javascripts/bootstrap-switch.min.js +9 -21
  219. data/vendor/assets/javascripts/bs-custom-file-input.min.js +0 -1
  220. data/vendor/assets/javascripts/debounce.js +51 -0
  221. data/vendor/assets/javascripts/fontawesome/all.js +5977 -0
  222. data/vendor/assets/javascripts/fontawesome/all.min.js +6 -0
  223. data/vendor/assets/javascripts/fontawesome/brands.js +749 -0
  224. data/vendor/assets/javascripts/fontawesome/brands.min.js +6 -0
  225. data/vendor/assets/javascripts/fontawesome/conflict-detection.js +1138 -0
  226. data/vendor/assets/javascripts/fontawesome/conflict-detection.min.js +6 -0
  227. data/vendor/assets/javascripts/fontawesome/fontawesome.js +3126 -0
  228. data/vendor/assets/javascripts/fontawesome/fontawesome.min.js +6 -0
  229. data/vendor/assets/javascripts/fontawesome/regular.js +445 -0
  230. data/vendor/assets/javascripts/fontawesome/regular.min.js +6 -0
  231. data/vendor/assets/javascripts/fontawesome/solid.js +1672 -0
  232. data/vendor/assets/javascripts/fontawesome/solid.min.js +6 -0
  233. data/vendor/assets/javascripts/fontawesome/v4-shims.js +225 -0
  234. data/vendor/assets/javascripts/fontawesome/v4-shims.min.js +6 -0
  235. data/vendor/assets/javascripts/fuzzysort.js +562 -0
  236. data/vendor/assets/javascripts/jquery-3.7.0.min.js +2 -0
  237. data/vendor/assets/javascripts/jquery.multi-select.min.js +725 -1
  238. data/vendor/assets/stylesheets/bootstrap-multiselect.sass +115 -0
  239. data/vendor/assets/stylesheets/bootstrap-switch.scss +211 -0
  240. data/vendor/assets/stylesheets/fontawesome/_animated.scss +142 -9
  241. data/vendor/assets/stylesheets/fontawesome/_bordered-pulled.scss +13 -13
  242. data/vendor/assets/stylesheets/fontawesome/_core.scss +28 -6
  243. data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +2 -1
  244. data/vendor/assets/stylesheets/fontawesome/_functions.scss +57 -0
  245. data/vendor/assets/stylesheets/fontawesome/_icons.scss +7 -1438
  246. data/vendor/assets/stylesheets/fontawesome/_list.scss +4 -4
  247. data/vendor/assets/stylesheets/fontawesome/_mixins.scss +53 -34
  248. data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +25 -18
  249. data/vendor/assets/stylesheets/fontawesome/_screen-reader.scss +12 -3
  250. data/vendor/assets/stylesheets/fontawesome/_shims.scss +640 -664
  251. data/vendor/assets/stylesheets/fontawesome/_sizing.scss +16 -0
  252. data/vendor/assets/stylesheets/fontawesome/_stacked.scss +5 -4
  253. data/vendor/assets/stylesheets/fontawesome/_variables.scss +4896 -1393
  254. data/vendor/assets/stylesheets/fontawesome/brands.scss +17 -10
  255. data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +7 -2
  256. data/vendor/assets/stylesheets/fontawesome/regular.scss +13 -10
  257. data/vendor/assets/stylesheets/fontawesome/solid.scss +13 -11
  258. data/vendor/assets/stylesheets/fontawesome/v4-shims.scss +6 -1
  259. data/vendor/assets/stylesheets/multi-select.css +92 -0
  260. metadata +126 -348
  261. data/.gitlab-ci.yml +0 -17
  262. data/.travis.yml +0 -24
  263. data/lib/ui_bibz/ui/extensions/core/component/popover_extension.rb +0 -70
  264. data/structure.md +0 -68
  265. data/test/dummy/README.rdoc +0 -28
  266. data/test/dummy/app/assets/javascripts/application.js +0 -13
  267. data/test/dummy/app/javascripts/packs/index.js +0 -3
  268. data/test/dummy/config/initializers/application_controller_renderer.rb +0 -9
  269. data/test/dummy/config/initializers/assets.rb +0 -14
  270. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -8
  271. data/test/dummy/config/initializers/cookies_serializer.rb +0 -7
  272. data/test/dummy/config/initializers/mime_types.rb +0 -5
  273. data/test/dummy/config/initializers/session_store.rb +0 -5
  274. data/test/dummy/config/initializers/ui_bibz.rb +0 -5
  275. data/test/dummy/config/initializers/wrap_parameters.rb +0 -16
  276. data/test/dummy/config/secrets.yml +0 -22
  277. data/test/dummy/config/spring.rb +0 -8
  278. data/test/dummy/test/models/user_test.rb +0 -9
  279. data/vendor/assets/fonts/fa-brands-400.eot +0 -0
  280. data/vendor/assets/fonts/fa-brands-400.svg +0 -3570
  281. data/vendor/assets/fonts/fa-brands-400.ttf +0 -0
  282. data/vendor/assets/fonts/fa-brands-400.woff +0 -0
  283. data/vendor/assets/fonts/fa-brands-400.woff2 +0 -0
  284. data/vendor/assets/fonts/fa-regular-400.eot +0 -0
  285. data/vendor/assets/fonts/fa-regular-400.svg +0 -803
  286. data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
  287. data/vendor/assets/fonts/fa-regular-400.woff +0 -0
  288. data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
  289. data/vendor/assets/fonts/fa-solid-900.eot +0 -0
  290. data/vendor/assets/fonts/fa-solid-900.svg +0 -4938
  291. data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
  292. data/vendor/assets/fonts/fa-solid-900.woff +0 -0
  293. data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
  294. data/vendor/assets/javascripts/all.js +0 -4441
  295. data/vendor/assets/javascripts/all.min.js +0 -5
  296. data/vendor/assets/stylesheets/all.min.css +0 -5
  297. data/vendor/assets/stylesheets/fontawesome/_larger.scss +0 -23
  298. data/vendor/assets/stylesheets/svg-with-js.css +0 -5
  299. /data/{test/dummy/app/mailers/.keep → app/assets/stylesheets/sass/forms/_dropdown.sass} +0 -0
  300. /data/{test/dummy/app/views/users/index.html.erb → app/assets/stylesheets/sass/forms/_input_refresh_button.sass} +0 -0
@@ -0,0 +1,562 @@
1
+ // https://github.com/farzher/fuzzysort v2.0.4
2
+ /*
3
+ SublimeText-like Fuzzy Search
4
+
5
+ fuzzysort.single('fs', 'Fuzzy Search') // {score: -16}
6
+ fuzzysort.single('test', 'test') // {score: 0}
7
+ fuzzysort.single('doesnt exist', 'target') // null
8
+
9
+ fuzzysort.go('mr', [{file:'Monitor.cpp'}, {file:'MeshRenderer.cpp'}], {key:'file'})
10
+ // [{score:-18, obj:{file:'MeshRenderer.cpp'}}, {score:-6009, obj:{file:'Monitor.cpp'}}]
11
+
12
+ fuzzysort.go('mr', ['Monitor.cpp', 'MeshRenderer.cpp'])
13
+ // [{score: -18, target: "MeshRenderer.cpp"}, {score: -6009, target: "Monitor.cpp"}]
14
+
15
+ fuzzysort.highlight(fuzzysort.single('fs', 'Fuzzy Search'), '<b>', '</b>')
16
+ // <b>F</b>uzzy <b>S</b>earch
17
+ */
18
+
19
+ // UMD (Universal Module Definition) for fuzzysort
20
+ ;((root, UMD) => {
21
+ if(typeof define === 'function' && define.amd) define([], UMD)
22
+ else if(typeof module === 'object' && module.exports) module.exports = UMD()
23
+ else root['fuzzysort'] = UMD()
24
+ })(this || (typeof window !== 'undefined' ? window : global), _ => {
25
+ 'use strict'
26
+
27
+ var single = (search, target) => { if(search=='farzher')return{target:"farzher was here (^-^*)/",score:0,_indexes:[0]}
28
+ if(!search || !target) return NULL
29
+
30
+ var preparedSearch = getPreparedSearch(search)
31
+ if(!isObj(target)) target = getPrepared(target)
32
+
33
+ var searchBitflags = preparedSearch.bitflags
34
+ if((searchBitflags & target._bitflags) !== searchBitflags) return NULL
35
+
36
+ return algorithm(preparedSearch, target)
37
+ }
38
+
39
+
40
+ var go = (search, targets, options) => { if(search=='farzher')return[{target:"farzher was here (^-^*)/",score:0,_indexes:[0],obj:targets?targets[0]:NULL}]
41
+ if(!search) return options&&options.all ? all(search, targets, options) : noResults
42
+
43
+ var preparedSearch = getPreparedSearch(search)
44
+ var searchBitflags = preparedSearch.bitflags
45
+ var containsSpace = preparedSearch.containsSpace
46
+
47
+ var threshold = options&&options.threshold || INT_MIN
48
+ var limit = options&&options['limit'] || INT_MAX // for some reason only limit breaks when minified
49
+
50
+ var resultsLen = 0; var limitedCount = 0
51
+ var targetsLen = targets.length
52
+
53
+ // This code is copy/pasted 3 times for performance reasons [options.keys, options.key, no keys]
54
+
55
+ // options.key
56
+ if(options && options.key) {
57
+ var key = options.key
58
+ for(var i = 0; i < targetsLen; ++i) { var obj = targets[i]
59
+ var target = getValue(obj, key)
60
+ if(!target) continue
61
+ if(!isObj(target)) target = getPrepared(target)
62
+
63
+ if((searchBitflags & target._bitflags) !== searchBitflags) continue
64
+ var result = algorithm(preparedSearch, target)
65
+ if(result === NULL) continue
66
+ if(result.score < threshold) continue
67
+
68
+ // have to clone result so duplicate targets from different obj can each reference the correct obj
69
+ result = {target:result.target, _targetLower:'', _targetLowerCodes:NULL, _nextBeginningIndexes:NULL, _bitflags:0, score:result.score, _indexes:result._indexes, obj:obj} // hidden
70
+
71
+ if(resultsLen < limit) { q.add(result); ++resultsLen }
72
+ else {
73
+ ++limitedCount
74
+ if(result.score > q.peek().score) q.replaceTop(result)
75
+ }
76
+ }
77
+
78
+ // options.keys
79
+ } else if(options && options.keys) {
80
+ var scoreFn = options['scoreFn'] || defaultScoreFn
81
+ var keys = options.keys
82
+ var keysLen = keys.length
83
+ for(var i = 0; i < targetsLen; ++i) { var obj = targets[i]
84
+ var objResults = new Array(keysLen)
85
+ for (var keyI = 0; keyI < keysLen; ++keyI) {
86
+ var key = keys[keyI]
87
+ var target = getValue(obj, key)
88
+ if(!target) { objResults[keyI] = NULL; continue }
89
+ if(!isObj(target)) target = getPrepared(target)
90
+
91
+ if((searchBitflags & target._bitflags) !== searchBitflags) objResults[keyI] = NULL
92
+ else objResults[keyI] = algorithm(preparedSearch, target)
93
+ }
94
+ objResults.obj = obj // before scoreFn so scoreFn can use it
95
+ var score = scoreFn(objResults)
96
+ if(score === NULL) continue
97
+ if(score < threshold) continue
98
+ objResults.score = score
99
+ if(resultsLen < limit) { q.add(objResults); ++resultsLen }
100
+ else {
101
+ ++limitedCount
102
+ if(score > q.peek().score) q.replaceTop(objResults)
103
+ }
104
+ }
105
+
106
+ // no keys
107
+ } else {
108
+ for(var i = 0; i < targetsLen; ++i) { var target = targets[i]
109
+ if(!target) continue
110
+ if(!isObj(target)) target = getPrepared(target)
111
+
112
+ if((searchBitflags & target._bitflags) !== searchBitflags) continue
113
+ var result = algorithm(preparedSearch, target)
114
+ if(result === NULL) continue
115
+ if(result.score < threshold) continue
116
+ if(resultsLen < limit) { q.add(result); ++resultsLen }
117
+ else {
118
+ ++limitedCount
119
+ if(result.score > q.peek().score) q.replaceTop(result)
120
+ }
121
+ }
122
+ }
123
+
124
+ if(resultsLen === 0) return noResults
125
+ var results = new Array(resultsLen)
126
+ for(var i = resultsLen - 1; i >= 0; --i) results[i] = q.poll()
127
+ results.total = resultsLen + limitedCount
128
+ return results
129
+ }
130
+
131
+
132
+ var highlight = (result, hOpen, hClose) => {
133
+ if(typeof hOpen === 'function') return highlightCallback(result, hOpen)
134
+ if(result === NULL) return NULL
135
+ if(hOpen === undefined) hOpen = '<b>'
136
+ if(hClose === undefined) hClose = '</b>'
137
+ var highlighted = ''
138
+ var matchesIndex = 0
139
+ var opened = false
140
+ var target = result.target
141
+ var targetLen = target.length
142
+ var indexes = result._indexes
143
+ indexes = indexes.slice(0, indexes.len).sort((a,b)=>a-b)
144
+ for(var i = 0; i < targetLen; ++i) { var char = target[i]
145
+ if(indexes[matchesIndex] === i) {
146
+ ++matchesIndex
147
+ if(!opened) { opened = true
148
+ highlighted += hOpen
149
+ }
150
+
151
+ if(matchesIndex === indexes.length) {
152
+ highlighted += char + hClose + target.substr(i+1)
153
+ break
154
+ }
155
+ } else {
156
+ if(opened) { opened = false
157
+ highlighted += hClose
158
+ }
159
+ }
160
+ highlighted += char
161
+ }
162
+
163
+ return highlighted
164
+ }
165
+ var highlightCallback = (result, cb) => {
166
+ if(result === NULL) return NULL
167
+ var target = result.target
168
+ var targetLen = target.length
169
+ var indexes = result._indexes
170
+ indexes = indexes.slice(0, indexes.len).sort((a,b)=>a-b)
171
+ var highlighted = ''
172
+ var matchI = 0
173
+ var indexesI = 0
174
+ var opened = false
175
+ var result = []
176
+ for(var i = 0; i < targetLen; ++i) { var char = target[i]
177
+ if(indexes[indexesI] === i) {
178
+ ++indexesI
179
+ if(!opened) { opened = true
180
+ result.push(highlighted); highlighted = ''
181
+ }
182
+
183
+ if(indexesI === indexes.length) {
184
+ highlighted += char
185
+ result.push(cb(highlighted, matchI++)); highlighted = ''
186
+ result.push(target.substr(i+1))
187
+ break
188
+ }
189
+ } else {
190
+ if(opened) { opened = false
191
+ result.push(cb(highlighted, matchI++)); highlighted = ''
192
+ }
193
+ }
194
+ highlighted += char
195
+ }
196
+ return result
197
+ }
198
+
199
+
200
+ var indexes = result => result._indexes.slice(0, result._indexes.len).sort((a,b)=>a-b)
201
+
202
+
203
+ var prepare = (target) => {
204
+ if(typeof target !== 'string') target = ''
205
+ var info = prepareLowerInfo(target)
206
+ return {'target':target, _targetLower:info._lower, _targetLowerCodes:info.lowerCodes, _nextBeginningIndexes:NULL, _bitflags:info.bitflags, 'score':NULL, _indexes:[0], 'obj':NULL} // hidden
207
+ }
208
+
209
+
210
+ // Below this point is only internal code
211
+ // Below this point is only internal code
212
+ // Below this point is only internal code
213
+ // Below this point is only internal code
214
+
215
+
216
+ var prepareSearch = (search) => {
217
+ if(typeof search !== 'string') search = ''
218
+ search = search.trim()
219
+ var info = prepareLowerInfo(search)
220
+
221
+ var spaceSearches = []
222
+ if(info.containsSpace) {
223
+ var searches = search.split(/\s+/)
224
+ searches = [...new Set(searches)] // distinct
225
+ for(var i=0; i<searches.length; i++) {
226
+ if(searches[i] === '') continue
227
+ var _info = prepareLowerInfo(searches[i])
228
+ spaceSearches.push({lowerCodes:_info.lowerCodes, _lower:searches[i].toLowerCase(), containsSpace:false})
229
+ }
230
+ }
231
+
232
+ return {lowerCodes: info.lowerCodes, bitflags: info.bitflags, containsSpace: info.containsSpace, _lower: info._lower, spaceSearches: spaceSearches}
233
+ }
234
+
235
+
236
+
237
+ var getPrepared = (target) => {
238
+ if(target.length > 999) return prepare(target) // don't cache huge targets
239
+ var targetPrepared = preparedCache.get(target)
240
+ if(targetPrepared !== undefined) return targetPrepared
241
+ targetPrepared = prepare(target)
242
+ preparedCache.set(target, targetPrepared)
243
+ return targetPrepared
244
+ }
245
+ var getPreparedSearch = (search) => {
246
+ if(search.length > 999) return prepareSearch(search) // don't cache huge searches
247
+ var searchPrepared = preparedSearchCache.get(search)
248
+ if(searchPrepared !== undefined) return searchPrepared
249
+ searchPrepared = prepareSearch(search)
250
+ preparedSearchCache.set(search, searchPrepared)
251
+ return searchPrepared
252
+ }
253
+
254
+
255
+ var all = (search, targets, options) => {
256
+ var results = []; results.total = targets.length
257
+
258
+ var limit = options && options.limit || INT_MAX
259
+
260
+ if(options && options.key) {
261
+ for(var i=0;i<targets.length;i++) { var obj = targets[i]
262
+ var target = getValue(obj, options.key)
263
+ if(!target) continue
264
+ if(!isObj(target)) target = getPrepared(target)
265
+ target.score = INT_MIN
266
+ target._indexes.len = 0
267
+ var result = target
268
+ result = {target:result.target, _targetLower:'', _targetLowerCodes:NULL, _nextBeginningIndexes:NULL, _bitflags:0, score:target.score, _indexes:NULL, obj:obj} // hidden
269
+ results.push(result); if(results.length >= limit) return results
270
+ }
271
+ } else if(options && options.keys) {
272
+ for(var i=0;i<targets.length;i++) { var obj = targets[i]
273
+ var objResults = new Array(options.keys.length)
274
+ for (var keyI = options.keys.length - 1; keyI >= 0; --keyI) {
275
+ var target = getValue(obj, options.keys[keyI])
276
+ if(!target) { objResults[keyI] = NULL; continue }
277
+ if(!isObj(target)) target = getPrepared(target)
278
+ target.score = INT_MIN
279
+ target._indexes.len = 0
280
+ objResults[keyI] = target
281
+ }
282
+ objResults.obj = obj
283
+ objResults.score = INT_MIN
284
+ results.push(objResults); if(results.length >= limit) return results
285
+ }
286
+ } else {
287
+ for(var i=0;i<targets.length;i++) { var target = targets[i]
288
+ if(!target) continue
289
+ if(!isObj(target)) target = getPrepared(target)
290
+ target.score = INT_MIN
291
+ target._indexes.len = 0
292
+ results.push(target); if(results.length >= limit) return results
293
+ }
294
+ }
295
+
296
+ return results
297
+ }
298
+
299
+
300
+ var algorithm = (preparedSearch, prepared, allowSpaces=false) => {
301
+ if(allowSpaces===false && preparedSearch.containsSpace) return algorithmSpaces(preparedSearch, prepared)
302
+
303
+ var searchLower = preparedSearch._lower
304
+ var searchLowerCodes = preparedSearch.lowerCodes
305
+ var searchLowerCode = searchLowerCodes[0]
306
+ var targetLowerCodes = prepared._targetLowerCodes
307
+ var searchLen = searchLowerCodes.length
308
+ var targetLen = targetLowerCodes.length
309
+ var searchI = 0 // where we at
310
+ var targetI = 0 // where you at
311
+ var matchesSimpleLen = 0
312
+
313
+ // very basic fuzzy match; to remove non-matching targets ASAP!
314
+ // walk through target. find sequential matches.
315
+ // if all chars aren't found then exit
316
+ for(;;) {
317
+ var isMatch = searchLowerCode === targetLowerCodes[targetI]
318
+ if(isMatch) {
319
+ matchesSimple[matchesSimpleLen++] = targetI
320
+ ++searchI; if(searchI === searchLen) break
321
+ searchLowerCode = searchLowerCodes[searchI]
322
+ }
323
+ ++targetI; if(targetI >= targetLen) return NULL // Failed to find searchI
324
+ }
325
+
326
+ var searchI = 0
327
+ var successStrict = false
328
+ var matchesStrictLen = 0
329
+
330
+ var nextBeginningIndexes = prepared._nextBeginningIndexes
331
+ if(nextBeginningIndexes === NULL) nextBeginningIndexes = prepared._nextBeginningIndexes = prepareNextBeginningIndexes(prepared.target)
332
+ var firstPossibleI = targetI = matchesSimple[0]===0 ? 0 : nextBeginningIndexes[matchesSimple[0]-1]
333
+
334
+ // Our target string successfully matched all characters in sequence!
335
+ // Let's try a more advanced and strict test to improve the score
336
+ // only count it as a match if it's consecutive or a beginning character!
337
+ var backtrackCount = 0
338
+ if(targetI !== targetLen) for(;;) {
339
+ if(targetI >= targetLen) {
340
+ // We failed to find a good spot for this search char, go back to the previous search char and force it forward
341
+ if(searchI <= 0) break // We failed to push chars forward for a better match
342
+
343
+ ++backtrackCount; if(backtrackCount > 200) break // exponential backtracking is taking too long, just give up and return a bad match
344
+
345
+ --searchI
346
+ var lastMatch = matchesStrict[--matchesStrictLen]
347
+ targetI = nextBeginningIndexes[lastMatch]
348
+
349
+ } else {
350
+ var isMatch = searchLowerCodes[searchI] === targetLowerCodes[targetI]
351
+ if(isMatch) {
352
+ matchesStrict[matchesStrictLen++] = targetI
353
+ ++searchI; if(searchI === searchLen) { successStrict = true; break }
354
+ ++targetI
355
+ } else {
356
+ targetI = nextBeginningIndexes[targetI]
357
+ }
358
+ }
359
+ }
360
+
361
+ // check if it's a substring match
362
+ var substringIndex = prepared._targetLower.indexOf(searchLower, matchesSimple[0]) // perf: this is slow
363
+ var isSubstring = ~substringIndex
364
+ if(isSubstring && !successStrict) { // rewrite the indexes from basic to the substring
365
+ for(var i=0; i<matchesSimpleLen; ++i) matchesSimple[i] = substringIndex+i
366
+ }
367
+ var isSubstringBeginning = false
368
+ if(isSubstring) {
369
+ isSubstringBeginning = prepared._nextBeginningIndexes[substringIndex-1] === substringIndex
370
+ }
371
+
372
+ { // tally up the score & keep track of matches for highlighting later
373
+ if(successStrict) { var matchesBest = matchesStrict; var matchesBestLen = matchesStrictLen }
374
+ else { var matchesBest = matchesSimple; var matchesBestLen = matchesSimpleLen }
375
+
376
+ var score = 0
377
+
378
+ var extraMatchGroupCount = 0
379
+ for(var i = 1; i < searchLen; ++i) {
380
+ if(matchesBest[i] - matchesBest[i-1] !== 1) {score -= matchesBest[i]; ++extraMatchGroupCount}
381
+ }
382
+ var unmatchedDistance = matchesBest[searchLen-1] - matchesBest[0] - (searchLen-1)
383
+
384
+ score -= (12+unmatchedDistance) * extraMatchGroupCount // penality for more groups
385
+
386
+ if(matchesBest[0] !== 0) score -= matchesBest[0]*matchesBest[0]*.2 // penality for not starting near the beginning
387
+
388
+ if(!successStrict) {
389
+ score *= 1000
390
+ } else {
391
+ // successStrict on a target with too many beginning indexes loses points for being a bad target
392
+ var uniqueBeginningIndexes = 1
393
+ for(var i = nextBeginningIndexes[0]; i < targetLen; i=nextBeginningIndexes[i]) ++uniqueBeginningIndexes
394
+
395
+ if(uniqueBeginningIndexes > 24) score *= (uniqueBeginningIndexes-24)*10 // quite arbitrary numbers here ...
396
+ }
397
+
398
+ if(isSubstring) score /= 1+searchLen*searchLen*1 // bonus for being a full substring
399
+ if(isSubstringBeginning) score /= 1+searchLen*searchLen*1 // bonus for substring starting on a beginningIndex
400
+
401
+ score -= targetLen - searchLen // penality for longer targets
402
+ prepared.score = score
403
+
404
+ for(var i = 0; i < matchesBestLen; ++i) prepared._indexes[i] = matchesBest[i]
405
+ prepared._indexes.len = matchesBestLen
406
+
407
+ return prepared
408
+ }
409
+ }
410
+ var algorithmSpaces = (preparedSearch, target) => {
411
+ var seen_indexes = new Set()
412
+ var score = 0
413
+ var result = NULL
414
+
415
+ var first_seen_index_last_search = 0
416
+ var searches = preparedSearch.spaceSearches
417
+ for(var i=0; i<searches.length; ++i) {
418
+ var search = searches[i]
419
+
420
+ result = algorithm(search, target)
421
+ if(result === NULL) return NULL
422
+
423
+ score += result.score
424
+
425
+ // dock points based on order otherwise "c man" returns Manifest.cpp instead of CheatManager.h
426
+ if(result._indexes[0] < first_seen_index_last_search) {
427
+ score -= first_seen_index_last_search - result._indexes[0]
428
+ }
429
+ first_seen_index_last_search = result._indexes[0]
430
+
431
+ for(var j=0; j<result._indexes.len; ++j) seen_indexes.add(result._indexes[j])
432
+ }
433
+
434
+ // allows a search with spaces that's an exact substring to score well
435
+ var allowSpacesResult = algorithm(preparedSearch, target, /*allowSpaces=*/true)
436
+ if(allowSpacesResult !== NULL && allowSpacesResult.score > score) {
437
+ return allowSpacesResult
438
+ }
439
+
440
+ result.score = score
441
+
442
+ var i = 0
443
+ for (let index of seen_indexes) result._indexes[i++] = index
444
+ result._indexes.len = i
445
+
446
+ return result
447
+ }
448
+
449
+
450
+ var prepareLowerInfo = (str) => {
451
+ var strLen = str.length
452
+ var lower = str.toLowerCase()
453
+ var lowerCodes = [] // new Array(strLen) sparse array is too slow
454
+ var bitflags = 0
455
+ var containsSpace = false // space isn't stored in bitflags because of how searching with a space works
456
+
457
+ for(var i = 0; i < strLen; ++i) {
458
+ var lowerCode = lowerCodes[i] = lower.charCodeAt(i)
459
+
460
+ if(lowerCode === 32) {
461
+ containsSpace = true
462
+ continue // it's important that we don't set any bitflags for space
463
+ }
464
+
465
+ var bit = lowerCode>=97&&lowerCode<=122 ? lowerCode-97 // alphabet
466
+ : lowerCode>=48&&lowerCode<=57 ? 26 // numbers
467
+ // 3 bits available
468
+ : lowerCode<=127 ? 30 // other ascii
469
+ : 31 // other utf8
470
+ bitflags |= 1<<bit
471
+ }
472
+
473
+ return {lowerCodes:lowerCodes, bitflags:bitflags, containsSpace:containsSpace, _lower:lower}
474
+ }
475
+ var prepareBeginningIndexes = (target) => {
476
+ var targetLen = target.length
477
+ var beginningIndexes = []; var beginningIndexesLen = 0
478
+ var wasUpper = false
479
+ var wasAlphanum = false
480
+ for(var i = 0; i < targetLen; ++i) {
481
+ var targetCode = target.charCodeAt(i)
482
+ var isUpper = targetCode>=65&&targetCode<=90
483
+ var isAlphanum = isUpper || targetCode>=97&&targetCode<=122 || targetCode>=48&&targetCode<=57
484
+ var isBeginning = isUpper && !wasUpper || !wasAlphanum || !isAlphanum
485
+ wasUpper = isUpper
486
+ wasAlphanum = isAlphanum
487
+ if(isBeginning) beginningIndexes[beginningIndexesLen++] = i
488
+ }
489
+ return beginningIndexes
490
+ }
491
+ var prepareNextBeginningIndexes = (target) => {
492
+ var targetLen = target.length
493
+ var beginningIndexes = prepareBeginningIndexes(target)
494
+ var nextBeginningIndexes = [] // new Array(targetLen) sparse array is too slow
495
+ var lastIsBeginning = beginningIndexes[0]
496
+ var lastIsBeginningI = 0
497
+ for(var i = 0; i < targetLen; ++i) {
498
+ if(lastIsBeginning > i) {
499
+ nextBeginningIndexes[i] = lastIsBeginning
500
+ } else {
501
+ lastIsBeginning = beginningIndexes[++lastIsBeginningI]
502
+ nextBeginningIndexes[i] = lastIsBeginning===undefined ? targetLen : lastIsBeginning
503
+ }
504
+ }
505
+ return nextBeginningIndexes
506
+ }
507
+
508
+
509
+ var cleanup = () => { preparedCache.clear(); preparedSearchCache.clear(); matchesSimple = []; matchesStrict = [] }
510
+
511
+ var preparedCache = new Map()
512
+ var preparedSearchCache = new Map()
513
+ var matchesSimple = []; var matchesStrict = []
514
+
515
+
516
+ // for use with keys. just returns the maximum score
517
+ var defaultScoreFn = (a) => {
518
+ var max = INT_MIN
519
+ var len = a.length
520
+ for (var i = 0; i < len; ++i) {
521
+ var result = a[i]; if(result === NULL) continue
522
+ var score = result.score
523
+ if(score > max) max = score
524
+ }
525
+ if(max === INT_MIN) return NULL
526
+ return max
527
+ }
528
+
529
+ // prop = 'key' 2.5ms optimized for this case, seems to be about as fast as direct obj[prop]
530
+ // prop = 'key1.key2' 10ms
531
+ // prop = ['key1', 'key2'] 27ms
532
+ var getValue = (obj, prop) => {
533
+ var tmp = obj[prop]; if(tmp !== undefined) return tmp
534
+ var segs = prop
535
+ if(!Array.isArray(prop)) segs = prop.split('.')
536
+ var len = segs.length
537
+ var i = -1
538
+ while (obj && (++i < len)) obj = obj[segs[i]]
539
+ return obj
540
+ }
541
+
542
+ var isObj = (x) => { return typeof x === 'object' } // faster as a function
543
+ // var INT_MAX = 9007199254740991; var INT_MIN = -INT_MAX
544
+ var INT_MAX = Infinity; var INT_MIN = -INT_MAX
545
+ var noResults = []; noResults.total = 0
546
+ var NULL = null
547
+
548
+
549
+ // Hacked version of https://github.com/lemire/FastPriorityQueue.js
550
+ var fastpriorityqueue=r=>{var e=[],o=0,a={},v=r=>{for(var a=0,v=e[a],c=1;c<o;){var s=c+1;a=c,s<o&&e[s].score<e[c].score&&(a=s),e[a-1>>1]=e[a],c=1+(a<<1)}for(var f=a-1>>1;a>0&&v.score<e[f].score;f=(a=f)-1>>1)e[a]=e[f];e[a]=v};return a.add=(r=>{var a=o;e[o++]=r;for(var v=a-1>>1;a>0&&r.score<e[v].score;v=(a=v)-1>>1)e[a]=e[v];e[a]=r}),a.poll=(r=>{if(0!==o){var a=e[0];return e[0]=e[--o],v(),a}}),a.peek=(r=>{if(0!==o)return e[0]}),a.replaceTop=(r=>{e[0]=r,v()}),a}
551
+ var q = fastpriorityqueue() // reuse this
552
+
553
+
554
+ // fuzzysort is written this way for minification. all names are mangeled unless quoted
555
+ return {'single':single, 'go':go, 'highlight':highlight, 'prepare':prepare, 'indexes':indexes, 'cleanup':cleanup}
556
+ }) // UMD
557
+
558
+ // TODO: (feature) frecency
559
+ // TODO: (perf) use different sorting algo depending on the # of results?
560
+ // TODO: (perf) preparedCache is a memory leak
561
+ // TODO: (like sublime) backslash === forwardslash
562
+ // TODO: (perf) prepareSearch seems slow