├── .github ├── FUNDING.yml └── workflows │ ├── pytest.yml │ └── python-publish.yml ├── .gitignore ├── LICENSE.md ├── MANIFEST.in ├── README.md ├── citeurl ├── __init__.py ├── authority.py ├── citation.py ├── citator.py ├── cli.py ├── mdx.py ├── regex_mods.py ├── templates │ ├── caselaw.yaml │ ├── general federal law.yaml │ ├── secondary sources.yaml │ ├── specific federal laws.yaml │ └── state law.yaml ├── tokens.py └── web │ ├── __init__.py │ ├── citeurl.js │ ├── logo.svg │ ├── makejs.py │ ├── resources.py │ ├── server.py │ └── style.css ├── docs ├── 404.html ├── assets │ ├── _mkdocstrings.css │ ├── favicon.png │ ├── images │ │ └── favicon.png │ ├── javascripts │ │ ├── bundle.d6f25eb3.min.js │ │ ├── bundle.d6f25eb3.min.js.map │ │ ├── lunr │ │ │ ├── min │ │ │ │ ├── lunr.ar.min.js │ │ │ │ ├── lunr.da.min.js │ │ │ │ ├── lunr.de.min.js │ │ │ │ ├── lunr.du.min.js │ │ │ │ ├── lunr.el.min.js │ │ │ │ ├── lunr.es.min.js │ │ │ │ ├── lunr.fi.min.js │ │ │ │ ├── lunr.fr.min.js │ │ │ │ ├── lunr.he.min.js │ │ │ │ ├── lunr.hi.min.js │ │ │ │ ├── lunr.hu.min.js │ │ │ │ ├── lunr.hy.min.js │ │ │ │ ├── lunr.it.min.js │ │ │ │ ├── lunr.ja.min.js │ │ │ │ ├── lunr.jp.min.js │ │ │ │ ├── lunr.kn.min.js │ │ │ │ ├── lunr.ko.min.js │ │ │ │ ├── lunr.multi.min.js │ │ │ │ ├── lunr.nl.min.js │ │ │ │ ├── lunr.no.min.js │ │ │ │ ├── lunr.pt.min.js │ │ │ │ ├── lunr.ro.min.js │ │ │ │ ├── lunr.ru.min.js │ │ │ │ ├── lunr.sa.min.js │ │ │ │ ├── lunr.stemmer.support.min.js │ │ │ │ ├── lunr.sv.min.js │ │ │ │ ├── lunr.ta.min.js │ │ │ │ ├── lunr.te.min.js │ │ │ │ ├── lunr.th.min.js │ │ │ │ ├── lunr.tr.min.js │ │ │ │ ├── lunr.vi.min.js │ │ │ │ └── lunr.zh.min.js │ │ │ ├── tinyseg.js │ │ │ └── wordcut.js │ │ └── workers │ │ │ ├── search.6ce7567c.min.js │ │ │ └── search.6ce7567c.min.js.map │ ├── logo.svg │ └── stylesheets │ │ ├── main.8c3ca2c6.min.css │ │ ├── main.8c3ca2c6.min.css.map │ │ ├── palette.06af60db.min.css │ │ └── palette.06af60db.min.css.map ├── frontends │ └── index.html ├── index.html ├── library │ └── index.html ├── objects.inv ├── search │ └── search_index.json ├── sitemap.xml ├── sitemap.xml.gz └── template-yamls │ └── index.html ├── docs_source ├── assets │ ├── favicon.png │ └── logo.svg ├── frontends.md ├── index.md ├── library.md └── template-yamls.md ├── mkdocs.yml ├── setup.py └── tests ├── __init__.py ├── _test_links.py ├── test_core.py ├── test_js.py ├── test_mdx.py └── test_templates.py /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: simonsherred 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | -------------------------------------------------------------------------------- /.github/workflows/pytest.yml: -------------------------------------------------------------------------------- 1 | name: tests 2 | on: [push, pull_request] 3 | jobs: 4 | build: 5 | name: Run Tests 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v2 9 | 10 | - name: Set up Python 3.9 11 | uses: actions/setup-python@v2 12 | with: 13 | python-version: 3.9 14 | 15 | - name: Install CiteURL 16 | run: python3 -m pip install citeurl 17 | 18 | - name: Install test dependencies 19 | run: python3 -m pip install pytest pytest-cov pytest-github-actions-annotate-failures quickjs markdown 20 | 21 | - name: Test with pytest 22 | run: python3 -m pytest . --exitfirst --verbose --failed-first --cov=citeurl 23 | -------------------------------------------------------------------------------- /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Upload Python Package 10 | 11 | on: push 12 | 13 | jobs: 14 | pypi-publish: 15 | name: upload release to PyPI 16 | runs-on: ubuntu-latest 17 | environment: 18 | name: pypi 19 | url: https://pypi.org/p/citeurl 20 | permissions: 21 | id-token: write 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Set up Python 25 | uses: actions/setup-python@v2 26 | with: 27 | python-version: '3.x' 28 | - name: Install dependencies 29 | run: | 30 | python -m pip install --upgrade pip 31 | pip install build 32 | - name: Build package 33 | run: python -m build 34 | - name: publish package distributions 35 | uses: pypa/gh-action-pypi-publish@release/v1 36 | 37 | # deploy: 38 | # runs-on: ubuntu-latest 39 | # steps: 40 | # - uses: actions/checkout@v2 41 | # - name: Set up Python 42 | # uses: actions/setup-python@v2 43 | # with: 44 | # python-version: '3.x' 45 | # - name: Install dependencies 46 | # run: | 47 | # python -m pip install --upgrade pip 48 | # pip install build 49 | # - name: Build package 50 | # run: python -m build 51 | # - name: Publish package 52 | # uses: pypa/gh-action-pypi-#publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 53 | # with: 54 | # user: __token__ 55 | # password: ${{ secrets.PYPI_API_TOKEN }} 56 | 57 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sh 2 | *.egg-info/ 3 | **/__pycache__/* 4 | **/.pytest_cache/* 5 | **/.mypy_cache/* 6 | **.sync-conflict 7 | build/ 8 | demo/ 9 | dist/ 10 | custom_templates/ 11 | .coverage 12 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Simon Raindrum Sherred 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE.md 2 | include README.md 3 | graft citeurl 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

CiteURL Logo

2 |

pytest GitHub issues GitHub license PyPI

3 | 4 | CiteURL is an extensible tool that parses legal citations and makes links to websites where you can read the relevant law for free. It can be used to quickly look up a reference, or to insert a hyperlink for every long- or short-form citation found in a longer text. 5 | 6 | If you want to quickly try it out, it's available as a web app at [citation.link](https://www.citation.link). 7 | 8 | --- 9 | 10 | Here's a sample of the links CiteURL can make: 11 | 12 | > Federal law provides that courts should award prevailing civil rights plaintiffs reasonable attorneys fees, 42 USC § 1988(b), and, by discretion, expert fees, id. at (c). This is because the importance of civil rights litigation cannot be measured by a damages judgment. See Riverside v. Rivera, 477 U.S. 561 (1986). But Evans v. Jeff D. upheld a settlement where the plaintiffs got everything they wanted, on condition that they waive attorneys' fees. 475 U.S. 717 (1986). This ruling lets savvy defendants create a wedge between plaintiffs and their attorneys, discouraging civil rights suits and undermining the court's logic in Riverside, 477 U.S. at 574-78. 13 | 14 | --- 15 | 16 | By default, CiteURL supports Bluebook-style citations to [over 130 sources](https://github.com/raindrum/citeurl/blob/main/citeurl/templates) of U.S. law, including: 17 | 18 | - most reported state and federal court opinions 19 | - the U.S. Code and Code of Federal Regulations 20 | - the U.S. Constitution and all state constitutions 21 | - the codified laws for every state and territory except Arkansas, Georgia, Guam, and Puerto Rico. 22 | 23 | You can also add more sources of law by [writing your own citation templates](https://raindrum.github.io/citeurl/template-yamls/) in YAML format. 24 | 25 | ## Installation 26 | 27 | To install just enough to make CiteURL work, run this command: 28 | 29 | ```bash 30 | python3 -m pip install citeurl 31 | ``` 32 | 33 | Substitute `citeurl[full]` for `citeurl` if you want to install the optional dependencies `flask` and `appdirs`, necessary for hosting citeurl as a website and reading custom templates from the user's home directory. 34 | 35 | 36 | 37 | ## Usage 38 | 39 | CiteURL provides four command-line tools: 40 | 41 | - `citeurl process`: Parse a text and insert an HTML hyperlink for every citation it contains, including shortform citations. 42 | - `citeurl lookup`: Look up a single citation and display information about it. 43 | - `citeurl host`: Host an instance of CiteURL as a web app like [citation.link](https://www.citation.link). 44 | - `citeurl makejs`: Export an instance of CiteURL's lookup feature as JavaScript or a static web page. More info is available [here](https://raindrum.github.io/citeurl/frontends#javascript). 45 | 46 | Each command has its own command-line arguments you can view with the `-h` option. They all share the `-t` option, which allows you to load a list of custom [citation templates](https://raindrum.github.io/citeurl/template-yamls/) in YAML form. 47 | 48 | Here are a few common use cases: 49 | 50 | ```bash 51 | # Process a court opinion and output a version where each citation is hyperlinked: 52 | citeurl process -i INPUT_FILE.html -o OUTPUT_FILE.html 53 | ``` 54 | 55 | ```bash 56 | # Look up a single citation and open it directly in a browser 57 | citeurl lookup "42 USC 1983" -b 58 | ``` 59 | 60 | ```bash 61 | # List the top ten authorities cited in a text, from most citations to least: 62 | cat INPUT_FILE.html | citeurl process -a 10 63 | ``` 64 | 65 | ```bash 66 | # Host a lookup tool with custom templates, and serve it on the local network: 67 | citeurl host -t PATH_TO_YOUR_TEMPLATES.YAML -s 68 | ``` 69 | 70 | CiteURL is also available in a few other forms besides the command-line tool: 71 | 72 | - [citation.link](https://www.citation.link), the web app 73 | - [a flexible Python library](https://raindrum.github.io/citeurl/library) 74 | - [an extension](https://raindrum.github.io/citeurl/frontends#markdown-extension) to [Python-Markdown](https://python-markdown.github.io/) 75 | - [a desktop search provider](https://extensions.gnome.org/extension/4225/gnome-citeurl-search-provider/) for Linux users with the GNOME shell 76 | 77 | ## Credits 78 | 79 | Many thanks to these websites, which CiteURL's default templates frequently link to: 80 | 81 | - Harvard's [Caselaw Access Project](https://cite.case.law/) - for most court cases 82 | - [CourtListener](https://www.courtlistener.com/) - for other court cases 83 | - Cornell's [Legal Information Institute](https://www.law.cornell.edu/) - for the U.S. Code and many federal rules 84 | - [Ballotpedia](https://ballotpedia.org) - for the vast majority of state constitutions 85 | - [LawServer.com](https://www.lawserver.com/tools/laws) - for statutes in about a dozen states and territories whose websites don't have a compatible URL scheme 86 | -------------------------------------------------------------------------------- /citeurl/__init__.py: -------------------------------------------------------------------------------- 1 | from .citation import Citation 2 | from .citator import Citator, Template, cite, list_cites, insert_links 3 | from .authority import Authority, list_authorities 4 | from .tokens import TokenType, TokenOperation, StringBuilder 5 | -------------------------------------------------------------------------------- /citeurl/authority.py: -------------------------------------------------------------------------------- 1 | import re 2 | from typing import Union 3 | from functools import cached_property 4 | from copy import copy 5 | 6 | from .citation import Citation 7 | 8 | class Authority: 9 | def __init__( 10 | self, 11 | model_cite: Union[Citation, str], 12 | ignored_tokens = [ 13 | 'subsection', 14 | 'subdivision', 15 | 'clause', 16 | 'pincite', 17 | 'paragraph', 18 | ], 19 | ): 20 | self.template = model_cite.template 21 | self.ignored_tokens = ignored_tokens 22 | self.tokens = {} 23 | for key, value in model_cite.tokens.items(): 24 | if key in ignored_tokens: 25 | break 26 | else: 27 | self.tokens[key] = value 28 | self.citations = [model_cite] 29 | 30 | def __str__(self): 31 | return self.name 32 | 33 | def __repr__(self): 34 | return ( 35 | f'{self.name} ({len(self.citations)} ' 36 | f'cite{"s" if len(self.citations) > 1 else ""})' 37 | ) 38 | 39 | def __contains__(self, cite: Citation): 40 | """ 41 | Whether the citation is a reference to this authority, i.e. 42 | """ 43 | if cite.template.name != self.template.name: 44 | return False 45 | for key, value in self.tokens.items(): 46 | counterpart_value = cite.tokens.get(key) 47 | if counterpart_value == value: 48 | continue 49 | elif ( 50 | self.template.tokens[key].severable 51 | and type(counterpart_value) is str 52 | and counterpart_value.startswith(value) 53 | ): 54 | continue 55 | return False 56 | return True 57 | 58 | @cached_property 59 | def name(self): 60 | # build a name the proper way if a name_builder is defined 61 | if self.template.name_builder: 62 | return self.template.name_builder(self.tokens) 63 | 64 | # otherwise use horrible regex magic to reverse-engineer a name. 65 | # first find a longform citation to use as a starting point 66 | base_cite = self.citations[0] 67 | while base_cite.parent: 68 | base_cite = base_cite.parent 69 | 70 | # next construct a regex pattern to pull out the relevant 71 | # tokens, along with the non-token text preceding each one. 72 | # the non-token "prelude" text lets us replace the text of each 73 | # token only when it appears in the proper context 74 | pattern = '' 75 | for token in self.tokens: 76 | regex = re.escape(base_cite.tokens[token]) 77 | segment = f"""((?P<{token}_prelude>.*?)(?P<{token}>{regex}))?""" 78 | if pattern: 79 | pattern = pattern[:-2] + segment + ')?' 80 | else: 81 | pattern = segment 82 | 83 | match = re.match(pattern, base_cite.text) 84 | 85 | # slice off all the text after the last relevant token. This is 86 | # to remove thingsl like subsections, etc. It assumes that all 87 | # the optional tokens (subsection, pincite, etc) appear *after* 88 | # all the mandatory ones. 89 | base_cite_text = base_cite.text[:match.span(token)[1]] 90 | 91 | # for each token, replace the value from the longform citation 92 | # with the corresponding value for *this* authority 93 | for token in self.tokens: 94 | if not match.group(token): 95 | continue 96 | prelude = str(match.group(f'{token}_prelude')) 97 | old_value = prelude + match.group(token) 98 | new_value = prelude + self.tokens[token] 99 | base_cite_text = base_cite_text.replace(old_value, new_value) 100 | return base_cite_text 101 | 102 | @cached_property 103 | def URL(self): 104 | if self.template.URL_builder: 105 | url = self.template.URL_builder(self.tokens) 106 | if url: 107 | url = url.replace(' ', '%20') 108 | else: 109 | url = None 110 | return url 111 | 112 | 113 | def list_authorities( 114 | cites: list[Citation], 115 | ignored_tokens = ['subsection', 'clause', 'pincite', 'paragraph'], 116 | known_authorities: list[Authority] = [], 117 | sort_by_cites: bool = True, 118 | ) -> list[Authority]: 119 | """ 120 | Get a list of all the authorities that appear in the given list of 121 | citations. An authority represents a distinct section of law or 122 | court case. Two citations to the same authority can have different 123 | tokens, as long as those tokens are in the list of ignored_tokens. 124 | """ 125 | authorities = copy(known_authorities) or [] 126 | for cite in cites: 127 | for authority in authorities: 128 | if cite in authority: 129 | authority.citations.append(cite) 130 | break 131 | else: 132 | authorities.append(Authority(cite, ignored_tokens)) 133 | if sort_by_cites: 134 | authorities.sort(key=lambda x: -len(x.citations)) 135 | return authorities 136 | -------------------------------------------------------------------------------- /citeurl/citation.py: -------------------------------------------------------------------------------- 1 | # python standard imports 2 | from typing import Iterable 3 | import re 4 | 5 | # internal imports 6 | from .regex_mods import process_pattern, match_regexes 7 | 8 | BASIC_ID_REGEX = re.compile(r'(? str: 132 | if self.template.URL_builder: 133 | url = self.template.URL_builder(self.tokens) 134 | if url: 135 | url = url.replace(' ', '%20') 136 | else: 137 | url = None 138 | return url 139 | 140 | @property 141 | def name(self) -> str: 142 | if self.template.name_builder: 143 | return self.template.name_builder(self.tokens) 144 | else: 145 | return None 146 | 147 | def get_shortform_cites(self) -> Iterable: 148 | keep_trying = True 149 | span_start = self.span[1] 150 | while keep_trying: 151 | try: 152 | match = next(match_regexes( 153 | regexes=self.shortform_regexes, 154 | text=self.source_text, 155 | span=(span_start,), 156 | )) 157 | span_start = match.span()[1] 158 | try: 159 | yield Citation( 160 | match=match, 161 | template=self.template, 162 | parent=self, 163 | ) 164 | except SyntaxError: # it's an invalid citation 165 | pass 166 | except StopIteration: 167 | keep_trying = False 168 | 169 | def get_idform_cite(self, until_index: int=None): 170 | try: 171 | match = next(match_regexes( 172 | regexes = self.idform_regexes, 173 | text = self.source_text, 174 | span = (self.span[1], until_index) 175 | )) 176 | return Citation(match=match, template=self.template, parent=self) 177 | except StopIteration: 178 | return None 179 | except SyntaxError: 180 | return None 181 | 182 | def get_next_child(self, span: tuple=None): 183 | try: 184 | match = next(match_regexes( 185 | regexes = self.shortform_regexes + self.idform_regexes, 186 | text = self.source_text, 187 | span = span if span else (self.span[1], ), 188 | )) 189 | return Citation(match=match, template=self.template, parent=self) 190 | except StopIteration: 191 | return None 192 | 193 | def __str__(self): 194 | return str(self.text) 195 | 196 | def __repr__(self): 197 | return str(self.text) 198 | return ( 199 | f'Citation(match={self.match}, template={repr(self.template)}' 200 | + (f', parent={repr(self.parent)}' if self.parent else '') 201 | ) 202 | 203 | def __contains__(self, other_cite): 204 | """ 205 | Returns True if both citations are from templates with the same 206 | name, and the only difference between their tokens is that the 207 | other one has a more specific (i.e. higher-indexed) token than 208 | any of this one's. Severable tokens are considered a match if 209 | the other token's value *starts with* this one's. 210 | """ 211 | if ( 212 | other_cite.template.name != self.template.name 213 | or other_cite.tokens == self.tokens 214 | ): 215 | return False 216 | for key, value in self.tokens.items(): 217 | if value and other_cite.tokens.get(key) != value: 218 | if ( 219 | self.template.tokens[key].severable 220 | and other_cite.tokens[key] 221 | and other_cite.tokens[key].startswith(value) 222 | ): 223 | continue 224 | else: 225 | return False 226 | else: 227 | return True 228 | 229 | def __eq__(self, other_cite): 230 | """ 231 | Returns True if both citations are from templates with the same 232 | name, and they have the exact same token values. 233 | """ 234 | return ( 235 | other_cite.template.name == self.template.name 236 | and other_cite.tokens == self.tokens 237 | ) 238 | 239 | def __len__(self): 240 | return len(self.text) 241 | 242 | -------------------------------------------------------------------------------- /citeurl/mdx.py: -------------------------------------------------------------------------------- 1 | """ 2 | A Python-Markdown extension to detect citations and insert them into 3 | the processed text as hyperlinks. 4 | """ 5 | 6 | # python standard imports 7 | import re 8 | import xml.etree.ElementTree as etree 9 | from pathlib import Path 10 | 11 | # markdown imports 12 | from markdown.extensions import Extension 13 | from markdown.postprocessors import Postprocessor 14 | 15 | # internal imports 16 | from . import Citator, insert_links 17 | from .citator import _get_default_citator 18 | 19 | # store citator in a global variable so it isn't remade each document 20 | CITATOR: Citator = None 21 | 22 | class CitationPostprocessor(Postprocessor): 23 | def __init__( 24 | self, 25 | citator, 26 | attributes: dict, 27 | redundant_links: bool, 28 | URL_optional: bool, 29 | break_id_on_regex: str, 30 | ignore_markup: bool, 31 | ): 32 | super().__init__() 33 | self.citator = citator 34 | self.attributes = attributes 35 | self.redundant_links = redundant_links 36 | self.URL_optional = URL_optional 37 | self.ignore_markup = ignore_markup, 38 | 39 | if break_id_on_regex: 40 | self.id_breaks = re.compile(break_id_on_regex) 41 | else: 42 | self.id_breaks = None 43 | 44 | def run(self, text): 45 | return insert_links( 46 | text = text, 47 | attrs = self.attributes, 48 | redundant_links = self.redundant_links, 49 | URL_optional = self.URL_optional, 50 | id_breaks = self.id_breaks, 51 | ignore_markup = self.ignore_markup, 52 | citator = self.citator, 53 | ) 54 | 55 | class CiteURLExtension(Extension): 56 | """Detects legal citations and inserts relevant hyperlinks.""" 57 | def __init__(self, **kwargs): 58 | self.config = { 59 | 'custom_templates': [ 60 | [], 61 | 'List of paths to YAML files containing additional citation' 62 | + 'templates to load. - Default: []', 63 | ], 64 | 'use_defaults': [ 65 | True, 66 | "Load CiteURL's default citation templates? - Default: True" 67 | ], 68 | 'redundant_links': [ 69 | False, 70 | ( 71 | "Whether to insert links links whose URLs are identical " 72 | "to the previous URL" 73 | ) 74 | ], 75 | 'URL_optional': [ 76 | False, 77 | ( 78 | "Whether to add elements for citations that have " 79 | "no URL" 80 | ) 81 | ], 82 | 'break_id_on_regex': [ 83 | None, 84 | "Anywhere this string (parsed as regex) appears in the text, " 85 | + "chains of citations like 'id.' will be interrupted. Note " 86 | + "that this is based on the output HTML, *not* the original " 87 | + f"Markdown text." 88 | ], 89 | 'attributes': [ 90 | {'class': 'citation'}, 91 | ("A dictionary of attributes (besides href) that the inserted" 92 | + " links should have. - Default: '{'class': 'citation'}'") 93 | ], 94 | 'ignore_markup': [ 95 | True, 96 | ( 97 | "Whether to detect citations even when they are " 98 | 'interrupted by inline markup, like "Id. at 32. ' 99 | 'Default: True' 100 | ) 101 | ], 102 | } 103 | super(CiteURLExtension, self).__init__(**kwargs) 104 | 105 | def extendMarkdown(self, md): 106 | global CITATOR 107 | if not CITATOR: 108 | if self.config['use_defaults'][0]: 109 | CITATOR = _get_default_citator() 110 | else: 111 | CITATOR = Citator(defaults=None) 112 | for path in self.config['custom_templates'][0] or []: 113 | CITATOR.load_yaml(Path(path).read_text()) 114 | 115 | md.postprocessors.register( 116 | CitationPostprocessor( 117 | CITATOR, 118 | self.config['attributes'][0], 119 | self.config['redundant_links'][0], 120 | self.config['URL_optional'][0], 121 | self.config['break_id_on_regex'][0], 122 | self.config['ignore_markup'][0], 123 | ), 124 | "CiteURL", 125 | 1 126 | ) 127 | 128 | def makeExtension(**kwargs): 129 | return CiteURLExtension(**kwargs) 130 | -------------------------------------------------------------------------------- /citeurl/regex_mods.py: -------------------------------------------------------------------------------- 1 | # python standard imports 2 | from typing import Iterable 3 | import re 4 | 5 | def process_pattern( 6 | pattern: str, 7 | replacements: dict[str, str], 8 | token_prefix: str = None, 9 | add_word_breaks: bool = False, 10 | ): 11 | """ 12 | For a given regex pattern, find all the places that a key in the 13 | replacements dict appears, enclosed in curly braces. Replace each 14 | one with the corresponding value, enclosed in parentheses. 15 | 16 | If token_prefix is provided, it will only replace placeholders that 17 | start with that prefix, e.g. the 'same' in "{same volume}" or 18 | "{same reporter}". 19 | 20 | If add_word_breaks is True, a mandatory word break will be added at 21 | the beginning and end of the pattern. 22 | """ 23 | for key, value in replacements.items(): 24 | if not value: 25 | continue 26 | if token_prefix: 27 | marker = '{%s %s}' % (token_prefix, key) 28 | else: 29 | marker = '{%s}' % key 30 | if not (value.startswith('(') and value.endswith(')')): 31 | value = f'({value})' 32 | value = fr'{value}(?=\W|$)' 33 | pattern = pattern.replace(marker, value) 34 | if add_word_breaks: 35 | pattern = rf'(? Iterable: 40 | """ 41 | For a given text and set of regex Pattern objects, generate each 42 | non-overlapping match found for any regex. Regexes earlier in 43 | the list take priority over later ones, such that a span of text 44 | that matches the first regex cannot also match the second. 45 | """ 46 | start = span[0] 47 | if len(span) > 1: 48 | end = span[1] 49 | else: 50 | end = None 51 | 52 | keep_trying = True 53 | while keep_trying: 54 | span = (start, end) if end else (start,) 55 | matches = [] 56 | for regex in regexes: 57 | match = regex.search(text, *span) 58 | if match: 59 | matches.append(match) 60 | if matches: 61 | matches.sort(key=lambda x: (x.span()[0], -len(x.group()))) 62 | start = matches[0].span()[1] 63 | yield matches[0] 64 | else: 65 | keep_trying = False 66 | -------------------------------------------------------------------------------- /citeurl/templates/general federal law.yaml: -------------------------------------------------------------------------------- 1 | U.S. Constitution: 2 | meta: 3 | name regex: (United States|U\.? ?S\.?) ?Const(itution|\.?) 4 | tokens: 5 | article: 6 | regex: &cardinals_to_20 '\d|[ivIV]{1,3}|[Oo]ne|[Tt](woo|hree|welve|hirteen)|[Ff](our(teen)?|ive|ifteen)|[Ss](ix(teen)?|even(teen)?)|[Ee]ight(een)?|[Nn]ine(teen)?|[Tt]en|[Ee]leven' 7 | edits: [number style: digit] 8 | section: 9 | regex: \d+|[IVXivx]+ 10 | edits: [number style: digit] 11 | clause: {regex: '\d+'} 12 | patterns: 13 | - - '{name regex},? ' 14 | - &art_sec_cl '[Aa]rt(icle|\.?) ?{article}(,? ([Ss]ec(tions?|t?s?\.?)|§§?) ?{section}(,? [Cc]l(ause|\.?) ?{clause})?)?' 15 | - [*art_sec_cl, ' [Oo]f [Tt]he {name regex}'] 16 | shortform patterns: 17 | - [&standalone_art_sec_cl '[Aa]rt(icle|\.?) ?{article}(?! of )(,? ([Ss]ec(tions?|t?s?\.?)|§§?) ?{section}(?! of )(,? [Cc]l(ause|\.?) ?{clause}(?! of ))?)?'] 18 | idform patterns: &sec_cl_idforms 19 | - '([Ii]d\. (at )?)?([Ss]ec(tions?|t?s?\.?)|§§?) ?{section},? [Cc]l(ause|\.?) ?{clause}?(?! of )' 20 | - '([Ii]d\. (at )?)?[Cc]l(ause|\.?) ?{clause}(?! of )' 21 | #broad patterns: 22 | # - ['^', *standalone_art_sec_cl] 23 | name builder: 24 | parts: 25 | - 'Article {article}' 26 | - ', Section {section}' 27 | - ', Clause. {clause}' 28 | - ' of the U.S. Constitution' 29 | edits: 30 | - token: article 31 | number style: roman 32 | URL builder: 33 | parts: 34 | - https://constitution.congress.gov/browse/ 35 | - article-{article} 36 | - '#{article_roman}_S{section}' 37 | - _C{clause} 38 | edits: 39 | - token: article 40 | number style: roman 41 | output: article_roman 42 | 43 | 44 | U.S. Constitution Amendments: 45 | meta: 46 | name regex: (United States|U\.? ?S\.?) ?Const(itution|\.?) 47 | tokens: 48 | amendment: 49 | regex: &ordinals_to_20 '\d{1,2}(st|nd|rd|th)?|[xivXIV]+|([Tt]wenty(-| )?)?([Ff]irst|[Ss]econd|[Tt]hird|[Ff]ourth|[Ff]ifth|[Ss]ixth|[Ss]eventh|[Ee]ighth|[Nn]inth)|[Tt]enth|[Ee]leventh|[Tt]welfth|([Tt]hir|[Ff]our|[Ff]if|[Ss]ix|[Ss]even|[Ee]igh|[Nn]ine)teenth|[Tt]wentieth' 50 | edits: [number style: digit] 51 | section: 52 | regex: \d{1,2}|[ivxIVX]{1,5} 53 | edits: [number style: digit] 54 | clause: {regex: '\d+'} 55 | patterns: 56 | - - '{name regex},? ' 57 | - &amdt_sec_cl '[Aa]m(end(ment|\.)|dt?\.?) ?{amendment}(,? ([Ss]ec(tions?|s?\.?)|§§?) ?{section}(,? [Cc]l(ause|\.?) ?{clause})?)?' 58 | - - &sec_cl_of_the_amdt '(([Ss]ec(tions?|t?s?\.?)|§§?) ?{section}(,? [Cc]l(ause|\.?) ?{clause})? of )?([Tt]he )?{amendment} [Aa]mendment' 59 | - ' ([Oo]f|[Tt]o) the {name regex}' 60 | broad patterns: 61 | - &bare_amdt_sec_cl [*amdt_sec_cl, '(?! of)'] 62 | - [*sec_cl_of_the_amdt, '(?! to)'] 63 | shortform patterns: 64 | - *bare_amdt_sec_cl 65 | idform patterns: *sec_cl_idforms 66 | name builder: 67 | parts: 68 | - 'Section {section}' 69 | - ', Clause {clause} of ' 70 | - 'The {amendment} Amendment to the U.S. Constitution' 71 | edits: 72 | - token: section 73 | lookup: {'.+': ''} 74 | output: has_section 75 | - token: amendment 76 | number style: ordinal 77 | - token: amendment 78 | case: title 79 | URL builder: 80 | parts: 81 | - https://constitution.congress.gov/browse/ 82 | - amendment-{amendment}/ 83 | - '#{amendment}_S{section}' 84 | - _C{clause} 85 | edits: 86 | - token: article 87 | number style: roman 88 | output: article_roman 89 | 90 | 91 | U.S. Code: 92 | meta: {name regex: 'U\. ?S\. ?C(ode|\.)( ?A(nn(otated|\.)|\.)| ?S(erv(ice|\.)|\.?))?|USC[AS]?|United States Code'} 93 | tokens: &title_sec_subsec_tokens 94 | title: {regex: \d+} 95 | section: {regex: '\d[\w.-]*\w|\d'} 96 | subsection: &subsec_token 97 | regex: '(\(([A-Za-z]{1,5}|\d{1,3})\))+' 98 | severable: yes 99 | patterns: &title_sec_subsec_patterns 100 | - - &title ([Tt]itle )?{title} 101 | - ',? {name regex}(,? )?(' 102 | - §ion_sign ((§|§|§){1,2}|[Ss]ec(tions?|t?s?\.)) 103 | - ')? ?{section}' 104 | - &subsec '(((,? )?sub(sections?|divisions?|(sec|d(iv)?)?s?\.))? ?{subsection})?' 105 | - ['[Tt]itle {title},? (', *section_sign, ')? ?{section}', *subsec, ' of the {name regex}'] 106 | - ['(', *section_sign, ')? ?{section}', *subsec, ' of [Tt]itle {title} of the {name regex}'] 107 | idform patterns: &id_sec_subsec 108 | - '[Ii]d\.,?( at)?( §§?)? ?{section}( ?{subsection})?' 109 | - '((§|§|§){1,2}|[Ss]ec(tions?|t?s?\.)) {section}( ?{subsection})?(?! of)' 110 | - '[Ii]d\.,? at {subsection}' 111 | shortform pattern: [*section_sign, '{same section}(?! of )', *subsec, '(?! of )'] 112 | name builder: 113 | parts: 114 | - '{title} U.S.C. § {section}' 115 | - '{subsection}' 116 | URL builder: 117 | parts: 118 | - https://www.law.cornell.edu/uscode/text/{title}/{section} 119 | - '#{subsection}' 120 | edits: 121 | - token: subsection 122 | sub: ['\)\(', '_'] 123 | - token: subsection 124 | sub: ['[()]', ''] 125 | 126 | 127 | U.S. Public Laws: 128 | tokens: 129 | congress: {regex: \d+} 130 | law: {regex: \d+} 131 | pattern: Pub(\.?|lic) ?L(\.?|aw) ?(No\.?)? ?{congress}[–‑-]{law} 132 | name builder: 133 | parts: ['Public Law No. {congress}–{law}'] 134 | URL builder: 135 | parts: ['https://uscode.house.gov/statutes/pl/{congress}/{law}.pdf'] 136 | 137 | 138 | U.S. Statutes at Large: 139 | tokens: &vol_page_pin_tokens 140 | volume: {regex: \d+} 141 | page: 142 | regex: '\d([,\d]*\d)?' 143 | edits: [sub: [',', '']] 144 | pincite: {regex: \d+} 145 | pattern: '{volume} Stat\.? {page}(,? {pincite})?' 146 | idform pattern: '[Ii]d\.,? at {pincite}' 147 | URL builder: 148 | parts: ['https://www.govinfo.gov/content/pkg/STATUTE-{volume}/html/STATUTE-{volume}-Pg{page}.htm'] 149 | name builder: 150 | parts: ['{volume} Stat. {page}', ', {pincite}'] 151 | 152 | 153 | Federal Register: 154 | tokens: *vol_page_pin_tokens 155 | pattern: '{volume} (Fed\. ?Reg\.|F\.? ?R\.?) {page}(,? {pincite})?' 156 | idform pattern: '[Ii]d\.,? at {pincite}' 157 | URL builder: 158 | parts: ['https://www.govinfo.gov/link/fr/{volume}/{page}'] 159 | name builder: 160 | parts: ['{volume} FR {page}', ', {pincite}'] 161 | 162 | 163 | Code of Federal Regulations: 164 | inherit: U.S. Code 165 | meta: {name regex: 'C\.? ?F\.? ?R\.?|Code of Federal Regulations'} 166 | name builder: 167 | parts: 168 | - '{title} C.F.R. § {section}' 169 | - '{subsection}' 170 | URL builder: 171 | parts: 172 | - https://ecfr.federalregister.gov/cfr-reference?cfr%5Bdate%5D=current&cfr%5Breference%5D={title} CFR {section} 173 | - '#p-{section}{subsection}' 174 | 175 | 176 | Federal Rules of Civil Procedure: 177 | meta: 178 | acronym: frcp 179 | name: Fed. R. Civ. P. 180 | name regex: Civ(il|\.) ?P(rocedure|(roc?)?\.)|C\.? ?P\.? 181 | tokens: 182 | rule: 183 | regex: '\d+(\.\d+)?[a-z]?' 184 | subsection: *subsec_token 185 | patterns: 186 | - (Fed(eral|\.) ?R(ules?|\.)|F\.? ?R\.?)( of)? ?{name regex}( [Rr]ule)? {rule}( ?{subsection})? 187 | - '[Rr]ule {rule}( ?{subsection})? [Oo]f [Tt]he Fed(eral|\.) Rules of {name regex}' 188 | idform patterns: 189 | - '([Ii]d\.,? (at )?)?[Rr]ule {rule}( ?{subsection}?)?(?! of)' 190 | - '[Ii]d\.,? (at )?{subsection}' 191 | shortform pattern: ['[Rr]ule {same rule}(?! of )', *subsec, '(?! of )'] 192 | name builder: 193 | parts: ['{name} {rule}', '{subsection}'] 194 | URL builder: 195 | parts: 196 | - https://www.law.cornell.edu/rules/{acronym}/rule_{rule} 197 | - '#rule_{rule}_{subsection}' 198 | edits: 199 | - token: subsection 200 | sub: ['\)\(', '_'] 201 | - token: subsection 202 | sub: ['\W', ''] 203 | 204 | 205 | Federal Rules of Appellate Procedure: 206 | inherit: Federal Rules of Civil Procedure 207 | meta: 208 | acronym: frap 209 | name: Fed. R. App. Proc. 210 | name regex: App(ellate|\.) ?P(rocedure|(roc?)?\.)|A\.? ?P\.? 211 | 212 | 213 | Federal Rules of Criminal Procedure: 214 | inherit: Federal Rules of Civil Procedure 215 | meta: 216 | acronym: frcrmp 217 | name: Fed. R. Crim. Proc. 218 | name regex: Crim(inal|\.) ?P(rocedure|(roc?)?\.)|Cr\.? ?P\.? 219 | 220 | 221 | Federal Rules of Evidence: 222 | inherit: Federal Rules of Civil Procedure 223 | meta: 224 | acronym: fre 225 | name: Fed. R. Evid. 226 | name regex: Evid(ence|\.)|E\.? 227 | -------------------------------------------------------------------------------- /citeurl/templates/secondary sources.yaml: -------------------------------------------------------------------------------- 1 | Model Penal Code: 2 | meta: 3 | name: Model Penal Code 4 | name regex: 'M\.? ?P\.? ?C\.?|Model Pen(al|\.) Code' 5 | tokens: &art_sec_subsec_tokens 6 | article: {regex: \d+} 7 | section: {regex: \d+} 8 | subsection: 9 | regex: '(\(\w{1,4}\))+' 10 | severable: yes 11 | pattern: '{name regex} § {article}\.{section}( ?{subsection})?' 12 | name builder: 13 | parts: ['{name} § {article}.{section}', '{subsection}'] 14 | 15 | 16 | Revised Model Business Corporation Act: 17 | inherit: Model Penal Code 18 | meta: 19 | name: Revised Model Business Corporation Act 20 | name regex: Rev(ised|\.) ?Model Bus(iness|\.) ?Corp(orations?|s?\.) Act|R\.M\.B\.C\.A|RMBCA 21 | 22 | 23 | Uniform Commercial Code: 24 | tokens: *art_sec_subsec_tokens 25 | pattern: '(U\.? ?C\.? ?C\.?|Uniform Com(mercial|m?\.) Code) (§§? ?)?{article}[–‑-]{section}( ?{subsection})?' 26 | name builder: 27 | parts: ['UCC § {article}-{section}', '{subsection}'] 28 | URL builder: 29 | parts: 30 | - https://www.law.cornell.edu/ucc/{article}/{article}-{section} 31 | - '#{article}-{section}{subsection}' 32 | edits: # only use the first part of the subsection 33 | - token: subsection 34 | sub: ['\).+', ')'] 35 | -------------------------------------------------------------------------------- /citeurl/web/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raindrum/citeurl/a929a29d7b72b5bf376d90f48759a5496ecaf799/citeurl/web/__init__.py -------------------------------------------------------------------------------- /citeurl/web/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 23 | 27 | 31 | 32 | 38 | 44 | 50 | 59 | 60 | 84 | 86 | 87 | 89 | image/svg+xml 90 | 92 | 93 | 94 | 95 | 96 | 99 | 103 | 111 | 120 | 129 | 138 | 139 | 145 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /citeurl/web/makejs.py: -------------------------------------------------------------------------------- 1 | # python standard imports 2 | from argparse import ArgumentParser 3 | from json import dumps 4 | from pathlib import Path 5 | from re import sub 6 | 7 | # internal imports 8 | from .. import Citator 9 | from .resources import unify_regex, format_page, sources_table 10 | from .resources import VERSION 11 | 12 | COPYRIGHT_MESSAGE = f""" 13 | // This script was made with CiteURL {VERSION}, an extensible framework 14 | // to turn legal references into URLs. 15 | // 16 | // The "templates" variable below holds the data necessary to 17 | // turn each kind of citation into a URL. Some or all of the templates may 18 | // have been made by a third party and are not part of CiteURL itself. 19 | // 20 | // CiteURL is copyright of Simon Raindrum Sherred under the MIT License. 21 | // See https://raindrum.github.io/citeurl for more info. 22 | """ 23 | 24 | _dir = Path(__file__).parent.absolute() 25 | BASE_JS_PATH = _dir / 'citeurl.js' 26 | 27 | PAGE = """ 28 |
29 |

Paste a legal citation here, and you can 30 | go somewhere else on the Web to read what it refereneces:

31 |
32 | 36 |

37 | 38 |

39 |
40 |
41 | {sources_table} 42 | """ 43 | 44 | # these functions either uncomment or remove a commented-out code block 45 | # that looks like this: 46 | # /*blockname 47 | # 48 | # */ 49 | def _uncomment(blockname: str, source_js: str): 50 | return sub(fr' */\*{blockname}\n([^©]+?) *\*/\n', r'\1', source_js) 51 | def _remove(blockname: str, source_js: str): 52 | return sub(fr' */\*{blockname}\n[^©]+? *\*/\n', '', source_js) 53 | 54 | def makejs( 55 | citator: Citator, 56 | entire_page: bool = False, 57 | include_sources_table: bool = False, 58 | ) -> str: 59 | """ 60 | Generate a JavaScript implementation of a given citator's lookup 61 | features, so that it can be embedded in a website. Optionally 62 | package it as a standalone web page for end users. 63 | 64 | Arguments: 65 | citator: a CiteURL citator object, with any number of templates 66 | loaded. 67 | entire_page: whether to output an HTML page with a searchbar 68 | and styling 69 | include_sources_table: whether to provide a table listing each 70 | template that the page supports. Implies entire_page = True. 71 | Returns: 72 | a string containing JavaScript or HTML 73 | """ 74 | if include_sources_table: 75 | entire_page = True 76 | 77 | # translate each template to json 78 | json_templates = [] 79 | for template in citator.templates.values(): 80 | if not template.URL_builder: 81 | continue 82 | 83 | json = {} 84 | 85 | # some parts of a template can be copied over easily 86 | json['name'] = template.name 87 | 88 | defaults = template.meta 89 | for name, token in template.tokens.items(): 90 | if token.default: 91 | defaults[name] = token.default 92 | if defaults: 93 | json['defaults'] = defaults 94 | 95 | json['regexes'] = [ 96 | r.pattern.replace('?P<', '?<') for r in template.broad_regexes 97 | ] 98 | 99 | # only add the relevant information from each operation 100 | 101 | json['operations'] = [] 102 | 103 | for name, token in template.tokens.items(): 104 | for edit in token.edits: 105 | edit_dict = { 106 | 'token': name, 107 | edit.action: edit.data 108 | } 109 | if 'lookup' in edit_dict and not edit.mandatory: 110 | edit_dict['optionalLookup'] = edit_dict.pop('lookup') 111 | json['operations'].append(edit_dict) 112 | 113 | for edit in template.URL_builder.edits: 114 | edit_dict = { 115 | 'token': edit.token, 116 | edit.action: edit.data 117 | } 118 | if edit.output: 119 | edit_dict['output'] = edit.output 120 | if 'lookup' in edit_dict and not edit.mandatory: 121 | edit_dict['optionalLookup'] = edit_dict.pop('lookup') 122 | json['operations'].append(edit_dict) 123 | 124 | json['URL'] = [p for p in template.URL_builder.parts] 125 | 126 | json_templates.append(json) 127 | 128 | # write json to str 129 | json_str = dumps( 130 | json_templates, 131 | indent=4, 132 | sort_keys=False, 133 | ensure_ascii=False, 134 | ) 135 | 136 | # generate javascript 137 | javascript = ( 138 | COPYRIGHT_MESSAGE 139 | + '\nconst templates = ' 140 | + json_str + ';\n\n' 141 | + BASE_JS_PATH.read_text() 142 | ) 143 | 144 | # uncomment or remove browser-only features in the JS 145 | if entire_page: 146 | javascript = _uncomment('PAGEBEHAVIOR', javascript) 147 | javascript = _uncomment('LOGS', javascript) 148 | else: 149 | javascript = _remove('LOGS', javascript) 150 | javascript = _remove('PAGEBEHAVIOR', javascript) 151 | 152 | if include_sources_table: 153 | table = ( 154 | '

This static instance of ' 155 | 'CiteURL ' 156 | 'supports the following types of citation:

' 157 | f'\n{sources_table(citator)}' 158 | ) 159 | else: 160 | table = '' 161 | 162 | # optionally embed the javascript into an HTML page 163 | if entire_page: 164 | output = format_page( 165 | PAGE, 166 | sources_table=table, 167 | inline_logo=True, 168 | inline_css=True, 169 | js=javascript, 170 | relation='Static page generated with', 171 | ) 172 | else: 173 | output = javascript 174 | 175 | return output 176 | -------------------------------------------------------------------------------- /citeurl/web/resources.py: -------------------------------------------------------------------------------- 1 | "strings and functions that are used by both server.py and makejs.py" 2 | 3 | # python standard imports 4 | from urllib.parse import quote_plus, urlsplit 5 | from importlib.metadata import version 6 | from re import sub 7 | from pathlib import Path 8 | 9 | ######################################################################## 10 | # External Files 11 | ######################################################################## 12 | 13 | _dir = Path(__file__).parent.absolute() 14 | CSS_PATH = _dir / 'style.css' 15 | LOGO_PATH = _dir / 'logo.svg' 16 | 17 | ######################################################################## 18 | # HTML Templates 19 | ######################################################################## 20 | 21 | PAGE_TEMPLATE = """ 22 | 23 | 24 | {head} 25 | 26 | 27 |
28 | {content} 29 |
30 | 33 | """ 34 | 35 | SOURCES_TABLE = """ 36 |
37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | {rows} 45 | 46 |
Source of LawWebsiteCitation Format
47 |
""" 48 | 49 | SOURCES_TABLE_ROW = """ 50 | 51 | {name} 52 | {domain_name} 53 | view regex 54 | """ 55 | 56 | VERSION = f"v{version('citeurl')}" 57 | 58 | ######################################################################## 59 | # Functions 60 | ######################################################################## 61 | 62 | def format_page( 63 | text: str, 64 | js: str='', 65 | inline_css: bool=False, 66 | inline_logo: bool=False, 67 | relation_to_citeurl: str='Powered by', 68 | **kwargs 69 | ): 70 | """ 71 | Returns PAGE_TEMPLATE with the given text inserted into the body. 72 | All placeholders (in curly braces) in the given text must be filled 73 | via keyword arguments. In addition to those mandatory keywords, you 74 | may provide any of the following: 75 | 76 | Arguments: 77 | js: JavaScript to be inserted directly into the page head 78 | inline_css: whether the CSS styling should be embedded in the 79 | instead of an outside link. Default: False 80 | inline_logo: whether the logo SVG should be embedded in the page 81 | instead of an outside link. Default: False 82 | relation_to_citeurl: a string that will be inserted into the 83 | page footer, just before the link to CiteURL and the 84 | subsequent disclaimer. Default: 'Powered by'. 85 | title: the HTML page title 86 | """ 87 | for k, v in kwargs.items(): 88 | text = text.replace('{' + k + '}', v) 89 | #text = text.format(**kwargs) 90 | if inline_logo: 91 | logo = LOGO_PATH.read_text() 92 | else: 93 | logo = 'CiteURL logo' 94 | if inline_css: 95 | css_section = f'' 96 | else: 97 | css_section = '' 98 | if not inline_logo: # add favicon to header 99 | favicon = '\n' 100 | else: 101 | favicon = '' 102 | js_section = f"" if js else '' 103 | return PAGE_TEMPLATE.format( 104 | head=favicon + css_section + '\n' + js_section, 105 | content=logo + '\n' + text, 106 | version=VERSION, 107 | relation=kwargs.get('relation') or 'Powered by', 108 | ) 109 | 110 | def sources_table(citator): 111 | """ 112 | Return the content for an HTML table listing every template that the 113 | citator can link to. 114 | """ 115 | rows = [] 116 | for template in citator.templates.values(): 117 | # skip templates that can't make URLs 118 | if not template.__dict__.get('URL_builder'): 119 | continue 120 | 121 | URL = urlsplit(''.join(template.URL_builder.parts)) 122 | domain_URL = f'{URL.scheme}://{URL.netloc}' 123 | domain_name = URL.hostname 124 | regex = unify_regex(template, simplify_for_regexper=True) 125 | 126 | rows.append(SOURCES_TABLE_ROW.format( 127 | name=template.name, 128 | domain_URL=domain_URL, 129 | domain_name=domain_name, 130 | escaped_regex=quote_plus(regex).replace('+', '%20') 131 | )) 132 | 133 | return SOURCES_TABLE.format(rows=''.join(rows)) 134 | 135 | def unify_regex(template, simplify_for_regexper: bool=False): 136 | """ 137 | Combine the given template's regexes (if there are multiple) into 138 | one long regex that matches any one of them. Wherever possible, 139 | insert any mandatory lookups from the template's operations, so that 140 | the resulting regex will be restricted to each option from the 141 | lookups. 142 | 143 | Arguments: 144 | template: the template object to get a regex for 145 | simplify_for_regexper: whether to strip lookbehinds, lookaheads, 146 | and the names of capture groups so that the resulting URL is 147 | compatible with regexper.com. Note that if this is false, 148 | duplicated capture groups will be renamed to avoid conflict. 149 | """ 150 | regexes = [p.pattern for p in template.regexes.copy()] 151 | # append numbers to repeated capture group names to prevent conflict 152 | for i, regex in enumerate(regexes[1:]): 153 | regexes[i+1] = sub(r'\?P<(.+?)>', '?P<\1' + f'{i}>', regex) 154 | regex = '|'.join(regexes) 155 | 156 | # whenever a template operation uses a token for a mandatory lookup, 157 | # and that token hasn't been modified by another operation yet, 158 | # insert the lookup's regexes where the token goes, to make the 159 | # final regex more specific. 160 | for token_name, token in template.tokens.items(): 161 | for i, edit in enumerate(token.edits): 162 | # only lookup operations are used here 163 | if edit.action is not 'lookup': 164 | continue 165 | 166 | # don't bother if the lookup's input token is modified before 167 | # the lookup 168 | already_modified = False 169 | for prior_op in token.edits[:i-1]: 170 | if prior_op != edit: 171 | already_modified = True 172 | break 173 | if already_modified: 174 | continue 175 | 176 | # modify the regex 177 | pattern = '\(\?P<' + token_name + '\d*>.+?(?', '', regex) 191 | 192 | return regex 193 | -------------------------------------------------------------------------------- /citeurl/web/server.py: -------------------------------------------------------------------------------- 1 | # python standard imports 2 | import socket 3 | from urllib.parse import unquote, urlsplit 4 | from re import sub 5 | from html import escape 6 | 7 | # internal imports 8 | from .resources import format_page, sources_table 9 | from .. import Citator, insert_links 10 | 11 | # third-party imports 12 | from flask import Flask, redirect, make_response, send_file, request 13 | # from gevent import monkey (imported in serve()) 14 | # from gevent.pywsgi import WSGIServer (imported in serve()) 15 | 16 | _APP = Flask(__name__, static_url_path='') 17 | 18 | ######################################################################## 19 | # Messages 20 | ######################################################################## 21 | 22 | INDEX_PAGE = """ 23 |
24 |

Paste a legal citation here, and you can 25 | go somewhere else on the Web to read what it refereneces:

26 | 30 |
31 | """ 32 | 33 | CITATIONS_PAGE = """ 34 |

Citations

Citations 35 |
36 |

This web app is powered by 37 | CiteURL, 38 | an open-source tool that recognizes legal citations and generates links to 39 | publicly-available websites where you can read the cited documents.

40 |

"Legal citations" here means formal references to U.S. federal and state 41 | laws and court opinions. This is not a search engine. If you enter something 42 | ambiguous, like the name of a court case, nothing will happen.

43 |

Instead, citations generally need to follow 44 | bluebook style, 45 | so that CiteURL can recognize the relevant info (volume, page number, section, 46 | etc) and turn it into a URL. But just because you know how to cite something 47 | doesn't mean it'll work. Below, you will find the kinds of citation this app 48 | can recognize, along with the websites it will send you to if it does:

49 | {table} 50 |

By the way, CiteURL can also detect multiple citations in a longer text, 51 | and insert hyperlinks for each one! Feel free to try that out 52 | here.

53 |
54 |

55 | """ 56 | 57 | PARSER_PAGE = """ 58 |

Text Parser

Text Parser 59 |

Paste some text into the box below and click "Parse" to process 60 | the text and find every supported citation 61 | it contains.

62 |
63 | 66 |

67 |

68 |
69 | {output} 70 | """ 71 | 72 | INFO_PAGE = """ 73 |

How it Works

74 | 75 | """ 76 | 77 | # Errors 78 | 79 | ERROR_400 = """ 80 |

Unknown Citation

Unknown Citation 81 |

Sorry, "{query}" isn't a citation I recognize.

82 |

83 | """ 84 | 85 | ERROR_501 = """ 86 |

Missing URL

Missing URL 87 |

Sorry, I can tell that's a {template} citation but I don't have a 88 | link for it.

89 |

90 | """ 91 | 92 | ERROR_413 = """ 93 |

Query Too Long

Query Too Long 94 |

Sorry, that's too many characters for the server to process.

95 | 96 | """ 97 | 98 | ######################################################################## 99 | # Routes 100 | ######################################################################## 101 | 102 | @_APP.route('/') 103 | def _handle_query(query: str): 104 | """ 105 | Try to interpret query as a citation and return a 301 redirect if 106 | it returns a URL. Otherwise return 501 error if it matches a 107 | citation without a URL, or 400 if no match. 108 | """ 109 | if len(query) > _APP.max_chars: 110 | return format_page(ERROR_501) 111 | 112 | query = escape(unquote(query)) 113 | cite = _APP.citator.cite(query) 114 | if cite: 115 | if cite.URL: 116 | return redirect(cite.URL, code=301) 117 | else: 118 | return make_response( 119 | format_page(ERROR_501, template=cite.template.name), 120 | 501 121 | ) 122 | else: 123 | return make_response(format_page(ERROR_400, query=query), 400) 124 | 125 | @_APP.route('/') 126 | def _index(): 127 | """ 128 | Handle query if one is provided with the 's' parameter, otherwise 129 | show the main page. 130 | """ 131 | query = request.args.get('s') 132 | if query: 133 | return _handle_query(query) 134 | else: 135 | return _APP.index_page 136 | 137 | # Pregenerated Pages 138 | 139 | @_APP.route('/citations') 140 | def _sources(): 141 | """ 142 | return a page explaining what a citation is, and 143 | listing the citator's templates in a table 144 | """ 145 | return _APP.citations_page 146 | 147 | @_APP.route('/parser', methods= ['POST', 'GET']) 148 | def _linker(): 149 | "return a page that parses user-provided text" 150 | if request.method == 'GET': 151 | return format_page(PARSER_PAGE, given_text='', output='') 152 | 153 | given_text = escape(request.form['text']) 154 | if _APP.max_chars and len(given_text) > _APP.max_chars: 155 | return format_page(ERROR_501) 156 | citations = _APP.citator.list_cites(given_text) 157 | 158 | if not citations: 159 | return format_page( 160 | PARSER_PAGE, 161 | given_text=given_text, 162 | output="

Sorry, I couldn't find any citations in that.

" 163 | ) 164 | 165 | output = insert_links( 166 | text = given_text, 167 | redundant_links = True, 168 | ignore_markup = False, 169 | citator = _APP.citator, 170 | ) 171 | output = '

' + sub(r'\n+', '

\n

', output) + '

' 172 | 173 | return format_page( 174 | PARSER_PAGE, 175 | given_text=given_text, 176 | output=( 177 | '

Output

\n' 178 | + f'
{output}
' 179 | ), 180 | ) 181 | 182 | # Static Files 183 | 184 | @_APP.route('/logo.svg') 185 | def _logo(): 186 | return send_file('logo.svg') 187 | 188 | @_APP.route('/style.css') 189 | def _css(): 190 | return send_file('style.css') 191 | 192 | ######################################################################## 193 | # Utility Functions 194 | ######################################################################## 195 | 196 | def _get_local_ip(): 197 | "get local IP address. source: https://stackoverflow.com/a/28950776" 198 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 199 | try: 200 | s.connect(('10.255.255.255', 1)) 201 | IP = s.getsockname()[0] 202 | except Exception: 203 | IP = '127.0.0.1' 204 | finally: 205 | s.close() 206 | return IP 207 | 208 | ######################################################################## 209 | # Public Functions 210 | ######################################################################## 211 | 212 | def App(citator: Citator=Citator(), name: str='CiteURL'): 213 | """ 214 | Return a flask application to implement the given citator. If called 215 | repeatedly, it will probably overwrite earlier instances. 216 | """ 217 | # store variables in the app itself 218 | _APP.name = name 219 | _APP.index_page = format_page(INDEX_PAGE, name=name) 220 | _APP.citator = citator 221 | _APP.max_chars=400000 # limit query length 222 | _APP.citations_page = format_page( 223 | CITATIONS_PAGE, 224 | table=sources_table(citator), 225 | ) 226 | return _APP 227 | 228 | def serve(app, localhost=True, port=53037): 229 | """ 230 | Use gevent to host the app as a WSGI server at the given port. If 231 | not localhost, use _get_local_ip() to find the IP address to use. 232 | """ 233 | from gevent import monkey 234 | from gevent.pywsgi import WSGIServer 235 | monkey.patch_all() 236 | 237 | if localhost: 238 | IP = 'localhost' 239 | else: 240 | IP = _get_local_ip() 241 | 242 | base_URL = f'http://{IP}:{port}' 243 | 244 | server = WSGIServer((IP, port), app) 245 | print(f'Now hosting citation lookup server at {base_URL}...') 246 | try: 247 | server.serve_forever() 248 | except KeyboardInterrupt: 249 | print("Stopped hosting citation lookup server.") 250 | -------------------------------------------------------------------------------- /citeurl/web/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --font-color: #e5e0d7; 3 | --bg-color: #222c47; /* formerly 223159 */ 4 | --box-bg-color: transparent; 5 | --emph-color: #fe0052; 6 | --font-size: 18px; 7 | --content-width: 60ch; 8 | --narrow-content-width: 48ch; 9 | --content-padding: 1ch; 10 | --box-padding: 8px; 11 | --border-radius: 10px; 12 | --outline-width: 2px; 13 | } 14 | 15 | body { 16 | background-color: var(--bg-color); 17 | color: var(--font-color); 18 | margin: 0; 19 | font-size: var(--font-size); 20 | font-family: Sans-Serif; 21 | height: calc(100vh - 4rem); 22 | text-align: center; 23 | } 24 | .content { 25 | min-height: calc(100vh - 4rem); 26 | max-width: var(--content-width); 27 | margin: auto; 28 | padding: var(--content-padding); 29 | vertical-align: middle; 30 | display: flex; 31 | flex-direction: column; 32 | justify-content: center; 33 | align-items: center; 34 | } 35 | footer { 36 | font-size: 75%; 37 | height: 2rem; 38 | } 39 | h1, h2, h3, h4, h5, h6, a, .explainer { color: var(--emph-color); } 40 | h1, h2, h3, h4, h5, h6 { margin-bottom: 0.5rem; } 41 | img + h1, svg + h1 { margin-top: 0; } 42 | .narrow { 43 | max-width: min( 44 | var(--narrow-content-width), 45 | calc(100vw - calc(2 * var(--content-padding))) 46 | ); 47 | margin: 0; 48 | padding: 0; 49 | } 50 | .left { 51 | text-align: left; 52 | } 53 | 54 | /*====================================================================== 55 | USER INPUT/OUTPUT 56 | ======================================================================*/ 57 | 58 | button { 59 | background-color: var(--emph-color); 60 | color: var(--font-color); 61 | font-size: 125%; 62 | font-weight: bold; 63 | padding: var(--box-padding); 64 | border: var(--outline-width) solid var(--emph-color); 65 | border-radius: var(--border-radius); 66 | text-align: center; 67 | cursor: pointer; 68 | } 69 | button:hover, button:focus { 70 | background-color: var(--font-color); 71 | color: var(--bg-color); 72 | border-color: var(--font-color); 73 | } 74 | input, textarea, .output-box { 75 | background-color: var(--box-bg-color); 76 | color: var(--font-color); 77 | text-align: left; 78 | border: var(--outline-width) solid var(--emph-color); 79 | border-radius: var(--border-radius); 80 | padding: var(--box-padding); 81 | resize: none; 82 | } 83 | .output-box { 84 | width: 100%; 85 | margin-top: 0.25em; 86 | margin-bottom: 0.25em; 87 | } 88 | textarea, form { width: 100% !important; } 89 | textarea { 90 | scrollbar-width: none; 91 | -ms-overflow-style: none; 92 | } 93 | textarea::-webkit-scrollbar { display: none; } 94 | input:focus, textarea:focus, .output-box { 95 | outline: none; 96 | border-color: var(--font-color); 97 | } 98 | .searchbar { 99 | display: flex; 100 | flex-wrap: nowrap; 101 | box-sizing: border-box; 102 | max-width: 100% !important; 103 | overflow: hidden; 104 | } 105 | .searchbar * { 106 | padding: var(--box-padding); 107 | flex-basis: 0; 108 | } 109 | .searchbar button { 110 | border-radius: 0 var(--border-radius) var(--border-radius) 0; 111 | } 112 | .searchbar input { 113 | font-size: 125%; 114 | min-width: 0; 115 | flex-grow: 1; 116 | border-radius: var(--border-radius) 0 0 var(--border-radius); 117 | } 118 | 119 | /*====================================================================== 120 | TABLES 121 | ======================================================================*/ 122 | .table-wrapper { 123 | overflow-x: auto; 124 | width: 100%; 125 | } 126 | table { 127 | min-width: 100%; 128 | table-layout: fixed; 129 | overflow-x: auto; 130 | border-collapse: separate; 131 | border-spacing: 0; 132 | } 133 | th, td { overflow: auto; } 134 | td { 135 | border: solid calc(var(--outline-width) / 2) var(--font-color); 136 | padding: var(--box-padding); 137 | background-color: var(--box-bg-color); 138 | } 139 | td:first-child { border-left-width: var(--outline-width); } 140 | td:last-child { border-right-width: var(--outline-width); } 141 | tr:first-child td { border-top-width: var(--outline-width); } 142 | tr:last-child td { border-bottom-width: var(--outline-width); } 143 | tr:first-child td:first-child { 144 | border-top-left-radius: var(--border-radius); 145 | -webkit-border-top-left-radius: var(--border-radius); 146 | -moz-border-radius-topleft: var(--border-radius); 147 | } 148 | tr:first-child td:last-child { 149 | border-top-right-radius: var(--border-radius); 150 | -webkit-border-top-right-radius: var(--border-radius); 151 | -moz-border-radius-topright: var(--border-radius); 152 | } 153 | tr:last-child td:first-child { 154 | border-bottom-left-radius: var(--border-radius); 155 | -webkit-border-bottom-left-radius: var(--border-radius); 156 | -moz-border-radius-bottomleft: var(--border-radius); 157 | } 158 | tr:last-child td:last-child { 159 | border-bottom-right-radius: var(--border-radius); 160 | -webkit-border-bottom-right-radius: var(--border-radius); 161 | -moz-border-radius-bottomright: var(--border-radius); 162 | } 163 | -------------------------------------------------------------------------------- /docs/assets/_mkdocstrings.css: -------------------------------------------------------------------------------- 1 | 2 | /* Avoid breaking parameter names, etc. in table cells. */ 3 | .doc-contents td code { 4 | word-break: normal !important; 5 | } 6 | 7 | /* No line break before first paragraph of descriptions. */ 8 | .doc-md-description, 9 | .doc-md-description>p:first-child { 10 | display: inline; 11 | } 12 | 13 | /* Max width for docstring sections tables. */ 14 | .doc .md-typeset__table, 15 | .doc .md-typeset__table table { 16 | display: table !important; 17 | width: 100%; 18 | } 19 | 20 | .doc .md-typeset__table tr { 21 | display: table-row; 22 | } 23 | 24 | /* Defaults in Spacy table style. */ 25 | .doc-param-default { 26 | float: right; 27 | } 28 | 29 | /* Backward-compatibility: docstring section titles in bold. */ 30 | .doc-section-title { 31 | font-weight: bold; 32 | } 33 | 34 | /* Symbols in Navigation and ToC. */ 35 | :root, 36 | [data-md-color-scheme="default"] { 37 | --doc-symbol-attribute-fg-color: #953800; 38 | --doc-symbol-function-fg-color: #8250df; 39 | --doc-symbol-method-fg-color: #8250df; 40 | --doc-symbol-class-fg-color: #0550ae; 41 | --doc-symbol-module-fg-color: #5cad0f; 42 | 43 | --doc-symbol-attribute-bg-color: #9538001a; 44 | --doc-symbol-function-bg-color: #8250df1a; 45 | --doc-symbol-method-bg-color: #8250df1a; 46 | --doc-symbol-class-bg-color: #0550ae1a; 47 | --doc-symbol-module-bg-color: #5cad0f1a; 48 | } 49 | 50 | [data-md-color-scheme="slate"] { 51 | --doc-symbol-attribute-fg-color: #ffa657; 52 | --doc-symbol-function-fg-color: #d2a8ff; 53 | --doc-symbol-method-fg-color: #d2a8ff; 54 | --doc-symbol-class-fg-color: #79c0ff; 55 | --doc-symbol-module-fg-color: #baff79; 56 | 57 | --doc-symbol-attribute-bg-color: #ffa6571a; 58 | --doc-symbol-function-bg-color: #d2a8ff1a; 59 | --doc-symbol-method-bg-color: #d2a8ff1a; 60 | --doc-symbol-class-bg-color: #79c0ff1a; 61 | --doc-symbol-module-bg-color: #baff791a; 62 | } 63 | 64 | code.doc-symbol { 65 | border-radius: .1rem; 66 | font-size: .85em; 67 | padding: 0 .3em; 68 | font-weight: bold; 69 | } 70 | 71 | code.doc-symbol-attribute { 72 | color: var(--doc-symbol-attribute-fg-color); 73 | background-color: var(--doc-symbol-attribute-bg-color); 74 | } 75 | 76 | code.doc-symbol-attribute::after { 77 | content: "attr"; 78 | } 79 | 80 | code.doc-symbol-function { 81 | color: var(--doc-symbol-function-fg-color); 82 | background-color: var(--doc-symbol-function-bg-color); 83 | } 84 | 85 | code.doc-symbol-function::after { 86 | content: "func"; 87 | } 88 | 89 | code.doc-symbol-method { 90 | color: var(--doc-symbol-method-fg-color); 91 | background-color: var(--doc-symbol-method-bg-color); 92 | } 93 | 94 | code.doc-symbol-method::after { 95 | content: "meth"; 96 | } 97 | 98 | code.doc-symbol-class { 99 | color: var(--doc-symbol-class-fg-color); 100 | background-color: var(--doc-symbol-class-bg-color); 101 | } 102 | 103 | code.doc-symbol-class::after { 104 | content: "class"; 105 | } 106 | 107 | code.doc-symbol-module { 108 | color: var(--doc-symbol-module-fg-color); 109 | background-color: var(--doc-symbol-module-bg-color); 110 | } 111 | 112 | code.doc-symbol-module::after { 113 | content: "mod"; 114 | } 115 | 116 | .doc-signature .autorefs { 117 | color: inherit; 118 | border-bottom: 1px dotted currentcolor; 119 | } 120 | -------------------------------------------------------------------------------- /docs/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raindrum/citeurl/a929a29d7b72b5bf376d90f48759a5496ecaf799/docs/assets/favicon.png -------------------------------------------------------------------------------- /docs/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raindrum/citeurl/a929a29d7b72b5bf376d90f48759a5496ecaf799/docs/assets/images/favicon.png -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.da.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `Danish` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){var e,r=f.cursor+3;if(d=f.limit,0<=r&&r<=f.limit){for(a=r;;){if(e=f.cursor,f.in_grouping(w,97,248)){f.cursor=e;break}if(f.cursor=e,e>=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.de.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `German` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!v.eq_s(1,e)||(v.ket=v.cursor,!v.in_grouping(p,97,252)))&&(v.slice_from(r),v.cursor=n,!0)}function i(){for(var r,n,i,s,t=v.cursor;;)if(r=v.cursor,v.bra=r,v.eq_s(1,"ß"))v.ket=v.cursor,v.slice_from("ss");else{if(r>=v.limit)break;v.cursor=r+1}for(v.cursor=t;;)for(n=v.cursor;;){if(i=v.cursor,v.in_grouping(p,97,252)){if(s=v.cursor,v.bra=s,e("u","U",i))break;if(v.cursor=s,e("y","Y",i))break}if(i>=v.limit)return void(v.cursor=n);v.cursor=i+1}}function s(){for(;!v.in_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}for(;!v.out_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}return!1}function t(){m=v.limit,l=m;var e=v.cursor+3;0<=e&&e<=v.limit&&(d=e,s()||(m=v.cursor,m=v.limit)return;v.cursor++}}}function c(){return m<=v.cursor}function u(){return l<=v.cursor}function a(){var e,r,n,i,s=v.limit-v.cursor;if(v.ket=v.cursor,(e=v.find_among_b(w,7))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:v.slice_del(),v.ket=v.cursor,v.eq_s_b(1,"s")&&(v.bra=v.cursor,v.eq_s_b(3,"nis")&&v.slice_del());break;case 3:v.in_grouping_b(g,98,116)&&v.slice_del()}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(f,4))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:if(v.in_grouping_b(k,98,116)){var t=v.cursor-3;v.limit_backward<=t&&t<=v.limit&&(v.cursor=t,v.slice_del())}}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(_,8))&&(v.bra=v.cursor,u()))switch(e){case 1:v.slice_del(),v.ket=v.cursor,v.eq_s_b(2,"ig")&&(v.bra=v.cursor,r=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-r,u()&&v.slice_del()));break;case 2:n=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-n,v.slice_del());break;case 3:if(v.slice_del(),v.ket=v.cursor,i=v.limit-v.cursor,!v.eq_s_b(2,"er")&&(v.cursor=v.limit-i,!v.eq_s_b(2,"en")))break;v.bra=v.cursor,c()&&v.slice_del();break;case 4:v.slice_del(),v.ket=v.cursor,e=v.find_among_b(b,2),e&&(v.bra=v.cursor,u()&&1==e&&v.slice_del())}}var d,l,m,h=[new r("",-1,6),new r("U",0,2),new r("Y",0,1),new r("ä",0,3),new r("ö",0,4),new r("ü",0,5)],w=[new r("e",-1,2),new r("em",-1,1),new r("en",-1,2),new r("ern",-1,1),new r("er",-1,1),new r("s",-1,3),new r("es",5,2)],f=[new r("en",-1,1),new r("er",-1,1),new r("st",-1,2),new r("est",2,1)],b=[new r("ig",-1,1),new r("lich",-1,1)],_=[new r("end",-1,1),new r("ig",-1,2),new r("ung",-1,1),new r("lich",-1,3),new r("isch",-1,2),new r("ik",-1,2),new r("heit",-1,3),new r("keit",-1,4)],p=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],g=[117,30,5],k=[117,30,4],v=new n;this.setCurrent=function(e){v.setCurrent(e)},this.getCurrent=function(){return v.getCurrent()},this.stem=function(){var e=v.cursor;return i(),v.cursor=e,t(),v.limit_backward=e,v.cursor=v.limit,a(),v.cursor=v.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.du.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `Dutch` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");console.warn('[Lunr Languages] Please use the "nl" instead of the "du". The "nl" code is the standard code for Dutch language, and "du" will be removed in the next major versions.'),e.du=function(){this.pipeline.reset(),this.pipeline.add(e.du.trimmer,e.du.stopWordFilter,e.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.du.stemmer))},e.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.du.trimmer=e.trimmerSupport.generateTrimmer(e.du.wordCharacters),e.Pipeline.registerFunction(e.du.trimmer,"trimmer-du"),e.du.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e,r,i,o=C.cursor;;){if(C.bra=C.cursor,e=C.find_among(b,11))switch(C.ket=C.cursor,e){case 1:C.slice_from("a");continue;case 2:C.slice_from("e");continue;case 3:C.slice_from("i");continue;case 4:C.slice_from("o");continue;case 5:C.slice_from("u");continue;case 6:if(C.cursor>=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(r=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=r);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=r;else if(n(r))break}else if(n(r))break}function n(e){return C.cursor=e,e>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,f=_,t()||(_=C.cursor,_<3&&(_=3),t()||(f=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var e;;)if(C.bra=C.cursor,e=C.find_among(p,3))switch(C.ket=C.cursor,e){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return f<=C.cursor}function a(){var e=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-e,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var e;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.slice_del(),w=!0,a())))}function m(){var e;u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.eq_s_b(3,"gem")||(C.cursor=C.limit-e,C.slice_del(),a())))}function d(){var e,r,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,e=C.find_among_b(h,5))switch(C.bra=C.cursor,e){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(z,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(r=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-r,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,e=C.find_among_b(k,6))switch(C.bra=C.cursor,e){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(j,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var f,_,w,b=[new r("",-1,6),new r("á",0,1),new r("ä",0,1),new r("é",0,2),new r("ë",0,2),new r("í",0,3),new r("ï",0,3),new r("ó",0,4),new r("ö",0,4),new r("ú",0,5),new r("ü",0,5)],p=[new r("",-1,3),new r("I",0,2),new r("Y",0,1)],g=[new r("dd",-1,-1),new r("kk",-1,-1),new r("tt",-1,-1)],h=[new r("ene",-1,2),new r("se",-1,3),new r("en",-1,2),new r("heden",2,1),new r("s",-1,3)],k=[new r("end",-1,1),new r("ig",-1,2),new r("ing",-1,1),new r("lijk",-1,3),new r("baar",-1,4),new r("bar",-1,5)],v=[new r("aa",-1,-1),new r("ee",-1,-1),new r("oo",-1,-1),new r("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(e){C.setCurrent(e)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var r=C.cursor;return e(),C.cursor=r,o(),C.limit_backward=r,C.cursor=C.limit,d(),C.cursor=C.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.du.stemmer,"stemmer-du"),e.du.stopWordFilter=e.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),e.Pipeline.registerFunction(e.du.stopWordFilter,"stopWordFilter-du")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.fi.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `Finnish` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=function(){var e=i.stemmerSupport.Among,r=i.stemmerSupport.SnowballProgram,n=new function(){function i(){f=A.limit,d=f,n()||(f=A.cursor,n()||(d=A.cursor))}function n(){for(var i;;){if(i=A.cursor,A.in_grouping(W,97,246))break;if(A.cursor=i,i>=A.limit)return!0;A.cursor++}for(A.cursor=i;!A.out_grouping(W,97,246);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}function t(){return d<=A.cursor}function s(){var i,e;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(h,10)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.in_grouping_b(x,97,246))return;break;case 2:if(!t())return}A.slice_del()}else A.limit_backward=e}function o(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(v,9))switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"k")||(A.cursor=A.limit-r,A.slice_del());break;case 2:A.slice_del(),A.ket=A.cursor,A.eq_s_b(3,"kse")&&(A.bra=A.cursor,A.slice_from("ksi"));break;case 3:A.slice_del();break;case 4:A.find_among_b(p,6)&&A.slice_del();break;case 5:A.find_among_b(g,6)&&A.slice_del();break;case 6:A.find_among_b(j,2)&&A.slice_del()}else A.limit_backward=e}function l(){return A.find_among_b(q,7)}function a(){return A.eq_s_b(1,"i")&&A.in_grouping_b(L,97,246)}function u(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(C,30)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.eq_s_b(1,"a"))return;break;case 2:case 9:if(!A.eq_s_b(1,"e"))return;break;case 3:if(!A.eq_s_b(1,"i"))return;break;case 4:if(!A.eq_s_b(1,"o"))return;break;case 5:if(!A.eq_s_b(1,"ä"))return;break;case 6:if(!A.eq_s_b(1,"ö"))return;break;case 7:if(r=A.limit-A.cursor,!l()&&(A.cursor=A.limit-r,!A.eq_s_b(2,"ie"))){A.cursor=A.limit-r;break}if(A.cursor=A.limit-r,A.cursor<=A.limit_backward){A.cursor=A.limit-r;break}A.cursor--,A.bra=A.cursor;break;case 8:if(!A.in_grouping_b(W,97,246)||!A.out_grouping_b(W,97,246))return}A.slice_del(),k=!0}else A.limit_backward=e}function c(){var i,e,r;if(A.cursor>=d)if(e=A.limit_backward,A.limit_backward=d,A.ket=A.cursor,i=A.find_among_b(P,14)){if(A.bra=A.cursor,A.limit_backward=e,1==i){if(r=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-r}A.slice_del()}else A.limit_backward=e}function m(){var i;A.cursor>=f&&(i=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.find_among_b(F,2)?(A.bra=A.cursor,A.limit_backward=i,A.slice_del()):A.limit_backward=i)}function w(){var i,e,r,n,t,s;if(A.cursor>=f){if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.eq_s_b(1,"t")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.in_grouping_b(W,97,246)&&(A.cursor=A.limit-r,A.slice_del(),A.limit_backward=e,n=A.limit-A.cursor,A.cursor>=d&&(A.cursor=d,t=A.limit_backward,A.limit_backward=A.cursor,A.cursor=A.limit-n,A.ket=A.cursor,i=A.find_among_b(S,2))))){if(A.bra=A.cursor,A.limit_backward=t,1==i){if(s=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-s}return void A.slice_del()}A.limit_backward=e}}function _(){var i,e,r,n;if(A.cursor>=f){for(i=A.limit_backward,A.limit_backward=f,e=A.limit-A.cursor,l()&&(A.cursor=A.limit-e,A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.in_grouping_b(y,97,228)&&(A.bra=A.cursor,A.out_grouping_b(W,97,246)&&A.slice_del()),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"j")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.eq_s_b(1,"o")?A.slice_del():(A.cursor=A.limit-r,A.eq_s_b(1,"u")&&A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"o")&&(A.bra=A.cursor,A.eq_s_b(1,"j")&&A.slice_del()),A.cursor=A.limit-e,A.limit_backward=i;;){if(n=A.limit-A.cursor,A.out_grouping_b(W,97,246)){A.cursor=A.limit-n;break}if(A.cursor=A.limit-n,A.cursor<=A.limit_backward)return;A.cursor--}A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,b=A.slice_to(),A.eq_v_b(b)&&A.slice_del())}}var k,b,d,f,h=[new e("pa",-1,1),new e("sti",-1,2),new e("kaan",-1,1),new e("han",-1,1),new e("kin",-1,1),new e("hän",-1,1),new e("kään",-1,1),new e("ko",-1,1),new e("pä",-1,1),new e("kö",-1,1)],p=[new e("lla",-1,-1),new e("na",-1,-1),new e("ssa",-1,-1),new e("ta",-1,-1),new e("lta",3,-1),new e("sta",3,-1)],g=[new e("llä",-1,-1),new e("nä",-1,-1),new e("ssä",-1,-1),new e("tä",-1,-1),new e("ltä",3,-1),new e("stä",3,-1)],j=[new e("lle",-1,-1),new e("ine",-1,-1)],v=[new e("nsa",-1,3),new e("mme",-1,3),new e("nne",-1,3),new e("ni",-1,2),new e("si",-1,1),new e("an",-1,4),new e("en",-1,6),new e("än",-1,5),new e("nsä",-1,3)],q=[new e("aa",-1,-1),new e("ee",-1,-1),new e("ii",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1),new e("ää",-1,-1),new e("öö",-1,-1)],C=[new e("a",-1,8),new e("lla",0,-1),new e("na",0,-1),new e("ssa",0,-1),new e("ta",0,-1),new e("lta",4,-1),new e("sta",4,-1),new e("tta",4,9),new e("lle",-1,-1),new e("ine",-1,-1),new e("ksi",-1,-1),new e("n",-1,7),new e("han",11,1),new e("den",11,-1,a),new e("seen",11,-1,l),new e("hen",11,2),new e("tten",11,-1,a),new e("hin",11,3),new e("siin",11,-1,a),new e("hon",11,4),new e("hän",11,5),new e("hön",11,6),new e("ä",-1,8),new e("llä",22,-1),new e("nä",22,-1),new e("ssä",22,-1),new e("tä",22,-1),new e("ltä",26,-1),new e("stä",26,-1),new e("ttä",26,9)],P=[new e("eja",-1,-1),new e("mma",-1,1),new e("imma",1,-1),new e("mpa",-1,1),new e("impa",3,-1),new e("mmi",-1,1),new e("immi",5,-1),new e("mpi",-1,1),new e("impi",7,-1),new e("ejä",-1,-1),new e("mmä",-1,1),new e("immä",10,-1),new e("mpä",-1,1),new e("impä",12,-1)],F=[new e("i",-1,-1),new e("j",-1,-1)],S=[new e("mma",-1,1),new e("imma",0,-1)],y=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],W=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],x=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],A=new r;this.setCurrent=function(i){A.setCurrent(i)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return i(),k=!1,A.limit_backward=e,A.cursor=A.limit,s(),A.cursor=A.limit,o(),A.cursor=A.limit,u(),A.cursor=A.limit,c(),A.cursor=A.limit,k?(m(),A.cursor=A.limit):(A.cursor=A.limit,w(),A.cursor=A.limit),_(),!0}};return function(i){return"function"==typeof i.update?i.update(function(i){return n.setCurrent(i),n.stem(),n.getCurrent()}):(n.setCurrent(i),n.stem(),n.getCurrent())}}(),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.he.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.he=function(){this.pipeline.reset(),this.pipeline.add(e.he.trimmer,e.he.stopWordFilter,e.he.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.he.stemmer))},e.he.wordCharacters="֑-״א-תa-zA-Za-zA-Z0-90-9",e.he.trimmer=e.trimmerSupport.generateTrimmer(e.he.wordCharacters),e.Pipeline.registerFunction(e.he.trimmer,"trimmer-he"),e.he.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ה ו י ת",pre2:"ב כ ל מ ש כש",pre3:"הב הכ הל המ הש בש לכ",pre4:"וב וכ ול ומ וש",pre5:"מה שה כל",pre6:"מב מכ מל ממ מש",pre7:"בה בו בי בת כה כו כי כת לה לו לי לת",pre8:"ובה ובו ובי ובת וכה וכו וכי וכת ולה ולו ולי ולת"},e.suf={suf1:"ך כ ם ן נ",suf2:"ים ות וך וכ ום ון ונ הם הן יכ יך ינ ים",suf3:"תי תך תכ תם תן תנ",suf4:"ותי ותך ותכ ותם ותן ותנ",suf5:"נו כם כן הם הן",suf6:"ונו וכם וכן והם והן",suf7:"תכם תכן תנו תהם תהן",suf8:"הוא היא הם הן אני אתה את אנו אתם אתן",suf9:"ני נו כי כו כם כן תי תך תכ תם תן",suf10:"י ך כ ם ן נ ת"},e.patterns=JSON.parse('{"hebrewPatterns": [{"pt1": [{"c": "ה", "l": 0}]}, {"pt2": [{"c": "ו", "l": 0}]}, {"pt3": [{"c": "י", "l": 0}]}, {"pt4": [{"c": "ת", "l": 0}]}, {"pt5": [{"c": "מ", "l": 0}]}, {"pt6": [{"c": "ל", "l": 0}]}, {"pt7": [{"c": "ב", "l": 0}]}, {"pt8": [{"c": "כ", "l": 0}]}, {"pt9": [{"c": "ש", "l": 0}]}, {"pt10": [{"c": "כש", "l": 0}]}, {"pt11": [{"c": "בה", "l": 0}]}, {"pt12": [{"c": "וב", "l": 0}]}, {"pt13": [{"c": "וכ", "l": 0}]}, {"pt14": [{"c": "ול", "l": 0}]}, {"pt15": [{"c": "ומ", "l": 0}]}, {"pt16": [{"c": "וש", "l": 0}]}, {"pt17": [{"c": "הב", "l": 0}]}, {"pt18": [{"c": "הכ", "l": 0}]}, {"pt19": [{"c": "הל", "l": 0}]}, {"pt20": [{"c": "המ", "l": 0}]}, {"pt21": [{"c": "הש", "l": 0}]}, {"pt22": [{"c": "מה", "l": 0}]}, {"pt23": [{"c": "שה", "l": 0}]}, {"pt24": [{"c": "כל", "l": 0}]}]}'),e.execArray=["cleanWord","removeDiacritics","removeStopWords","normalizeHebrewCharacters"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHebrewCharacters=function(){return e.word=e.word.replace("ך","כ"),e.word=e.word.replace("ם","מ"),e.word=e.word.replace("ן","נ"),e.word=e.word.replace("ף","פ"),e.word=e.word.replace("ץ","צ"),!1},function(r){return"function"==typeof r.update?r.update(function(r){return e.setCurrent(r),e.stem(),e.getCurrent()}):(e.setCurrent(r),e.stem(),e.getCurrent())}}(),e.Pipeline.registerFunction(e.he.stemmer,"stemmer-he"),e.he.stopWordFilter=e.generateStopWordFilter("אבל או אולי אותו אותי אותך אותם אותן אותנו אז אחר אחרות אחרי אחריכן אחרים אחרת אי איזה איך אין איפה אל אלה אלו אם אנחנו אני אף אפשר את אתה אתכם אתכן אתם אתן באיזה באיזו בגלל בין בלבד בעבור בעזרת בכל בכן בלי במידה במקום שבו ברוב בשביל בשעה ש בתוך גם דרך הוא היא היה היי היכן היתה היתי הם הן הנה הסיבה שבגללה הרי ואילו ואת זאת זה זות יהיה יוכל יוכלו יותר מדי יכול יכולה יכולות יכולים יכל יכלה יכלו יש כאן כאשר כולם כולן כזה כי כיצד כך כל כלל כמו כן כפי כש לא לאו לאיזותך לאן לבין לה להיות להם להן לו לזה לזות לי לך לכם לכן למה למעלה למעלה מ למטה למטה מ למעט למקום שבו למרות לנו לעבר לעיכן לפיכך לפני מאד מאחורי מאיזו סיבה מאין מאיפה מבלי מבעד מדוע מה מהיכן מול מחוץ מי מידע מכאן מכל מכן מלבד מן מנין מסוגל מעט מעטים מעל מצד מקום בו מתחת מתי נגד נגר נו עד עז על עלי עליו עליה עליהם עליך עלינו עם עצמה עצמהם עצמהן עצמו עצמי עצמם עצמן עצמנו פה רק שוב של שלה שלהם שלהן שלו שלי שלך שלכה שלכם שלכן שלנו שם תהיה תחת".split(" ")),e.Pipeline.registerFunction(e.he.stopWordFilter,"stopWordFilter-he")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.hi.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Za-zA-Z0-90-9",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.hu.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `Hungarian` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,n=L.cursor;if(d=L.limit,L.in_grouping(W,97,252))for(;;){if(e=L.cursor,L.out_grouping(W,97,252))return L.cursor=e,L.find_among(g,8)||(L.cursor=e,e=L.limit)return void(d=e);L.cursor++}if(L.cursor=n,L.out_grouping(W,97,252)){for(;!L.in_grouping(W,97,252);){if(L.cursor>=L.limit)return;L.cursor++}d=L.cursor}}function i(){return d<=L.cursor}function a(){var e;if(L.ket=L.cursor,(e=L.find_among_b(h,2))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e")}}function t(){var e=L.limit-L.cursor;return!!L.find_among_b(p,23)&&(L.cursor=L.limit-e,!0)}function s(){if(L.cursor>L.limit_backward){L.cursor--,L.ket=L.cursor;var e=L.cursor-1;L.limit_backward<=e&&e<=L.limit&&(L.cursor=e,L.bra=e,L.slice_del())}}function c(){var e;if(L.ket=L.cursor,(e=L.find_among_b(_,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function o(){L.ket=L.cursor,L.find_among_b(v,44)&&(L.bra=L.cursor,i()&&(L.slice_del(),a()))}function w(){var e;if(L.ket=L.cursor,(e=L.find_among_b(z,3))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("e");break;case 2:case 3:L.slice_from("a")}}function l(){var e;if(L.ket=L.cursor,(e=L.find_among_b(y,6))&&(L.bra=L.cursor,i()))switch(e){case 1:case 2:L.slice_del();break;case 3:L.slice_from("a");break;case 4:L.slice_from("e")}}function u(){var e;if(L.ket=L.cursor,(e=L.find_among_b(j,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function m(){var e;if(L.ket=L.cursor,(e=L.find_among_b(C,7))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:L.slice_del()}}function k(){var e;if(L.ket=L.cursor,(e=L.find_among_b(P,12))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 9:L.slice_del();break;case 2:case 5:case 8:L.slice_from("e");break;case 3:case 6:L.slice_from("a")}}function f(){var e;if(L.ket=L.cursor,(e=L.find_among_b(F,31))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:L.slice_del();break;case 2:case 5:case 10:case 14:case 19:L.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:L.slice_from("e")}}function b(){var e;if(L.ket=L.cursor,(e=L.find_among_b(S,42))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:L.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:L.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:L.slice_from("e")}}var d,g=[new n("cs",-1,-1),new n("dzs",-1,-1),new n("gy",-1,-1),new n("ly",-1,-1),new n("ny",-1,-1),new n("sz",-1,-1),new n("ty",-1,-1),new n("zs",-1,-1)],h=[new n("á",-1,1),new n("é",-1,2)],p=[new n("bb",-1,-1),new n("cc",-1,-1),new n("dd",-1,-1),new n("ff",-1,-1),new n("gg",-1,-1),new n("jj",-1,-1),new n("kk",-1,-1),new n("ll",-1,-1),new n("mm",-1,-1),new n("nn",-1,-1),new n("pp",-1,-1),new n("rr",-1,-1),new n("ccs",-1,-1),new n("ss",-1,-1),new n("zzs",-1,-1),new n("tt",-1,-1),new n("vv",-1,-1),new n("ggy",-1,-1),new n("lly",-1,-1),new n("nny",-1,-1),new n("tty",-1,-1),new n("ssz",-1,-1),new n("zz",-1,-1)],_=[new n("al",-1,1),new n("el",-1,2)],v=[new n("ba",-1,-1),new n("ra",-1,-1),new n("be",-1,-1),new n("re",-1,-1),new n("ig",-1,-1),new n("nak",-1,-1),new n("nek",-1,-1),new n("val",-1,-1),new n("vel",-1,-1),new n("ul",-1,-1),new n("nál",-1,-1),new n("nél",-1,-1),new n("ból",-1,-1),new n("ról",-1,-1),new n("tól",-1,-1),new n("bõl",-1,-1),new n("rõl",-1,-1),new n("tõl",-1,-1),new n("ül",-1,-1),new n("n",-1,-1),new n("an",19,-1),new n("ban",20,-1),new n("en",19,-1),new n("ben",22,-1),new n("képpen",22,-1),new n("on",19,-1),new n("ön",19,-1),new n("képp",-1,-1),new n("kor",-1,-1),new n("t",-1,-1),new n("at",29,-1),new n("et",29,-1),new n("ként",29,-1),new n("anként",32,-1),new n("enként",32,-1),new n("onként",32,-1),new n("ot",29,-1),new n("ért",29,-1),new n("öt",29,-1),new n("hez",-1,-1),new n("hoz",-1,-1),new n("höz",-1,-1),new n("vá",-1,-1),new n("vé",-1,-1)],z=[new n("án",-1,2),new n("én",-1,1),new n("ánként",-1,3)],y=[new n("stul",-1,2),new n("astul",0,1),new n("ástul",0,3),new n("stül",-1,2),new n("estül",3,1),new n("éstül",3,4)],j=[new n("á",-1,1),new n("é",-1,2)],C=[new n("k",-1,7),new n("ak",0,4),new n("ek",0,6),new n("ok",0,5),new n("ák",0,1),new n("ék",0,2),new n("ök",0,3)],P=[new n("éi",-1,7),new n("áéi",0,6),new n("ééi",0,5),new n("é",-1,9),new n("ké",3,4),new n("aké",4,1),new n("eké",4,1),new n("oké",4,1),new n("áké",4,3),new n("éké",4,2),new n("öké",4,1),new n("éé",3,8)],F=[new n("a",-1,18),new n("ja",0,17),new n("d",-1,16),new n("ad",2,13),new n("ed",2,13),new n("od",2,13),new n("ád",2,14),new n("éd",2,15),new n("öd",2,13),new n("e",-1,18),new n("je",9,17),new n("nk",-1,4),new n("unk",11,1),new n("ánk",11,2),new n("énk",11,3),new n("ünk",11,1),new n("uk",-1,8),new n("juk",16,7),new n("ájuk",17,5),new n("ük",-1,8),new n("jük",19,7),new n("éjük",20,6),new n("m",-1,12),new n("am",22,9),new n("em",22,9),new n("om",22,9),new n("ám",22,10),new n("ém",22,11),new n("o",-1,18),new n("á",-1,19),new n("é",-1,20)],S=[new n("id",-1,10),new n("aid",0,9),new n("jaid",1,6),new n("eid",0,9),new n("jeid",3,6),new n("áid",0,7),new n("éid",0,8),new n("i",-1,15),new n("ai",7,14),new n("jai",8,11),new n("ei",7,14),new n("jei",10,11),new n("ái",7,12),new n("éi",7,13),new n("itek",-1,24),new n("eitek",14,21),new n("jeitek",15,20),new n("éitek",14,23),new n("ik",-1,29),new n("aik",18,26),new n("jaik",19,25),new n("eik",18,26),new n("jeik",21,25),new n("áik",18,27),new n("éik",18,28),new n("ink",-1,20),new n("aink",25,17),new n("jaink",26,16),new n("eink",25,17),new n("jeink",28,16),new n("áink",25,18),new n("éink",25,19),new n("aitok",-1,21),new n("jaitok",32,20),new n("áitok",-1,22),new n("im",-1,5),new n("aim",35,4),new n("jaim",36,1),new n("eim",35,4),new n("jeim",38,1),new n("áim",35,2),new n("éim",35,3)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var n=L.cursor;return e(),L.limit_backward=n,L.cursor=L.limit,c(),L.cursor=L.limit,o(),L.cursor=L.limit,w(),L.cursor=L.limit,l(),L.cursor=L.limit,u(),L.cursor=L.limit,k(),L.cursor=L.limit,f(),L.cursor=L.limit,b(),L.cursor=L.limit,m(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.hy.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hy=function(){this.pipeline.reset(),this.pipeline.add(e.hy.trimmer,e.hy.stopWordFilter)},e.hy.wordCharacters="[A-Za-z԰-֏ff-ﭏ]",e.hy.trimmer=e.trimmerSupport.generateTrimmer(e.hy.wordCharacters),e.Pipeline.registerFunction(e.hy.trimmer,"trimmer-hy"),e.hy.stopWordFilter=e.generateStopWordFilter("դու և եք էիր էիք հետո նաև նրանք որը վրա է որ պիտի են այս մեջ ն իր ու ի այդ որոնք այն կամ էր մի ես համար այլ իսկ էին ենք հետ ին թ էինք մենք նրա նա դուք եմ էի ըստ որպես ում".split(" ")),e.Pipeline.registerFunction(e.hy.stopWordFilter,"stopWordFilter-hy"),e.hy.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}(),e.Pipeline.registerFunction(e.hy.stemmer,"stemmer-hy")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.ja.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(e=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=e);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=e;else if(n(e))break}else if(n(e))break}function n(r){return C.cursor=r,r>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,d=_,t()||(_=C.cursor,_<3&&(_=3),t()||(d=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var r;;)if(C.bra=C.cursor,r=C.find_among(p,3))switch(C.ket=C.cursor,r){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return d<=C.cursor}function a(){var r=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-r,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var r;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.slice_del(),w=!0,a())))}function m(){var r;u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.eq_s_b(3,"gem")||(C.cursor=C.limit-r,C.slice_del(),a())))}function f(){var r,e,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,r=C.find_among_b(h,5))switch(C.bra=C.cursor,r){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(j,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(e=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-e,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,r=C.find_among_b(k,6))switch(C.bra=C.cursor,r){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(z,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var d,_,w,b=[new e("",-1,6),new e("á",0,1),new e("ä",0,1),new e("é",0,2),new e("ë",0,2),new e("í",0,3),new e("ï",0,3),new e("ó",0,4),new e("ö",0,4),new e("ú",0,5),new e("ü",0,5)],p=[new e("",-1,3),new e("I",0,2),new e("Y",0,1)],g=[new e("dd",-1,-1),new e("kk",-1,-1),new e("tt",-1,-1)],h=[new e("ene",-1,2),new e("se",-1,3),new e("en",-1,2),new e("heden",2,1),new e("s",-1,3)],k=[new e("end",-1,1),new e("ig",-1,2),new e("ing",-1,1),new e("lijk",-1,3),new e("baar",-1,4),new e("bar",-1,5)],v=[new e("aa",-1,-1),new e("ee",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(r){C.setCurrent(r)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var e=C.cursor;return r(),C.cursor=e,o(),C.limit_backward=e,C.cursor=C.limit,f(),C.cursor=C.limit_backward,s(),!0}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.nl.stemmer,"stemmer-nl"),r.nl.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.nl.stopWordFilter,"stopWordFilter-nl")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.no.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `Norwegian` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.pt.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `Portuguese` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(k,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("a~");continue;case 2:z.slice_from("o~");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function n(){if(z.out_grouping(y,97,250)){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!0;z.cursor++}return!1}return!0}function i(){if(z.in_grouping(y,97,250))for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return g=z.cursor,!0}function o(){var e,r,s=z.cursor;if(z.in_grouping(y,97,250))if(e=z.cursor,n()){if(z.cursor=e,i())return}else g=z.cursor;if(z.cursor=s,z.out_grouping(y,97,250)){if(r=z.cursor,n()){if(z.cursor=r,!z.in_grouping(y,97,250)||z.cursor>=z.limit)return;z.cursor++}g=z.cursor}}function t(){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return!0}function a(){var e=z.cursor;g=z.limit,b=g,h=g,o(),z.cursor=e,t()&&(b=z.cursor,t()&&(h=z.cursor))}function u(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(q,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("ã");continue;case 2:z.slice_from("õ");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function w(){return g<=z.cursor}function m(){return b<=z.cursor}function c(){return h<=z.cursor}function l(){var e;if(z.ket=z.cursor,!(e=z.find_among_b(F,45)))return!1;switch(z.bra=z.cursor,e){case 1:if(!c())return!1;z.slice_del();break;case 2:if(!c())return!1;z.slice_from("log");break;case 3:if(!c())return!1;z.slice_from("u");break;case 4:if(!c())return!1;z.slice_from("ente");break;case 5:if(!m())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(j,4),e&&(z.bra=z.cursor,c()&&(z.slice_del(),1==e&&(z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del()))));break;case 6:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(C,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 7:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(P,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 8:if(!c())return!1;z.slice_del(),z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del());break;case 9:if(!w()||!z.eq_s_b(1,"e"))return!1;z.slice_from("ir")}return!0}function f(){var e,r;if(z.cursor>=g){if(r=z.limit_backward,z.limit_backward=g,z.ket=z.cursor,e=z.find_among_b(S,120))return z.bra=z.cursor,1==e&&z.slice_del(),z.limit_backward=r,!0;z.limit_backward=r}return!1}function d(){var e;z.ket=z.cursor,(e=z.find_among_b(W,7))&&(z.bra=z.cursor,1==e&&w()&&z.slice_del())}function v(e,r){if(z.eq_s_b(1,e)){z.bra=z.cursor;var s=z.limit-z.cursor;if(z.eq_s_b(1,r))return z.cursor=z.limit-s,w()&&z.slice_del(),!1}return!0}function p(){var e;if(z.ket=z.cursor,e=z.find_among_b(L,4))switch(z.bra=z.cursor,e){case 1:w()&&(z.slice_del(),z.ket=z.cursor,z.limit-z.cursor,v("u","g")&&v("i","c"));break;case 2:z.slice_from("c")}}function _(){if(!l()&&(z.cursor=z.limit,!f()))return z.cursor=z.limit,void d();z.cursor=z.limit,z.ket=z.cursor,z.eq_s_b(1,"i")&&(z.bra=z.cursor,z.eq_s_b(1,"c")&&(z.cursor=z.limit,w()&&z.slice_del()))}var h,b,g,k=[new r("",-1,3),new r("ã",0,1),new r("õ",0,2)],q=[new r("",-1,3),new r("a~",0,1),new r("o~",0,2)],j=[new r("ic",-1,-1),new r("ad",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],C=[new r("ante",-1,1),new r("avel",-1,1),new r("ível",-1,1)],P=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],F=[new r("ica",-1,1),new r("ância",-1,1),new r("ência",-1,4),new r("ira",-1,9),new r("adora",-1,1),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,8),new r("eza",-1,1),new r("logía",-1,2),new r("idade",-1,7),new r("ante",-1,1),new r("mente",-1,6),new r("amente",12,5),new r("ável",-1,1),new r("ível",-1,1),new r("ución",-1,3),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,1),new r("imento",-1,1),new r("ivo",-1,8),new r("aça~o",-1,1),new r("ador",-1,1),new r("icas",-1,1),new r("ências",-1,4),new r("iras",-1,9),new r("adoras",-1,1),new r("osas",-1,1),new r("istas",-1,1),new r("ivas",-1,8),new r("ezas",-1,1),new r("logías",-1,2),new r("idades",-1,7),new r("uciones",-1,3),new r("adores",-1,1),new r("antes",-1,1),new r("aço~es",-1,1),new r("icos",-1,1),new r("ismos",-1,1),new r("osos",-1,1),new r("amentos",-1,1),new r("imentos",-1,1),new r("ivos",-1,8)],S=[new r("ada",-1,1),new r("ida",-1,1),new r("ia",-1,1),new r("aria",2,1),new r("eria",2,1),new r("iria",2,1),new r("ara",-1,1),new r("era",-1,1),new r("ira",-1,1),new r("ava",-1,1),new r("asse",-1,1),new r("esse",-1,1),new r("isse",-1,1),new r("aste",-1,1),new r("este",-1,1),new r("iste",-1,1),new r("ei",-1,1),new r("arei",16,1),new r("erei",16,1),new r("irei",16,1),new r("am",-1,1),new r("iam",20,1),new r("ariam",21,1),new r("eriam",21,1),new r("iriam",21,1),new r("aram",20,1),new r("eram",20,1),new r("iram",20,1),new r("avam",20,1),new r("em",-1,1),new r("arem",29,1),new r("erem",29,1),new r("irem",29,1),new r("assem",29,1),new r("essem",29,1),new r("issem",29,1),new r("ado",-1,1),new r("ido",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("indo",-1,1),new r("ara~o",-1,1),new r("era~o",-1,1),new r("ira~o",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("ir",-1,1),new r("as",-1,1),new r("adas",47,1),new r("idas",47,1),new r("ias",47,1),new r("arias",50,1),new r("erias",50,1),new r("irias",50,1),new r("aras",47,1),new r("eras",47,1),new r("iras",47,1),new r("avas",47,1),new r("es",-1,1),new r("ardes",58,1),new r("erdes",58,1),new r("irdes",58,1),new r("ares",58,1),new r("eres",58,1),new r("ires",58,1),new r("asses",58,1),new r("esses",58,1),new r("isses",58,1),new r("astes",58,1),new r("estes",58,1),new r("istes",58,1),new r("is",-1,1),new r("ais",71,1),new r("eis",71,1),new r("areis",73,1),new r("ereis",73,1),new r("ireis",73,1),new r("áreis",73,1),new r("éreis",73,1),new r("íreis",73,1),new r("ásseis",73,1),new r("ésseis",73,1),new r("ísseis",73,1),new r("áveis",73,1),new r("íeis",73,1),new r("aríeis",84,1),new r("eríeis",84,1),new r("iríeis",84,1),new r("ados",-1,1),new r("idos",-1,1),new r("amos",-1,1),new r("áramos",90,1),new r("éramos",90,1),new r("íramos",90,1),new r("ávamos",90,1),new r("íamos",90,1),new r("aríamos",95,1),new r("eríamos",95,1),new r("iríamos",95,1),new r("emos",-1,1),new r("aremos",99,1),new r("eremos",99,1),new r("iremos",99,1),new r("ássemos",99,1),new r("êssemos",99,1),new r("íssemos",99,1),new r("imos",-1,1),new r("armos",-1,1),new r("ermos",-1,1),new r("irmos",-1,1),new r("ámos",-1,1),new r("arás",-1,1),new r("erás",-1,1),new r("irás",-1,1),new r("eu",-1,1),new r("iu",-1,1),new r("ou",-1,1),new r("ará",-1,1),new r("erá",-1,1),new r("irá",-1,1)],W=[new r("a",-1,1),new r("i",-1,1),new r("o",-1,1),new r("os",-1,1),new r("á",-1,1),new r("í",-1,1),new r("ó",-1,1)],L=[new r("e",-1,1),new r("ç",-1,2),new r("é",-1,1),new r("ê",-1,1)],y=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],z=new s;this.setCurrent=function(e){z.setCurrent(e)},this.getCurrent=function(){return z.getCurrent()},this.stem=function(){var r=z.cursor;return e(),z.cursor=r,a(),z.limit_backward=r,z.cursor=z.limit,_(),z.cursor=z.limit,p(),z.cursor=z.limit_backward,u(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.ru.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `Russian` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,"trimmer-ru"),e.ru.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,t=new function(){function e(){for(;!W.in_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function t(){for(;!W.out_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function w(){b=W.limit,_=b,e()&&(b=W.cursor,t()&&e()&&t()&&(_=W.cursor))}function i(){return _<=W.cursor}function u(e,n){var r,t;if(W.ket=W.cursor,r=W.find_among_b(e,n)){switch(W.bra=W.cursor,r){case 1:if(t=W.limit-W.cursor,!W.eq_s_b(1,"а")&&(W.cursor=W.limit-t,!W.eq_s_b(1,"я")))return!1;case 2:W.slice_del()}return!0}return!1}function o(){return u(h,9)}function s(e,n){var r;return W.ket=W.cursor,!!(r=W.find_among_b(e,n))&&(W.bra=W.cursor,1==r&&W.slice_del(),!0)}function c(){return s(g,26)}function m(){return!!c()&&(u(C,8),!0)}function f(){return s(k,2)}function l(){return u(P,46)}function a(){s(v,36)}function p(){var e;W.ket=W.cursor,(e=W.find_among_b(F,2))&&(W.bra=W.cursor,i()&&1==e&&W.slice_del())}function d(){var e;if(W.ket=W.cursor,e=W.find_among_b(q,4))switch(W.bra=W.cursor,e){case 1:if(W.slice_del(),W.ket=W.cursor,!W.eq_s_b(1,"н"))break;W.bra=W.cursor;case 2:if(!W.eq_s_b(1,"н"))break;case 3:W.slice_del()}}var _,b,h=[new n("в",-1,1),new n("ив",0,2),new n("ыв",0,2),new n("вши",-1,1),new n("ивши",3,2),new n("ывши",3,2),new n("вшись",-1,1),new n("ившись",6,2),new n("ывшись",6,2)],g=[new n("ее",-1,1),new n("ие",-1,1),new n("ое",-1,1),new n("ые",-1,1),new n("ими",-1,1),new n("ыми",-1,1),new n("ей",-1,1),new n("ий",-1,1),new n("ой",-1,1),new n("ый",-1,1),new n("ем",-1,1),new n("им",-1,1),new n("ом",-1,1),new n("ым",-1,1),new n("его",-1,1),new n("ого",-1,1),new n("ему",-1,1),new n("ому",-1,1),new n("их",-1,1),new n("ых",-1,1),new n("ею",-1,1),new n("ою",-1,1),new n("ую",-1,1),new n("юю",-1,1),new n("ая",-1,1),new n("яя",-1,1)],C=[new n("ем",-1,1),new n("нн",-1,1),new n("вш",-1,1),new n("ивш",2,2),new n("ывш",2,2),new n("щ",-1,1),new n("ющ",5,1),new n("ующ",6,2)],k=[new n("сь",-1,1),new n("ся",-1,1)],P=[new n("ла",-1,1),new n("ила",0,2),new n("ыла",0,2),new n("на",-1,1),new n("ена",3,2),new n("ете",-1,1),new n("ите",-1,2),new n("йте",-1,1),new n("ейте",7,2),new n("уйте",7,2),new n("ли",-1,1),new n("или",10,2),new n("ыли",10,2),new n("й",-1,1),new n("ей",13,2),new n("уй",13,2),new n("л",-1,1),new n("ил",16,2),new n("ыл",16,2),new n("ем",-1,1),new n("им",-1,2),new n("ым",-1,2),new n("н",-1,1),new n("ен",22,2),new n("ло",-1,1),new n("ило",24,2),new n("ыло",24,2),new n("но",-1,1),new n("ено",27,2),new n("нно",27,1),new n("ет",-1,1),new n("ует",30,2),new n("ит",-1,2),new n("ыт",-1,2),new n("ют",-1,1),new n("уют",34,2),new n("ят",-1,2),new n("ны",-1,1),new n("ены",37,2),new n("ть",-1,1),new n("ить",39,2),new n("ыть",39,2),new n("ешь",-1,1),new n("ишь",-1,2),new n("ю",-1,2),new n("ую",44,2)],v=[new n("а",-1,1),new n("ев",-1,1),new n("ов",-1,1),new n("е",-1,1),new n("ие",3,1),new n("ье",3,1),new n("и",-1,1),new n("еи",6,1),new n("ии",6,1),new n("ами",6,1),new n("ями",6,1),new n("иями",10,1),new n("й",-1,1),new n("ей",12,1),new n("ией",13,1),new n("ий",12,1),new n("ой",12,1),new n("ам",-1,1),new n("ем",-1,1),new n("ием",18,1),new n("ом",-1,1),new n("ям",-1,1),new n("иям",21,1),new n("о",-1,1),new n("у",-1,1),new n("ах",-1,1),new n("ях",-1,1),new n("иях",26,1),new n("ы",-1,1),new n("ь",-1,1),new n("ю",-1,1),new n("ию",30,1),new n("ью",30,1),new n("я",-1,1),new n("ия",33,1),new n("ья",33,1)],F=[new n("ост",-1,1),new n("ость",-1,1)],q=[new n("ейше",-1,1),new n("н",-1,2),new n("ейш",-1,1),new n("ь",-1,3)],S=[33,65,8,232],W=new r;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){return w(),W.cursor=W.limit,!(W.cursor=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursors||e>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor>1),f=0,l=o0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.sv.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `Swedish` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.ta.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ta=function(){this.pipeline.reset(),this.pipeline.add(e.ta.trimmer,e.ta.stopWordFilter,e.ta.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ta.stemmer))},e.ta.wordCharacters="஀-உஊ-ஏஐ-ஙச-ட஠-னப-யர-ஹ஺-ிீ-௉ொ-௏ௐ-௙௚-௟௠-௩௪-௯௰-௹௺-௿a-zA-Za-zA-Z0-90-9",e.ta.trimmer=e.trimmerSupport.generateTrimmer(e.ta.wordCharacters),e.Pipeline.registerFunction(e.ta.trimmer,"trimmer-ta"),e.ta.stopWordFilter=e.generateStopWordFilter("அங்கு அங்கே அது அதை அந்த அவர் அவர்கள் அவள் அவன் அவை ஆக ஆகவே ஆகையால் ஆதலால் ஆதலினால் ஆனாலும் ஆனால் இங்கு இங்கே இது இதை இந்த இப்படி இவர் இவர்கள் இவள் இவன் இவை இவ்வளவு உனக்கு உனது உன் உன்னால் எங்கு எங்கே எது எதை எந்த எப்படி எவர் எவர்கள் எவள் எவன் எவை எவ்வளவு எனக்கு எனது எனவே என் என்ன என்னால் ஏது ஏன் தனது தன்னால் தானே தான் நாங்கள் நாம் நான் நீ நீங்கள்".split(" ")),e.ta.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.ta.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.ta.stemmer,"stemmer-ta"),e.Pipeline.registerFunction(e.ta.stopWordFilter,"stopWordFilter-ta")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.te.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.te=function(){this.pipeline.reset(),this.pipeline.add(e.te.trimmer,e.te.stopWordFilter,e.te.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.te.stemmer))},e.te.wordCharacters="ఀ-ఄఅ-ఔక-హా-ౌౕ-ౖౘ-ౚౠ-ౡౢ-ౣ౦-౯౸-౿఼ఽ్ౝ౷౤౥",e.te.trimmer=e.trimmerSupport.generateTrimmer(e.te.wordCharacters),e.Pipeline.registerFunction(e.te.trimmer,"trimmer-te"),e.te.stopWordFilter=e.generateStopWordFilter("అందరూ అందుబాటులో అడగండి అడగడం అడ్డంగా అనుగుణంగా అనుమతించు అనుమతిస్తుంది అయితే ఇప్పటికే ఉన్నారు ఎక్కడైనా ఎప్పుడు ఎవరైనా ఎవరో ఏ ఏదైనా ఏమైనప్పటికి ఒక ఒకరు కనిపిస్తాయి కాదు కూడా గా గురించి చుట్టూ చేయగలిగింది తగిన తర్వాత దాదాపు దూరంగా నిజంగా పై ప్రకారం ప్రక్కన మధ్య మరియు మరొక మళ్ళీ మాత్రమే మెచ్చుకో వద్ద వెంట వేరుగా వ్యతిరేకంగా సంబంధం".split(" ")),e.te.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.te.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.te.stemmer,"stemmer-te"),e.Pipeline.registerFunction(e.te.stopWordFilter,"stopWordFilter-te")}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.th.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[฀-๿]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.vi.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}}); -------------------------------------------------------------------------------- /docs/assets/javascripts/lunr/min/lunr.zh.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("@node-rs/jieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 為 以 于 於 上 他 而 后 後 之 来 來 及 了 因 下 可 到 由 这 這 与 與 也 此 但 并 並 个 個 其 已 无 無 小 我 们 們 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 當 从 從 得 打 凡 儿 兒 尔 爾 该 該 各 给 給 跟 和 何 还 還 即 几 幾 既 看 据 據 距 靠 啦 另 么 麽 每 嘛 拿 哪 您 凭 憑 且 却 卻 让 讓 仍 啥 如 若 使 谁 誰 虽 雖 随 隨 同 所 她 哇 嗡 往 些 向 沿 哟 喲 用 咱 则 則 怎 曾 至 致 着 著 诸 諸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}}); -------------------------------------------------------------------------------- /docs/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 23 | 27 | 31 | 32 | 38 | 44 | 50 | 59 | 60 | 84 | 86 | 87 | 89 | image/svg+xml 90 | 92 | 93 | 94 | 95 | 96 | 99 | 103 | 111 | 120 | 129 | 138 | 139 | 145 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/palette.06af60db.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["src/templates/assets/stylesheets/palette/_scheme.scss","../../../../src/templates/assets/stylesheets/palette.scss","src/templates/assets/stylesheets/palette/_accent.scss","src/templates/assets/stylesheets/palette/_primary.scss","src/templates/assets/stylesheets/utilities/_break.scss"],"names":[],"mappings":"AA2BA,cAGE,6BAME,sDAAA,CACA,6DAAA,CACA,+DAAA,CACA,gEAAA,CACA,mDAAA,CACA,6DAAA,CACA,+DAAA,CACA,gEAAA,CAGA,mDAAA,CACA,gDAAA,CAGA,0BAAA,CACA,mCAAA,CAGA,iCAAA,CACA,kCAAA,CACA,mCAAA,CACA,mCAAA,CACA,kCAAA,CACA,iCAAA,CACA,+CAAA,CACA,6DAAA,CACA,gEAAA,CACA,4DAAA,CACA,4DAAA,CACA,6DAAA,CAGA,6CAAA,CAGA,+CAAA,CAGA,uDAAA,CACA,6DAAA,CACA,2DAAA,CAGA,iCAAA,CAGA,yDAAA,CACA,iEAAA,CAGA,mDAAA,CACA,mDAAA,CAGA,qDAAA,CACA,uDAAA,CAGA,8DAAA,CAKA,8DAAA,CAKA,0DAAA,CAvEA,iBCeF,CD6DE,kHAEE,YC3DJ,CDkFE,yDACE,4BChFJ,CD+EE,2DACE,4BC7EJ,CD4EE,gEACE,4BC1EJ,CDyEE,2DACE,4BCvEJ,CDsEE,yDACE,4BCpEJ,CDmEE,0DACE,4BCjEJ,CDgEE,gEACE,4BC9DJ,CD6DE,0DACE,4BC3DJ,CD0DE,2OACE,4BC/CJ,CDsDA,+FAGE,iCCpDF,CACF,CC/CE,2BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD2CN,CCrDE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDkDN,CC5DE,8BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDyDN,CCnEE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDgEN,CC1EE,8BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDuEN,CCjFE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD8EN,CCxFE,kCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDqFN,CC/FE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD4FN,CCtGE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDmGN,CC7GE,6BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD0GN,CCpHE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDiHN,CC3HE,4BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCD2HN,CClIE,8BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDkIN,CCzIE,6BACE,yBAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDyIN,CChJE,8BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDgJN,CCvJE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDoJN,CEzJE,4BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsJN,CEjKE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8JN,CEzKE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsKN,CEjLE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8KN,CEzLE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsLN,CEjME,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8LN,CEzME,mCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsMN,CEjNE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8MN,CEzNE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsNN,CEjOE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8NN,CEzOE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsON,CEjPE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFiPN,CEzPE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFyPN,CEjQE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFiQN,CEzQE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFyQN,CEjRE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8QN,CEzRE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsRN,CEjSE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCAAA,CAKA,4BF0RN,CE1SE,kCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCAAA,CAKA,4BFmSN,CEpRE,sEACE,4BFuRJ,CExRE,+DACE,4BF2RJ,CE5RE,iEACE,4BF+RJ,CEhSE,gEACE,4BFmSJ,CEpSE,iEACE,4BFuSJ,CE9RA,8BACE,mDAAA,CACA,4DAAA,CACA,0DAAA,CACA,oDAAA,CACA,2DAAA,CAGA,4BF+RF,CE5RE,yCACE,+BF8RJ,CE3RI,kDAEE,0CAAA,CACA,sCAAA,CAFA,mCF+RN,CG3MI,mCD1EA,+CACE,8CFwRJ,CErRI,qDACE,8CFuRN,CElRE,iEACE,mCFoRJ,CACF,CGtNI,sCDvDA,uCACE,oCFgRJ,CACF,CEvQA,8BACE,kDAAA,CACA,4DAAA,CACA,wDAAA,CACA,oDAAA,CACA,6DAAA,CAGA,4BFwQF,CErQE,yCACE,+BFuQJ,CEpQI,kDAEE,0CAAA,CACA,sCAAA,CAFA,mCFwQN,CEjQE,yCACE,6CFmQJ,CG5NI,0CDhCA,8CACE,gDF+PJ,CACF,CGjOI,0CDvBA,iFACE,6CF2PJ,CACF,CGzPI,sCDKA,uCACE,6CFuPJ,CACF","file":"palette.css"} -------------------------------------------------------------------------------- /docs/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raindrum/citeurl/a929a29d7b72b5bf376d90f48759a5496ecaf799/docs/objects.inv -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /docs/sitemap.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raindrum/citeurl/a929a29d7b72b5bf376d90f48759a5496ecaf799/docs/sitemap.xml.gz -------------------------------------------------------------------------------- /docs_source/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raindrum/citeurl/a929a29d7b72b5bf376d90f48759a5496ecaf799/docs_source/assets/favicon.png -------------------------------------------------------------------------------- /docs_source/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 23 | 27 | 31 | 32 | 38 | 44 | 50 | 59 | 60 | 84 | 86 | 87 | 89 | image/svg+xml 90 | 92 | 93 | 94 | 95 | 96 | 99 | 103 | 111 | 120 | 129 | 138 | 139 | 145 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /docs_source/frontends.md: -------------------------------------------------------------------------------- 1 | # CiteURL Frontends 2 | 3 | CiteURL can be used in a few forms besides the [command-line tool](../index#usage) and [the Python library](../library). Here's what they are: 4 | 5 | ## CiteURL Server 6 | 7 | If you just want to use CiteURL from your web browser, it's hosted as a web app at [citation.link](https://www.citation.link). 8 | 9 | You can also host your own instance of it on your local network or beyond. This is useful if you want to add support for your own [custom citation templates](template-yamls). The simplest way is to run this command: 10 | 11 | ```citeurl 12 | citeurl host -st PATH_TO_YOUR_TEMPLATES.YAML 13 | ``` 14 | 15 | Or, if you're using a hosting provider like [pythonanywhere.com](https://pythonanywhere.com), you can give it direct access to CiteURL as a Flask application: 16 | 17 | ```python 18 | from citeurl.web.server import App 19 | from citeurl import Citator 20 | 21 | APP = App(Citator(yaml_paths=['PATH_TO_YOUR_TEMPLATES.YAML'])) 22 | ``` 23 | 24 | ## JavaScript 25 | 26 | Although CiteURL is primarily a Python program, you can also use it to generate a JavaScript implementation of its citation lookup functionality, including any extra citation templates you've written. This allows it to be hosted on a static website (like [mine](https://raindrum.github.io/lawsearch), for example), or distributed as an HTML file that people can save to their own computers and bookmark as a [custom search engine](https://www.howtogeek.com/114176/HOW-TO-EASILY-CREATE-SEARCH-PLUGINS-ADD-ANY-SEARCH-ENGINE-TO-YOUR-BROWSER/). 27 | 28 | To make a JavaScript implementation, first [make a YAML file](template-yamls) with any custom citation templates you'd like to support. Next, open a command line and run the following command: 29 | 30 | ``` bash 31 | citeurl makejs -e -o output.html -t PATH_TO_YOUR_TEMPLATES.YAML 32 | ``` 33 | 34 | Alternatively, to omit CiteURL's default templates, include the `-n` option in that command. For more info, run `citeurl makejs -h`. 35 | 36 | ## Markdown Extension 37 | 38 | CiteURL can also be used as an extension to [Python-Markdown](https://python-markdown.github.io/). You can load the extension as `citeurl`, and it supports the following options: 39 | 40 | - `custom_templates`: A list of paths to YAML files containing [custom citation templates](../template-yamls). Defaults to none. 41 | - `use_defaults`: Whether CiteURL should load the default citation templates. Defaults to `True`. 42 | - `attributes`: A dictionary of HTML attributes to give each hyperlink that CiteURL inserts into the text. Defaults to `{'class': 'citation'}`. 43 | - `redundant_links`: Whether to insert a link even when its URL would be the same as the last one. 44 | - `URL_optional`: Whether to insert a link even when it doesn't have a URL. 45 | - `break_id_on_regex`: Anywhere this string (parsed as regex) appears in the text, chains of citations like `id.` will be interrupted. Note that this is based on the output HTML, *not* the original Markdown text. Defaults to `L\. ?Rev\.|J\. ?Law|\. ?([Cc]ode|[Cc]onst)` 46 | - `ignore_markup`: Whether CiteURL should detect citations even when they are interrupted by markup, like "\Id.\ at 37." Defaults to `True`. 47 | 48 | ## GNOME Shell Search Provider 49 | 50 | If you use the GNOME desktop environment, you can install [my other project](https://extensions.gnome.org/extension/4225/gnome-citeurl-search-provider/) to look up citations directly from your desktop! 51 | -------------------------------------------------------------------------------- /docs_source/index.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 |

CiteURL Logo

4 |

pytest GitHub issues GitHub license PyPI

5 | 6 | CiteURL is an extensible tool that parses legal citations and makes links to websites where you can read the relevant law for free. It can be used to quickly look up a reference, or to insert a hyperlink for every long- or short-form citation found in a longer text. 7 | 8 | If you want to quickly try it out, it's available as a web app at [citation.link](https://www.citation.link). 9 | 10 | --- 11 | 12 | Here's a sample of the links CiteURL can make: 13 | 14 | > Federal law provides that courts should award prevailing civil rights plaintiffs reasonable attorneys fees, 42 USC § 1988(b), and, by discretion, expert fees, id. at (c). This is because the importance of civil rights litigation cannot be measured by a damages judgment. See Riverside v. Rivera, 477 U.S. 561 (1986). But Evans v. Jeff D. upheld a settlement where the plaintiffs got everything they wanted, on condition that they waive attorneys' fees. 475 U.S. 717 (1986). This ruling lets savvy defendants create a wedge between plaintiffs and their attorneys, discouraging civil rights suits and undermining the court's logic in Riverside, 477 U.S. at 574-78. 15 | 16 | --- 17 | 18 | By default, CiteURL supports Bluebook-style citations to [over 130 sources](https://github.com/raindrum/citeurl/blob/main/citeurl/templates) of U.S. law, including: 19 | 20 | - most reported state and federal court opinions 21 | - the U.S. Code and Code of Federal Regulations 22 | - the U.S. Constitution and all state constitutions 23 | - the codified laws for every state and territory except Arkansas, Georgia, Guam, and Puerto Rico. 24 | 25 | You can also add more sources of law by [writing your own citation templates](https://raindrum.github.io/citeurl/template-yamls/) in YAML format. 26 | 27 | ## Installation 28 | 29 | To install just enough to make CiteURL work, run this command: 30 | 31 | ```bash 32 | python3 -m pip install citeurl 33 | ``` 34 | 35 | Substitute `citeurl[full]` for `citeurl` if you want to install the optional dependencies `flask` and `appdirs`, necessary for hosting citeurl as a website and reading custom templates from the user's home directory. 36 | 37 | 38 | 39 | ## Usage 40 | 41 | CiteURL provides four command-line tools: 42 | 43 | - `citeurl process`: Parse a text and insert an HTML hyperlink for every citation it contains, including shortform citations. 44 | - `citeurl lookup`: Look up a single citation and display information about it. 45 | - `citeurl host`: Host an instance of CiteURL as a web app like [citation.link](https://www.citation.link). 46 | - `citeurl makejs`: Export an instance of CiteURL's lookup feature as JavaScript or a static web page. More info is available [here](https://raindrum.github.io/citeurl/frontends#javascript). 47 | 48 | Each command has its own command-line arguments you can view with the `-h` option. They all share the `-t` option, which allows you to load a list of custom [citation templates](https://raindrum.github.io/citeurl/template-yamls/) in YAML form. 49 | 50 | Here are a few common use cases: 51 | 52 | ```bash 53 | # Process a court opinion and output a version where each citation is hyperlinked: 54 | citeurl process -i INPUT_FILE.html -o OUTPUT_FILE.html 55 | ``` 56 | 57 | ```bash 58 | # Look up a single citation and open it directly in a browser 59 | citeurl lookup "42 USC 1983" -b 60 | ``` 61 | 62 | ```bash 63 | # List the top ten authorities cited in a text, from most citations to least: 64 | cat INPUT_FILE.html | citeurl process -a 10 65 | ``` 66 | 67 | ```bash 68 | # Host a lookup tool with custom templates, and serve it on the local network: 69 | citeurl host -t PATH_TO_YOUR_TEMPLATES.YAML -s 70 | ``` 71 | 72 | CiteURL is also available in a few other forms besides the command-line tool: 73 | 74 | - [citation.link](https://www.citation.link), the web app 75 | - [a flexible Python library](https://raindrum.github.io/citeurl/library) 76 | - [an extension](https://raindrum.github.io/citeurl/frontends#markdown-extension) to [Python-Markdown](https://python-markdown.github.io/) 77 | - [a desktop search provider](https://extensions.gnome.org/extension/4225/gnome-citeurl-search-provider/) for Linux users with the GNOME shell 78 | 79 | ## Credits 80 | 81 | Many thanks to these websites, which CiteURL's default templates frequently link to: 82 | 83 | - Harvard's [Caselaw Access Project](https://cite.case.law/) - for most court cases 84 | - [CourtListener](https://www.courtlistener.com/) - for other court cases 85 | - Cornell's [Legal Information Institute](https://www.law.cornell.edu/) - for the U.S. Code and many federal rules 86 | - [Ballotpedia](https://ballotpedia.org) - for the vast majority of state constitutions 87 | - [LawServer.com](https://www.lawserver.com/tools/laws) - for statutes in about a dozen states and territories whose websites don't have a compatible URL scheme 88 | -------------------------------------------------------------------------------- /docs_source/library.md: -------------------------------------------------------------------------------- 1 | # Library Reference 2 | 3 | This page documents how to include CiteURL in your Python programming projects. 4 | 5 | The first step is to instantiate a [Citator](#citator), which by default contains all of CiteURL's built-in [Templates](#templates): 6 | 7 | ``` python 8 | from citeurl import Citator 9 | citator = Citator() 10 | ``` 11 | 12 | After that, you can feed it text to return a list of [Citations](#citation) it finds: 13 | 14 | ``` python 15 | text = """ 16 | Federal law provides that courts should award prevailing civil rights plaintiffs reasonable attorneys fees, 42 USC § 1988(b), and, by discretion, expert fees, id. at (c). This is because the importance of civil rights litigation cannot be measured by a damages judgment. See Riverside v. Rivera, 477 U.S. 561 (1986). But Evans v. Jeff D. upheld a settlement where the plaintiffs got everything they wanted, on condition that they waive attorneys' fees. 475 U.S. 717 (1986). This ruling lets savvy defendants create a wedge between plaintiffs and their attorneys, discouraging civil rights suits and undermining the court's logic in Riverside, 477 U.S. at 574-78. 17 | """ 18 | citations = citator.list_cites(text) 19 | ``` 20 | 21 | Once you have a list of citations, you can get information about each one: 22 | 23 | ```python 24 | print(citations[0].text) 25 | # 42 USC § 1988(b) 26 | print(citations[0].tokens) 27 | # {'Title': '42', 'Section': '1988', 'subsection': '(b)'} 28 | print(citations[0].URL) 29 | # https://www.law.cornell.edu/uscode/text/42/1988#b 30 | ``` 31 | 32 | You can also compare citations to one another, to determine whether they reference the same material or a subsection thereof: 33 | 34 | ```python 35 | art_I = citator.cite('U.S. Const. Art. I') 36 | also_art_I = citator.cite('Article I of the U.S. Constitution') 37 | art_I_sec_3 = citator.cite('U.S. Const. Art. I, § 3') 38 | 39 | assert art_I == also_art_I 40 | assert art_I_sec_3 in art_I 41 | ``` 42 | 43 | If you don't want to bother with all the details, you can also just use [insert_links()](#insert_links) to turn all the citations in a text into hyperlinks: 44 | 45 | ```python 46 | from citeurl import insert_links 47 | 48 | text = "42 USC § 1988. Id. at (b)." 49 | output = insert_links(text) 50 | 51 | assert output == '42 USC § 1988. Id. at (b).' 52 | ``` 53 | 54 | ## Citator 55 | 56 | ::: citeurl.Citator 57 | 58 | ## Citation 59 | 60 | ::: citeurl.Citation 61 | 62 | ## Template 63 | 64 | ::: citeurl.Template 65 | 66 | ## TokenType 67 | 68 | ::: citeurl.TokenType 69 | 70 | ## TokenOperation 71 | 72 | ::: citeurl.TokenOperation 73 | 74 | ## StringBuilder 75 | 76 | ::: citeurl.StringBuilder 77 | 78 | ## insert_links() 79 | 80 | ::: citeurl.insert_links 81 | 82 | ## cite() 83 | 84 | ::: citeurl.cite 85 | 86 | ## list_cites() 87 | 88 | ::: citeurl.list_cites 89 | 90 | ## DEFAULT_CITATOR 91 | 92 | The [insert_links](#insert_links), [cite](#cite), and [list_cites](#list_cites) functions all make use of a built-in [citator](#Citator) that is not defined by the library user. By default, this is the citator that is returned when you run `Citator()`. However, it is possible to add additional templates to this default citator, by installing the wonderful [AppDirs](https://pypi.org/project/appdirs) library and placing the templates in one of the following directories: 93 | 94 | Linux: `~/.config/citeurl` 95 | 96 | Mac: `~/Library/Preferences/citeurl` 97 | 98 | Windows 7+: `C:\Users\\AppData\Local\raindrum\citeurl` 99 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: CiteURL 2 | repo_url: https://github.com/raindrum/citeurl 3 | docs_dir: docs_source 4 | site_dir: docs 5 | 6 | theme: 7 | name: material 8 | logo: assets/logo.svg 9 | favicon: assets/favicon.png 10 | palette: 11 | scheme: slate 12 | primary: blue 13 | accent: pink 14 | icon: 15 | repo: fontawesome/brands/github 16 | 17 | edit_uri: edit/main/docs_source 18 | 19 | plugins: 20 | - search 21 | - mkdocstrings: 22 | default_handler: python 23 | handlers: 24 | python: 25 | rendering: 26 | show_root_heading: no 27 | show_root_full_path: no 28 | show_root_toc_entry: no 29 | show_object_full_path: no 30 | heading_level: 3 31 | 32 | markdown_extensions: 33 | - attr_list 34 | - pymdownx.highlight 35 | - pymdownx.superfences 36 | 37 | extra: 38 | version: 11.5.1 39 | history_buttons: false 40 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open('README.md', 'r') as f: 4 | readme = f.read() 5 | 6 | setuptools.setup( 7 | name = 'citeurl', 8 | version = '11.5.1', 9 | description = 'an extensible tool to process legal citations in text', 10 | author = 'Simon Raindrum Sherred', 11 | author_email = 'simonraindrum@gmail.com', 12 | license = 'MIT', 13 | long_description = readme, 14 | long_description_content_type = "text/markdown", 15 | url="https://raindrum.github.io/citeurl", 16 | packages = setuptools.find_packages(), 17 | entry_points = { 18 | 'console_scripts': ['citeurl=citeurl.cli:main'], 19 | 'markdown.extensions': ['citeurl=citeurl.mdx:CiteURLExtension'], 20 | }, 21 | include_package_data = True, 22 | install_requires = ['pyyaml'], 23 | extras_require = { 24 | 'web': ['flask', 'gevent'], 25 | 'config': ['appdirs'], 26 | 'full': ['flask', 'gevent', 'appdirs'], 27 | }, 28 | classifiers = [ 29 | 'Development Status :: 5 - Production/Stable', 30 | 'Intended Audience :: Legal Industry', 31 | 'Programming Language :: Python :: 3.9', 32 | 'License :: OSI Approved :: MIT License', 33 | 'Operating System :: OS Independent', 34 | 'Topic :: Text Processing :: Filters', 35 | 'Topic :: Text Processing :: Markup :: HTML', 36 | 'Topic :: Text Processing :: Markup :: Markdown', 37 | 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', 38 | 'Topic :: Software Development :: Libraries :: Python Modules', 39 | ], 40 | ) 41 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raindrum/citeurl/a929a29d7b72b5bf376d90f48759a5496ecaf799/tests/__init__.py -------------------------------------------------------------------------------- /tests/_test_links.py: -------------------------------------------------------------------------------- 1 | "tests for individual citation templates. not all of them are ready yet" 2 | 3 | # import requests 4 | # import time 5 | 6 | from warnings import warn 7 | 8 | import requests 9 | import pytest 10 | 11 | from citeurl import Citator 12 | from .test_templates import TESTS 13 | 14 | @pytest.mark.parametrize('template', TESTS.keys()) 15 | def test_link(template): 16 | test_data = TESTS[template] 17 | if not test_data.get('URL'): 18 | warn(f'SKIPPED {template} - no URL') 19 | return 20 | print(f'{template} ({test_data["URL"]}) ... ', end='') 21 | try: 22 | response = requests.get(test_data['URL']) 23 | except requests.exceptions.SSLError: 24 | warn(f'SKIPPED {template} - SSL error') 25 | return 26 | if response.status_code == 403: 27 | warn(f'SKIPPED {template} - Error 403 (Forbidden)') 28 | return 29 | assert response.ok, f"{test_data['URL']} returned {response.status_code}" 30 | 31 | -------------------------------------------------------------------------------- /tests/test_core.py: -------------------------------------------------------------------------------- 1 | """ 2 | tests of CiteURL's core functions: 3 | recognizing long and shortform citations, inserting links into text, 4 | and aggregating citations into authorities 5 | """ 6 | 7 | from citeurl import Citator, insert_links, list_cites, cite 8 | 9 | TEXT = """Federal law provides that courts should award prevailing civil rights plaintiffs reasonable attorneys fees, 42 USC § 1988(b), and, by discretion, expert fees, id. at (c). This is because the importance of civil rights litigation cannot be measured by a damages judgment. See Riverside v. Rivera, 477 U.S. 561 (1986). But Evans v. Jeff D. upheld a settlement where the plaintiffs got everything they wanted, on condition that they waive attorneys' fees. 475 U.S. 717 (1986). This ruling lets savvy defendants create a wedge between plaintiffs and their attorneys, discouraging civil rights suits and undermining the court's logic in Riverside, 477 U.S. at 574-78.""" 10 | 11 | def test_init_citator(): 12 | Citator() 13 | 14 | def test_list_citations(): 15 | citations = list_cites(TEXT) 16 | 17 | assert str(citations[0]) == '42 USC § 1988(b)' 18 | assert citations[0].tokens == { 19 | 'title': '42', 20 | 'section': '1988', 21 | 'subsection': '(b)' 22 | } 23 | assert citations[0].URL == ( 24 | 'https://www.law.cornell.edu/uscode/text/42/1988#b' 25 | ) 26 | assert citations[1].tokens == { 27 | 'title': '42', 28 | 'section': '1988', 29 | 'subsection': '(c)' 30 | } 31 | 32 | def test_insert_links(): 33 | citations = list_cites(TEXT) 34 | output = insert_links(TEXT) 35 | assert output == """Federal law provides that courts should award prevailing civil rights plaintiffs reasonable attorneys fees, 42 USC § 1988(b), and, by discretion, expert fees, id. at (c). This is because the importance of civil rights litigation cannot be measured by a damages judgment. See Riverside v. Rivera, 477 U.S. 561 (1986). But Evans v. Jeff D. upheld a settlement where the plaintiffs got everything they wanted, on condition that they waive attorneys\' fees. 475 U.S. 717 (1986). This ruling lets savvy defendants create a wedge between plaintiffs and their attorneys, discouraging civil rights suits and undermining the court\'s logic in Riverside, 477 U.S. at 574-78.""" 36 | 37 | #def test_list_authorities(): 38 | # citations = Citator().list_cites(TEXT) 39 | # authorities = list_authorities(citations) 40 | # assert str(authorities[0]) == '42 USC § 1988' 41 | # assert str(authorities[1]) == '477 U.S. 561' 42 | # assert len(authorities[1].citations) == 2 43 | 44 | def test_lookup(): 45 | citation = cite('42 usc 1983') 46 | assert citation is not None 47 | 48 | def test_redundant_links(): 49 | text = '42 U.S.C. § 1983. Id.' 50 | cites = list_cites(text) 51 | output = insert_links(text, redundant_links=True) 52 | assert 'Id.' in output 53 | 54 | def test_require_wordbreaks_after_tokens(): 55 | text = """ 56 | Initial cite: Cal. Const. Art. I § 7. 57 | Intervening cite: 56 U.S. 365. 58 | False shortform: Section 778a.""" 59 | assert len(list_cites(text)) == 2 60 | 61 | def test_ignore_markup(): 62 | text = '42 USC § 1983. Id. at (b)' 63 | output = insert_links(text) 64 | assert '(b)' in output 65 | -------------------------------------------------------------------------------- /tests/test_js.py: -------------------------------------------------------------------------------- 1 | "tests of CiteURL's ability to export JavaScript search engines" 2 | 3 | from citeurl import Citator 4 | from citeurl.web.makejs import makejs 5 | from quickjs import Function 6 | 7 | citator = Citator() 8 | 9 | def test_makejs(): 10 | "make sure the program can generate JavaScript without error" 11 | makejs(citator) 12 | 13 | def test_js_search_function(): 14 | "make sure the generated javascript actually works" 15 | getUrlForQuery = Function('getUrlForQuery', makejs(citator)) 16 | URL = getUrlForQuery("42 USC § 1988(b)") 17 | assert URL == 'https://www.law.cornell.edu/uscode/text/42/1988#b' 18 | -------------------------------------------------------------------------------- /tests/test_mdx.py: -------------------------------------------------------------------------------- 1 | "tests for CiteURL's extension to Python-Markdown" 2 | 3 | from markdown import markdown 4 | 5 | def test_default_mdx(): 6 | "make sure the default markdown extension works" 7 | output = markdown('413 F. Supp. 1281', extensions=['citeurl']) 8 | assert output == '

413 F. Supp. 1281

' 9 | 10 | def test_configured_mdx(): 11 | "make sure at least a few of the markdown config options work" 12 | output = markdown( 13 | '413 F. Supp. 1281', 14 | extensions=['citeurl'], 15 | extension_configs={'citeurl': {'attributes': {'class': 'cite'}}} 16 | ) 17 | assert output == '

413 F. Supp. 1281

' 18 | --------------------------------------------------------------------------------