diff --git a/.gitignore b/.gitignore index 21bc08883e..8b38903942 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,6 @@ _site/* .DS_Store tmp/ -vendor/ +/vendor .bundle/ .vscode/ diff --git a/_data/snippets.yml b/_data/snippets.yml index 25430b65d0..34cafcfce2 100644 --- a/_data/snippets.yml +++ b/_data/snippets.yml @@ -352,6 +352,40 @@ filtering-results: es: Filtradas por fr: Filtrage par pt: +loading-search: + en: LOADING SEARCH... + es: CARGANDO LA BÚSQUEDA... + fr: RECHERCHE EN COURS... + pt: +search-lessons: + en: SEARCH LESSONS + es: BUSCAR LECCIONES + fr: RECHERCHER LES LEÇONS + pt: +start-searching: + en: START SEARCHING + es: INICIAR BÚSQUEDA + fr: DÉMARRER LA RECHERCHE + pt: +type-search-terms: + en: TYPE SEARCH TERMS... + es: ESCRIBE LOS TÉRMINOS DE BÚSQUEDA... + fr: ENTRER UN OU PLUSIEURS TERMES DE RECHERCHE... + pt: +search-info: + en: | + To search for relevant terms, enter them into the search bar and either press the enter key or the search button. All searches are case insensitive. If multiple terms are entered, results will include lessons that have all terms, as well as lessons that contain *either term*. Results with more of the terms will be scored higher in the list. + + To only return results with multiple terms, add the `+` symbol before the term. For example, `+Twitter +Network` will return lessons that contain *both* "twitter" and "network". To only return results that *do not* contain a term use the `-` symbol. For example, `-Twitter +Network` will return lessons that contain "network" but not "twitter". For more detailed information, visit this guide on searching: + es: | + Para buscar términos relevantes, escríbelos en la barra de búsqueda y aprieta la tecla "enter" o haz clic en el botón "buscar lecciones". Las búsquedas no distinguen mayúsculas y minúsculas. Si se ingresan múltiples términos, los resultados incluirán tanto lecciones que los contengan todos, como lecciones que contengan *solo alguno*. Los resultados que incluyan más de un término aparecerán primero en la lista. + + Para obtener solo resultados con múltiples términos, agrega el símbolo `+` antes de cada uno. Por ejemplo, `+Twitter +Red` devolverá lecciones que contienen *tanto* "twitter" como "red". Para obtener solo resultados que *no* contengan cierto término, utiliza el símbolo `-`. Por ejemplo, `-Twitter +Red` devolverá lecciones que contienen "red" pero no "twitter". Para información más detallada, puedes revisar la guía sobre búsquedas (en inglés): + fr: | + Pour obtenir des résultats en utilisant plusieurs termes de recherche, faites précéder chaque terme du symbole `+`. Par exemple, en insérant `+Twitter +réseau`, vous obtiendrez les tutoriels qui contiennent tous les deux termes. Pour *exclure* un terme des résultats obtenus, vous pouvez utiliser le symbole `-`. Par exemple, en insérant `-Twitter +réseau`, vous obtiendrez les tutoriels qui contiennent le terme "réseau", mais pas "Twitter". Pour en savoir plus sur les modalités de recherche, merci de consulter ce guide + + pt: | + # lesson headers editor: diff --git a/_includes/lesson-index.html b/_includes/lesson-index.html index dc94f87d79..2eedd4b9d9 100644 --- a/_includes/lesson-index.html +++ b/_includes/lesson-index.html @@ -1,32 +1,61 @@ {% comment %} - Core code for generating filterable lesson indexes on lessons.md and es/lecciones.md. This will repeatedly call lesson_describe.html in which individual lessons have their metadata formatted for display. +Core code for generating filterable lesson indexes on lessons.md and es/lecciones.md. This will repeatedly call +lesson_describe.html in which individual lessons have their metadata formatted for display. {% endcomment %} - + +
+ + + + + + + + + + +
    {% for activity in site.data.activities %} {% assign atype = activity.type %} -
  • {{ activity[page.lang]}} ({{ alllessons | where:"activity",atype | size }})
  • +
  • {{ activity[page.lang]}} ({{ alllessons | where:"activity",atype | size }}) +
  • {% endfor %}
    -{% for topic in site.data.topics %} -{% assign type = topic.type %} -{% assign count = alllessons | where:"topics",type | size }} %} + {% for topic in site.data.topics %} + {% assign type = topic.type %} + {% assign count = alllessons | where:"topics",type | size }} %} {% if count > 0 %}
  • {{ topic.displayname[page.lang] }} ({{count}})
  • {% endif %} -{% endfor %} + {% endfor %}
-
{{site.data.snippets.reset-button[page.lang]}} ({{ alllessons | size }})
+
{{site.data.snippets.reset-button[page.lang]}} ({{ alllessons | size }})
+ +
+ +
+
-
  • {{site.data.snippets.sort-by-date[page.lang]}}
  • -
  • {{site.data.snippets.sort-by-difficulty[page.lang]}}
  • +
  • {{site.data.snippets.sort-by-difficulty[page.lang]}} +
-

{{ site.data.snippets.filtering-results[page.lang] }}: {{ site.data.snippets.all-lessons[page.lang] }} {{site.data.snippets.date[page.lang]}}

+ +

{{ site.data.snippets.filtering-results[page.lang] }}: {{ site.data.snippets.all-lessons[page.lang] }} {{site.data.snippets.date[page.lang]}}

    {% for lesson in alllessons %} {% capture author_string %} {% include author.html %} {% endcapture %} -
  • {% include lesson_describe.html authors=author_string %}
  • +
  • {% include lesson_describe.html authors=author_string %}
  • {% endfor %}
@@ -56,10 +89,15 @@

{{ site.data.snippets.filtering-results[page.lang] }}: + + +{% if page.lang != "en" %} + +{% endif %} diff --git a/_includes/lesson_describe.html b/_includes/lesson_describe.html index 504e43dfd6..9b309aaf17 100755 --- a/_includes/lesson_describe.html +++ b/_includes/lesson_describe.html @@ -9,7 +9,6 @@ {% endcomment %}
- {% if lesson.original %} {% assign canonical_slug = lesson.original %} {% else %} @@ -23,7 +22,9 @@

{{ include.authors }}

{{ lesson.title }}

-

{{ lesson.abstract | markdownify }}

+

+ {{ lesson.abstract | markdownify | remove: '

' | remove: '

'}} +

{% comment %} Activity and topic are hidden via CSS as a hack to let JS sorting by activity and topic work. Note that the date sort is based on translation date first, falling back to publication date. @@ -32,5 +33,13 @@

{{ include.authors }}

{{ lesson.topics | join: ' '}} {% if lesson.translation_date %}{{ lesson.translation_date }}{% else %}{{ lesson.date }}{% endif %} {{ lesson.difficulty }} + + + + +
diff --git a/css/style.css b/css/style.css index 0ed604d81f..4dec597ec4 100644 --- a/css/style.css +++ b/css/style.css @@ -316,6 +316,74 @@ Lessons Index background-color:#ededed; } + /***************** + SEARCH + *****************/ + + .search-input { + width:55%; + clear:both; + margin-bottom:1rem; + background-color:#fefefe; + color:#666; + border:1px solid #999; + font: .9rem/1.1rem 'Open Sans', + sans-serif; + padding: .4rem .6rem; + border-radius: 3px; + display:inline-block; + text-transform:uppercase; + text-decoration: none; + } + + #search-button, + #enable-search-button { + background-color: #efefef; + color: rgb(153, 143, 143); + width: 35%; + font: .9rem/1.1rem 'Open Sans', + sans-serif; + padding: .4rem .6rem; + border: none; + border-radius: 3px; + display: inline-block; + text-transform: uppercase; + text-decoration: none; + } + + @media only screen and (max-width: 767px) { + /* phones */ + #search-button, + #enable-search-button { + width: 80%; + } + } + + + #search-info-button { + padding: 0.5rem; + color: rgb(153, 143, 143); + } + + #search-info { + display: none; + height:0px; + background:#efefef; + overflow:hidden; + transition:0.5s; + -webkit-transition:0.5s; + width: 100%; + text-align: left; + box-sizing: border-box; + } + + #search-info.visible { + display: block; + height: fit-content; + height: -moz-max-content; + padding: 10px; + margin-top: 10px; + } /***************** SORT BUTTONS @@ -426,11 +494,6 @@ Lessons Index clear:none; } - p.abstract { - font: .8rem/1.2rem 'Open Sans', sans-serif; - margin:0; - } - .list .date, .lesson-description .activity, .lesson-description .topics, @@ -438,7 +501,20 @@ Lessons Index display: none; } - + #pre-loader { + visibility: hidden; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + width: 100%; + position: fixed; + top: 0; + left: 0; + z-index: 9999; + transition: opacity 0.3s linear; + background: rgba(211, 211, 211, 0.8); + } /* ============================================================================= Top Navigation Bar ========================================================================== */ diff --git a/js/lessonfilter.js b/js/lessonfilter.js index 0c5062067c..ac2f849892 100644 --- a/js/lessonfilter.js +++ b/js/lessonfilter.js @@ -1,4 +1,6 @@ function resetSort() { + /* Function to reset sort buttons */ + $('#current-sort').text('date'); $('#current-sort').removeClass().addClass("sort-desc"); $("#sort-by-date").removeClass().addClass("sort desc my-asc"); $("#sort-by-difficulty").removeClass().addClass("sort my-desc"); @@ -6,18 +8,16 @@ function resetSort() { function applySortFromURI(uri, featureList) { + /* Function to update lesson-list using featureList and sort direction + - uses URI to generate sort directions + */ - console.log("applying sort from URI"); - - var params = uri.search(true); - var sortOrder = params.sortOrder; - var sortType = params.sortType; - var nonSortOrder = (sortOrder == "desc" ? "asc" : "desc"); + const params = uri.search(true); + let sortOrder = params.sortOrder; + let sortType = params.sortType; + let nonSortOrder = (sortOrder == "desc" ? "asc" : "desc"); if (sortType) { - console.log("SortType: " + sortType); - console.log("sortOrder: " + sortOrder); - console.log("nonSortOrder: " + nonSortOrder); // Update arrow of selected sort button $("#sort-by-" + sortType).removeClass().addClass("sort " + sortOrder + " my-" + nonSortOrder); @@ -27,17 +27,16 @@ function applySortFromURI(uri, featureList) { // Update filter header and restore defaults to other button if (sortType == "date") { - $('#current-sort').text(dateSort); + $('#current-sort').text('date'); $('#sort-by-difficulty').removeClass().addClass("sort my-asc"); } else { - $('#current-sort').text(difficultySort); + $('#current-sort').text('difficulty'); $('#sort-by-date').removeClass().addClass("sort my-desc"); } } else { // If no sort params, perform default sort - console.log("default sorting"); sortType = "date"; sortOrder = "desc"; @@ -45,24 +44,223 @@ function applySortFromURI(uri, featureList) { resetSort(); } - // Performm new sort + // Perform new sort featureList.sort(sortType, { order: sortOrder }); + + // Reset filter results header + $('#results-value').text($(this).text().split(' ')[0] + '(' + featureList.update().matchingItems.length + ')' + " "); + $('#results-value').css('textTransform', 'uppercase'); +} + +function lunrSearch(searchString, idx, corpus, featureList, uri) { + /* Function to generate search using lunr + - find search results using index + - load in original corpus and find relevant lessons + - generate new html to show search snippet + - use featureList to show lessons with search results (also relevant filters) + - display html + */ + + // Get lessons that contain search string using lunr index + const results = idx.search(searchString); + + // Get lessons from corpus that contain the search string + let docs = results.filter(result => corpus.some(doc => result.ref === doc.url)).map(result => { + let doc = corpus.find(o => o.url === result.ref); + return { + ...result, + ...doc + }; + }); + + const BUFFER = 30 // Number of characters to show for kwic-results + const MAX_KWIC = 3 + // Create html to show search results using html mark + let elements = [] + docs.map((doc) => { + // Gets element name from absolute url that is generated by search.json. If URL syntax is changed, will need to double check that this code still works. Currently it gets /language/lessons/lesson-url. + let elementName = '/' + doc.url.split('/').slice(3).join('/'); + let search_keys = Object.keys(doc.matchData.metadata); + // Gets exact position of search results and highlights them using mark tags + let inner_results = search_keys.map((token) => { + let all_positions = doc.matchData.metadata[token].body.position; + let grouped_kwic = all_positions.slice(0, MAX_KWIC).map(function (pos) { + let loc1 = pos[0] + let loc2 = loc1 + pos[1] + let rendered_text = `... ${doc.body.substring(loc1 - BUFFER, loc1)} ${doc.body.substring(loc1, loc2)} ${doc.body.substring(loc2, loc2 + BUFFER)} ...` + return rendered_text + }).join("") + return grouped_kwic + }).join("").replace(/(\r\n|\n|\r)/gm, ""); + // Saves element name and results to array to be displayed once featureList is updated. + elements.push({ 'elementName': elementName, 'innerResults': inner_results }); + // Updates score element for search results + $(`span[id="${elementName}-score"]`).html(doc.score); + }); + // Filter featureList to only show items from search results and active filters + const params = uri.search(true); + // + let type = params.activity ? params.activity : params.topic; + featureList.filter((item) => { + let topicsArray = item.values().topics.split(/\s/); + let condition = params.topic ? topicsArray.includes(type) : item.values().activity == type; + // return items in list that are in search results and filter if clicked + return docs.find((doc) => { + if (doc.title === item.values().title) { + // update score values for item + item.values().score = doc.score; + // Could simply to just do Object.keys(params) > 1 here but in case we add more URI values this will explicitly check for filters along with search + return ['topic', 'activity'].some(key => Object.keys(params).includes(key)) ? ((doc.title === item.values().title) && condition) : (doc.title === item.values().title); + } + + }); + }); + // remove existing sorts and indicate sorted by search results + $('#sort-by-difficulty').removeClass().addClass("sort my-asc"); + $('#sort-by-date').removeClass().addClass("sort my-desc"); + $('#current-sort').text('search'); + $('#current-sort').removeClass().addClass("sort-desc"); + + // Sort featureList by score + featureList.sort('score', { order: "desc" }); + + // Hide original abstracts and update Filtering to show number of results + $('.abstract').css('display', 'none'); + $('#results-value').text($(this).text().split(' ')[0] + '(' + featureList.update().matchingItems.length + ')' + " "); + $('#results-value').css('textTransform', 'uppercase'); + + // Display updated search results + elements.map((elm) => { + $(`p[id="${elm.elementName}-search_results"]`).css('display', ''); + $(`p[id="${elm.elementName}-search_results"]`).html(elm.innerResults); + }); + } +function resetSearch() { + /* Function to reset search values and display to original settings */ + // Empty search input + $('#search').val(''); + // Hide and empty search results + $('.search_results').css('display', 'none'); + $('.search_results').html(''); + // Show original abstract results + $('.abstract').css('display', 'block'); + // Reset score + $('.score').html(0); +}; function wireButtons() { + /* Main function for page load */ // set URI object to current Window location - var uri = new URI(location); - console.log(uri.toString()); + let uri = new URI(location); - var options = { - valueNames: ['date', 'title', 'difficulty', 'activity', 'topics'] + let options = { + valueNames: ['date', 'title', 'difficulty', 'activity', 'topics', 'abstract', 'content', 'score'] }; - var featureList = new List('lesson-list', options); + let featureList = new List('lesson-list', options); // We need a stateObj for adjusting the URIs on button clicks, but the value is moot for now; could be useful for future functionality. - var stateObj = { foo: "bar" }; + let stateObj = { foo: "bar" }; + + // Get search indices and corpuses using URI to make a call to search-index for each language + let idx; + let corpus; + + async function loadSearchData() { + /*Function to load search data asynchronously*/ + + // Hide enable button and show search input + $("#enable-search-div").css("display", "none"); + $("#search-div").css("display", ""); + $('#loading-search').css('display', 'none'); + $('#search').css('display', ''); + $('#search-button').prop('disabled', false); + + // Get language and load idx and corpus + const language = uri.toString().split('/').slice(-3)[0]; + const indexResponse = await fetch(`https://programminghistorian.github.io/search-index/indices/index${language.toUpperCase()}.json`); + const indexJSON = await indexResponse.json(); + idx = lunr.Index.load(indexJSON); + const corpusResponse = await fetch(`https://programminghistorian.org/${language}/search.json`); + const corpusJSON = await corpusResponse.json(); + corpus = corpusJSON; + + } + + // Enable search on button click + $("#enable-search-div").on("click", function () { + // Start loading search data + loadSearchData(); + }); + + + + $("#search-button").on("click", function () { + /* Function that does ALL filtering and searching of list (whether search exists or not) + - checks if search string exists or not and updates URI + - if search string exists calls lunrSearch + - else performs filtering (if filter exists) or resets list + */ + + // Get search string + const searchString = $("#search").val(); + + // Check that's it's not empty + if (searchString.length > 0) { + // Update URI + uri.setSearch("search", searchString) + uri.removeSearch('sortOrder'); + uri.removeSearch('sortType'); + history.pushState(stateObj, "", uri.toString()); + // Call lunr search + lunrSearch(searchString, idx, corpus, featureList, uri, stateObj); + + } else { + // If empty check if topic or activity filter selected + + // Call reset search to empty out search values and update URI + uri.removeSearch('search'); + history.pushState(stateObj, "", uri.toString()); + resetSearch(); + const params = uri.search(true); + let type = params.activity ? params.activity : params.topic; + if (type) { + + // If filter selected, return filter lessons based on URI + + featureList.filter((item) => { + item.values().score = 0; + + let topicsArray = item.values().topics.split(/\s/); + let condition = params.topic ? topicsArray.includes(type) : item.values().activity == type; + return condition + + }); + + applySortFromURI(uri, featureList); + } else { + $('#filter-none').click(); + } + } + + }); + // Search lessons on enter press + $('#search').on('keyup', function (event) { + if (event.which == 13) { + $("#search-button").click(); + } + }); + + // Search info button clicked show additional information + $('#search-info-button').click(function() { + if ($("#search-info").hasClass("visible")) { + $("#search-info").removeClass("visible"); + } else { + $("#search-info").addClass("visible"); + } + }); // When a filter button is clicked $('.filter').children().click(function () { @@ -70,13 +268,24 @@ function wireButtons() { $('.filter').children().removeClass("current"); $(this).addClass("current"); - // Update the results header - $('#results-value').text($(this).text() + " "); - $('#results-value').css('textTransform', 'uppercase'); + let type = $(this).attr("id").substr(7); + let filterType = $(this).parent().attr('class').split(' ')[1]; + // Reset url parameters + if (filterType === 'activities') { + uri.removeSearch("topic") + uri.setSearch("activity", type) + } else { + uri.removeSearch("activity") + uri.setSearch("topic", type) + } - applySortFromURI(uri, featureList); - }); + // returns the URI instance for chaining + history.pushState(stateObj, "", uri.toString()); + // Use search to perform filtering + $("#search-button").click(); + return false; + }); // When the reset button is clicked $('#filter-none').click(function () { @@ -84,18 +293,27 @@ function wireButtons() { $('.filter').children().removeClass("current"); // Reset filter results header - $('#results-value').text($('#results-value').text()); + $('#results-value').text(featureList.update().items.length); + + // Reset search results + resetSearch(); + // Reset uri to remove query params uri.search(""); history.pushState(stateObj, "", uri.toString()); // Reset filtering and perform default sort - featureList.filter(); - featureList.sort('date', { order: "desc" }); + featureList.filter(item => { + item.values().score = 0; + return true + }); + featureList.sort('date', { order: "desc" }); // Reset sort buttons to defaults resetSort(); + // Call reset search a second time seems to refresh html (very hacky solution) + resetSearch(); }); @@ -103,18 +321,14 @@ function wireButtons() { $('.sort').click(function () { // Get sort type from button (date or difficulty) - var sortType = $(this).attr("data-sort"); + let sortType = $(this).attr("data-sort"); // Get sort order info from button - var curSortOrder = $(this).hasClass("my-asc") ? "desc" : "asc"; - var newSortOrder = (curSortOrder == "asc" ? "desc" : "asc"); - - console.log("curSort:" + curSortOrder); - console.log("newSort:" + newSortOrder); + let curSortOrder = $(this).hasClass("my-asc") ? "desc" : "asc"; + let newSortOrder = (curSortOrder == "asc" ? "desc" : "asc"); // update class for clicked button $(this).removeClass("my-" + newSortOrder).addClass("my-" + curSortOrder); - // Update filter results header to show current sorting (date or difficulty) // Reset the other (non-pressed) button to its default sort arrow. if (sortType == "date") { @@ -138,53 +352,6 @@ function wireButtons() { uri.setSearch("sortType", sortType); uri.setSearch("sortOrder", newSortOrder); history.pushState(stateObj, "", uri.toString()); - console.log(uri.toString()); - }); - - // Wire up each of the activity filter buttons. - $('.filter.activities').children().click(function () { - - var type = $(this).attr("id").substr(7); - - featureList.filter(function (item) { - if (item.values().activity == type) { - return true; - } else { - return false; - } - }); - - // reset url parameter - uri.removeSearch("topic"); - uri.setSearch("activity", type); // returns the URI instance for chaining - history.pushState(stateObj, "", uri.toString()); - console.log(uri.toString()); - - return false; - }); - - - // Wire up each of the topic filter buttons. - $('.filter.topics').children().click(function () { - - var type = $(this).attr("id").substr(7); - - featureList.filter(function (item) { - var topicsArray = item.values().topics.split(/\s/); - if (topicsArray.includes(type)) { - return true; - } else { - return false; - } - }); - - // Reset url parameters - uri.removeSearch("activity"); - uri.setSearch("topic", type); // returns the URI instance for chaining - history.pushState(stateObj, "", uri.toString()); - console.log(uri.toString()); - - return false; }); /*************************************** @@ -193,17 +360,27 @@ function wireButtons() { // set labels based on the current language - var dateSort = $('#date-sort-text').attr('label'); - var difficultySort = $('#difficulty-sort-text').attr("label"); - - // Look for URI query params - var params = uri.search(true); - var filter = params.activity ? params.activity : params.topic; - - // If a filter is present in the URI, simulate a click to run filter - // Clicking a filter button checks for sort params in URI, so don't do it twice. - if (filter) { - console.log("FILTER:" + filter); + const dateSort = $('#date-sort-text').attr('label'); + const difficultySort = $('#difficulty-sort-text').attr("label"); + + // // Look for URI query params + const params = uri.search(true); + let filter = params.activity ? params.activity : params.topic; + let search = params.search; + + // If a filter or search is present in the URI, simulate a click to run filter + // Clicking a filter button checks for sort params in URI, so don't do it twice OR load search data and simulate search click. + const preloader = $('#pre-loader'); + + if (search) { + // If search is true, load pre-loading graph to allow search results time to load + preloader.css('visibility', 'visible'); + $('#search').val(search); + loadSearchData().then(() => { + preloader.fadeOut(1500); + $('#search-button').click(); + }); + } else if (filter) { $("#filter-" + filter).click(); } else { diff --git a/js/vendor/lunr.es.js b/js/vendor/lunr.es.js new file mode 100644 index 0000000000..197eda41c6 --- /dev/null +++ b/js/vendor/lunr.es.js @@ -0,0 +1,599 @@ +/*! + * Lunr languages, `Spanish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function () { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function (lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.es = function () { + this.pipeline.reset(); + this.pipeline.add( + lunr.es.trimmer, + lunr.es.stopWordFilter, + lunr.es.stemmer + ); + + // for lunr version 2 + // this is necessary so that every searched word is also stemmed before + // in lunr <= 1 this is not needed, as it is done using the normal pipeline + if (this.searchPipeline) { + this.searchPipeline.reset(); + this.searchPipeline.add(lunr.es.stemmer) + } + }; + + /* lunr trimmer function */ + lunr.es.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.es.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.es.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.es.trimmer, 'trimmer-es'); + + /* lunr stemmer function */ + lunr.es.stemmer = (function () { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function SpanishStemmer() { + var a_0 = [new Among("", -1, 6), new Among("\u00E1", 0, 1), + new Among("\u00E9", 0, 2), new Among("\u00ED", 0, 3), + new Among("\u00F3", 0, 4), new Among("\u00FA", 0, 5) + ], + a_1 = [ + new Among("la", -1, -1), new Among("sela", 0, -1), + new Among("le", -1, -1), new Among("me", -1, -1), + new Among("se", -1, -1), new Among("lo", -1, -1), + new Among("selo", 5, -1), new Among("las", -1, -1), + new Among("selas", 7, -1), new Among("les", -1, -1), + new Among("los", -1, -1), new Among("selos", 10, -1), + new Among("nos", -1, -1) + ], + a_2 = [new Among("ando", -1, 6), + new Among("iendo", -1, 6), new Among("yendo", -1, 7), + new Among("\u00E1ndo", -1, 2), new Among("i\u00E9ndo", -1, 1), + new Among("ar", -1, 6), new Among("er", -1, 6), + new Among("ir", -1, 6), new Among("\u00E1r", -1, 3), + new Among("\u00E9r", -1, 4), new Among("\u00EDr", -1, 5) + ], + a_3 = [ + new Among("ic", -1, -1), new Among("ad", -1, -1), + new Among("os", -1, -1), new Among("iv", -1, 1) + ], + a_4 = [ + new Among("able", -1, 1), new Among("ible", -1, 1), + new Among("ante", -1, 1) + ], + a_5 = [new Among("ic", -1, 1), + new Among("abil", -1, 1), new Among("iv", -1, 1) + ], + a_6 = [ + new Among("ica", -1, 1), new Among("ancia", -1, 2), + new Among("encia", -1, 5), new Among("adora", -1, 2), + new Among("osa", -1, 1), new Among("ista", -1, 1), + new Among("iva", -1, 9), new Among("anza", -1, 1), + new Among("log\u00EDa", -1, 3), new Among("idad", -1, 8), + new Among("able", -1, 1), new Among("ible", -1, 1), + new Among("ante", -1, 2), new Among("mente", -1, 7), + new Among("amente", 13, 6), new Among("aci\u00F3n", -1, 2), + new Among("uci\u00F3n", -1, 4), new Among("ico", -1, 1), + new Among("ismo", -1, 1), new Among("oso", -1, 1), + new Among("amiento", -1, 1), new Among("imiento", -1, 1), + new Among("ivo", -1, 9), new Among("ador", -1, 2), + new Among("icas", -1, 1), new Among("ancias", -1, 2), + new Among("encias", -1, 5), new Among("adoras", -1, 2), + new Among("osas", -1, 1), new Among("istas", -1, 1), + new Among("ivas", -1, 9), new Among("anzas", -1, 1), + new Among("log\u00EDas", -1, 3), new Among("idades", -1, 8), + new Among("ables", -1, 1), new Among("ibles", -1, 1), + new Among("aciones", -1, 2), new Among("uciones", -1, 4), + new Among("adores", -1, 2), new Among("antes", -1, 2), + new Among("icos", -1, 1), new Among("ismos", -1, 1), + new Among("osos", -1, 1), new Among("amientos", -1, 1), + new Among("imientos", -1, 1), new Among("ivos", -1, 9) + ], + a_7 = [ + new Among("ya", -1, 1), new Among("ye", -1, 1), + new Among("yan", -1, 1), new Among("yen", -1, 1), + new Among("yeron", -1, 1), new Among("yendo", -1, 1), + new Among("yo", -1, 1), new Among("yas", -1, 1), + new Among("yes", -1, 1), new Among("yais", -1, 1), + new Among("yamos", -1, 1), new Among("y\u00F3", -1, 1) + ], + a_8 = [ + new Among("aba", -1, 2), new Among("ada", -1, 2), + new Among("ida", -1, 2), new Among("ara", -1, 2), + new Among("iera", -1, 2), new Among("\u00EDa", -1, 2), + new Among("ar\u00EDa", 5, 2), new Among("er\u00EDa", 5, 2), + new Among("ir\u00EDa", 5, 2), new Among("ad", -1, 2), + new Among("ed", -1, 2), new Among("id", -1, 2), + new Among("ase", -1, 2), new Among("iese", -1, 2), + new Among("aste", -1, 2), new Among("iste", -1, 2), + new Among("an", -1, 2), new Among("aban", 16, 2), + new Among("aran", 16, 2), new Among("ieran", 16, 2), + new Among("\u00EDan", 16, 2), new Among("ar\u00EDan", 20, 2), + new Among("er\u00EDan", 20, 2), new Among("ir\u00EDan", 20, 2), + new Among("en", -1, 1), new Among("asen", 24, 2), + new Among("iesen", 24, 2), new Among("aron", -1, 2), + new Among("ieron", -1, 2), new Among("ar\u00E1n", -1, 2), + new Among("er\u00E1n", -1, 2), new Among("ir\u00E1n", -1, 2), + new Among("ado", -1, 2), new Among("ido", -1, 2), + new Among("ando", -1, 2), new Among("iendo", -1, 2), + new Among("ar", -1, 2), new Among("er", -1, 2), + new Among("ir", -1, 2), new Among("as", -1, 2), + new Among("abas", 39, 2), new Among("adas", 39, 2), + new Among("idas", 39, 2), new Among("aras", 39, 2), + new Among("ieras", 39, 2), new Among("\u00EDas", 39, 2), + new Among("ar\u00EDas", 45, 2), new Among("er\u00EDas", 45, 2), + new Among("ir\u00EDas", 45, 2), new Among("es", -1, 1), + new Among("ases", 49, 2), new Among("ieses", 49, 2), + new Among("abais", -1, 2), new Among("arais", -1, 2), + new Among("ierais", -1, 2), new Among("\u00EDais", -1, 2), + new Among("ar\u00EDais", 55, 2), new Among("er\u00EDais", 55, 2), + new Among("ir\u00EDais", 55, 2), new Among("aseis", -1, 2), + new Among("ieseis", -1, 2), new Among("asteis", -1, 2), + new Among("isteis", -1, 2), new Among("\u00E1is", -1, 2), + new Among("\u00E9is", -1, 1), new Among("ar\u00E9is", 64, 2), + new Among("er\u00E9is", 64, 2), new Among("ir\u00E9is", 64, 2), + new Among("ados", -1, 2), new Among("idos", -1, 2), + new Among("amos", -1, 2), new Among("\u00E1bamos", 70, 2), + new Among("\u00E1ramos", 70, 2), new Among("i\u00E9ramos", 70, 2), + new Among("\u00EDamos", 70, 2), new Among("ar\u00EDamos", 74, 2), + new Among("er\u00EDamos", 74, 2), new Among("ir\u00EDamos", 74, 2), + new Among("emos", -1, 1), new Among("aremos", 78, 2), + new Among("eremos", 78, 2), new Among("iremos", 78, 2), + new Among("\u00E1semos", 78, 2), new Among("i\u00E9semos", 78, 2), + new Among("imos", -1, 2), new Among("ar\u00E1s", -1, 2), + new Among("er\u00E1s", -1, 2), new Among("ir\u00E1s", -1, 2), + new Among("\u00EDs", -1, 2), new Among("ar\u00E1", -1, 2), + new Among("er\u00E1", -1, 2), new Among("ir\u00E1", -1, 2), + new Among("ar\u00E9", -1, 2), new Among("er\u00E9", -1, 2), + new Among("ir\u00E9", -1, 2), new Among("i\u00F3", -1, 2) + ], + a_9 = [ + new Among("a", -1, 1), new Among("e", -1, 2), + new Among("o", -1, 1), new Among("os", -1, 1), + new Among("\u00E1", -1, 1), new Among("\u00E9", -1, 2), + new Among("\u00ED", -1, 1), new Among("\u00F3", -1, 1) + ], + g_v = [17, + 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 10 + ], + I_p2, I_p1, I_pV, sbp = new SnowballProgram(); + this.setCurrent = function (word) { + sbp.setCurrent(word); + }; + this.getCurrent = function () { + return sbp.getCurrent(); + }; + + function habr1() { + if (sbp.out_grouping(g_v, 97, 252)) { + while (!sbp.in_grouping(g_v, 97, 252)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + return false; + } + return true; + } + + function habr2() { + if (sbp.in_grouping(g_v, 97, 252)) { + var v_1 = sbp.cursor; + if (habr1()) { + sbp.cursor = v_1; + if (!sbp.in_grouping(g_v, 97, 252)) + return true; + while (!sbp.out_grouping(g_v, 97, 252)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + } + return false; + } + return true; + } + + function habr3() { + var v_1 = sbp.cursor, + v_2; + if (habr2()) { + sbp.cursor = v_1; + if (!sbp.out_grouping(g_v, 97, 252)) + return; + v_2 = sbp.cursor; + if (habr1()) { + sbp.cursor = v_2; + if (!sbp.in_grouping(g_v, 97, 252) || sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + } + } + I_pV = sbp.cursor; + } + + function habr4() { + while (!sbp.in_grouping(g_v, 97, 252)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + while (!sbp.out_grouping(g_v, 97, 252)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + return true; + } + + function r_mark_regions() { + var v_1 = sbp.cursor; + I_pV = sbp.limit; + I_p1 = I_pV; + I_p2 = I_pV; + habr3(); + sbp.cursor = v_1; + if (habr4()) { + I_p1 = sbp.cursor; + if (habr4()) + I_p2 = sbp.cursor; + } + } + + function r_postlude() { + var among_var; + while (true) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among(a_0, 6); + if (among_var) { + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("a"); + continue; + case 2: + sbp.slice_from("e"); + continue; + case 3: + sbp.slice_from("i"); + continue; + case 4: + sbp.slice_from("o"); + continue; + case 5: + sbp.slice_from("u"); + continue; + case 6: + if (sbp.cursor >= sbp.limit) + break; + sbp.cursor++; + continue; + } + } + break; + } + } + + function r_RV() { + return I_pV <= sbp.cursor; + } + + function r_R1() { + return I_p1 <= sbp.cursor; + } + + function r_R2() { + return I_p2 <= sbp.cursor; + } + + function r_attached_pronoun() { + var among_var; + sbp.ket = sbp.cursor; + if (sbp.find_among_b(a_1, 13)) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among_b(a_2, 11); + if (among_var && r_RV()) + switch (among_var) { + case 1: + sbp.bra = sbp.cursor; + sbp.slice_from("iendo"); + break; + case 2: + sbp.bra = sbp.cursor; + sbp.slice_from("ando"); + break; + case 3: + sbp.bra = sbp.cursor; + sbp.slice_from("ar"); + break; + case 4: + sbp.bra = sbp.cursor; + sbp.slice_from("er"); + break; + case 5: + sbp.bra = sbp.cursor; + sbp.slice_from("ir"); + break; + case 6: + sbp.slice_del(); + break; + case 7: + if (sbp.eq_s_b(1, "u")) + sbp.slice_del(); + break; + } + } + } + + function habr5(a, n) { + if (!r_R2()) + return true; + sbp.slice_del(); + sbp.ket = sbp.cursor; + var among_var = sbp.find_among_b(a, n); + if (among_var) { + sbp.bra = sbp.cursor; + if (among_var == 1 && r_R2()) + sbp.slice_del(); + } + return false; + } + + function habr6(c1) { + if (!r_R2()) + return true; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, c1)) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + } + return false; + } + + function r_standard_suffix() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_6, 46); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (!r_R2()) + return false; + sbp.slice_del(); + break; + case 2: + if (habr6("ic")) + return false; + break; + case 3: + if (!r_R2()) + return false; + sbp.slice_from("log"); + break; + case 4: + if (!r_R2()) + return false; + sbp.slice_from("u"); + break; + case 5: + if (!r_R2()) + return false; + sbp.slice_from("ente"); + break; + case 6: + if (!r_R1()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_3, 4); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R2()) { + sbp.slice_del(); + if (among_var == 1) { + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "at")) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + } + } + } + } + break; + case 7: + if (habr5(a_4, 3)) + return false; + break; + case 8: + if (habr5(a_5, 3)) + return false; + break; + case 9: + if (habr6("at")) + return false; + break; + } + return true; + } + return false; + } + + function r_y_verb_suffix() { + var among_var, v_1; + if (sbp.cursor >= I_pV) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_7, 12); + sbp.limit_backward = v_1; + if (among_var) { + sbp.bra = sbp.cursor; + if (among_var == 1) { + if (!sbp.eq_s_b(1, "u")) + return false; + sbp.slice_del(); + } + return true; + } + } + return false; + } + + function r_verb_suffix() { + var among_var, v_1, v_2, v_3; + if (sbp.cursor >= I_pV) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_8, 96); + sbp.limit_backward = v_1; + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + v_2 = sbp.limit - sbp.cursor; + if (sbp.eq_s_b(1, "u")) { + v_3 = sbp.limit - sbp.cursor; + if (sbp.eq_s_b(1, "g")) + sbp.cursor = sbp.limit - v_3; + else + sbp.cursor = sbp.limit - v_2; + } else + sbp.cursor = sbp.limit - v_2; + sbp.bra = sbp.cursor; + case 2: + sbp.slice_del(); + break; + } + } + } + } + + function r_residual_suffix() { + var among_var, v_1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_9, 8); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (r_RV()) + sbp.slice_del(); + break; + case 2: + if (r_RV()) { + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "u")) { + sbp.bra = sbp.cursor; + v_1 = sbp.limit - sbp.cursor; + if (sbp.eq_s_b(1, "g")) { + sbp.cursor = sbp.limit - v_1; + if (r_RV()) + sbp.slice_del(); + } + } + } + break; + } + } + } + this.stem = function () { + var v_1 = sbp.cursor; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_attached_pronoun(); + sbp.cursor = sbp.limit; + if (!r_standard_suffix()) { + sbp.cursor = sbp.limit; + if (!r_y_verb_suffix()) { + sbp.cursor = sbp.limit; + r_verb_suffix(); + } + } + sbp.cursor = sbp.limit; + r_residual_suffix(); + sbp.cursor = sbp.limit_backward; + r_postlude(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function (token) { + // for lunr version 2 + if (typeof token.update === "function") { + return token.update(function (word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + }) + } else { // for lunr version <= 1 + st.setCurrent(token); + st.stem(); + return st.getCurrent(); + } + } + })(); + + lunr.Pipeline.registerFunction(lunr.es.stemmer, 'stemmer-es'); + + lunr.es.stopWordFilter = lunr.generateStopWordFilter('a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos'.split(' ')); + + lunr.Pipeline.registerFunction(lunr.es.stopWordFilter, 'stopWordFilter-es'); + }; +})) \ No newline at end of file diff --git a/js/vendor/lunr.fr.js b/js/vendor/lunr.fr.js new file mode 100644 index 0000000000..acd8dd3f9b --- /dev/null +++ b/js/vendor/lunr.fr.js @@ -0,0 +1,703 @@ +/*! + * Lunr languages, `French` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function () { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function (lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.fr = function () { + this.pipeline.reset(); + this.pipeline.add( + lunr.fr.trimmer, + lunr.fr.stopWordFilter, + lunr.fr.stemmer + ); + + // for lunr version 2 + // this is necessary so that every searched word is also stemmed before + // in lunr <= 1 this is not needed, as it is done using the normal pipeline + if (this.searchPipeline) { + this.searchPipeline.reset(); + this.searchPipeline.add(lunr.fr.stemmer) + } + }; + + /* lunr trimmer function */ + lunr.fr.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.fr.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.fr.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.fr.trimmer, 'trimmer-fr'); + + /* lunr stemmer function */ + lunr.fr.stemmer = (function () { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function FrenchStemmer() { + var a_0 = [new Among("col", -1, -1), new Among("par", -1, -1), + new Among("tap", -1, -1) + ], + a_1 = [new Among("", -1, 4), + new Among("I", 0, 1), new Among("U", 0, 2), new Among("Y", 0, 3) + ], + a_2 = [ + new Among("iqU", -1, 3), new Among("abl", -1, 3), + new Among("I\u00E8r", -1, 4), new Among("i\u00E8r", -1, 4), + new Among("eus", -1, 2), new Among("iv", -1, 1) + ], + a_3 = [ + new Among("ic", -1, 2), new Among("abil", -1, 1), + new Among("iv", -1, 3) + ], + a_4 = [new Among("iqUe", -1, 1), + new Among("atrice", -1, 2), new Among("ance", -1, 1), + new Among("ence", -1, 5), new Among("logie", -1, 3), + new Among("able", -1, 1), new Among("isme", -1, 1), + new Among("euse", -1, 11), new Among("iste", -1, 1), + new Among("ive", -1, 8), new Among("if", -1, 8), + new Among("usion", -1, 4), new Among("ation", -1, 2), + new Among("ution", -1, 4), new Among("ateur", -1, 2), + new Among("iqUes", -1, 1), new Among("atrices", -1, 2), + new Among("ances", -1, 1), new Among("ences", -1, 5), + new Among("logies", -1, 3), new Among("ables", -1, 1), + new Among("ismes", -1, 1), new Among("euses", -1, 11), + new Among("istes", -1, 1), new Among("ives", -1, 8), + new Among("ifs", -1, 8), new Among("usions", -1, 4), + new Among("ations", -1, 2), new Among("utions", -1, 4), + new Among("ateurs", -1, 2), new Among("ments", -1, 15), + new Among("ements", 30, 6), new Among("issements", 31, 12), + new Among("it\u00E9s", -1, 7), new Among("ment", -1, 15), + new Among("ement", 34, 6), new Among("issement", 35, 12), + new Among("amment", 34, 13), new Among("emment", 34, 14), + new Among("aux", -1, 10), new Among("eaux", 39, 9), + new Among("eux", -1, 1), new Among("it\u00E9", -1, 7) + ], + a_5 = [ + new Among("ira", -1, 1), new Among("ie", -1, 1), + new Among("isse", -1, 1), new Among("issante", -1, 1), + new Among("i", -1, 1), new Among("irai", 4, 1), + new Among("ir", -1, 1), new Among("iras", -1, 1), + new Among("ies", -1, 1), new Among("\u00EEmes", -1, 1), + new Among("isses", -1, 1), new Among("issantes", -1, 1), + new Among("\u00EEtes", -1, 1), new Among("is", -1, 1), + new Among("irais", 13, 1), new Among("issais", 13, 1), + new Among("irions", -1, 1), new Among("issions", -1, 1), + new Among("irons", -1, 1), new Among("issons", -1, 1), + new Among("issants", -1, 1), new Among("it", -1, 1), + new Among("irait", 21, 1), new Among("issait", 21, 1), + new Among("issant", -1, 1), new Among("iraIent", -1, 1), + new Among("issaIent", -1, 1), new Among("irent", -1, 1), + new Among("issent", -1, 1), new Among("iront", -1, 1), + new Among("\u00EEt", -1, 1), new Among("iriez", -1, 1), + new Among("issiez", -1, 1), new Among("irez", -1, 1), + new Among("issez", -1, 1) + ], + a_6 = [new Among("a", -1, 3), + new Among("era", 0, 2), new Among("asse", -1, 3), + new Among("ante", -1, 3), new Among("\u00E9e", -1, 2), + new Among("ai", -1, 3), new Among("erai", 5, 2), + new Among("er", -1, 2), new Among("as", -1, 3), + new Among("eras", 8, 2), new Among("\u00E2mes", -1, 3), + new Among("asses", -1, 3), new Among("antes", -1, 3), + new Among("\u00E2tes", -1, 3), new Among("\u00E9es", -1, 2), + new Among("ais", -1, 3), new Among("erais", 15, 2), + new Among("ions", -1, 1), new Among("erions", 17, 2), + new Among("assions", 17, 3), new Among("erons", -1, 2), + new Among("ants", -1, 3), new Among("\u00E9s", -1, 2), + new Among("ait", -1, 3), new Among("erait", 23, 2), + new Among("ant", -1, 3), new Among("aIent", -1, 3), + new Among("eraIent", 26, 2), new Among("\u00E8rent", -1, 2), + new Among("assent", -1, 3), new Among("eront", -1, 2), + new Among("\u00E2t", -1, 3), new Among("ez", -1, 2), + new Among("iez", 32, 2), new Among("eriez", 33, 2), + new Among("assiez", 33, 3), new Among("erez", 32, 2), + new Among("\u00E9", -1, 2) + ], + a_7 = [new Among("e", -1, 3), + new Among("I\u00E8re", 0, 2), new Among("i\u00E8re", 0, 2), + new Among("ion", -1, 1), new Among("Ier", -1, 2), + new Among("ier", -1, 2), new Among("\u00EB", -1, 4) + ], + a_8 = [ + new Among("ell", -1, -1), new Among("eill", -1, -1), + new Among("enn", -1, -1), new Among("onn", -1, -1), + new Among("ett", -1, -1) + ], + g_v = [17, 65, 16, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 128, 130, 103, 8, 5 + ], + g_keep_with_s = [1, 65, 20, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 + ], + I_p2, I_p1, I_pV, sbp = new SnowballProgram(); + this.setCurrent = function (word) { + sbp.setCurrent(word); + }; + this.getCurrent = function () { + return sbp.getCurrent(); + }; + + function habr1(c1, c2, v_1) { + if (sbp.eq_s(1, c1)) { + sbp.ket = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 251)) { + sbp.slice_from(c2); + sbp.cursor = v_1; + return true; + } + } + return false; + } + + function habr2(c1, c2, v_1) { + if (sbp.eq_s(1, c1)) { + sbp.ket = sbp.cursor; + sbp.slice_from(c2); + sbp.cursor = v_1; + return true; + } + return false; + } + + function r_prelude() { + var v_1, v_2; + while (true) { + v_1 = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 251)) { + sbp.bra = sbp.cursor; + v_2 = sbp.cursor; + if (habr1("u", "U", v_1)) + continue; + sbp.cursor = v_2; + if (habr1("i", "I", v_1)) + continue; + sbp.cursor = v_2; + if (habr2("y", "Y", v_1)) + continue; + } + sbp.cursor = v_1; + sbp.bra = v_1; + if (!habr1("y", "Y", v_1)) { + sbp.cursor = v_1; + if (sbp.eq_s(1, "q")) { + sbp.bra = sbp.cursor; + if (habr2("u", "U", v_1)) + continue; + } + sbp.cursor = v_1; + if (v_1 >= sbp.limit) + return; + sbp.cursor++; + } + } + } + + function habr3() { + while (!sbp.in_grouping(g_v, 97, 251)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + while (!sbp.out_grouping(g_v, 97, 251)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + return false; + } + + function r_mark_regions() { + var v_1 = sbp.cursor; + I_pV = sbp.limit; + I_p1 = I_pV; + I_p2 = I_pV; + if (sbp.in_grouping(g_v, 97, 251) && sbp.in_grouping(g_v, 97, 251) && + sbp.cursor < sbp.limit) + sbp.cursor++; + else { + sbp.cursor = v_1; + if (!sbp.find_among(a_0, 3)) { + sbp.cursor = v_1; + do { + if (sbp.cursor >= sbp.limit) { + sbp.cursor = I_pV; + break; + } + sbp.cursor++; + } while (!sbp.in_grouping(g_v, 97, 251)); + } + } + I_pV = sbp.cursor; + sbp.cursor = v_1; + if (!habr3()) { + I_p1 = sbp.cursor; + if (!habr3()) + I_p2 = sbp.cursor; + } + } + + function r_postlude() { + var among_var, v_1; + while (true) { + v_1 = sbp.cursor; + sbp.bra = v_1; + among_var = sbp.find_among(a_1, 4); + if (!among_var) + break; + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("i"); + break; + case 2: + sbp.slice_from("u"); + break; + case 3: + sbp.slice_from("y"); + break; + case 4: + if (sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + break; + } + } + } + + function r_RV() { + return I_pV <= sbp.cursor; + } + + function r_R1() { + return I_p1 <= sbp.cursor; + } + + function r_R2() { + return I_p2 <= sbp.cursor; + } + + function r_standard_suffix() { + var among_var, v_1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_4, 43); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (!r_R2()) + return false; + sbp.slice_del(); + break; + case 2: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "ic")) { + sbp.bra = sbp.cursor; + if (!r_R2()) + sbp.slice_from("iqU"); + else + sbp.slice_del(); + } + break; + case 3: + if (!r_R2()) + return false; + sbp.slice_from("log"); + break; + case 4: + if (!r_R2()) + return false; + sbp.slice_from("u"); + break; + case 5: + if (!r_R2()) + return false; + sbp.slice_from("ent"); + break; + case 6: + if (!r_RV()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_2, 6); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (r_R2()) { + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "at")) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + } + } + break; + case 2: + if (r_R2()) + sbp.slice_del(); + else if (r_R1()) + sbp.slice_from("eux"); + break; + case 3: + if (r_R2()) + sbp.slice_del(); + break; + case 4: + if (r_RV()) + sbp.slice_from("i"); + break; + } + } + break; + case 7: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_3, 3); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (r_R2()) + sbp.slice_del(); + else + sbp.slice_from("abl"); + break; + case 2: + if (r_R2()) + sbp.slice_del(); + else + sbp.slice_from("iqU"); + break; + case 3: + if (r_R2()) + sbp.slice_del(); + break; + } + } + break; + case 8: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "at")) { + sbp.bra = sbp.cursor; + if (r_R2()) { + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "ic")) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + else + sbp.slice_from("iqU"); + break; + } + } + } + break; + case 9: + sbp.slice_from("eau"); + break; + case 10: + if (!r_R1()) + return false; + sbp.slice_from("al"); + break; + case 11: + if (r_R2()) + sbp.slice_del(); + else if (!r_R1()) + return false; + else + sbp.slice_from("eux"); + break; + case 12: + if (!r_R1() || !sbp.out_grouping_b(g_v, 97, 251)) + return false; + sbp.slice_del(); + break; + case 13: + if (r_RV()) + sbp.slice_from("ant"); + return false; + case 14: + if (r_RV()) + sbp.slice_from("ent"); + return false; + case 15: + v_1 = sbp.limit - sbp.cursor; + if (sbp.in_grouping_b(g_v, 97, 251) && r_RV()) { + sbp.cursor = sbp.limit - v_1; + sbp.slice_del(); + } + return false; + } + return true; + } + return false; + } + + function r_i_verb_suffix() { + var among_var, v_1; + if (sbp.cursor < I_pV) + return false; + v_1 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_5, 35); + if (!among_var) { + sbp.limit_backward = v_1; + return false; + } + sbp.bra = sbp.cursor; + if (among_var == 1) { + if (!sbp.out_grouping_b(g_v, 97, 251)) { + sbp.limit_backward = v_1; + return false; + } + sbp.slice_del(); + } + sbp.limit_backward = v_1; + return true; + } + + function r_verb_suffix() { + var among_var, v_2, v_3; + if (sbp.cursor < I_pV) + return false; + v_2 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_6, 38); + if (!among_var) { + sbp.limit_backward = v_2; + return false; + } + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (!r_R2()) { + sbp.limit_backward = v_2; + return false; + } + sbp.slice_del(); + break; + case 2: + sbp.slice_del(); + break; + case 3: + sbp.slice_del(); + v_3 = sbp.limit - sbp.cursor; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "e")) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + } else + sbp.cursor = sbp.limit - v_3; + break; + } + sbp.limit_backward = v_2; + return true; + } + + function r_residual_suffix() { + var among_var, v_1 = sbp.limit - sbp.cursor, + v_2, v_4, v_5; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "s")) { + sbp.bra = sbp.cursor; + v_2 = sbp.limit - sbp.cursor; + if (sbp.out_grouping_b(g_keep_with_s, 97, 232)) { + sbp.cursor = sbp.limit - v_2; + sbp.slice_del(); + } else + sbp.cursor = sbp.limit - v_1; + } else + sbp.cursor = sbp.limit - v_1; + if (sbp.cursor >= I_pV) { + v_4 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_7, 7); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (r_R2()) { + v_5 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "s")) { + sbp.cursor = sbp.limit - v_5; + if (!sbp.eq_s_b(1, "t")) + break; + } + sbp.slice_del(); + } + break; + case 2: + sbp.slice_from("i"); + break; + case 3: + sbp.slice_del(); + break; + case 4: + if (sbp.eq_s_b(2, "gu")) + sbp.slice_del(); + break; + } + } + sbp.limit_backward = v_4; + } + } + + function r_un_double() { + var v_1 = sbp.limit - sbp.cursor; + if (sbp.find_among_b(a_8, 5)) { + sbp.cursor = sbp.limit - v_1; + sbp.ket = sbp.cursor; + if (sbp.cursor > sbp.limit_backward) { + sbp.cursor--; + sbp.bra = sbp.cursor; + sbp.slice_del(); + } + } + } + + function r_un_accent() { + var v_1, v_2 = 1; + while (sbp.out_grouping_b(g_v, 97, 251)) + v_2--; + if (v_2 <= 0) { + sbp.ket = sbp.cursor; + v_1 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "\u00E9")) { + sbp.cursor = sbp.limit - v_1; + if (!sbp.eq_s_b(1, "\u00E8")) + return; + } + sbp.bra = sbp.cursor; + sbp.slice_from("e"); + } + } + + function habr5() { + if (!r_standard_suffix()) { + sbp.cursor = sbp.limit; + if (!r_i_verb_suffix()) { + sbp.cursor = sbp.limit; + if (!r_verb_suffix()) { + sbp.cursor = sbp.limit; + r_residual_suffix(); + return; + } + } + } + sbp.cursor = sbp.limit; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "Y")) { + sbp.bra = sbp.cursor; + sbp.slice_from("i"); + } else { + sbp.cursor = sbp.limit; + if (sbp.eq_s_b(1, "\u00E7")) { + sbp.bra = sbp.cursor; + sbp.slice_from("c"); + } + } + } + this.stem = function () { + var v_1 = sbp.cursor; + r_prelude(); + sbp.cursor = v_1; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + habr5(); + sbp.cursor = sbp.limit; + r_un_double(); + sbp.cursor = sbp.limit; + r_un_accent(); + sbp.cursor = sbp.limit_backward; + r_postlude(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function (token) { + // for lunr version 2 + if (typeof token.update === "function") { + return token.update(function (word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + }) + } else { // for lunr version <= 1 + st.setCurrent(token); + st.stem(); + return st.getCurrent(); + } + } + })(); + + lunr.Pipeline.registerFunction(lunr.fr.stemmer, 'stemmer-fr'); + + lunr.fr.stopWordFilter = lunr.generateStopWordFilter('ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes'.split(' ')); + + lunr.Pipeline.registerFunction(lunr.fr.stopWordFilter, 'stopWordFilter-fr'); + }; +})) \ No newline at end of file diff --git a/js/vendor/lunr.stemmer.support.js b/js/vendor/lunr.stemmer.support.js new file mode 100644 index 0000000000..1eb1636884 --- /dev/null +++ b/js/vendor/lunr.stemmer.support.js @@ -0,0 +1,326 @@ +/*! + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function () { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function (lunr) { + /* provides utilities for the included stemmers */ + lunr.stemmerSupport = { + Among: function (s, substring_i, result, method) { + this.toCharArray = function (s) { + var sLength = s.length, + charArr = new Array(sLength); + for (var i = 0; i < sLength; i++) + charArr[i] = s.charCodeAt(i); + return charArr; + }; + + if ((!s && s != "") || (!substring_i && (substring_i != 0)) || !result) + throw ("Bad Among initialisation: s:" + s + ", substring_i: " + + substring_i + ", result: " + result); + this.s_size = s.length; + this.s = this.toCharArray(s); + this.substring_i = substring_i; + this.result = result; + this.method = method; + }, + SnowballProgram: function () { + var current; + return { + bra: 0, + ket: 0, + limit: 0, + cursor: 0, + limit_backward: 0, + setCurrent: function (word) { + current = word; + this.cursor = 0; + this.limit = word.length; + this.limit_backward = 0; + this.bra = this.cursor; + this.ket = this.limit; + }, + getCurrent: function () { + var result = current; + current = null; + return result; + }, + in_grouping: function (s, min, max) { + if (this.cursor < this.limit) { + var ch = current.charCodeAt(this.cursor); + if (ch <= max && ch >= min) { + ch -= min; + if (s[ch >> 3] & (0X1 << (ch & 0X7))) { + this.cursor++; + return true; + } + } + } + return false; + }, + in_grouping_b: function (s, min, max) { + if (this.cursor > this.limit_backward) { + var ch = current.charCodeAt(this.cursor - 1); + if (ch <= max && ch >= min) { + ch -= min; + if (s[ch >> 3] & (0X1 << (ch & 0X7))) { + this.cursor--; + return true; + } + } + } + return false; + }, + out_grouping: function (s, min, max) { + if (this.cursor < this.limit) { + var ch = current.charCodeAt(this.cursor); + if (ch > max || ch < min) { + this.cursor++; + return true; + } + ch -= min; + if (!(s[ch >> 3] & (0X1 << (ch & 0X7)))) { + this.cursor++; + return true; + } + } + return false; + }, + out_grouping_b: function (s, min, max) { + if (this.cursor > this.limit_backward) { + var ch = current.charCodeAt(this.cursor - 1); + if (ch > max || ch < min) { + this.cursor--; + return true; + } + ch -= min; + if (!(s[ch >> 3] & (0X1 << (ch & 0X7)))) { + this.cursor--; + return true; + } + } + return false; + }, + eq_s: function (s_size, s) { + if (this.limit - this.cursor < s_size) + return false; + for (var i = 0; i < s_size; i++) + if (current.charCodeAt(this.cursor + i) != s.charCodeAt(i)) + return false; + this.cursor += s_size; + return true; + }, + eq_s_b: function (s_size, s) { + if (this.cursor - this.limit_backward < s_size) + return false; + for (var i = 0; i < s_size; i++) + if (current.charCodeAt(this.cursor - s_size + i) != s + .charCodeAt(i)) + return false; + this.cursor -= s_size; + return true; + }, + find_among: function (v, v_size) { + var i = 0, + j = v_size, + c = this.cursor, + l = this.limit, + common_i = 0, + common_j = 0, + first_key_inspected = false; + while (true) { + var k = i + ((j - i) >> 1), + diff = 0, + common = common_i < common_j ? + common_i : + common_j, + w = v[k]; + for (var i2 = common; i2 < w.s_size; i2++) { + if (c + common == l) { + diff = -1; + break; + } + diff = current.charCodeAt(c + common) - w.s[i2]; + if (diff) + break; + common++; + } + if (diff < 0) { + j = k; + common_j = common; + } else { + i = k; + common_i = common; + } + if (j - i <= 1) { + if (i > 0 || j == i || first_key_inspected) + break; + first_key_inspected = true; + } + } + while (true) { + var w = v[i]; + if (common_i >= w.s_size) { + this.cursor = c + w.s_size; + if (!w.method) + return w.result; + var res = w.method(); + this.cursor = c + w.s_size; + if (res) + return w.result; + } + i = w.substring_i; + if (i < 0) + return 0; + } + }, + find_among_b: function (v, v_size) { + var i = 0, + j = v_size, + c = this.cursor, + lb = this.limit_backward, + common_i = 0, + common_j = 0, + first_key_inspected = false; + while (true) { + var k = i + ((j - i) >> 1), + diff = 0, + common = common_i < common_j ? + common_i : + common_j, + w = v[k]; + for (var i2 = w.s_size - 1 - common; i2 >= 0; i2--) { + if (c - common == lb) { + diff = -1; + break; + } + diff = current.charCodeAt(c - 1 - common) - w.s[i2]; + if (diff) + break; + common++; + } + if (diff < 0) { + j = k; + common_j = common; + } else { + i = k; + common_i = common; + } + if (j - i <= 1) { + if (i > 0 || j == i || first_key_inspected) + break; + first_key_inspected = true; + } + } + while (true) { + var w = v[i]; + if (common_i >= w.s_size) { + this.cursor = c - w.s_size; + if (!w.method) + return w.result; + var res = w.method(); + this.cursor = c - w.s_size; + if (res) + return w.result; + } + i = w.substring_i; + if (i < 0) + return 0; + } + }, + replace_s: function (c_bra, c_ket, s) { + var adjustment = s.length - (c_ket - c_bra), + left = current + .substring(0, c_bra), + right = current.substring(c_ket); + current = left + s + right; + this.limit += adjustment; + if (this.cursor >= c_ket) + this.cursor += adjustment; + else if (this.cursor > c_bra) + this.cursor = c_bra; + return adjustment; + }, + slice_check: function () { + if (this.bra < 0 || this.bra > this.ket || this.ket > this.limit || + this.limit > current.length) + throw ("faulty slice operation"); + }, + slice_from: function (s) { + this.slice_check(); + this.replace_s(this.bra, this.ket, s); + }, + slice_del: function () { + this.slice_from(""); + }, + insert: function (c_bra, c_ket, s) { + var adjustment = this.replace_s(c_bra, c_ket, s); + if (c_bra <= this.bra) + this.bra += adjustment; + if (c_bra <= this.ket) + this.ket += adjustment; + }, + slice_to: function () { + this.slice_check(); + return current.substring(this.bra, this.ket); + }, + eq_v_b: function (s) { + return this.eq_s_b(s.length, s); + } + }; + } + }; + + lunr.trimmerSupport = { + generateTrimmer: function (wordCharacters) { + var startRegex = new RegExp("^[^" + wordCharacters + "]+") + var endRegex = new RegExp("[^" + wordCharacters + "]+$") + + return function (token) { + // for lunr version 2 + if (typeof token.update === "function") { + return token.update(function (s) { + return s + .replace(startRegex, '') + .replace(endRegex, ''); + }) + } else { // for lunr version 1 + return token + .replace(startRegex, '') + .replace(endRegex, ''); + } + }; + } + } + } +})); \ No newline at end of file