Showing preview only (1,383K chars total). Download the full file or copy to clipboard to get everything.
Repository: WeDontPanic/Jotoba
Branch: dev
Commit: 52073c380906
Files: 435
Total size: 1.2 MB
Directory structure:
gitextract_jueqquxr/
├── .dockerignore
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows/
│ └── docker-image.yml
├── .gitignore
├── Cargo.toml
├── Dockerfile
├── LICENSE
├── README.md
├── deny.toml
├── docker-compose.yaml
├── html/
│ └── assets/
│ ├── css/
│ │ ├── main.css
│ │ ├── mobile.css
│ │ ├── overlay/
│ │ │ ├── croppingOverlay.css
│ │ │ ├── footerOverlay.css
│ │ │ ├── imgUploadOverlay.css
│ │ │ ├── notificationOverlay.css
│ │ │ ├── overlayBase.css
│ │ │ ├── radicalOverlay.css
│ │ │ ├── settingsOverlay.css
│ │ │ └── suggestionOverlay.css
│ │ ├── page/
│ │ │ ├── aboutPage.css
│ │ │ ├── errorPage.css
│ │ │ ├── footer.css
│ │ │ ├── helpPage.css
│ │ │ ├── indexPage.css
│ │ │ ├── infoPage.css
│ │ │ ├── kanjiPage.css
│ │ │ ├── multiPage/
│ │ │ │ ├── kana.css
│ │ │ │ ├── kanji.css
│ │ │ │ └── markdown.css
│ │ │ ├── namePage.css
│ │ │ ├── newsPage.css
│ │ │ ├── sentencePage.css
│ │ │ ├── wordExtensions/
│ │ │ │ ├── searchAnnotation.css
│ │ │ │ └── sentenceReader.css
│ │ │ └── wordPage.css
│ │ ├── search/
│ │ │ ├── choices.css
│ │ │ └── searchRow.css
│ │ └── tools/
│ │ ├── alerts.css
│ │ ├── pagination.css
│ │ └── ripple.css
│ ├── docs.html
│ ├── fonts/
│ │ └── fonts.css
│ ├── js/
│ │ ├── lib/
│ │ │ ├── d3.js
│ │ │ ├── jc.js
│ │ │ └── jotobaChoices.js
│ │ ├── locales/
│ │ │ └── collection.js
│ │ ├── mobile.js
│ │ ├── page/
│ │ │ ├── infoPage.js
│ │ │ ├── kanjiPage.js
│ │ │ ├── newsPage.js
│ │ │ ├── overlay/
│ │ │ │ ├── notifications.js
│ │ │ │ ├── settings.js
│ │ │ │ └── settings_overlay.js
│ │ │ ├── sentencePage.js
│ │ │ └── wordPage.js
│ │ ├── qol.js
│ │ ├── search/
│ │ │ ├── api.js
│ │ │ ├── eventHandler.js
│ │ │ ├── overlay/
│ │ │ │ ├── imageSearch.js
│ │ │ │ ├── radicalSearch.js
│ │ │ │ ├── speechSearch.js
│ │ │ │ └── suggestionOverlay.js
│ │ │ ├── search.js
│ │ │ ├── shared.js
│ │ │ └── suggestions.js
│ │ └── tools/
│ │ ├── jotoTools.js
│ │ ├── ripple.js
│ │ ├── service-worker.js
│ │ ├── theme.js
│ │ ├── utils.js
│ │ └── utils2.js
│ └── settings/
│ ├── manifest.json
│ └── opensearch.xml
├── jotoba_bin/
│ ├── Cargo.toml
│ ├── benches/
│ │ ├── my_benchmark.rs
│ │ └── resources.rs
│ └── src/
│ ├── check.rs
│ ├── cli.rs
│ ├── main.rs
│ └── webserver.rs
├── lib/
│ ├── api/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── app/
│ │ │ ├── completions/
│ │ │ │ ├── kanji/
│ │ │ │ │ ├── meaning.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── reading.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── names/
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── opensearch/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── parse.rs
│ │ │ │ ├── request.rs
│ │ │ │ └── words/
│ │ │ │ ├── foreign.rs
│ │ │ │ ├── hashtag.rs
│ │ │ │ ├── kana_end_ext.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── native.rs
│ │ │ ├── details/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── sentences.rs
│ │ │ │ └── word.rs
│ │ │ ├── img/
│ │ │ │ ├── mod.rs
│ │ │ │ └── request.rs
│ │ │ ├── kanji/
│ │ │ │ ├── ids_tree/
│ │ │ │ │ ├── builder.rs
│ │ │ │ │ └── mod.rs
│ │ │ │ └── mod.rs
│ │ │ ├── mod.rs
│ │ │ ├── news/
│ │ │ │ ├── detailed.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── short.rs
│ │ │ ├── radical/
│ │ │ │ ├── kanji.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── search/
│ │ │ │ ├── jp_search.rs
│ │ │ │ ├── meaning.rs
│ │ │ │ └── mod.rs
│ │ │ └── search/
│ │ │ ├── kanji.rs
│ │ │ ├── mod.rs
│ │ │ ├── names.rs
│ │ │ ├── sentences.rs
│ │ │ └── words.rs
│ │ ├── internal/
│ │ │ ├── info/
│ │ │ │ ├── mod.rs
│ │ │ │ └── words.rs
│ │ │ └── mod.rs
│ │ ├── lib.rs
│ │ └── search/
│ │ ├── kanji/
│ │ │ └── mod.rs
│ │ ├── mod.rs
│ │ ├── name/
│ │ │ └── mod.rs
│ │ ├── sentence/
│ │ │ └── mod.rs
│ │ └── word/
│ │ └── mod.rs
│ ├── config/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── lib.rs
│ ├── engine/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── pushable/
│ │ │ ├── counter.rs
│ │ │ ├── f_max_cnt.rs
│ │ │ ├── max_cnt.rs
│ │ │ ├── mod.rs
│ │ │ ├── push_dbg.rs
│ │ │ ├── push_fn.rs
│ │ │ └── push_mod.rs
│ │ ├── relevance/
│ │ │ ├── data.rs
│ │ │ ├── item.rs
│ │ │ └── mod.rs
│ │ ├── result.rs
│ │ ├── task.rs
│ │ └── utils.rs
│ ├── error/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── api_error.rs
│ │ └── lib.rs
│ ├── frontend/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── about.rs
│ │ │ ├── actix_ructe.rs
│ │ │ ├── build.rs
│ │ │ ├── direct.rs
│ │ │ ├── help_page.rs
│ │ │ ├── index.rs
│ │ │ ├── lib.rs
│ │ │ ├── liveness.rs
│ │ │ ├── news_ep.rs
│ │ │ ├── og_tags.rs
│ │ │ ├── search_ep.rs
│ │ │ ├── search_help.rs
│ │ │ ├── session.rs
│ │ │ ├── templ_utils.rs
│ │ │ ├── unescaped.rs
│ │ │ ├── url_query.rs
│ │ │ ├── user_settings.rs
│ │ │ └── web_error.rs
│ │ └── templates/
│ │ ├── base.rs.html
│ │ ├── base_index.rs.html
│ │ ├── error_page.rs.html
│ │ ├── functional/
│ │ │ └── render_sentence.rs.html
│ │ ├── overlays/
│ │ │ ├── info/
│ │ │ │ ├── collocations.rs.html
│ │ │ │ ├── definitions_jp.rs.html
│ │ │ │ └── inflections.rs.html
│ │ │ ├── mobile_overlays.rs.html
│ │ │ ├── page/
│ │ │ │ ├── decomposition_graph.rs.html
│ │ │ │ ├── image_crop.rs.html
│ │ │ │ ├── loading.rs.html
│ │ │ │ └── settings.rs.html
│ │ │ ├── page_overlays.rs.html
│ │ │ ├── search_overlays.rs.html
│ │ │ └── searchbar/
│ │ │ ├── image_input.rs.html
│ │ │ ├── radicals.rs.html
│ │ │ ├── speech.rs.html
│ │ │ └── suggestions.rs.html
│ │ ├── pages/
│ │ │ ├── about.rs.html
│ │ │ ├── info.rs.html
│ │ │ ├── kanji.rs.html
│ │ │ ├── names.rs.html
│ │ │ ├── news.rs.html
│ │ │ ├── search_help.rs.html
│ │ │ ├── sentences.rs.html
│ │ │ └── words.rs.html
│ │ └── subtemplates/
│ │ ├── footer.rs.html
│ │ ├── head.rs.html
│ │ ├── input_dropdown.rs.html
│ │ ├── main_body.rs.html
│ │ └── paginator.rs.html
│ ├── indexes/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── hashtag.rs
│ │ ├── kanji/
│ │ │ ├── mod.rs
│ │ │ ├── reading.rs
│ │ │ └── reading_freq/
│ │ │ ├── k_freq_item.rs
│ │ │ ├── mod.rs
│ │ │ └── reading.rs
│ │ ├── lib.rs
│ │ ├── names.rs
│ │ ├── ng_freq.rs
│ │ ├── radical.rs
│ │ ├── regex.rs
│ │ ├── sentences.rs
│ │ ├── storage/
│ │ │ ├── kanji.rs
│ │ │ ├── mod.rs
│ │ │ ├── name.rs
│ │ │ ├── radical.rs
│ │ │ ├── sentence.rs
│ │ │ ├── suggestions.rs
│ │ │ ├── utils.rs
│ │ │ └── word.rs
│ │ ├── term_freq.rs
│ │ └── words/
│ │ ├── foreign.rs
│ │ ├── mod.rs
│ │ └── native.rs
│ ├── japanese/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── furigana/
│ │ │ ├── generate/
│ │ │ │ ├── mod.rs
│ │ │ │ └── traits.rs
│ │ │ ├── mod.rs
│ │ │ └── tests.rs
│ │ ├── guessing.rs
│ │ ├── lib.rs
│ │ └── radicals.rs
│ ├── localization/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── error.rs
│ │ ├── language.rs
│ │ ├── lib.rs
│ │ └── traits.rs
│ ├── news/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── lib.rs
│ ├── resources/
│ │ ├── Cargo.toml
│ │ ├── build.rs
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── retrieve/
│ │ │ ├── kanji.rs
│ │ │ ├── mod.rs
│ │ │ ├── name.rs
│ │ │ ├── sentence.rs
│ │ │ └── word.rs
│ │ └── storage/
│ │ ├── feature.rs
│ │ ├── kanji.rs
│ │ ├── mod.rs
│ │ ├── name.rs
│ │ ├── sentence.rs
│ │ └── word.rs
│ ├── search/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── engine/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── names/
│ │ │ │ │ ├── foreign.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── native.rs
│ │ │ │ ├── radical/
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── sentences/
│ │ │ │ │ ├── foreign.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── native.rs
│ │ │ │ └── words/
│ │ │ │ ├── foreign.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── native/
│ │ │ │ ├── k_reading.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── regex.rs
│ │ │ ├── executor/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── out_builder.rs
│ │ │ │ ├── producer.rs
│ │ │ │ ├── search_result.rs
│ │ │ │ └── searchable.rs
│ │ │ ├── kanji/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── order.rs
│ │ │ │ ├── result.rs
│ │ │ │ └── tag_only.rs
│ │ │ ├── lib.rs
│ │ │ ├── name/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── order/
│ │ │ │ │ ├── foreign.rs
│ │ │ │ │ ├── japanese.rs
│ │ │ │ │ └── mod.rs
│ │ │ │ └── producer/
│ │ │ │ ├── foreign.rs
│ │ │ │ ├── kanji_reading.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── native/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── split.rs
│ │ │ │ └── sequence.rs
│ │ │ ├── query/
│ │ │ │ ├── form.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── parser/
│ │ │ │ │ ├── lang.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── prefix.rs
│ │ │ │ │ ├── req_terms.rs
│ │ │ │ │ └── tags.rs
│ │ │ │ ├── prefix.rs
│ │ │ │ ├── regex.rs
│ │ │ │ ├── tags.rs
│ │ │ │ └── user_settings.rs
│ │ │ ├── radical/
│ │ │ │ ├── mod.rs
│ │ │ │ └── word/
│ │ │ │ ├── foreign.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── romaji.rs
│ │ │ ├── sentence/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── order/
│ │ │ │ │ ├── foreign.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── native.rs
│ │ │ │ ├── producer/
│ │ │ │ │ ├── filter.rs
│ │ │ │ │ ├── foreign.rs
│ │ │ │ │ ├── kanji.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── native.rs
│ │ │ │ │ ├── sequence.rs
│ │ │ │ │ └── tag.rs
│ │ │ │ └── result.rs
│ │ │ └── word/
│ │ │ ├── filter.rs
│ │ │ ├── kanji.rs
│ │ │ ├── mod.rs
│ │ │ ├── order/
│ │ │ │ ├── foreign.rs
│ │ │ │ ├── kanji_reading.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── native.rs
│ │ │ │ └── regex.rs
│ │ │ ├── producer/
│ │ │ │ ├── foreign/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── romaji.rs
│ │ │ │ │ └── task.rs
│ │ │ │ ├── japanese/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── number.rs
│ │ │ │ │ ├── sentence_reader.rs
│ │ │ │ │ └── task.rs
│ │ │ │ ├── k_reading.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── regex.rs
│ │ │ │ ├── sequence.rs
│ │ │ │ └── tag.rs
│ │ │ └── result.rs
│ │ └── tests/
│ │ └── search_test.rs
│ ├── sentence_reader/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── analyzer.rs
│ │ ├── grammar/
│ │ │ ├── mod.rs
│ │ │ ├── rule.rs
│ │ │ └── rule_set.rs
│ │ ├── lib.rs
│ │ ├── output.rs
│ │ └── sentence/
│ │ ├── inflection.rs
│ │ ├── mod.rs
│ │ ├── owned_morpheme.rs
│ │ └── part.rs
│ ├── types/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── api/
│ │ │ ├── app/
│ │ │ │ ├── completions/
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── details/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── query.rs
│ │ │ │ │ ├── sentence.rs
│ │ │ │ │ └── word.rs
│ │ │ │ ├── image/
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── kanji/
│ │ │ │ │ ├── ids_tree.rs
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── news/
│ │ │ │ │ ├── long.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── short.rs
│ │ │ │ ├── radical/
│ │ │ │ │ ├── find_kanji.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── search.rs
│ │ │ │ └── search/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── query.rs
│ │ │ │ └── responses/
│ │ │ │ ├── k_compounds.rs
│ │ │ │ ├── kanji.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── names.rs
│ │ │ │ ├── sentences.rs
│ │ │ │ └── words/
│ │ │ │ ├── inflection.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── sentence.rs
│ │ │ │ └── word.rs
│ │ │ ├── internal/
│ │ │ │ ├── info/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── words.rs
│ │ │ │ └── mod.rs
│ │ │ ├── mod.rs
│ │ │ └── search/
│ │ │ ├── kanji.rs
│ │ │ ├── mod.rs
│ │ │ ├── name.rs
│ │ │ ├── sentence.rs
│ │ │ └── word.rs
│ │ ├── jotoba/
│ │ │ ├── indexes/
│ │ │ │ ├── hashtag.rs
│ │ │ │ └── mod.rs
│ │ │ ├── kanji/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── radical.rs
│ │ │ │ └── reading.rs
│ │ │ ├── language/
│ │ │ │ ├── mod.rs
│ │ │ │ └── param.rs
│ │ │ ├── mod.rs
│ │ │ ├── names/
│ │ │ │ ├── mod.rs
│ │ │ │ └── name_type.rs
│ │ │ ├── pagination/
│ │ │ │ ├── mod.rs
│ │ │ │ └── page.rs
│ │ │ ├── search/
│ │ │ │ ├── guess.rs
│ │ │ │ ├── help.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── query_type.rs
│ │ │ ├── sentences/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── tag.rs
│ │ │ │ └── translation.rs
│ │ │ └── words/
│ │ │ ├── dialect.rs
│ │ │ ├── dict.rs
│ │ │ ├── field.rs
│ │ │ ├── foreign_language.rs
│ │ │ ├── gtype.rs
│ │ │ ├── inflection.rs
│ │ │ ├── information.rs
│ │ │ ├── misc.rs
│ │ │ ├── mod.rs
│ │ │ ├── part_of_speech.rs
│ │ │ ├── pitch/
│ │ │ │ ├── border.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── raw_data.rs
│ │ │ ├── priority.rs
│ │ │ ├── reading/
│ │ │ │ ├── iter.rs
│ │ │ │ └── mod.rs
│ │ │ └── sense.rs
│ │ ├── lib.rs
│ │ └── raw/
│ │ ├── jmdict/
│ │ │ └── mod.rs
│ │ ├── jmnedict/
│ │ │ └── mod.rs
│ │ ├── kanjidict/
│ │ │ └── mod.rs
│ │ └── mod.rs
│ └── utils/
│ ├── Cargo.toml
│ └── src/
│ ├── binary_search.rs
│ ├── korean.rs
│ └── lib.rs
├── locales/
│ ├── de.mo
│ ├── de.po
│ ├── en.mo
│ ├── en.po
│ ├── hu.mo
│ └── hu.po
├── rustfmt.toml
└── scripts/
└── gen_locales.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .dockerignore
================================================
/html/assets/js/lib/loadAnalytics.js
/html/assets/svg
/html/audio
/html/*.html
!/html/docs.html
/target
out
*.old
.env
ipadic/
unidic/
unidic-mecab/
data/
data
/resources/
/suggestions
/suggestions_
audio_old
*.bat
=======
indexes/
indexes_old
massiv.out
*/*/target
tmp/
img_scan_tmp/
/news
.gitignore
/*.zip
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
custom: ["https://paypal.me/JojiiOfficial", "https://paypal.me/yukaru1"]
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve. Check the trello board first!
title: ''
labels: ''
assignees: ''
---
Before you file a bug report, check the [trello board](https://trello.com/b/nmG0xgaW/jotoba-roadmap) if this has already added on the road map.
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/workflows/docker-image.yml
================================================
name: Docker Image CI
on:
push:
branches: [ master ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build the Docker image
run: docker build . --file Dockerfile --tag ghcr.io/wedontpanic/jotoba:latest
- name: Export image
run: |
echo ${{ secrets.GH_TOKEN }} | docker login ghcr.io -u ${{ secrets.GH_USER }} --password-stdin
docker push ghcr.io/wedontpanic/jotoba:latest
# - name: Update server
# uses: garygrossgarten/github-action-ssh@release
# with:
# command: /home/jotoba/update.sh
# host: ${{ secrets.HOST }}
# port: ${{ secrets.PORT }}
# username: ${{ secrets.SSH_USER }}
# privateKey: ${{ secrets.SSH_KEY}}
================================================
FILE: .gitignore
================================================
/html/assets/js/lib/loadAnalytics.js
/html/assets/svg
/html/audio
/html/assets/sitemap.xml
/html/assets/*.html
!/html/assets/docs.html
/target
out
*.old
.env
ipadic/
unidic/
unidic-mecab/
data/
data
/resources/
/suggestions
/suggestions_
audio_old
*.bat
=======
/indexes/
indexes_old
massiv.out
*/*/target
tmp/
img_scan_tmp/
/news
cluster_find
.idea
/resources_src/
/*.zip
================================================
FILE: Cargo.toml
================================================
[workspace]
members = ["jotoba_bin", "lib/*"]
[profile.dev]
opt-level = 2
incremental = true
lto = false
strip = false
[profile.release]
lto = "fat"
strip = true
================================================
FILE: Dockerfile
================================================
FROM rust:1.70.0-bullseye as build
WORKDIR app
COPY ./lib ./lib
COPY ./.git ./.git
COPY ./locales ./locales
COPY ./Cargo.lock ./
COPY ./Cargo.toml ./
COPY ./tests ./tests
COPY ./scripts ./scripts
COPY ./jotoba_bin ./jotoba_bin
COPY ./LICENSE ./
RUN apt clean
RUN apt-get update --allow-releaseinfo-change -y
RUN apt upgrade -y
RUN apt install build-essential cmake pkg-config libssl-dev libleptonica-dev libtesseract-dev clang tesseract-ocr-jpn -y
# Build your program for release
RUN cargo build --release
RUN mv target/release/jotoba .
FROM debian:bullseye
WORKDIR app
RUN apt-get update --allow-releaseinfo-change -y
RUN apt upgrade -y
RUN apt install build-essential pkg-config cmake libssl-dev libleptonica-dev libtesseract-dev clang tesseract-ocr-jpn -y
COPY --from=build /app/jotoba .
COPY --from=build /app/locales ./locales
RUN useradd -s /bin/bash runuser
USER runuser
# Run the binary
CMD ["./jotoba","-s"]
================================================
FILE: LICENSE
================================================
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.
================================================
FILE: README.md
================================================
# Jotoba <img width="30" align="center" src="/html/assets/jotokun/JotoBook.svg">
Jotoba is a free online multi-language japanese dictionary based on lots of various free resources.<br>
Public instance: [jotoba.de](https://jotoba.de)<br>
<a href="https://discord.gg/ysSkFFxmjr"><img src="https://img.shields.io/discord/854657468867936267?style=for-the-badge" alt="Discord"></a>
<br>
### Get the new [Android App](https://play.google.com/store/apps/details?id=com.jotoba.mobile) now!
# Team
<table>
<tr align="center">
<td><a href="https://github.com/JojiiOfficial">JojiiOfficial</a></td>
<td><a href="https://github.com/Yukaru-san">Yukaru</a></td>
</tr>
<tr align="center">
<td><a href="https://github.com/JojiiOfficial"><img src="https://avatars.githubusercontent.com/u/15957865?v=4" width="100" height="100"></a></td>
<td><a href="https://github.com/Yukaru-san"><img src="https://avatars.githubusercontent.com/u/57414313?v=4" width="100" height="100"></a></td>
</tr>
<tr align="center">
<td>Backend dev</td>
<td>Frontend dev</td>
</tr>
</table>
# Dictionary licenses
Almost all of the data used by [jotoba.de](https://jotoba.de) comes from external sources like [edrdg](http://www.edrdg.org/)
for Words, Kanji, Names and Radicales or [WaniKani](https://www.wanikani.com/) and [Kanjialive](https://kanjialive.com/) for audio sources.
For a detailed list of used resources and their licenses please visit [jotoba.de/about](https://jotoba.de/about).
# Roadmap
Please refer to our [Trello board](https://trello.com/b/nmG0xgaW/jotoba-roadmap) for a roadmap and the developing progress.
# Developing
Jotoba is open source. Contributions are highly welcome and can be made by anyone who wants to help Jotoba grow.<br>
That being said, all API endpoints exposed by Jotoba are documented and allowed to be used (within a fair amount).<br>
Refer to [API-Docs](https://jotoba.de/docs.html) for the API documentations and to [CONTRIBUTION](https://github.com/WeDontPanic/Jotoba/wiki/Contributing) for an introduction in how to contribute code to Jotoba.
# Translations
Jotoba is aimed to be a multi-language dictionary thus the website is aimed to be fully translated into all available languages.<br>
However, the main developers of this project don't speak ~10 languages.
If you're interested in contributing to this project we are thankful for each translation contribution.<br>
For a guide on how to add translations please refer to the [wiki](https://github.com/WeDontPanic/Jotoba/wiki/Translate-%5BPage%5D).
# License
Jotoba itself is licensed under AGPL 3.0 or later.
Please refer to the [license file](https://github.com/WeDontPanic/Jotoba/blob/master/LICENSE) for further information.
Joto-kun (including all of his variants) is licensed under [CC BY-NC-ND 4.0](https://creativecommons.org/licenses/by-nc-nd/4.0/).
================================================
FILE: deny.toml
================================================
# This template contains all of the possible sections and their default values
# Note that all fields that take a lint level have these possible values:
# * deny - An error will be produced and the check will fail
# * warn - A warning will be produced, but the check will not fail
# * allow - No warning or error will be produced, though in some cases a note
# will be
# The values provided in this template are the default values that will be used
# when any section or field is not specified in your own configuration
# If 1 or more target triples (and optionally, target_features) are specified,
# only the specified targets will be checked when running `cargo deny check`.
# This means, if a particular package is only ever used as a target specific
# dependency, such as, for example, the `nix` crate only being used via the
# `target_family = "unix"` configuration, that only having windows targets in
# this list would mean the nix crate, as well as any of its exclusive
# dependencies not shared by any other crates, would be ignored, as the target
# list here is effectively saying which targets you are building for.
targets = [
# The triple can be any string, but only the target triples built in to
# rustc (as of 1.40) can be checked against actual config expressions
#{ triple = "x86_64-unknown-linux-musl" },
# You can also specify which target_features you promise are enabled for a
# particular target. target_features are currently not validated against
# the actual valid features supported by the target architecture.
#{ triple = "wasm32-unknown-unknown", features = ["atomics"] },
]
# This section is considered when running `cargo deny check advisories`
# More documentation for the advisories section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html
[advisories]
# The path where the advisory database is cloned/fetched into
db-path = "~/.cargo/advisory-db"
# The url(s) of the advisory databases to use
db-urls = ["https://github.com/rustsec/advisory-db"]
# The lint level for security vulnerabilities
vulnerability = "deny"
# The lint level for unmaintained crates
unmaintained = "warn"
# The lint level for crates that have been yanked from their source registry
yanked = "warn"
# The lint level for crates with security notices. Note that as of
# 2019-12-17 there are no security notice advisories in
# https://github.com/rustsec/advisory-db
notice = "warn"
# A list of advisory IDs to ignore. Note that ignored advisories will still
# output a note when they are encountered.
ignore = [
#"RUSTSEC-0000-0000",
]
# Threshold for security vulnerabilities, any vulnerability with a CVSS score
# lower than the range specified will be ignored. Note that ignored advisories
# will still output a note when they are encountered.
# * None - CVSS Score 0.0
# * Low - CVSS Score 0.1 - 3.9
# * Medium - CVSS Score 4.0 - 6.9
# * High - CVSS Score 7.0 - 8.9
# * Critical - CVSS Score 9.0 - 10.0
#severity-threshold =
# If this is true, then cargo deny will use the git executable to fetch advisory database.
# If this is false, then it uses a built-in git library.
# Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support.
# See Git Authentication for more information about setting up git authentication.
#git-fetch-with-cli = true
# This section is considered when running `cargo deny check licenses`
# More documentation for the licenses section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html
[licenses]
# The lint level for crates which do not have a detectable license
unlicensed = "warn"
# List of explicitly allowed licenses
# See https://spdx.org/licenses/ for list of possible licenses
# [possible values: any SPDX 3.11 short identifier (+ optional exception)].
allow = [
"MIT",
"AGPL-3.0",
"GPL-3.0",
"Apache-2.0",
"BSD-3-Clause",
"MPL-2.0",
"BSD-2-Clause",
"CC0-1.0",
"Unicode-DFS-2016",
"ISC",
#"Apache-2.0 WITH LLVM-exception",
]
# List of explicitly disallowed licenses
# See https://spdx.org/licenses/ for list of possible licenses
# [possible values: any SPDX 3.11 short identifier (+ optional exception)].
deny = [
#"Nokia",
]
# Lint level for licenses considered copyleft
copyleft = "warn"
# Blanket approval or denial for OSI-approved or FSF Free/Libre licenses
# * both - The license will be approved if it is both OSI-approved *AND* FSF
# * either - The license will be approved if it is either OSI-approved *OR* FSF
# * osi-only - The license will be approved if is OSI-approved *AND NOT* FSF
# * fsf-only - The license will be approved if is FSF *AND NOT* OSI-approved
# * neither - This predicate is ignored and the default lint level is used
allow-osi-fsf-free = "neither"
# Lint level used when no other predicates are matched
# 1. License isn't in the allow or deny lists
# 2. License isn't copyleft
# 3. License isn't OSI/FSF, or allow-osi-fsf-free = "neither"
default = "deny"
# The confidence threshold for detecting a license from license text.
# The higher the value, the more closely the license text must be to the
# canonical license text of a valid SPDX license file.
# [possible values: any between 0.0 and 1.0].
confidence-threshold = 0.8
# Allow 1 or more licenses on a per-crate basis, so that particular licenses
# aren't accepted for every possible crate as with the normal allow list
exceptions = [
# Each entry is the crate and version constraint, and its specific allow
# list
#{ allow = ["Zlib"], name = "adler32", version = "*" },
]
# Some crates don't have (easily) machine readable licensing information,
# adding a clarification entry for it allows you to manually specify the
# licensing information
#[[licenses.clarify]]
# The name of the crate the clarification applies to
#name = "ring"
# The optional version constraint for the crate
#version = "*"
# The SPDX expression for the license requirements of the crate
#expression = "MIT AND ISC AND OpenSSL"
# One or more files in the crate's source used as the "source of truth" for
# the license expression. If the contents match, the clarification will be used
# when running the license check, otherwise the clarification will be ignored
# and the crate will be checked normally, which may produce warnings or errors
# depending on the rest of your configuration
#license-files = [
# Each entry is a crate relative path, and the (opaque) hash of its contents
#{ path = "LICENSE", hash = 0xbd0eed23 }
#]
[licenses.private]
# If true, ignores workspace crates that aren't published, or are only
# published to private registries.
# To see how to mark a crate as unpublished (to the official registry),
# visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field.
ignore = false
# One or more private registries that you might publish crates to, if a crate
# is only published to private registries, and ignore is true, the crate will
# not have its license(s) checked
registries = [
#"https://sekretz.com/registry
]
# This section is considered when running `cargo deny check bans`.
# More documentation about the 'bans' section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html
[bans]
# Lint level for when multiple versions of the same crate are detected
multiple-versions = "warn"
# Lint level for when a crate version requirement is `*`
wildcards = "allow"
# The graph highlighting used when creating dotgraphs for crates
# with multiple versions
# * lowest-version - The path to the lowest versioned duplicate is highlighted
# * simplest-path - The path to the version with the fewest edges is highlighted
# * all - Both lowest-version and simplest-path are used
highlight = "all"
# List of crates that are allowed. Use with care!
allow = [
#{ name = "ansi_term", version = "=0.11.0" },
]
# List of crates to deny
deny = [
# Each entry the name of a crate and a version range. If version is
# not specified, all versions will be matched.
#{ name = "ansi_term", version = "=0.11.0" },
#
# Wrapper crates can optionally be specified to allow the crate when it
# is a direct dependency of the otherwise banned crate
#{ name = "ansi_term", version = "=0.11.0", wrappers = [] },
]
# Certain crates/versions that will be skipped when doing duplicate detection.
skip = [
#{ name = "ansi_term", version = "=0.11.0" },
]
# Similarly to `skip` allows you to skip certain crates during duplicate
# detection. Unlike skip, it also includes the entire tree of transitive
# dependencies starting at the specified crate, up to a certain depth, which is
# by default infinite
skip-tree = [
#{ name = "ansi_term", version = "=0.11.0", depth = 20 },
]
# This section is considered when running `cargo deny check sources`.
# More documentation about the 'sources' section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html
[sources]
# Lint level for what to happen when a crate from a crate registry that is not
# in the allow list is encountered
unknown-registry = "warn"
# Lint level for what to happen when a crate from a git repository that is not
# in the allow list is encountered
unknown-git = "warn"
# List of URLs for allowed crate registries. Defaults to the crates.io index
# if not specified. If it is specified but empty, no registries are allowed.
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
# List of URLs for allowed Git repositories
allow-git = []
[sources.allow-org]
# 1 or more github.com organizations to allow git sources for
github = [""]
# 1 or more gitlab.com organizations to allow git sources for
gitlab = [""]
# 1 or more bitbucket.org organizations to allow git sources for
bitbucket = [""]
================================================
FILE: docker-compose.yaml
================================================
version: "3.7"
services:
app:
image: ghcr.io/wedontpanic/jotoba:latest
restart: always
ports:
- 8080:8080
working_dir: /app
volumes:
- ./html:/app/html
- ./resources:/app/resources
- ./data:/app/data
================================================
FILE: html/assets/css/main.css
================================================
/* ----------------- Color Themes ----------------- */
:root,
:root.light {
--background: #f2f1f0;
--overlay: #f3f3f3;
--primaryColor: #34a83c;
--bgPrimaryColor: #50c058;
--secondaryColor: #909dc0;
--primaryTextColor: #222222;
--secondaryTextColor: #ffffff;
--searchBackground: #ffffff;
--searchTextColor: #555555;
--shadowColor: #222222;
--tagColor: #808080;
--itemBG: #d3d3d3;
--alert: #ff4254;
--danger: #dc3545;
--danger2: #dd4c5b;
/* Special */
--itemBG_075: rgb(211, 211, 211, 0.75);
--langSep: rgba(50, 103, 51, 0.1);
--lineColor: rgba(0, 0, 0, 0.1);
--backgroundShadow: rgba(34, 34, 34, 0.1);
/* Used by Radical Picker */
--borderColor: var(--searchTextColor);
--disabledColor: #bdbdbd;
/* Used by overlays */
--headerColor: var(--borderColor);
--headerScrollBar: var(--borderColor);
/* Overlay Button */
--buttonText: #1f1f1f;
--buttonBg: #dedede;
--buttonBgActive: #e6e6e6;
/* Overlay Graph */
--graphLink: #d1d1d1;
--graphCircle: var(--bgPrimaryColor);
--graphStroke: rgb(116 116 116 / 6%);
--graphPath: white;
--graphText: white;
}
:root.dark {
--background: #202324;
--overlay: #1f2123;
--primaryColor: #2d9034;
--bgPrimaryColor: #338f4f;
--secondaryColor: #435993;
--primaryTextColor: #d3cfc9;
--secondaryTextColor: #e8e6e3;
--searchBackground: #181a1b;
--searchTextColor: #b2aca2;
--shadowColor: #9d9488;
--tagColor: #787878;
--itemBG: #7a7a7a;
--itemBG_075: rgba(122, 122, 122, 0.75);
--lineColor: rgba(211, 207, 201, 0.1);
--backgroundShadow: rgba(34, 34, 34, 0.2);
--borderColor: var(--itemBG_075);
--disabledColor: #3c3c3c;
--headerColor: var(--lineColor);
--headerScrollBar: #434344;
--buttonText: #fff;
--buttonBg: #404040;
--buttonBgActive: #515151;
--alert: #e93849;
}
:root.dark ::-moz-selection {
background: var(--secondaryColor);
}
:root.dark ::selection {
background: var(--secondaryColor);
}
/* ------------------- Scrollbar Adjustments ------------------- */
* {
scrollbar-width: thin;
}
::-webkit-scrollbar {
width: 20px;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: #c1c1c1;
border-radius: 20px;
border: 6px solid transparent;
background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
background-color: #a8a8a8;
}
:root.dark ::-webkit-scrollbar-thumb {
background-color: var(--itemBG);
}
/* ----------------- Overall Page Adjustments ----------------- */
html,
body {
font-size: 100%;
background: var(--background) !important;
}
body {
color: var(--primaryTextColor);
cursor: auto;
font-family: "Helvetica Neue", Helvetica, Arial, "Source Han Sans",
"源ノ角ゴシック", "Hiragino Sans", "HiraKakuProN-W3",
"Hiragino Kaku Gothic ProN W3", "Hiragino Kaku Gothic ProN",
"ヒラギノ角ゴ ProN W3", "Noto Sans", "Noto Sans JP", "Noto Sans CJK JP",
"メイリオ", Meiryo, "游ゴシック", YuGothic, "MS Pゴシック",
"MS PGothic", "MS ゴシック", "MS Gothic", sans-serif;
font-style: normal;
font-weight: normal;
line-height: 1.5;
margin: 0;
padding: 0;
position: relative;
-webkit-font-smoothing: auto;
}
h3,
h4 {
font-family: "Helvetica", "Arial", sans-serif;
}
body {
min-height: 100vh;
height: 100vh;
}
body.index {
display: grid;
grid-template-rows: 1fr auto;
overflow-x: hidden;
}
.noselect,
.tags,
.clickable,
.entry-count,
.no-drag {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */ /* Konqueror HTML */
-moz-user-select: none; /* Old versions of Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
-o-user-select: none; /* Opera */
user-select: none; /* Non-prefixed version, currently supported by Chrome, Edge, Opera and Firefox */
}
#backdrop {
position: fixed;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 999999;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: var(--backgroundShadow);
}
button {
display: flex;
place-content: center;
place-items: center;
}
.btn-danger {
color: white !important;
background-color: var(--danger) !important;
border-color: var(--danger) !important;
}
.btn-danger:not(:disabled):not(.disabled).active:focus,
.btn-danger:not(:disabled):not(.disabled):active:focus {
box-shadow: unset;
}
.btn-danger:hover {
background-color: var(--danger2) !important;
}
.close:focus {
outline: 0;
}
object {
pointer-events: none;
}
.vl {
border-left: 1px solid var(--searchTextColor);
}
:root.dark hr {
border-top: 1px solid rgba(255,255,255,.1);
}
h3 {
font-size: 22px;
text-align: center;
text-align: -webkit-center;
font-weight: bold;
}
h4 {
font-size: 11px;
color: var(--searchTextColor);
margin: 2px 0 0 0;
}
.hidden {
display: none !important;
}
.highlight {
color: var(--primaryColor);
}
.indented {
margin-left: 5%;
}
.clickable {
color: var(--primaryColor);
text-align: center;
text-align: -webkit-center;
cursor: pointer;
}
.clickable.title {
font-size: 22px;
font-weight: bold;
}
.clickable.fat {
font-size: 20px;
}
.clickable:hover {
text-decoration: underline;
color: var(--primaryColor);
}
.no-margin {
margin: 0px 0px 0px 0px !important;
}
.no-align {
text-align: unset;
}
.text-left {
text-align: left;
}
.top-padding-05-rem {
padding-top: 0.5rem;
}
.right-padding-10 {
padding-right: 10px;
}
.right-padding-20 {
padding-right: 20px;
}
.d-flex.wrap {
flex-wrap: wrap;
}
.no-highlight {
color: var(--primaryTextColor);
}
.no-highlight:hover {
text-decoration: none;
}
a:hover {
color: unset;
text-decoration: unset !important;
}
.black {
color: var(--primaryTextColor);
}
.fat {
font-weight: bold;
}
.center-text {
text-align: center;
text-align: -webkit-center;
}
/* ----------------- Commonly Used CSS ----------------- */
.search-suggestion {
color: inherit;
}
.search-suggestion:focus,
.search-suggestion:link,
.search-suggestion:visited,
.search-suggestion:hover {
text-decoration: none;
}
#page-container {
padding-top: 10px;
padding-left: 10px;
padding-right: 10px;
}
.main-container {
width: 100%;
max-width: 1145px;
height: -webkit-max-content;
height: -moz-max-content;
height: max-content;
}
.main-info {
width: 100%;
height: -webkit-max-content;
height: -moz-max-content;
height: max-content;
padding-bottom: 10px;
}
.secondary-info {
height: -webkit-max-content;
height: -moz-max-content;
height: max-content;
width: 35%;
padding-bottom: 10px;
padding-left: 10px;
}
@media only screen and (max-width: 600px) {
.secondary-info {
padding-left: 0px;
}
}
.tags {
color: var(--tagColor);
font-size: 12px;
margin-top: 6px;
}
.tags.fat {
font-size: 20px;
font-weight: bold;
color: var(--primaryTextColor);
}
.tags.slim {
font-size: 20px;
font-weight: 400;
color: var(--primaryTextColor);
margin-top: -5px !important;
}
.tags.no-margin {
margin-top: 0px;
}
.d-flex .row-tag-entry + .row-tag-entry {
padding-left: 10px;
}
.entry-count {
color: var(--tagColor);
line-height: 30px;
margin-right: 5px;
position: relative;
height: 100%;
}
/* --- Slider adjustments --- */
.slider-parent {
padding-top: 30px;
padding-right: 20px;
width: 150px;
}
.slider-output {
font-size: 13px;
padding-top: 10px;
color: var(--primaryColor);
}
/* The slider itself */
.slider {
-webkit-appearance: none;
width: 130px;
height: 15px;
border-radius: 10px;
background: var(--itemBG);
outline: none;
opacity: 0.7;
transition: opacity 0.2s;
}
/* Mouse-over effects */
.slider:hover {
opacity: 1;
}
:root.dark .slider:hover {
opacity: 0.8;
}
/* The slider handle for webkit and mozilla with its extra shit */
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
border-color: var(--bgPrimaryColor);
background: var(--bgPrimaryColor);
cursor: pointer;
}
:root.dark .slider::-webkit-slider-thumb {
border-color: #3ace67;
background: #3ace67;
}
.slider::-webkit-slider-thumb:hover {
background-color: var(--primaryColor);
}
:root.dark .slider::-webkit-slider-thumb:hover {
border-color: #2eeb67;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
border-radius: 50%;
background: var(--bgPrimaryColor);
cursor: pointer;
}
:root.dark .slider::-moz-range-thumb:hover {
background: #3ace67;
}
.slider::-moz-range-thumb:hover {
background-color: var(--primaryColor);
}
:root.dark .slider::-moz-range-thumb:hover {
border-color: #2eeb67;
}
.res-separator {
border-top: 2px solid var(--lineColor);
margin-right: 5px;
}
.res-separator.sentence {
width: 100%;
}
/* Useful stuff */
.flex-center {
display: flex;
place-content: center;
}
#loading-screen {
visibility: hidden;
background-color: #000;
opacity: 0;
transition: opacity 0.15s linear;
z-index: 2000;
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
#loading-screen.show {
display: block;
opacity: 0.5;
}
.loading-animation {
border: 16px solid var(--itemBG);
border-radius: 50%;
border-top: 16px solid var(--primaryColor);
width: 100px;
height: 100px;
-webkit-animation: spin 2s linear infinite; /* Safari */
animation: spin 2s linear infinite;
}
/* Safari */
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* SVG Colors */
:root.dark .mobile-nav-btn > div,
:root.dark .mobile-nav-inner-btn > div:not(.jumpSvg) {
background-color: var(--searchTextColor) !important;
color: var(--searchTextColor) !important;
}
:root.dark .mobile-nav-inner-btn > span {
color: var(--searchTextColor) !important;
}
.searchSvg,
.settingsSvg,
.clearSvg,
.voiceSvg {
mask-size: cover !important;
-webkit-mask-size: cover !important;
}
.searchSvg {
height: 18px;
width: 18px;
background-color: var(--primaryColor);
mask: url("/assets/svg/ui/search.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/search.svg") no-repeat center;
}
.searchSvg.index {
height: 16px;
width: 16px;
margin-top: 3px;
margin-left: 5px;
background-color: var(--secondaryTextColor);
}
.settingsSvg {
height: 30px;
width: 30px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/settings.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/settings.svg") no-repeat center;
}
.infoSvg {
scale: 1.1;
height: 30px;
width: 30px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/info.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/info.svg") no-repeat center;
}
.notificationSvg {
scale: 1.1;
height: 30px;
width: 30px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/notification.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/notification.svg") no-repeat center;
}
.settingsSvg.mobile {
height: 26px;
width: 26px;
}
.clearSvg {
height: 20px;
width: 20px;
margin-top: 2px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/clear.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/clear.svg") no-repeat center;
}
.voiceSvg {
margin-top: 2px;
height: 24px;
width: 24px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/voice.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/voice.svg") no-repeat center;
}
.voiceSvg.mobile {
height: 30px;
width: 30px;
background-color: var(--tagColor);
}
.voiceSvg.index {
margin-top: -7px;
height: 30px;
width: 30px;
}
.voiceSvg.active {
background-color: var(--primaryColor) !important;
}
.cameraSvg {
height: 28px;
width: 28px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/camera.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/camera.svg") no-repeat center;
}
.cameraSvg.index {
margin-top: -5px;
margin-right: 33px;
}
.jumpSvg {
margin-left: -1px;
height: 26px;
width: 26px;
background-color: var(--primaryColor) !important;
mask: url("/assets/svg/ui/jump.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/jump.svg") no-repeat center;
}
.menuSvg {
height: 28px;
width: 28px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/menu.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/menu.svg") no-repeat center;
}
.undoSvg {
height: 20px;
width: 20px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/undo.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/undo.svg") no-repeat center;
cursor: pointer;
}
.imgUploadSvg {
margin: 11px 14px 0px -35px;
height: 20px;
width: 20px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/upload.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/upload.svg") no-repeat center;
cursor: pointer;
}
.downloadSvg {
height: 20px;
width: 20px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/download.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/download.svg") no-repeat center;
cursor: pointer;
pointer-events: none;
}
.conjugationSvg {
height: 20px;
width: 20px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/conjugation.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/conjugation.svg") no-repeat center;
cursor: pointer;
pointer-events: none;
}
.sentenceSvg {
height: 20px;
width: 20px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/sentence.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/sentence.svg") no-repeat center;
cursor: pointer;
pointer-events: none;
}
.transitivitySvg {
height: 20px;
width: 20px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/transitivity.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/transitivity.svg") no-repeat center;
cursor: pointer;
pointer-events: none;
}
.linkSvg {
height: 20px;
width: 20px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/link.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/link.svg") no-repeat center;
cursor: pointer;
pointer-events: none;
}
.copySvg {
height: 21px;
width: 21px;
background-color: var(--primaryColor);
mask: url("/assets/svg/ui/copy.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/copy.svg") no-repeat center;
cursor: pointer;
pointer-events: none;
}
.tooltipSvg {
height: 20px;
width: 20px;
background-color: var(--searchTextColor);
mask: url("/assets/svg/ui/3dot.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/3dot.svg") no-repeat center;
cursor: pointer;
}
.shareSvg {
height: 20px;
width: 20px;
background-color: var(--disabledColor);
mask: url("/assets/svg/ui/share.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/share.svg") no-repeat center;
cursor: pointer;
}
.discordSvg {
height: 35px;
width: 35px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/_discord.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/_discord.svg") no-repeat center;
cursor: pointer;
}
.githubSvg {
height: 35px;
width: 35px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/_github.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/_github.svg") no-repeat center;
cursor: pointer;
}
.donationSvg {
height: 35px;
width: 35px;
margin-top: -1px;
background-color: var(--tagColor);
mask: url("/assets/svg/ui/_donation.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/_donation.svg") no-repeat center;
cursor: pointer;
}
================================================
FILE: html/assets/css/mobile.css
================================================
/*
Used to make mobile stuff less ugly. Will be transfered into the others file bit-by-bit.
*/
@media only screen and (max-width: 600px) {
.modal-open {
margin-right: 0px;
}
/* -------- Index -------- */
.circle {
width: 1.25em;
height: 1.25em;
border-radius: 50%;
font-size: 50px;
text-align: center;
text-align: -webkit-center;
background-color: var(--itemBG_075);
line-height: 110%;
position: fixed;
bottom: .5em;
right: .5em;
}
article {
padding-left: 0.5em;
padding-right: 1em;
}
.voiceSvg.index {
margin-top: -4px;
}
/* -------- Word Search -------- */
.search-embedded-btn {
right: 5px;
margin-top: 9px;
}
.search-embedded-btn.search {
right: 7px;
margin-top: 10px;
}
.search-embedded-btn.radical {
display: none;
}
#voiceBtn > svg {
margin-top: 3px;
}
#search-vl {
position: absolute;
right: 39px;
}
#emptyInput {
right: 31px;
margin-top: 7px;
}
.choices__item--selectable.selected {
color: var(--primaryColor) !important;
}
.form-main > div > div > div > div .choices__list.choices__list--dropdown {
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
}
.searchDivInner form .inner-form .input-field.first-wrap .choices__list.choices__list--dropdown {
padding-right: 20px;
}
.overlay.suggestion {
width: 98%;
margin-left: 1%;
}
.image-search-input {
width: 100%;
}
#shadow-text {
padding: 0px;
margin: 13px 15px;
}
#content-container {
flex-direction: column!important;
min-width: 350px;
}
body {
height: -webkit-max-content;
height: -moz-max-content;
height: max-content;
}
.searchDivInner form .inner-form .input-field.first-wrap .choices__inner .choices__list--single .choices__item {
display: none;
}
.searchDivInner form .inner-form .input-field.first-wrap {
width: 40px;
}
.searchDivInner form .inner-form .input-field input {
height: 100%;
background: transparent;
border: 0;
display: block;
width: 88%;
padding: 25px 0px 27px 15px;
font-size: 1em;
color: var(--searchTextcolor);
}
#searchDiv {
margin: 0px;
width: 100%;
max-width: 1000px;
}
h3 {
margin-bottom: 2rem;
}
.title-div {
width: 100%;
}
.btn-container, .main-tab-select {
display: none !important;
}
.title-div {
padding-top: 10px;
width: 100%;
}
.main-info {
height: -webkit-max-content;
height: -moz-max-content;
height: max-content;
width: 100%;
}
.mdl-menu__container {
margin-right: 15px;
}
.main-info > .d-flex.center {
flex-direction: column!important;
align-self: center;
align-items: center;
width: 100%;
}
.main-info > .d-flex.flex-row {
align-self: center;
align-items: center;
margin-left: -10px;
}
.definition-wrapper.d-flex.flex-row {
padding-bottom: 5px;
}
.secondary-info {
height: -webkit-max-content;
height: -moz-max-content;
height: max-content;
align-self: center;
width: 100%;
/* padding-left: 15%; */
}
.secondary-info > div > .kanji-entry {
justify-content: center;
}
.kanji-entry.left.fixed > .d-flex {
padding-bottom: 5px;
}
.kanji-entry.right {
padding-left: 2vw;
padding-right: 2vw;
width: 100%;
}
.kanji-preview.large {
position: absolute;
}
.translation.kanji {
padding-top: 70px !important;
padding-left: 0px !important;
padding-right: 0px !important;
text-align: center;
text-align: -webkit-center;
}
.kanji-parent > .tags {
padding-bottom: 5px;
text-align: center;
text-align: -webkit-center;
}
.list-entry > .tags, .kanji-entry.right, .tags.no-margin {
text-align: left;
}
.entry-min-height-1 {
min-height: unset;
}
.entry-min-height-2 {
min-height: unset;
}
/* ----------- Overlay ----------- */
.clickable.collocation {
width: 70%;
margin-left: 20%;
}
.table.conjugation {
margin-left: 0px;
width: 101%;
}
/* -------- Radical Picker -------- */
.rad-picker-icon {
font-size: 30px;
}
/* -------- Image Upload -------- */
.cropping-target-border {
width: calc(100% - 30px);
left: 15px;
}
.croppie-container {
width: calc(100% - 60px);
left: 30px;
}
.croppie-container .cr-boundary {
height: 485px;
overflow: scroll;
}
/* -------- Help Page --------- */
.help-joto {
display: none;
}
/* -------- Mobile only -------- */
.mobile-nav {
overflow-y: hidden;
position: fixed;
bottom: 75px;
right: 24px;
z-index: 100;
height: 50%;
width: 60px;
}
.mobile-nav-btn {
place-content: center;
place-items: center;
display: flex;
position: fixed;
bottom: 20px;
right: 30px;
z-index: 99;
border: none;
outline: none;
background-color: var(--itemBG_075);
border-radius: 50%;
width: 50px;
height: 50px;
text-align: center;
text-align: -webkit-center;
}
.mobile-nav-inner-btn {
width: 45px;
height: 45px;
border: none;
outline: none;
background: var(--itemBG_075);
border-radius: 50%;
margin-bottom: 5px;
margin-left: 6px;
transition: all .2s linear;
}
.mobile-nav.hidden > .mobile-nav-inner-btn {
margin-bottom: -50px;
}
#jmp-btn {
padding-bottom: 5px;
transform: rotate(180deg);
}
#jmp-btn > svg > polygon {
fill: var(--primaryColor);
}
.kanji-jump {
text-align: center;
text-align: -webkit-center;
margin-bottom: 20px;
}
.kanji-jump.parent {
text-align: center;
text-align: -webkit-center;
width: 100%;
}
.word-title {
display: none;
}
.info-h3 {
margin-bottom: 0px;
}
/* Radical Picker */
.rad-result-preview {
display: none;
}
.mobile-nav-btn:focus, .mobile-nav-inner-btn:focus {
outline: none;
box-shadow: 0 0 3pt 2pt var(--primaryColor);
}
}
/* Mobile only */
@media only screen and (min-width: 600px) {
.circle, .mobile-nav, .mobile-nav-btn, .mobile-nav-inner-btn, .kanji-jump, .desktop-br {
display: none;
}
}
================================================
FILE: html/assets/css/overlay/croppingOverlay.css
================================================
.modal.fade .modal-dialog.crop {
transition: unset;
transform: unset;
}
.cropping-target-border {
position: fixed;
width: 52vw;
height: 596px;
background: var(--itemBG);
left: 25%;
top: 25px;
}
.croppie-container {
position: fixed;
width: 50%;
height: 500px;
left: 26%;
top: 50px
}
.croppie-container .cr-boundary {
height: 525px;
}
.btn-search.crop {
width: 110px;
height: 30px;
display: inline;
position: absolute;
right: 25px;
top: 93.75%;
background: var(--bgPrimaryColor);
}
.btn-danger.crop {
left: 25px;
}
.croppie-container .cr-slider-wrap {
margin: 10px auto;
}
.cr-slider {
padding: 0;
}
.cr-slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
margin-top: -9px;
width: 25px;
height: 25px;
background: var(--primaryColor);
cursor: pointer;
}
.cr-slider::-moz-range-thumb {
width: 25px;
height: 25px;
margin-top: -9px;
background: var(--primaryColor);
cursor: pointer;
}
.cr-slider::-webkit-slider-runnable-track{
width:100%;
height:7px;
background:rgba(0,0,0,.5);
border:0;
border-radius:3px
}
.cr-slider::-moz-range-track{
width:100%;
height:7px;
background:rgba(0,0,0,.5);
border:0;
border-radius:3px
}
================================================
FILE: html/assets/css/overlay/footerOverlay.css
================================================
.cookie-footer {
display: block;
position: fixed;
bottom: 5%;
padding: 10px;
background: var(--overlay);
border: 2px solid var( --tagColor);
border-radius: 10px;
z-index: 100;
max-width: -webkit-max-content;
max-width: -moz-max-content;
max-width: max-content;
width: inherit;
width: 90%;
left: 50%;
transform: translate(-50%, 0);
}
.cookie-footer > .res-separator {
margin-top: 5px;
margin-bottom: 5px;
}
.cookie-btn {
margin-top: 10px;
margin-right: 10px;
}
.joto-cookie {
width: 85px;
margin-right: 25px;
}
/* Mobile adjustments */
@media only screen and (max-width: 600px) {
.cookie-footer span, .cookie-btn {
font-size: 12px;
}
.joto-cookie {
width: 125px;
margin-right: 25px;
}
}
================================================
FILE: html/assets/css/overlay/imgUploadOverlay.css
================================================
.image-search-input {
width: 50%;
padding: 0px 39px 0px 8px;
margin-top: 4px;
display: block;
border: 1px solid var(--lineColor);
background-color: var(--searchBackground);
}
.image-search-input.disabled {
cursor: not-allowed;
background: var(--backgroundShadow);
}
.image-search-input:focus {
outline: none;
}
.image-search-upload {
opacity: 0;
margin-left: -40px;
margin-right: 10px;
width: 30px;
margin-top: 5px;
cursor: pointer;
}
.image-search-upload-btn {
border: 1px solid var(--lineColor);
background: var(--overlay);
color: var(--primaryTextColor);
padding: 5px;
font-size: small;
margin-top: 4px;
}
================================================
FILE: html/assets/css/overlay/notificationOverlay.css
================================================
#notifications-container {
position: absolute;
top: 60px;
right: 55px;
width: 16rem;
z-index: 10;
overflow: hidden;
border-radius: .5rem;
background-color: var(--overlay);
color: var(--primaryTextColor);
box-shadow: 0px 8px 20px 0px var(--backgroundShadow);
}
.notifications-info-container {
display: flex;
flex-flow: column;
width: 100%;
padding: 1rem;
overflow: hidden;
}
.notification-title {
padding: .5rem;
margin: -1rem -1rem .5rem;
background-color: var(--bgPrimaryColor);
background: linear-gradient(45deg,var(--bgPrimaryColor),var(--primaryColor));
color: var(--secondaryTextColor);
text-align: center;
text-transform: uppercase;
font-size: large;
}
:root.dark .notification-title {
background: var(--bgPrimaryColor);
}
#notification-content {
margin: .5rem 0;
opacity: .85;
font-weight: 400;
}
#no-result {
padding-bottom: 10px;
text-align: center;
}
.notification-entry {
border-bottom: 1px solid var(--borderColor);
padding: 5px;
cursor: pointer;
}
.notification-entry:not(#no-result):hover {
background: rgba(0, 0, 0, 0.02);
}
:root.dark .notification-entry:not(#no-result):hover {
background: rgba(255, 255, 255, 0.02);
}
.entry-title {
font-weight: bold;
font-size: 16px;
text-overflow: ellipsis;
overflow: hidden;
max-width: 60%;
}
.date-tag {
position: absolute;
right: 25px;
margin-top: -20px;
font-size: 10px;
}
.content > li {
line-height: 15px;
}
.button-container {
display: flex;
grid-gap: .5rem;
gap: .5rem;
margin-top: 10px;
margin-bottom: -10px;
justify-content: flex-end;
}
#notificationModal h1 {
font-size: 1.5rem;
}
#notificationModal h2 {
font-size: 1.25rem;
}
================================================
FILE: html/assets/css/overlay/overlayBase.css
================================================
.overlay {
z-index: 1;
margin-top: 2px;
position: absolute;
width: 100%;
height: -webkit-max-content;
height: -moz-max-content;
height: max-content;
border: 2px solid var(--searchBackground);
border-radius: 20px;
border-top: none;
background-color: var(--searchBackground);
box-shadow: 0px 8px 20px 0px var(--backgroundShadow)
}
.overlay > * {
z-index: 2;
}
.overlay > .flex-column {
margin: 5px 10px;
}
.x-button {
position: absolute;
right: 10px;
font-size: larger;
}
.x-button:hover {
cursor: pointer;
}
.modal-header {
border-bottom-color: var(--lineColor);
}
:root.dark .modal-header > .close {
color: #fff;
}
:root.dark .modal-header > .close:hover {
color: #97a495;
}
.modal-footer {
border-top-color: var(--lineColor);
}
.modal-content {
background-color: var(--overlay);
}
#default_lang_settings {
margin-top: 0.25rem !important;
}
.form-control.small {
width: 100%;
height: 20px;
padding: 0;
padding-left: 1%;
display: inline;
color: var(--searchTextColor);
background: var(--searchBackground);
border-color: var(--lineColor);
}
.form-control.small:focus {
box-shadow: unset;
}
.overlay-button {
position: relative;
display: inline-flex;
flex: auto 0 0;
justify-content: center;
align-items: center;
grid-gap: 4px;
gap: 4px;
padding: 0 0.625rem;
margin: 0;
border: none;
height: 2rem;
font-size: 1rem;
border-radius: 4px;
cursor: pointer;
}
.overlay-button {
color: var(--buttonText);
background-color: var(--buttonBg);
flex-grow: 1;
outline: 0px solid var(--primaryColor);
transition: all .05s ease;
}
.overlay-button:hover, .overlay-button:active {
background-color: var(--buttonBgActive);
}
.overlay-button:active {
outline: 2px solid var(--primaryColor);
}
================================================
FILE: html/assets/css/overlay/radicalOverlay.css
================================================
/*
Used by the radical picker only.
*/
.rad-results {
padding-left: 5px;
padding-top: 10px;
min-height: 90px;
max-height: 25vh;
overflow-y: scroll;
}
.rad-suggestion-wrapper {
width: 100%;
border-top: 1px solid var(--borderColor);
margin-top: 10px;
overflow-x: scroll;
scrollbar-width: none;
background: var(--itemBG_075);
}
.rad-suggestion-wrapper::-webkit-scrollbar {
width: 0;
height: 0;
}
#suggestion-container-rad {
overflow-y: auto;
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
}
#suggestion-container-rad > .search-suggestion:first-child {
padding-top: 0px !important;
}
#suggestion-container-rad > .search-suggestion {
width: -webkit-max-content !important;
width: -moz-max-content !important;
width: max-content !important;
padding-bottom: 0px !important;
padding-left: 10px !important;
padding-right: 10px !important;
}
.rad-page-footer {
height: 50px;
border-top: 1px solid var(--borderColor);
}
.overlay.radical > .clickable {
padding-left: 5px;
}
.overlay.radical > .x-button {
margin: 1px 5px 5px 5px;
}
.rad-page-toggle {
display: flex;
flex-direction: row;
height: 28px;
margin-top: 10px;
margin-bottom: -2px;
cursor: default;
}
.rad-page-toggle:hover {
cursor: pointer;
}
.rad-page-toggle > span {
margin-left: 5px;
margin-right: 5px;
padding-bottom: 1px;
font-size: 18px;
width: 45px;
text-align: center;
cursor: pointer;
}
#r-tc {
display: none;
text-align: center;
text-align: -webkit-center;
}
#r-tc.show {
display: block;
}
#r-tc > .searchSvg {
background-color: var(--searchTextColor);
width: 15px;
height: 15px;
margin-top: 4px;
margin-left: auto;
margin-right: auto;
}
.rad-page-toggle > span:first-child {
margin-left: 20px;
}
.rad-page-toggle > span.disabled {
color: var(--disabledColor);
}
.rad-page-toggle > span.highlighted {
color: var(--primaryColor);
}
.rad-page-toggle span.selected {
color: var(--primaryColor);
border-color: var(--primaryColor);
border: 2px solid var(--borderColor);
border-bottom: unset;
background: var(--background);
border-radius: 6px 6px 0px 0px;
}
.rad-kanji-wrapper {
border: 2px solid var(--borderColor);
margin: 0px -2px -2px -2px;
border-radius: 15px;
overflow-x: auto;
}
.rad-kanji-title {
font-size: 17px;
color: var(--searchTextColor);
margin: 5px;
}
.rad-wrapper {
background-color: var(--background);
}
.kanji-wrapper {
background-color: var(--background);
margin-top: 10px;
margin-bottom: -10px;
border-top: 1px solid var(--borderColor);
border-top-width: 1px;
width: 100%;
}
.rad-picker {
overflow-y: scroll;
margin-bottom: -10px;
padding: 5px;
height: 86px;
scrollbar-width: none;
}
.rad-picker::-webkit-scrollbar {
width: 0px;
}
.rad-btn {
display: inline-block;
border-radius: 2px;
font-size: 24px;
text-align: center;
text-align: -webkit-center;
margin: 1px;
height: 36px;
width: 36px;
padding: 2px 4px;
line-height: 1.4;
}
.rad-btn.picker.selected {
color: var(--secondaryTextColor);
background-color: var(--bgPrimaryColor);
border-radius: 5px;
}
.rad-btn.picker.disabled {
color: var(--lineColor);
}
.rad-btn.picker.disabled:hover {
cursor: unset;
}
.rad-btn.picker {
background-color: none;
}
.rad-btn.num {
color: var(--secondaryTextColor);
background: none;
min-width: 32px;
line-height: 36px;
font-weight: bold;
font-size: 20px;
padding: 0 5px;
}
.rad-btn.num {
background-color: var(--borderColor);
}
.rad-btn:hover:not(.num) {
cursor: pointer;
}
.kanji-search-wrapper > .searchSvg{
display: inline-block;
margin: 15px 0px 0px 18px;
width: 20px;
height: 20px;
background-color: var(--tagColor);
}
.kanji-search-wrapper > .btn-search{
position: absolute;
height: 30px;
width: 100px;
right: 20px;
margin-top: -29px;
border-radius: 15px;
}
#kanji-search {
background-color: var(--searchBackground);
border: none;
border-bottom: 2px solid var(--backgroundShadow);
color: var(--searchTextColor);
position: absolute;
padding-left: 40px;
margin-top: 8px;
margin-left: 10px;
height: 35px;
width: 70%;
max-width: calc(100% - 175px);
}
.undoSvg {
position: absolute;
scale: 1.2;
left: calc(70% + 20px);
margin-top: 18px;
}
#kanji-search:focus-visible, #kanji-search:focus {
outline: unset;
border-bottom: 2px solid var(--tagColor);
}
/* ---------- Scrollbar changes ---------- */
/* Firefox */
.rad-results, .rad-picker, .overlay.radical, .rad-page-toggle {
scrollbar-width: none;
}
/* Literally everyone else */
.rad-results::-webkit-scrollbar, .rad-picker::-webkit-scrollbar, .overlay.radical::-webkit-scrollbar, .rad-page-toggle::-webkit-scrollbar {
width: 0px;
height: 0px;
}
/* Mobile Adjustments */
@media only screen and (max-width: 600px) {
body {
min-height: 650px;
}
.rad-results {
max-height: 20vh !important;
}
.rad-page-toggle {
height: 30px;
overflow-x: auto;
white-space: nowrap;
max-width: 90%;
}
.rad-page-toggle > span:first-child {
margin-left: 10px;
margin-right: 0px;
}
.rad-page-toggle > span:not(:first-child) {
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
padding: 0px 2px 0px 2px;
}
.rad-page-toggle > span {
margin-left: 2%;
margin-right: 2%;
}
.undoSvg {
scale: 1;
right: 132px;
left: unset;
margin-top: 16px;
}
}
================================================
FILE: html/assets/css/overlay/settingsOverlay.css
================================================
#settingsModal .modal-body {
height: 600px;
margin: 0;
padding: 0;
}
#settingsModal .choices__list--dropdown .choices__list {
max-height: 350px;
overflow-y: scroll;
}
#settingsModal .close {
margin: -1rem -1rem -1rem auto;
color: var(--secondaryTextColor);
}
#settingsModal .close:hover {
color: #a7a7a7;
}
#settingsModal .choices:after {
right: 15px;
margin-left: unset;
}
#show_anim_speed_settings_slider {
font-size: 14px;
}
.mdl-layout__header-row {
padding: 0 40px 0 25px !important;
}
.mdl-layout__tab {
padding: 0 24px !important;
}
.mdl-layout__tab-bar {
width: calc(100% - 56px);
}
.mdl-layout__header, .mdl-layout__tab-bar {
background-color: var(--headerColor);
}
.mdl-layout__tab-bar-button {
background-color: var(--headerScrollBar);
}
.mdl-layout.is-upgraded .mdl-layout__tab.is-active::after {
background-color: var(--bgPrimaryColor);
}
.page-content {
margin: 15px;
}
.settings-entry {
display: flex;
flex-direction: row;
}
.settings-entry.ex {
font-size: 0.8em;
}
.settings-entry.txt-input {
margin-top: 5px !important;
margin-bottom: -15px !important;
}
.settings-entry:not(:first-child, .no-gap) {
margin-top: 10px;
}
.inner-header {
font-weight: bold;
text-decoration: underline;
}
.inner-header:first-child {
margin-bottom: 5px;
}
.inner-title {
width: 60%;
font-size: 15px;
align-self: center;
}
.inner-header:not(:first-child) {
margin-bottom: -5px;
margin-top: 10px;
}
.inner-title.display {
width: 72%;
}
.inner-title.txt-input {
margin-top: -10px;
}
.settings-entry.sub > .inner-title {
width: 55%;
margin-left: 5%;
}
.settings-entry.sub > .inner-title::before {
content: "↪";
margin-left: -5px;
margin-right: 5px;
}
.mdl-checkbox {
width: 0%;
}
.mdl-textfield.mdl-js-textfield.is-upgraded {
width: 65%;
margin: -20px 0;
padding-right: 65px;
}
.mdl-textfield__input {
text-align: center;
}
.mdl-textfield.is-focused .mdl-textfield__label:after {
width: calc(100% - 65px);
}
.mdl-textfield__error {
width: 150%;
margin-left: -50px;
}
:root.dark .mdl-textfield__label {
color: var(--borderColor);
}
.mdl-textfield__label:after {
background-color: var(--bgPrimaryColor);
}
#show_anim_speed_settings {
margin-top: 10px;
}
.mdl-textfield__label:after {
left: 0px;
}
.mdl-checkbox.is-checked .mdl-checkbox__box-outline {
border-color: var(--primaryColor);
}
.mdl-checkbox.is-checked .mdl-checkbox__tick-outline {
background-color: var(--primaryColor);
}
:root.dark .mdl-checkbox__box-outline {
border-color: var(--borderColor);
}
:root.dark .mdl-textfield__input {
border-color: var(--itemBG);
}
@media only screen and (max-width: 600px) {
.inner-title {
width: 70%;
}
.settings-entry.sub > .inner-title {
width: 65%;
}
.inner-title.big {
width: 80%;
}
.inner-title.display {
width: 76%;
}
.mdl-textfield.mdl-js-textfield {
padding-right: 0px !important;
left: 7px !important;
}
.mdl-textfield.is-focused .mdl-textfield__label:after {
width: 100%;
}
.mdl-textfield__label:after {
left: 45%;
}
.slidercontainer.settings {
text-align: center;
}
}
================================================
FILE: html/assets/css/overlay/suggestionOverlay.css
================================================
#search::-moz-selection {
color: var(--primaryTextColor);
background-color: var(--secondaryColor);
}
#search::selection {
color: var(--primaryTextColor);
background-color: var(--secondaryColor);
}
.overlay.suggestion {
border: unset;
width: 76%;
margin-left: 17.5%;
}
.search-suggestion {
padding-left: 30px;
padding-bottom: 5px;
font-size: 16px;
cursor: pointer;
}
.search-suggestion:first-child {
padding-top: 5px;
}
.search-suggestion.selected, .search-suggestion:hover {
background: var(--lineColor);
font-weight: bold;
}
.secondary-suggestion {
color: var(--tagColor);
position: absolute;
font-size: 14px;
padding-left: 10px;
margin-top: 1px;
}
#shadow-text {
position: absolute;
pointer-events: none;
height: 100%;
background: transparent;
border: 0;
display: block;
width: 88%;
padding: 13px 32px;
font-size: 16px;
color: var(--searchTextColor);
z-index: 4;
opacity: 0.4;
overflow: hidden;
}
================================================
FILE: html/assets/css/page/aboutPage.css
================================================
article {
padding-left: 10px;
}
.about-title {
font-size: 22px;
font-weight: bold;
color: var(--primaryColor);
}
.joto-wizard {
width: 60px;
position: relative;
margin-top: -37px;
margin-left: 10px;
}
================================================
FILE: html/assets/css/page/errorPage.css
================================================
body {
background: #f2f1f0;
color: #222222;
font-family: 'Open Sans', sans-serif;
max-height: 700px;
overflow: hidden;
}
.err-parent {
text-align: center;
text-align: -webkit-center;
display: block;
position: relative;
width: 80%;
margin: 100px auto;
}
.err-parent > *:not(:first-child) {
margin-bottom: 10px;
}
.err-code {
font-size: 220px;
position: relative;
display: inline-block;
z-index: 2;
height: 250px;
letter-spacing: 15px;
}
.txt-primary {
text-align: center;
text-align: -webkit-center;
display: block;
position: relative;
padding-bottom: 5px;
letter-spacing: 8px;
font-size: 3em;
line-height: 80%;
text-transform: uppercase;
}
.txt-secondary {
text-align: center;
text-align: -webkit-center;
display: block;
position: relative;
font-size: 20px;
text-transform: uppercase;
padding-bottom: 5px;
}
.back-btn {
background-color: #50c058;
position: relative;
display: inline-block;
width: 358px;
padding: 5px;
z-index: 5;
font-size: 25px;
margin: 0 auto;
color: white;
text-decoration: none;
}
.issue-btn {
position: relative;
display: inline-block;
width: 308px;
padding: 5px;
z-index: 5;
font-size: 25px;
margin: 0 auto;
color: white;
text-decoration: none;
}
.git-logo {
fill: black;
}
a:hover {
text-decoration: none;
color: white;
}
hr {
padding: 0;
border: none;
border-top: 5px solid #50c058;
color: #50c058;
text-align: center;
text-align: -webkit-center;
margin: 0px auto;
width: 420px;
height: 10px;
z-index: -10;
}
/* Mobile adjustments */
@media only screen and (max-width: 600px) {
.err-code {
font-size: 150px;
height: 150px;
margin-left: 1vw;
}
.txt-primary {
font-size: 2.5em;
}
.back-btn, hr {
width: 100%;
}
.git-logo {
width: 100%;
}
}
/* Mobile adjustments */
@media only screen and (max-width: 300px) {
.err-code {
font-size: 120px;
margin-top: -30px;
}
}
================================================
FILE: html/assets/css/page/footer.css
================================================
footer {
margin: auto;
width: 50%;
padding-top: 50px;
padding-bottom: 15px;
max-width: 1150px;
width: 100%;
height: -webkit-max-content;
height: -moz-max-content;
height: max-content;
}
.ref-row {
display: flex;
place-content: center;
gap: 2em;
}
.ref-row > .discordSvg, .ref-row > .githubSvg , .ref-row .donationSvg {
background-color: var(--searchTextColor);
}
:root.dark .ref-row > .discordSvg, :root.dark .ref-row > .githubSvg, :root.dark .ref-row .donationSvg {
background-color: var(--tagColor);
}
.ref-row > .donation {
position: relative;
}
.ref-row > .donation > .tooltip {
position: absolute;
visibility: hidden;
width: max-content;
max-width: 33vw;
text-align: center;
border-radius: 6px;
padding: 0.5em;
z-index: 1;
color: #fff;
background-color: var(--bgPrimaryColor);
box-shadow: 0 0 10px 8px var(--backgroundShadow);
}
.ref-row > .donation:hover .tooltip {
visibility: visible;
}
.footer-hr {
border-top: 1px solid var(--primaryColor);
padding-bottom: 10px;
}
.footer-hr:before {
content: '';
border-radius: 100%;
position: absolute;
height: 20px;
width: 120px;
background: var(--background);
margin: -10px;
/* left: calc(50% - 50px); */
margin-left: -60px;
box-shadow: inherit
}
.footer-hr:after {
content: '';
border-radius: 100%;
position: absolute;
height: 10px;
width: 10px;
background: var(--bgPrimaryColor);
margin: -5px;
box-shadow: inherit
}
================================================
FILE: html/assets/css/page/helpPage.css
================================================
.help-joto {
width: 100px;
position: relative;
margin-top: -320px;
margin-left: 530px;
}
div > .fat:not(:first-child) {
margin-top: 1rem;
}
article .fat {
margin-top: 1rem;
}
================================================
FILE: html/assets/css/page/indexPage.css
================================================
/* ----------------- Index Page ----------------- */
.title {
padding-top: 5%;
padding-bottom: 1.25%;
margin: auto;
width: 30%;
}
.titleImg {
width: 30vw;
}
form {
-webkit-margin-after: 1em;
margin-block-end: 1em;
}
#searchDiv {
max-width: 1000px;
}
.overlay {
margin-top: -14px;
}
.overlay.suggestion {
width: 81%;
margin-left: 17.5%;
}
.x-button {
margin-right: 5px;
}
.index-btn-container {
display: flex;
place-content: center;
}
.settingsBtn, .infoBtn, .notificationBtn {
position: absolute !important;
cursor: pointer;
}
.settingsBtn {
top: 20px;
left: 20px;
}
.notificationBtn {
top: 29px;
right: 25px;
}
.notificationPoint {
display: none;
position: absolute;
pointer-events: none;
top: 32px;
right: 30px;
padding: 0.25rem;
border-radius: 2rem;
z-index: 500;
width: 9px;
height: 9px;
background-color: var(--alert);
}
.notificationBtn.update ~ .notificationPoint {
display: block;
}
.infoBtn {
top: 29px;
right: 60px;
}
.notificationBtn.update, .infoBtn.new {
background-color: var(--primaryColor);
}
.inner-form {
border-radius: 20px !important;
}
.input-field.third-wrap {
width: 120px;
height: 45px;
margin: 11px 4px;
}
.input-field.third-wrap.rad {
width: 180px;
height: 45px;
margin: 11px 4px;
}
.btn-search {
color: white !important;
}
.input-field.third-wrap.rad > .btn-search {
background: var(--secondaryColor);
}
.rad-picker-icon {
color: white;
font-size: 22px;
margin-left: 5px;
}
.searchDivInner form .inner-form .input-field input {
width: 96%;
}
.searchDivInner form .inner-form .input-field.first-wrap {
display: unset !important;
}
/* Mobile View */
@media only screen and (max-width: 600px) {
@-webkit-keyframes dropdownAnim {
from {height: 0px;}
to { height: 360%;}
}
@keyframes dropdownAnim {
from {height: 0px;}
to { height: 360%;}
}
.title {
padding-top: 15%;
width: 72%;
}
.titleImg {
width: 70vw;
}
.choices.main[data-type*="select-one"]:after {
border-color: var(--secondaryTextColor) transparent transparent transparent;
}
.choices.main[data-type*="select-one"].is-open:after {
border-color: transparent transparent var(--secondaryTextColor) transparent !important;
}
.inner-form > .index-btn-container {
position: absolute;
top: 75px;
width: 50%;
place-content: flex-start;
z-index: -1;
}
.choices__item.index {
color: white !important;
}
.searchDivInner form .inner-form .input-field.first-wrap .choices__inner .choices__list--single .choices__item {
display: unset !important;
margin-top: 4px;
}
.input-field.first-wrap {
background: var(--bgPrimaryColor);
border-radius: 3px;
height: 45px !important;
width: 100% !important;
margin-left: 10px;
}
.overlay {
z-index: 1;
}
.overlay.suggestion {
width: 100%;
margin-left: 0%;
}
#suggestion-container {
margin: 5px -5px;
}
.rad-picker {
max-height: 44vh;
}
#settingsModal {
display: none;
}
main > .index-btn-container {
flex-direction: row-reverse;
place-content: flex-start;
}
.settingsBtn {
display: unset !important;
left: 10px !important;
}
.btn-container {
display: block !important;
}
.infoBtn, .notificationBtn {
display: unset !important;
}
.infoBtn {
top: 20px;
right: 50px;
}
.notificationBtn {
top: 20px;
right: 15px;
}
.notificationPoint {
top: 20px;
right: 15px;
}
.input-field.third-wrap:not(.rad) {
display: none;
}
.input-field.third-wrap.rad {
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
margin-top: 9px;
padding-right: 15px;
}
.btn-search {
border-radius: 3px;
padding-left: 10px;
padding-right: 10px;
}
.mobile-nav-btn {
display: none;
}
footer > div > span {
font-size: 15px;
}
}
================================================
FILE: html/assets/css/page/infoPage.css
================================================
.help-cat {
padding-top: 25px;
}
.table {
display: flex;
flex-direction: column;
margin-left: 25px;
}
.row {
display: flex;
flex-direction: row;
}
.row span:first-child {
color: var(--primaryColor);
flex: 0 0 150px;
}
article {
max-width: 700px;
}
================================================
FILE: html/assets/css/page/kanjiPage.css
================================================
.kanji-entry.left.detail {
width: 155px;
padding-left: 25px;
}
.kanji-entry.right.detail {
overflow-x: hidden;
padding-left: 35px;
width: 100%;
max-width: 1000px;
}
.kanji-preview.x-large {
cursor: pointer;
font-size: 100px;
}
.kanji-preview-info {
padding-left: 5px;
}
.kanji-preview-right {
max-width: 350px;
text-align: right;
}
.translation.big {
font-size: 25px;
}
.kanji-preview-left {
width: 63%;
padding-right: 10%;
}
.kun-reading {
padding-left: 10px;
}
.kun-reading,
.on-reading {
width: 100%;
}
.speed-tag {
gap: 1em;
align-items: center;
}
.kanji-img {
position: absolute;
pointer-events: none;
margin-bottom: -130px;
opacity: 0;
}
.animation-container {
padding: 1em 0 1.5em 0 !important;
place-content: center;
}
.animation-controller {
margin: 0 1em -1em 0;
gap: 0.5em;
width: 35%;
}
.animation-controller .slider {
width: 100%;
}
.animation-group > .l {
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
}
.animation-group > .m {
margin-left: 2px;
margin-right: 2px;
width: 60%;
}
.animation-group > .m > span {
pointer-events: none;
}
.animation-group > .r {
border-top-right-radius: 15px;
border-bottom-right-radius: 15px;
}
.animation-group > button {
border: 0px;
background: var(--bgPrimaryColor);
color: white;
width: 20%;
height: 2em;
line-height: 2;
}
.reset-btn {
width: 24px;
position: relative;
left: 95px;
top: -25px;
}
.animation-group > button > img {
width: 45%;
}
.compounds-dropdown-parent {
width: 97%;
}
.compounds-dropdown:after {
position: absolute;
content: "";
height: 0;
width: 0;
border-style: solid;
border-width: 5px;
border-color: var(--tagColor) transparent transparent transparent;
pointer-events: none;
transition: linear 0.2s;
right: 0;
margin-top: -3px;
}
.compounds-dropdown.closed:after {
border-color: transparent transparent var(--tagColor) transparent;
margin-top: -8px;
}
.compounds-click-area {
position: absolute;
width: 100%;
height: 20px;
margin-top: -25px;
}
.anim-container svg {
user-select: none;
}
.anim-container text {
font-size: 8px;
}
.tree-parent {
position: relative;
cursor: initial;
width: 90%;
max-width: 1145px;
}
#tree-toggle {
position: absolute;
user-select: none;
cursor: pointer;
right: 1em;
top: 1em;
height: 26px;
width: 26px;
zoom: 1.2;
}
@media only screen and (max-width: 600px) {
#tree-toggle {
zoom: 1;
}
}
#tree-toggle {
background-color: var(--primaryColor) !important;
mask: url("/assets/svg/ui/graph_filled.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/graph_filled.svg") no-repeat center;
}
#tree-toggle.detailed {
mask: url("/assets/svg/ui/graph_empty.svg") no-repeat center;
-webkit-mask: url("/assets/svg/ui/graph_empty.svg") no-repeat center;
}
#tree-target {
align-items: center;
text-align: center;
padding: 5%;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
background-color: var(--overlay);
}
#tree-target > svg {
max-height: 80vh;
max-width: 80vw;
}
#tree-target .link {
fill: none;
stroke: var(--graphLink);
stroke-width: 3px;
}
#tree-target circle {
fill: var(--graphCircle) !important;
stroke: var(--graphStroke);
stroke-width: 2px;
}
#tree-target circle.clickable {
cursor: pointer;
}
#tree-target text {
fill: var(--graphText);
font: 20px sans-serif;
}
#tree-target path {
pointer-events: none;
stroke: none;
fill-rule: nonzero;
fill: var(--graphPath);
fill-opacity: 1;
transform: translateX(-15px) translateY(-15px) scale(0.03);
}
/* Kanji dark mode */
:root.dark .stroke-container > svg > path.active {
stroke: rgb(211, 207, 201) !important;
}
:root.dark .stroke-container > svg > path.not.active {
stroke: rgb(105, 105, 105) !important;
}
:root.dark .stroke-container > svg > line {
stroke: rgb(92, 92, 92) !important;
}
:root.dark .stroke-container > svg > circle {
fill: rgb(95, 241, 96) !important;
opacity: 0.75 !important;
}
:root.dark .anim-container > svg path:not(.bg) {
stroke: var(--primaryTextColor);
}
:root.dark .anim-container text {
fill: var(--primaryTextColor);
}
/* Everything lower than max size */
@media only screen and (max-width: 1150px) {
.animation-group > button > img {
width: 1.5em;
}
.animation-controller {
width: 50%;
}
}
/* Small screens */
@media only screen and (max-width: 600px) {
.compounds-parent {
flex-direction: column !important;
}
.compounds-dropdown:after {
right: -8px;
}
.kun-reading {
padding-left: 0px;
padding-top: 20px;
}
.main-container > .d-flex {
flex-direction: column;
}
.kanji-entry.left.detail {
width: 100%;
align-self: center;
padding-left: 0px;
}
.kanji-preview.x-large {
align-self: center;
}
.translation.big {
font-size: 20px;
padding-bottom: 10px;
}
.kanji-preview-info {
padding-left: 0px;
text-align: left;
}
.kanji-entry.right.detail {
width: unset;
padding-left: 0px;
}
.kanji-entry.right.detail > .kanji-entry {
flex-direction: column !important;
}
.kanji-preview-left {
padding: 0;
width: 100%;
text-align: center;
text-align: -webkit-center;
}
.rad-parts-parent {
display: flex !important;
flex-direction: row !important;
}
.notes.stroke {
text-align: center;
text-align: -webkit-center;
}
.notes.rad {
width: 50%;
}
.notes.parts {
width: 50%;
padding-right: 20px;
text-align: right;
}
.kanji-preview-left > .d-flex {
padding-left: 10px;
}
.kanji-preview-right {
max-width: unset;
padding-top: 10px;
text-align: left;
}
.notes {
padding-left: 10px;
}
.tags.fat {
font-size: 15px;
}
.clickable.fat {
font-size: 15px;
}
.stroke-container {
max-width: 99vw;
padding-left: 1vw;
}
.on-reading {
padding-top: 10px;
}
.slider {
width: 100px;
height: 10px;
}
.slider::-webkit-slider-thumb {
width: 20px;
height: 20px;
border-radius: 50%;
}
.slider::-moz-range-thumb {
width: 20px;
height: 20px;
border-radius: 50%;
}
.slider-output {
margin-left: -10px;
}
}
/* Very small screens */
@media only screen and (max-width: 400px) {
.animation-group > button > img {
width: 1.25em;
}
}
================================================
FILE: html/assets/css/page/multiPage/kana.css
================================================
.inline-kana-preview {
line-height: 1.1;
font-size: xx-large;
padding-top: 24px;
}
================================================
FILE: html/assets/css/page/multiPage/kanji.css
================================================
.kanji-entry {
height: -webkit-fit-content;
height: -moz-fit-content;
height: fit-content;
padding-bottom: 10px;
}
.kanji-entry.right {
position: relative;
width: 100%;
}
.kanji-preview {
line-height: 1.1;
font-size: xx-large;
}
.translation {
font-size: 19px;
}
.stroke-container {
max-width: 80vw;
overflow-x: auto;
}
.animation-container {
padding-left: 30%;
padding-top: 10px;
}
.kanji-entry > d-flex.flex-row {
flex-flow: row wrap;
}
.furigana-kanji-container {
text-align: center;
text-align: -webkit-center;
word-spacing: 10px;
}
.furigana-preview {
margin-bottom: 15px;
}
.draw2 {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
-webkit-animation: dash2 10s linear forwards;
animation: dash2 10s linear forwards;
}
.kanjisvg:hover {
cursor: pointer;
}
@-webkit-keyframes dash2 {
to { stroke-dashoffset: 0;}
}
@keyframes dash2 {
to { stroke-dashoffset: 0;}
}
================================================
FILE: html/assets/css/page/multiPage/markdown.css
================================================
h1 {
font-size: 1.5rem;
}
h2 {
font-size: 1rem;
}
p {
font-size: 14px;
}
.md-center {
display: flex;
justify-content: center;
margin-top: 10px;
}
================================================
FILE: html/assets/css/page/namePage.css
================================================
.kanji-preview.small {
font-size: x-large;
}
================================================
FILE: html/assets/css/page/newsPage.css
================================================
#news-list {
display: flex;
flex-direction: column;
align-items: center;
}
.news-container {
display: block;
width: 80%;
margin-top: 2rem;
border-radius: 1rem;
background-color: rgba(249, 249, 249, 0.75);
box-shadow: 0px 8px 20px 0px var(--backgroundShadow);
}
:root.dark .news-container {
background-color: rgba(47, 49, 55, 0.75);
}
.news-head {
background-color: var(--bgPrimaryColor);
background: linear-gradient(45deg,var(--bgPrimaryColor),var(--primaryColor));
color: var(--secondaryTextColor);
width: 100%;
height: 50px;
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
text-align: center;
font-size: 25px;
}
.news-head > span {
position: relative;
top: 5px;
}
.news-date {
position: relative;
text-align: right;
margin: 10px 10px -30px;
color: var(--tagColor);
}
@media only screen and (max-width: 600px) {
.news-date {
margin: 5px 10px -20px;
}
}
.news-body {
padding: 1.125rem;
}
================================================
FILE: html/assets/css/page/sentencePage.css
================================================
.furigana-kanji-container {
text-align: left;
}
.inline-kana-preview.small, .kanji-preview.small, .inline-kana-preview.small {
font-size: x-large;
}
.sentence-translation.original {
font-size: 19px;
padding-top: 0.2rem;
}
.sentence-toggle {
width: 100%;
margin-top: -10px;
margin-bottom: -10px;
color: var(--primaryColor);
font-family: "Roboto";
text-align: end;
font-size: small;
cursor: pointer;
}
.sentence-share {
display: flex;
flex-direction: column;
gap: 0.5em;
width: 100%;
font-size: 12px;
margin-top: -10px;
margin-bottom: -12px;
padding-top: 5px;
padding-right: 5px;
color: var(--primaryColor);
-webkit-writing-mode: tb;
-ms-writing-mode: tb;
writing-mode: tb;
}
.sentence-share > .searchSvg {
cursor: pointer;
color: var(--disabledColor);
background-color: var(--disabledColor);
}
================================================
FILE: html/assets/css/page/wordExtensions/searchAnnotation.css
================================================
.search-annotation {
color: var(--tagColor);
max-height: 150px;
margin-bottom: 15px;
overflow: auto;
display: flex;
justify-content: center;
}
.search-annotation .kanji-preview {
line-height: unset;
}
.search-annotation.no-center {
justify-content: unset;
}
.search-annotation::-webkit-scrollbar {
width: 0px;
}
.search-inflection {
padding: 0.5rem 1rem 0.5rem 1rem;
}
.search-inflection > span > .forms {
position: relative;
left: 5px;
top: 5px;
}
/* Mobile only */
@media only screen and (max-width: 600px) {
.search-annotation {
margin: -15px 0 0 5vw;
}
.search-inflection {
padding: 0.5rem 0rem 0.5rem 0rem;
width: 80vw;
}
}
================================================
FILE: html/assets/css/page/wordExtensions/sentenceReader.css
================================================
#sr {
justify-content: center;
}
.sentence-part {
color: var(--primaryTextColor) !important;
border-bottom: 2px solid var(--lineColor);
line-height: 1.1;
margin-right: 15px;
margin-top: 9px;
flex-grow: 0;
flex-shrink: 0;
overflow: hidden;
cursor: pointer;
}
.sentence-part.selected {
border-bottom: 2px solid var(--primaryColor);
}
.sentence-part:hover {
text-decoration: unset;
text-shadow: -1px -1px var(--primaryTextColor);
color: var(--primaryTextColor) !important;
}
.sentence-part.inline-kana-preview {
margin-top: 19px;
}
.sentence-part.symbol {
border-bottom: 0px;
margin-right: 0px;
margin-left: 0px;
}
.sentence-part:not(.symbol) + .symbol {
margin-left: -15px;
margin-right: 10px;
}
.sentence-part.particle {
color: var(--primaryColor) !important;
}
.sentence-part.particle:hover {
text-shadow: -1px -1px var(--primaryColor);
}
.sentence-part:empty {
padding-top: 19px;
}
.sentence-part > .furigana-kanji-container {
margin-top: 24px;
}
.sentence-part > .inline-kana-preview {
margin-top: 9px;
}
@media only screen and (max-width: 600px) {
#sr {
scrollbar-width: none;
flex-wrap: nowrap;
}
#sr::-webkit-scrollbar {
width: 0px;
}
.sentence-part {
min-width: -webkit-max-content;
min-width: -moz-max-content;
min-width: max-content;
margin-right: 20px;
}
}
================================================
FILE: html/assets/css/page/wordPage.css
================================================
.title-div {
text-align: center;
text-align: -webkit-center;
width: 80%;
}
.title-div h1 {
font-weight: bold;
font-size: xx-large;
}
.title-div h4 {
font-size: medium;
}
.main-tab-select {
padding-top: 25px;
width: 100%;
}
.main-tab-select.l {
padding-right: 10px;
display: flex;
justify-content: flex-start;
}
.main-tab-select.r {
padding-left: 10px;
display: flex;
justify-content: flex-end;
}
.main-tab-select h2 {
font-size: medium;
text-decoration: underline;
color: var(--primaryColor);
}
.tab-btn {
cursor: pointer;
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
}
.entry-min-height-1 {
min-height: 90px;
}
.entry-min-height-2 {
min-height: 180px;
}
.main-info > .d-flex.flex-row {
padding-left: 1vw;
}
.definition-wrapper {
max-width: 93%;
}
/* Example Sentences */
.example-sentence {
padding-top: 5px;
margin-bottom: 5px !important;
max-width: 90%;
overflow-y: hidden;
}
.example-sentence.collapsed {
max-height: 35px;
}
.example-sentence .wrap div {
margin-top: -5px;
}
.expander {
height: 0;
width: 0;
margin-top: 24px;
margin-left: 5px;
border-style: solid;
border-width: 5px;
border-color: var(--tagColor) transparent transparent transparent;
}
.expander.on {
transform: rotate(180deg);
transform-origin: top center;
margin-top: 29px;
}
.expander:hover {
cursor: pointer;
}
.tags .kanji-preview {
font-size: 15px;
}
.furigana-preview {
font-size: inherit;
}
.tags .furigana-preview {
font-size: 10px;
margin-bottom: 5px;
margin-top: 2px;
}
.tags .inline-kana-preview {
font-size: 15px;
padding-top: 18px;
}
/* Kanji Stuff Overwrite */
.kanji-entry.left.fixed {
min-width: 155px;
max-width: 155px;
justify-content: center;
align-items: center;
}
.kanji-preview.large {
font-size: 50px;
padding-top: 15px;
}
.kanji-preview.large:hover {
text-decoration: none;
}
.kanji-entry {
padding-bottom: 5px;
}
/* 3-dot Menu */
.dot-menu {
width: 100%;
}
.mdl-menu__item[disabled] + .mdl-menu__item[disabled], .mdl-menu__item:last-child[disabled], .mdl-menu__item:first-child[disabled] {
display: none;
}
.mdl-menu__item[disabled] {
height: 10px;
}
.mdl-menu__item[disabled] > hr {
margin: 0px;
margin-top: 5px;
}
#info-dropdown {
background-color: var(--background);
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
cursor: pointer;
}
.info-entry {
padding-left: 5px;
padding-right: 5px;
font-size: 18px;
line-height: 1.4;
cursor: pointer;
text-align: center;
display: flex;
flex-direction: row;
align-items: center;
width: auto;
}
.info-entry:hover {
background-color: var(--lineColor);
}
.info-entry > * {
margin: 0 5px;
}
.info-entry > div {
margin-top: 1px;
}
.info-entry a {
vertical-align: middle;
}
.info-entry > .extra {
border-left: 1px solid var(--lineColor);
padding-left: 7px;
margin-left: 1px;
}
.info-entry .copySvg {
pointer-events: all;
}
.word-tooltip {
position: absolute;
cursor: pointer;
top: 0px;
right: 10px;
}
.word-tooltip > span {
margin-bottom: -20px;
}
.mdl-menu__container {
margin-right: 10px;
}
/* -------- Words Column -------- */
.word-frequency {
margin-top: 10px;
width: 100px;
clear: right;
margin: 4px 0 8px 0;
padding: 2px 5px 3px 5px;
font-size: 10px;
-webkit-font-smoothing: antialiased;
background-color: var(--secondaryColor);
border-radius: 3px;
color: var(--secondaryTextColor);
font-weight: bold;
text-align: center;
text-align: -webkit-center;
}
.word-frequency.common {
background-color: var(--bgPrimaryColor);
}
.kanji-entry .list-entry + .list-entry {
padding-top: 5px;
}
/* Pitch Accent Borders */
.pitch {
border-radius: 0px;
margin-right: -4px;
font-size: large;
color: var(--primaryColor);
}
.pitch.t {
border-top: 1px solid var(--tagColor);
padding-left: 5px;
padding-right: 5px;
}
.pitch.r {
border-right: 1px solid var(--tagColor);
margin-right: -6px;
}
.pitch.b {
border-bottom: 1px solid var(--tagColor);
}
.pitch.b:not(.r) {
padding-left: 3px;
}
/* Info Overlay */
.table.conjugation, .table.collocation {
width: 80%;
margin-left: 10%;
}
.table.collocation tr:first-child > th {
border-top: 2px solid var(--lineColor) !important;
}
.table.collocation th, .table.collocation td {
width: 50%;
}
.table {
color: var(--primaryTextColor) !important;
}
thead > tr > th {
color: var(--secondaryTextColor) !important;
background-color: var(--bgPrimaryColor) !important;
}
table th {
padding: 0.75rem;
border-color: var(--searchTextColor) !important;
border-bottom: 2px solid var(--lineColor) !important;
border-top: 1px solid var(--lineColor) !important;
}
td {
border-top: 2px solid var(--lineColor) !important;
}
table tr:last-child > td {
border-bottom: 2px solid var(--lineColor) !important;
}
/* -------- Kanji Column -------- */
.translation.kanji {
padding-top: 10px;
padding-left: 10px;
}
================================================
FILE: html/assets/css/search/choices.css
================================================
/*
Used by the search bar only. So much css for a damn text field..
*/
.choices {
position: relative;
margin-bottom: 24px;
font-size: 16px;
}
.choices:focus {
outline: none;
}
.choices:last-child {
margin-bottom: 0;
}
.choices__item--choice:hover {
color: var(--primaryColor) !important;
}
.choices[data-type*="select-one"] {
cursor: pointer;
}
.choices[data-type*="select-one"] .choices__inner {
padding-bottom: 7.5px;
}
.choices[data-type*="select-one"]:after {
content: "";
height: 0;
width: 0;
border-style: solid;
border-width: 5px;
border-color: var(--tagColor) transparent transparent transparent;
position: absolute;
right: 30px;
top: 50%;
margin-top: -2.5px;
pointer-events: none;
}
.choices[data-type*="select-one"].is-open:after {
border-color: transparent transparent var(--tagColor) transparent !important;
margin-top: -7.5px;
}
.choices__inner {
display: inline-block;
vertical-align: top;
width: 100%;
padding: 7.5px 7.5px 3.75px;
border-radius: 2.5px;
font-size: 14px;
min-height: 44px;
overflow: hidden;
}
.is-open .choices__inner {
border-radius: 2.5px 2.5px 0 0;
}
.choices__list {
margin: 0;
padding-left: 0;
list-style: none;
}
.choices__list--single {
display: inline-block;
padding: 4px 16px 4px 4px;
width: 100%;
}
.choices__list--single .choices__item {
width: 100%;
}
.choices__list--dropdown {
display: none;
z-index: 1;
position: absolute;
width: 100%;
background-color: var(--searchBackground);
border: 1px solid var(--searchBackground);
top: 100%;
margin-top: -1px;
border-bottom-left-radius: 2.5px;
border-bottom-right-radius: 2.5px;
overflow: hidden;
word-break: break-all;
}
.choices__list--dropdown.is-active {
display: block;
}
.choices__list--dropdown .choices__list {
position: relative;
max-height: 300px;
overflow: auto;
overflow: -moz-hidden-unscrollable;
-webkit-overflow-scrolling: touch;
will-change: scroll-position;
}
.choices__list--dropdown .choices__item {
position: relative;
padding: 10px;
font-size: 14px;
}
@media (min-width: 640px) {
.choices__list--dropdown .choices__item--selectable {
padding-right: 100px;
}
.choices__list--dropdown .choices__item--selectable:after {
content: attr(data-select-text);
font-size: 12px;
opacity: 0;
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
}
}
.choices__item {
cursor: default;
}
.choices__item--selectable {
cursor: pointer;
}
.choices__item--disabled {
cursor: not-allowed;
-webkit-user-select: none;
-ms-user-select: none;
-moz-user-select: none;
user-select: none;
opacity: 0.5;
}
.choices__input {
display: inline-block;
vertical-align: baseline;
font-size: 14px;
margin-bottom: 5px;
border: 0;
border-radius: 0;
max-width: 100%;
padding: 4px 0 4px 2px;
}
.choices__input:focus {
outline: 0;
}
.choices__button:focus {
outline: none;
}
/* ----------------- Settings specific changes -------------- */
.modal-body .choices {
margin-bottom: 0px;
}
.modal-body .choices__inner {
width: -webkit-fit-content;
width: fit-content;
width: -moz-fit-content;
}
.modal-body .choices__list.choices__list--single {
box-shadow: 0px 1px 2px 0px var(--backgroundShadow);
border: 1px solid var(--backgroundShadow);
padding-right: 20px;
}
.modal-body .choices:after {
right: 15px;
margin-left: unset;
}
.modal-body .choices__list.choices__list--dropdown {
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
border: 0;
margin-top: 2px;
border-radius: 4px;
box-shadow: 0px 8px 20px 0px var(--backgroundShadow);
}
.modal-body .choices__list--dropdown .choices__item {
padding: 6px 17px 10px 10px;
}
@media (min-width: 640px) {
.modal-body .choices__list--dropdown .choices__item--selectable {
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
padding-right: 10px;
}
.modal-body .choices ::-webkit-scrollbar {
width: 10px;
}
.modal-body .choices ::-webkit-scrollbar-track {
background: var(--lineColor);
}
.modal-body .choices ::-webkit-scrollbar-thumb {
background: var(--itemBG_075);
}
.search-lang-txt {
position: absolute;
margin-top: -30px;
right: 8rem;
}
}
/* ----------------- Search Bar specific changes -------------- */
.searchDivInner form .inner-form {
background: var(--searchBackground);
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
box-shadow: 0px 8px 20px 0px var(--backgroundShadow);
border-radius: 20px;
}
.searchDivInner form .inner-form .input-field {
height: 68px;
}
.searchDivInner form .inner-form .input-field input {
height: 100%;
width: 100%;
background: transparent;
border: 0;
display: block;
padding: 10px 32px;
margin-right: 80px;
font-size: 16px;
color: var(--searchTextColor);
}
.searchDivInner form .inner-form .input-field input.placeholder {
color: var(--tagColor);
font-size: 16px;
}
.searchDivInner form .inner-form .input-field input:-moz-placeholder {
color: var(--tagColor);
font-size: 16px;
}
.searchDivInner form .inner-form .input-field input::-webkit-input-placeholder {
color: var(--tagColor);
font-size: 16px;
}
.searchDivInner form .inner-form .input-field.first-wrap {
width: 200px;
border-right: 1px solid var(--lineColor);
}
.searchDivInner form .inner-form .input-field.first-wrap .choices__inner {
background: transparent;
border-radius: 0;
border: 0;
height: 100%;
display: flex;
align-items: center;
padding: 10px 30px;
}
.searchDivInner form .inner-form .input-field.first-wrap .choices__inner .choices__list.choices__list--single {
display: flex;
padding: 0;
align-items: center;
height: 100%;
}
.searchDivInner form .inner-form .input-field.first-wrap .choices__inner .choices__item.choices__item--selectable.choices__placeholder {
display: flex;
align-items: center;
height: 100%;
opacity: 1;
color: var(--tagColor);
}
.searchDivInner form .inner-form .input-field.first-wrap .choices__inner .choices__list--single .choices__item {
display: flex;
align-items: center;
height: 100%;
color: var(--searchTextColor);
}
.searchDivInner form .inner-form .input-field input:hover, .searchDivInner form .inner-form .input-field input:focus {
box-shadow: none;
outline: 0;
}
.searchDivInner form .inner-form .input-field.first-wrap .choices__list.choices__list--dropdown {
border: 0;
margin-top: 2px;
border-radius: 4px;
box-shadow: 0px 8px 20px 0px var(--backgroundShadow);
}
.searchDivInner form .inner-form .input-field.first-wrap .choices__list.choices__list--dropdown .choices__item--selectable {
padding-right: 0;
}
.searchDivInner form .inner-form .input-field.first-wrap .choices__list--dropdown .choices__item {
color: var(--searchTextColor);
min-height: 24px;
}
.searchDivInner form .inner-form .input-field.second-wrap {
flex-grow: 1;
}
.searchDivInner form .inner-form .input-field.third-wrap {
/* width: 74px; */
width: 30px;
}
.btn-search {
height: 100%;
width: 100%;
white-space: nowrap;
border: 0;
cursor: pointer;
color: var(--searchBackground);
background: var(--bgPrimaryColor);
transition: all .2s ease-out, color .2s ease-out;
}
.btn-search svg {
width: 16px;
}
.btn-search:hover {
background: var(--primaryColor);
}
.btn-search:focus {
outline: 0;
box-shadow: none;
}
.searchDivInner form .inner-form .input-field .input-select {
height: 100%;
}
.searchDivInner form .inner-form .input-field .input-select .choices {
height: 100%;
}
.searchDivInner form .inner-form .input-field {
height: 50px;
}
.btn-search > svg > path {
fill: var(--secondaryTextColor);
}
.searchDivInner .choices__list--dropdown > .choices__list {
margin-left: 10px;
}
.choices__list.choices__list--dropdown.index.is-active {
-webkit-animation: dropdownAnim 0.2s linear forwards;
animation: dropdownAnim 0.2s linear forwards;
}
.choices__list.choices__list--dropdown.index.animate:not(.is-active) {
display: unset !important;
-webkit-animation: dropdownAnimClose 0.2s linear forwards;
animation: dropdownAnimClose 0.2s linear forwards;
}
@-webkit-keyframes dropdownAnim {
from {height: 0px;}
to { height: 330%;}
}
@keyframes dropdownAnim {
from {height: 0px;}
to { height: 330%;}
}
@-webkit-keyframes dropdownAnimClose {
from {height: 330%; }
to { height: 0%; display:hidden !important;}
}
@keyframes dropdownAnimClose {
from {height: 330%; }
to { height: 0%; display:hidden !important;}
}
.choices.main[data-type*="select-one"]:after {
transition: linear 0.2s;
}
.choices.main[data-type*="select-one"].is-open:after {
transition: linear 0.2s;
}
/* Mobile Only */
@media only screen and (max-width: 600px) {
.choices[data-type*="select-one"]:after {
right: 14px;
}
}
/* Dekstop Only */
@media only screen and (min-width: 600px) {
.searchDivInner form .inner-form .input-field.first-wrap .choices__list.choices__list--dropdown {
border-radius: 20px !important;
border-top-right-radius: 0px !important;
}
}
================================================
FILE: html/assets/css/search/searchRow.css
================================================
#search-row {
padding-top: 10px;
padding-left: 10px;
padding-right: 10px;
}
#emptyInput {
position: absolute;
height: 30px;
margin-top: 7px;
right: 70px;
}
#emptyInput:focus {
outline: none;
box-shadow: none;
}
#emptyInput > svg {
width: 20px;
fill: var(--tagColor);
}
#search-vl {
position: absolute;
border-left: 1px solid var(--lineColor);
height: 70%;
margin-top: 7px;
right: 75px;
}
.search-embedded-btn:focus {
outline: none;
box-shadow: none;
}
.search-embedded-btn {
background: unset;
position: absolute;
height: 30px;
margin-top: 11px;
right: 10px;
width: unset;
border: none;
}
.search-embedded-btn.search {
width: 30px;
right: 14px;
display: none;
}
#voiceBtn.search-embedded-btn {
display: none;
}
.search-embedded-btn.search > svg > path, #voiceBtn.search-embedded-btn > svg > path {
fill: var(--primaryColor);
}
.search-embedded-btn.radical {
right: 38px;
}
.search-embedded-btn.radical > span {
font-size: 20px;
text-shadow: 0px 0px var(--tagColor);
color: var(--tagColor);
}
.input-group {
height: 100%;
}
svg {
fill: var(--searchTextColor);
}
.kanjisvg > path {
stroke: var(--primaryTextColor);
}
.d-flex.center {
justify-content: center;
}
.btn-container {
position: absolute;
width: 100%;
top: 0;
text-align: center;
text-align: -webkit-center;
}
.btn-container div {
float: left;
width: 30px;
}
.btn-container.rad {
margin-top: -8px;
margin-right: -7px;
}
.settingsBtn, .infoBtn, .homeBtn {
position: absolute;
cursor: pointer;
z-index: 15;
}
.settingsBtn {
top: 22px;
left: 20px;
padding-top: 12px;
padding-bottom: 0px;
}
.infoBtn {
top: 21px;
right: 3em;
}
.homeBtn {
font-family: 'Material Icons';
font-size: 27px;
top: 16px;
right: 0.5em;
color: var(--tagColor);
}
.homeBtn.mobile {
position: relative;
font-size: 38px;
top: 0;
left: 0;
right: 0;
}
.rad-picker-icon {
font-size: 33px;
color: var(--searchTextColor);
}
.rad-picker-txt {
margin-top: -9px;
}
#searchDiv {
z-index: 1;
margin-left: 15px;
width: 100%;
max-width: 1150px;
position: relative;
}
#searchDiv.index {
max-width: 1150px;
margin-left: 0px;
}
.d-flex.left {
flex-direction: row;
justify-content: left;
}
/* Adjustments for the upper buttons */
@media only screen and (max-width: 1350px) {
#searchDiv {
width: 90%;
padding-right: 30px;
}
}
@media only screen and (max-width: 875px) {
#searchDiv {
padding-right: 45px;
}
.homeBtn {
right: 0.25em;
}
.infoBtn {
right: 2.5em;
}
}
@media only screen and (max-width: 600px) {
#searchDiv {
width: 100%;
padding-right: 0px;
}
}
================================================
FILE: html/assets/css/tools/alerts.css
================================================
/* ----------------- Alerts Color Design ----------------- */
.msg-message {
border: none !important;
border-radius: 15px !important;
text-shadow: none !important;
}
.msg-warning {
background-color: rgba(195,195,195,0.95) !important;
border-color: rgba(195,195,195,0.95) !important;
}
.mdl-tooltip {
font-size: 12px;
}
================================================
FILE: html/assets/css/tools/pagination.css
================================================
.pagination {
display: flex;
list-style: none;
justify-content: center;
padding: 0px 0 25px 0;
margin-top: -45px;
}
.pagination-item {
font-family: 'Roboto', sans-serif;
display: flex;
padding-left: 0;
list-style: none;
border-radius: .25rem;
background-color: none;
}
.pagination-item.disabled .pagination-circle {
cursor: unset;
color: var(--tagColor);
}
.pagination-item.disabled .pagination-circle:not(.active):hover {
animation: none !important;
-webkit-animation: none !important;
}
.pagination-circle {
color: var(--primaryTextColor);
background: none;
margin-right: 2px;
margin-left: 2px;
line-height: 1.25;
padding: .5rem .75rem;
font-size: .9rem;
border: 0;
border-radius: 50%;
outline: 0 !important;
}
.pagination-circle:not(.active):hover {
-webkit-animation: hoverEffect 0.5s forwards;
animation: hoverEffect 0.5s forwards;
}
.pagination-circle.active {
color: var(--secondaryTextColor);
background: var(--bgPrimaryColor);
border-radius: 50%;
box-shadow: 0 2px 5px 0 rgb(0 0 0 / 16%), 0 2px 10px 0 rgb(0 0 0 / 12%);
}
@-webkit-keyframes hoverEffect {
to {
background-color: var(--lineColor);
}
}
@keyframes hoverEffect {
to {
background-color: var(--lineColor);
}
}
================================================
FILE: html/assets/css/tools/ripple.css
================================================
.has-ripple{position:relative;overflow:hidden;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ripple-a{display:block;position:absolute;pointer-events:none;border-radius:50%;-webkit-transform:scale(0);-o-transform:scale(0);transform:scale(0);background:#fff;opacity:1}.ripple-animate{-webkit-animation:ripple;-o-animation:ripple;animation:ripple}@-webkit-keyframes ripple{100%{opacity:0;-webkit-transform:scale(2);transform:scale(2)}}@-o-keyframes ripple{100%{opacity:0;-o-transform:scale(2);transform:scale(2)}}@keyframes ripple{100%{opacity:0;transform:scale(2)}}
================================================
FILE: html/assets/docs.html
================================================
<html>
<head>
<meta charset="utf-8">
<script type="module" src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"></script>
<style>
rapi-doc::part(section-servers) { /* <<< targets the server div */
color: #888888;
margin:0 24px 0 24px;
border-radius: 5px;
}
rapi-doc::part(label-selected-server) { /* <<< targets selected server label */
color: #888888;
}
rapi-doc{ /* <<< targets selected server label */
color: #888888;
}
</style>
</head>
<body>
<rapi-doc id="thedoc" render-style = "read" allow-try="true" theme='dark' allow-authentication = "false" show-header = "false"
primary-color ="#34A83C"
bg-color = "#202324"
> </rapi-doc>
<script>
document.addEventListener('DOMContentLoaded', (event) => {
let docEl = document.getElementById("thedoc");
let strSpec = `
{
"swagger": "2.0",
"info": {
"description": "Jotoba search API<br><br>(Note: Jotoba doesn't own any of the provided resources! Please refer to https://jotoba.de/about for a list of used resources and their licenses. If you're using data provided by jotoba, you have to acknowledge the autors and creators of the used resoure and follow the terms and contiditons of the original license)",
"version": "0.1",
"title": "Jotoba"
},
"host": "jotoba.de",
"tags": [
{
"name": "Search",
"description": "Search endpoints to address jotoba from own applications"
},
{
"name": "Image",
"description": "Image text detection"
},
{
"name": "Radicals",
"description": "Radical API"
},
{
"name": "Completion",
"description": "Search completion related endpoints"
}
],
"paths": {
"/api/img_scan": {
"post": {
"tags": [
"Image"
],
"summary": "Get japanese text from an image",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"parameters": [
{
"name": "upfile",
"in": "formData",
"description": "The image to scan. Can be either jpg or png. Max 2MB.",
"required": false,
"type": "file"
}
],
"responses": {
"200": {
"description": "Success response",
"schema": {
"$ref": "#/definitions/ImgScanResponse"
}
},
"400": {
"description": "Bad request. Might occur if the query is empty or the provided image is malformed",
"schema": {
"$ref": "#/definitions/Error"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/api/search/words": {
"post": {
"tags": [
"Search"
],
"summary": "Search for words",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/RequestPayload"
}
}
],
"responses": {
"200": {
"description": "Success response",
"schema": {
"$ref": "#/definitions/WordResponse"
}
},
"400": {
"description": "Bad request. Might occur if the query is empty",
"schema": {
"$ref": "#/definitions/Error"
}
},
"408": {
"description": "Timeout. Occurs if search takes too long",
"schema": {
"$ref": "#/definitions/Error"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/api/search/names": {
"post": {
"tags": [
"Search"
],
"summary": "Search for japanese names",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/RequestPayload"
}
}
],
"responses": {
"200": {
"description": "Success response",
"schema": {
"$ref": "#/definitions/NameResponse"
}
},
"400": {
"description": "Bad request. Might occur if the query is empty",
"schema": {
"$ref": "#/definitions/Error"
}
},
"408": {
"description": "Timeout. Occurs if search takes too long",
"schema": {
"$ref": "#/definitions/Error"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/api/search/kanji": {
"post": {
"tags": [
"Search"
],
"summary": "Search for kanji",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/RequestPayload"
}
}
],
"responses": {
"200": {
"description": "Success response",
"schema": {
"$ref": "#/definitions/KanjiResponse"
}
},
"400": {
"description": "Bad request. Might occur if the query is empty",
"schema": {
"$ref": "#/definitions/Error"
}
},
"408": {
"description": "Timeout. Occurs if search takes too long",
"schema": {
"$ref": "#/definitions/Error"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/api/search/sentences": {
"post": {
"tags": [
"Search"
],
"summary": "Search for sentences",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/RequestPayload"
}
}
],
"responses": {
"200": {
"description": "Success response",
"schema": {
"$ref": "#/definitions/SentenceResponse"
}
},
"400": {
"description": "Bad request. Might occur if the query is empty",
"schema": {
"$ref": "#/definitions/Error"
}
},
"408": {
"description": "Timeout. Occurs if search takes too long",
"schema": {
"$ref": "#/definitions/Error"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/api/kanji/by_radical": {
"post": {
"tags": [
"Radicals"
],
"summary": "Search kanji by its radicals",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/RadicalsPayload"
}
}
],
"responses": {
"200": {
"description": "Success response",
"schema": {
"$ref": "#/definitions/RadicalsResponse"
}
},
"400": {
"description": "Bad request. Might occur if no radicals were passed",
"schema": {
"$ref": "#/definitions/Error"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/api/radical/search": {
"post": {
"tags": [
"Radicals"
],
"summary": "Search radicals",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/RadicalSearchPayload"
}
}
],
"responses": {
"200": {
"description": "Success response",
"schema": {
"$ref": "#/definitions/RadicalSearchResponse"
}
},
"400": {
"description": "Bad request. Might occur if no value was passed",
"schema": {
"$ref": "#/definitions/Error"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/api/suggestion": {
"post": {
"tags": [
"Completion"
],
"summary": "Retrieve word completions for search queries",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/CompletionPayload"
}
}
],
"responses": {
"200": {
"description": "Success response",
"schema": {
"$ref": "#/definitions/CompletionResponse"
}
},
"400": {
"description": "Bad request. Might occur if no radicals were passed",
"schema": {
"$ref": "#/definitions/Error"
}
},
"408": {
"description": "Timeout. Occurs if suggestion takes too long",
"schema": {
"$ref": "#/definitions/Error"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/api/news/short": {
"post": {
"tags": [
"News"
],
"summary": "Retrieve latest Jotoba news in short form",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/ShortNewsPayload"
}
}
],
"responses": {
"200": {
"description": "Success response",
"schema": {
"$ref": "#/definitions/ShortNewsResponse"
}
}
}
}
},
"/api/news/detailed": {
"post": {
"tags": [
"News"
],
"summary": "Retrieve single news entry detailed",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/DetailedNewsPayload"
}
}
],
"responses": {
"200": {
"description": "Success response",
"schema": {
"$ref": "#/definitions/DetailedNewsResponse"
}
},
"404": {
"description": "ID was not found",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
}
},
"definitions": {
"ShortNewsPayload": {
"type": "object",
"required": [
"after"
],
"properties": {
"after": {
"type": "integer",
"example": 1637499806,
"description": "Show news after"
}
}
},
"DetailedNewsPayload": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "integer",
"example": 3,
"description": "ID of the news enttry"
}
}
},
"ShortNewsResponse": {
"type": "object",
"properties": {
"entries": {
"type": "array",
"items": {
"$ref": "#/definitions/NewsEntry"
}
}
}
},
"DetailedNewsResponse": {
"type": "object",
"properties": {
"entry": {
"$ref": "#/definitions/NewsEntry"
}
}
},
"NewsEntry": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"example": 3,
"description": "The ID of the news entry"
},
"title": {
"type": "string",
"example": "V1.1",
"description": "The news entry title"
},
"html": {
"type": "string",
"example": "<h1 id='featuring'>Featuring</h1><br><br><ul><br><li>New radical-picker</li><br><br><li>Image to text sear</li><br></ul><br>",
"description": "The HTML formatted news content"
},
"creation_time": {
"type": "integer",
"example": 1637499806,
"description": "The unix timestamp of the time the given newes entry was released"
},
"trimmed": {
"type": "boolean",
"description": "Whether the html content was trimmed or not"
}
}
},
"RequestPayload": {
"type": "object",
"required": [
"query"
],
"properties": {
"query": {
"type": "string",
"example": "東京",
"description": "The search query"
},
"language": {
"$ref": "#/definitions/Language"
},
"no_english": {
"type": "boolean",
"example": false,
"description": "Does not return english results if the provided language differs from english",
"default": false
}
}
},
"Error": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"example": 400,
"description": "Error code"
},
"error": {
"type": "string",
"example": "BadRequest",
"description": "Error description"
},
"message": {
"type": "string",
"example": "Bad request",
"description": "Error informations"
}
}
},
"WordResponse": {
"type": "object",
"properties": {
"kanji": {
"type": "array",
"description": "Kanji used to write words found in search",
"items": {
"$ref": "#/definitions/Kanji"
}
},
"words": {
"type": "array",
"description": "Words found in search",
"items": {
"$ref": "#/definitions/Word"
}
}
}
},
"Kanji": {
"type": "object",
"properties": {
"literal": {
"type": "string",
"example": "今"
},
"meanings": {
"type": "array",
"example": [
"now"
],
"items": {
"type": "string"
}
},
"grade": {
"type": "integer",
"example": 2
},
"stroke_count": {
"type": "integer",
"example": 4
},
"frequency": {
"type": "integer",
"example": 49
},
"jlpt": {
"type": "integer",
"example": 5
},
"onyomi": {
"type": "array",
"items": {
"type": "string",
"example": ""
}
},
"kunyomi": {
"type": "array",
"items": {
"type": "string",
"example": ""
}
},
"chinese": {
"type": "array",
"items": {
"type": "string",
"example": ""
}
},
"korean_r": {
"type": "array",
"description": "Korean reading romanized",
"items": {
"type": "string",
"example": ""
}
},
"korean_h": {
"type": "array",
"description": "Korean reading(s) in hangul",
"items": {
"type": "string",
"example": ""
}
},
"parts": {
"type": "array",
"description": "Parts used to construct the kanji. (only available in kanji search)",
"items": {
"type": "string"
}
},
"radical": {
"type": "string",
"description": "(only available in kanji search)"
},
"stroke_frames": {
"type": "string",
"description": "Path to the stroke order svg image. (only available in kanji search)"
}
}
},
"Word": {
"type": "object",
"properties": {
"reading": {
"$ref": "#/definitions/Reading"
},
"common": {
"type": "boolean",
"description": "Whether the word is a common word or not"
},
"senses": {
"type": "array",
"items": {
"$ref": "#/definitions/Sense"
}
},
"audio": {
"type": "string",
"example": "/assets/audio/走る【はしる】.ogg",
"description": "Path of the audio file for the given word. Only provided if audio file exists"
},
"pitch": {
"type": "array",
"description": "Pitch accent of the word",
"items": {
"$ref": "#/definitions/PitchItem"
}
}
}
},
"Reading": {
"type": "object",
"properties": {
"kana": {
"type": "string",
"example": "はしる",
"description": "The kana reading"
},
"kanji": {
"type": "string",
"example": "走る",
"description": "The kanji reading (if available)"
},
"furigana": {
"type": "string",
"example": "[走|はし]る",
"description": "An encoded string representing the furigana parts of the kanji reading"
}
}
},
"Sense": {
"type": "object",
"properties": {
"glosses": {
"type": "array",
"example": [
"to run"
],
"description": "Equal meanings of the japanese word in the specified other language",
"items": {
"type": "string"
}
},
"pos": {
"type": "array",
"description": "Part of speech of the provided glosses",
"items": {
"type": "string"
}
},
"language": {
"$ref": "#/definitions/Language"
}
}
},
"PitchItem": {
"type": "object",
"properties": {
"part": {
"type": "string",
"example": "かお",
"description": "A part of the kana reading with the same pitch"
},
"high": {
"type": "boolean",
"example": false,
"description": "Whether its a high or low pitch"
}
},
"description": "A part of a Japanese word with the same pitch"
},
"KanjiResponse": {
"type": "object",
"properties": {
"kanji": {
"type": "array",
"items": {
"$ref": "#/definitions/Kanji"
}
}
}
},
"NameResponse": {
"type": "object",
"properties": {
"names": {
"type": "array",
"items": {
"$ref": "#/definitions/Name"
}
}
}
},
"Name": {
"type": "object",
"properties": {
"kana": {
"type": "string",
"example": "らん"
},
"kanji": {
"type": "string",
"example": "走"
},
"transcription": {
"type": "string",
"example": "Ran"
},
"name_type": {
"type": "array",
"items": {
"type": "string",
"enum": [
"Company",
"Female",
"Male",
"Place",
"Given",
"Organization",
"Person",
"Product",
"RailwayStation",
"Surname",
"Unclassified",
"Work"
]
}
}
}
},
"SentenceResponse": {
"type": "object",
"properties": {
"sentences": {
"type": "array",
"items": {
"$ref": "#/definitions/Sentence"
}
}
}
},
"Language": {
"type": "string",
"enum": [
"English",
"German",
"Spanish",
"Russain",
"Swedish",
"French",
"Dutch",
"Hungarian",
"Slovenian"
]
},
"Sentence": {
"properties": {
"content": {
"type": "string",
"example": "いい天気です"
},
"furigana": {
"type": "string",
"example": "いい[天気|てん|き]です"
},
"translation": {
"type": "string",
"example": "It is a nice day"
},
"language": {
"type": "string",
"example": "English"
}
}
},
"RadicalsPayload": {
"type": "object",
"properties": {
"radicals": {
"type": "array",
"example": [
"山",
"一",
"冂",
"干"
],
"items": {
"type": "string"
}
}
},
"description": "Payload for kanji-by-radicals search"
},
"RadicalSearchPayload": {
"type": "object",
"properties": {
"query": {
"type": "string",
"example": "heart"
}
},
"description": "Payload for radical search"
},
"RadicalsResponse": {
"type": "object",
"properties": {
"kanji": {
"type": "array",
"description": "All kanji which can be built using the provided radicals. The keys of the objects are the stroke counts",
"items": {
"type": "string"
}
},
"possible_radicals": {
"type": "array",
"example": [
"小",
"岡",
"幺",
"糸"
],
"description": "Left over radicals which will have a non empty kanji result",
"items": {
"type": "string"
}
}
},
"description": "Kanji-by-radicals response"
},
"RadicalSearchResponse": {
"type": "object",
"properties": {
"4": {
"type": "array",
"description": "Radical search result",
"items": {
"$ref": "#/definitions/RadicalSearchItem"
}
}
},
"description": "Radical search response"
},
"RadicalSearchItem": {
"type": "object",
"properties": {
"l": {
"type": "string",
"example": "心",
"description": "A kanji literal"
}
},
"description": "Radical search response item"
},
"CompletionPayload": {
"type": "object",
"required": [
"input",
"lang",
"search_type"
],
"properties": {
"input": {
"type": "string",
"example": "東",
"description": "Current search query to find completions for"
},
"lang": {
"type": "string",
"enum": [
"en-US",
"de-DE",
"es-ES",
"fr-FR",
"nl-NL",
"sv-SE",
"ru",
"hu",
"sl-SI"
]
},
"search_type": {
"$ref": "#/definitions/SearchType"
},
"radicals": {
"type": "array",
"example": [
"⺡"
],
"description": "Restrict results to certain radicals. This field is optional",
"items": {
"type": "string"
}
}
},
"description": "Payload for completion request"
},
"CompletionResponse": {
"type": "object",
"properties": {
"suggestions": {
"type": "array",
"items": {
"$ref": "#/definitions/Suggestion"
}
},
"suggestion_type": {
"type": "string",
"description": "Type of suggestion",
"default": "Default",
"enum": [
"Default",
"KanjiReading"
]
}
},
"description": "Completion response"
},
"Suggestion": {
"type": "object",
"properties": {
"primary": {
"type": "string",
"example": "ねこ"
},
"secondary": {
"type": "string",
"example": "猫"
}
},
"description": "A single suggestion item"
},
"ImgScanResponse": {
"type": "object",
"properties": {
"text": {
"type": "string",
"example": "音楽が大好き"
}
},
"description": "Sucess response for retrieving text from an image"
},
"SearchType": {
"type": "string",
"description": "Type of search (Words, Kanji, Sentences, Names)",
"enum": [
"0",
"1",
"2",
"3"
]
}
}
}
`;
let objSpec = JSON.parse(strSpec);
docEl.loadSpec(objSpec);
})
</script>
</body>
</html>
================================================
FILE: html/assets/fonts/fonts.css
================================================
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url("roboto.woff2") format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url("materialFont.woff2") format('woff2');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-feature-settings: 'liga';
-webkit-font-smoothing: antialiased;
}
================================================
FILE: html/assets/js/lib/d3.js
================================================
!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++i<u;)(t=r[i].on)&&t.apply(this,arguments);return n}var e=[],r=new c;return t.on=function(t,i){var u,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,u=e.indexOf(o)).concat(e.slice(u+1)),r.remove(t)),i&&e.push(r.set(t,{on:i})),n)},t}function S(){ao.event.preventDefault()}function k(){for(var n,t=ao.event;n=t.sourceEvent;)t=n;return t}function N(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(i){try{var u=i.sourceEvent=ao.event;i.target=n,ao.event=i,t[i.type].apply(e,r)}finally{ao.event=u}}},t}function E(n){return ko(n,Co),n}function A(n){return"function"==typeof n?n:function(){return No(n,this)}}function C(n){return"function"==typeof n?n:function(){return Eo(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function i(){this.setAttribute(n,t)}function u(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ao.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?u:i}function L(n){return n.trim().replace(/\s+/g," ")}function q(n){return new RegExp("(?:^|\\s+)"+ao.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<i;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<i;)n[e](this,r)}n=T(n).map(D);var i=n.length;return"function"==typeof t?r:e}function D(n){var t=q(n);return function(e,r){if(i=e.classList)return r?i.add(n):i.remove(n);var i=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(i)||e.setAttribute("class",L(i+" "+n))):e.setAttribute("class",L(i.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function i(){this.style.setProperty(n,t,e)}function u(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?u:i}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function i(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?i:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e===zo&&t.documentElement.namespaceURI===zo?t.createElement(n):t.createElementNS(e,n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ao.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return Ao(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t<l;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function i(){var i=l(t,co(arguments));r.call(this),this.addEventListener(n,this[o]=i,i.$=e),i._=t}function u(){var t,e=new RegExp("^__on([^.]+)"+ao.requote(n)+"$");for(var r in this)if(t=r.match(e)){var i=this[r];this.removeEventListener(t[1],i,i.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),l=$;a>0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t<e&&(e=t.t),t=(n=t).n):t=n?n.n=t.n:oa=t.n;return aa=n,e}function Pn(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Un(n,t){var e=Math.pow(10,3*xo(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(l,a)),null!=(i=ya[e=n.charAt(++a)])&&(e=n.charAt(++a)),(u=A[e])&&(e=u(t,null==i?"e"===e?" ":"0":i)),o.push(e),l=a+1);return o.push(n.slice(l,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},i=e(r,n,t,0);if(i!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var u=null!=r.Z&&va!==Hn,o=new(u?Hn:va);return"j"in r?o.setFullYear(r.y,0,r.j):"W"in r||"U"in r?("w"in r||(r.w="W"in r?1:0),o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),u?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var i,u,o,a=0,l=t.length,c=e.length;l>a;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function $n(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Bn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function Wn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Jn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Gn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.y=Qn(+r[0]),e+r[0].length):-1}function Kn(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Qn(n){return n+(n>68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ft(){}function st(n,t,e){var r=e.s=n+t,i=r-n,u=r-i;e.t=n-u+(t-i)}function ht(n,t){n&&wa.hasOwnProperty(n.type)&&wa[n.type](n,t)}function pt(n,t,e){var r,i=-1,u=n.length-e;for(t.lineStart();++i<u;)r=n[i],t.point(r[0],r[1],r[2]);t.lineEnd()}function gt(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)pt(n[e],t,1);t.polygonEnd()}function vt(){function n(n,t){n*=Yo,t=t*Yo/2+Fo/4;var e=n-r,o=e>=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])<Uo&&xo(n[1]-t[1])<Uo}function St(n,t){n*=Yo;var e=Math.cos(t*=Yo);kt(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function kt(n,t,e){++Ea,Ca+=(n-Ca)/Ea,za+=(t-za)/Ea,La+=(e-La)/Ea}function Nt(){function n(n,i){n*=Yo;var u=Math.cos(i*=Yo),o=u*Math.cos(n),a=u*Math.sin(n),l=Math.sin(i),c=Math.atan2(Math.sqrt((c=e*l-r*a)*c+(c=r*o-t*l)*c+(c=t*a-e*o)*c),t*o+e*a+r*l);Aa+=c,qa+=c*(t+(t=o)),Ta+=c*(e+(e=a)),Ra+=c*(r+(r=l)),kt(t,e,r)}var t,e,r;ja.point=function(i,u){i*=Yo;var o=Math.cos(u*=Yo);t=o*Math.cos(i),e=o*Math.sin(i),r=Math.sin(u),ja.point=n,kt(t,e,r)}}function Et(){ja.point=St}function At(){function n(n,t){n*=Yo;var e=Math.cos(t*=Yo),o=e*Math.cos(n),a=e*Math.sin(n),l=Math.sin(t),c=i*l-u*a,f=u*o-r*l,s=r*a-i*o,h=Math.sqrt(c*c+f*f+s*s),p=r*o+i*a+u*l,g=h&&-nn(p)/h,v=Math.atan2(h,p);Da+=g*c,Pa+=g*f,Ua+=g*s,Aa+=v,qa+=v*(r+(r=o)),Ta+=v*(i+(i=a)),Ra+=v*(u+(u=l)),kt(r,i,u)}var t,e,r,i,u;ja.point=function(o,a){t=o,e=a,ja.point=n,o*=Yo;var l=Math.cos(a*=Yo);r=l*Math.cos(o),i=l*Math.sin(o),u=Math.sin(a),kt(r,i,u)},ja.lineEnd=function(){n(t,e),ja.lineEnd=Et,ja.point=St}}function Ct(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function zt(){return!0}function Lt(n,t,e,r,i){var u=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(wt(e,r)){i.lineStart();for(var a=0;t>a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r<t;)i.n=e=n[r],e.p=i,i=e;i.n=e=n[0],e.p=i}}function Tt(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Rt(n,t,e,r){return function(i,u){function o(t,e){var r=i(t,e);n(t=r[0],e=r[1])&&u.point(t,e)}function a(n,t){var e=i(n,t);d.point(e[0],e[1])}function l(){m.point=a,d.lineStart()}function c(){m.point=o,d.lineEnd()}function f(n,t){v.push([n,t]);var e=i(n,t);x.point(e[0],e[1])}function s(){x.lineStart(),v=[]}function h(){f(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),g.push(v),v=null,r)if(1&t){n=e[0];var i,r=n.length-1,o=-1;if(r>0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o<r;)u.point((i=n[o])[0],i[1]);u.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)<Uo?(n.point(e,r=(r+o)/2>0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)<Uo&&(e-=i*Uo),xo(u-a)<Uo&&(u-=a*Uo),r=Ft(e,r,u,o),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=u,r=o),i=a},lineEnd:function(){n.lineEnd(),e=r=NaN},clean:function(){return 2-t}}}function Ft(n,t,e,r){var i,u,o=Math.sin(n-e);return xo(o)>Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]<t[0]?Fo:-Fo;i=e*u/2,r.point(-u,i),r.point(0,i),r.point(u,i)}else r.point(t[0],t[1])}function Ot(n,t){var e=n[0],r=n[1],i=[Math.sin(e),-Math.cos(e),0],u=0,o=0;ka.reset();for(var a=0,l=t.length;l>a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)<Uo,C=A||Uo>E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)<Uo?k:N):k<=b[1]&&b[1]<=N:E>Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)<Uo?i>0?0:3:xo(r[0]-e)<Uo?i>0?2:1:xo(r[1]-t)<Uo?i>0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:
gitextract_jueqquxr/
├── .dockerignore
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows/
│ └── docker-image.yml
├── .gitignore
├── Cargo.toml
├── Dockerfile
├── LICENSE
├── README.md
├── deny.toml
├── docker-compose.yaml
├── html/
│ └── assets/
│ ├── css/
│ │ ├── main.css
│ │ ├── mobile.css
│ │ ├── overlay/
│ │ │ ├── croppingOverlay.css
│ │ │ ├── footerOverlay.css
│ │ │ ├── imgUploadOverlay.css
│ │ │ ├── notificationOverlay.css
│ │ │ ├── overlayBase.css
│ │ │ ├── radicalOverlay.css
│ │ │ ├── settingsOverlay.css
│ │ │ └── suggestionOverlay.css
│ │ ├── page/
│ │ │ ├── aboutPage.css
│ │ │ ├── errorPage.css
│ │ │ ├── footer.css
│ │ │ ├── helpPage.css
│ │ │ ├── indexPage.css
│ │ │ ├── infoPage.css
│ │ │ ├── kanjiPage.css
│ │ │ ├── multiPage/
│ │ │ │ ├── kana.css
│ │ │ │ ├── kanji.css
│ │ │ │ └── markdown.css
│ │ │ ├── namePage.css
│ │ │ ├── newsPage.css
│ │ │ ├── sentencePage.css
│ │ │ ├── wordExtensions/
│ │ │ │ ├── searchAnnotation.css
│ │ │ │ └── sentenceReader.css
│ │ │ └── wordPage.css
│ │ ├── search/
│ │ │ ├── choices.css
│ │ │ └── searchRow.css
│ │ └── tools/
│ │ ├── alerts.css
│ │ ├── pagination.css
│ │ └── ripple.css
│ ├── docs.html
│ ├── fonts/
│ │ └── fonts.css
│ ├── js/
│ │ ├── lib/
│ │ │ ├── d3.js
│ │ │ ├── jc.js
│ │ │ └── jotobaChoices.js
│ │ ├── locales/
│ │ │ └── collection.js
│ │ ├── mobile.js
│ │ ├── page/
│ │ │ ├── infoPage.js
│ │ │ ├── kanjiPage.js
│ │ │ ├── newsPage.js
│ │ │ ├── overlay/
│ │ │ │ ├── notifications.js
│ │ │ │ ├── settings.js
│ │ │ │ └── settings_overlay.js
│ │ │ ├── sentencePage.js
│ │ │ └── wordPage.js
│ │ ├── qol.js
│ │ ├── search/
│ │ │ ├── api.js
│ │ │ ├── eventHandler.js
│ │ │ ├── overlay/
│ │ │ │ ├── imageSearch.js
│ │ │ │ ├── radicalSearch.js
│ │ │ │ ├── speechSearch.js
│ │ │ │ └── suggestionOverlay.js
│ │ │ ├── search.js
│ │ │ ├── shared.js
│ │ │ └── suggestions.js
│ │ └── tools/
│ │ ├── jotoTools.js
│ │ ├── ripple.js
│ │ ├── service-worker.js
│ │ ├── theme.js
│ │ ├── utils.js
│ │ └── utils2.js
│ └── settings/
│ ├── manifest.json
│ └── opensearch.xml
├── jotoba_bin/
│ ├── Cargo.toml
│ ├── benches/
│ │ ├── my_benchmark.rs
│ │ └── resources.rs
│ └── src/
│ ├── check.rs
│ ├── cli.rs
│ ├── main.rs
│ └── webserver.rs
├── lib/
│ ├── api/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── app/
│ │ │ ├── completions/
│ │ │ │ ├── kanji/
│ │ │ │ │ ├── meaning.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── reading.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── names/
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── opensearch/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── parse.rs
│ │ │ │ ├── request.rs
│ │ │ │ └── words/
│ │ │ │ ├── foreign.rs
│ │ │ │ ├── hashtag.rs
│ │ │ │ ├── kana_end_ext.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── native.rs
│ │ │ ├── details/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── sentences.rs
│ │ │ │ └── word.rs
│ │ │ ├── img/
│ │ │ │ ├── mod.rs
│ │ │ │ └── request.rs
│ │ │ ├── kanji/
│ │ │ │ ├── ids_tree/
│ │ │ │ │ ├── builder.rs
│ │ │ │ │ └── mod.rs
│ │ │ │ └── mod.rs
│ │ │ ├── mod.rs
│ │ │ ├── news/
│ │ │ │ ├── detailed.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── short.rs
│ │ │ ├── radical/
│ │ │ │ ├── kanji.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── search/
│ │ │ │ ├── jp_search.rs
│ │ │ │ ├── meaning.rs
│ │ │ │ └── mod.rs
│ │ │ └── search/
│ │ │ ├── kanji.rs
│ │ │ ├── mod.rs
│ │ │ ├── names.rs
│ │ │ ├── sentences.rs
│ │ │ └── words.rs
│ │ ├── internal/
│ │ │ ├── info/
│ │ │ │ ├── mod.rs
│ │ │ │ └── words.rs
│ │ │ └── mod.rs
│ │ ├── lib.rs
│ │ └── search/
│ │ ├── kanji/
│ │ │ └── mod.rs
│ │ ├── mod.rs
│ │ ├── name/
│ │ │ └── mod.rs
│ │ ├── sentence/
│ │ │ └── mod.rs
│ │ └── word/
│ │ └── mod.rs
│ ├── config/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── lib.rs
│ ├── engine/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── pushable/
│ │ │ ├── counter.rs
│ │ │ ├── f_max_cnt.rs
│ │ │ ├── max_cnt.rs
│ │ │ ├── mod.rs
│ │ │ ├── push_dbg.rs
│ │ │ ├── push_fn.rs
│ │ │ └── push_mod.rs
│ │ ├── relevance/
│ │ │ ├── data.rs
│ │ │ ├── item.rs
│ │ │ └── mod.rs
│ │ ├── result.rs
│ │ ├── task.rs
│ │ └── utils.rs
│ ├── error/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── api_error.rs
│ │ └── lib.rs
│ ├── frontend/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── about.rs
│ │ │ ├── actix_ructe.rs
│ │ │ ├── build.rs
│ │ │ ├── direct.rs
│ │ │ ├── help_page.rs
│ │ │ ├── index.rs
│ │ │ ├── lib.rs
│ │ │ ├── liveness.rs
│ │ │ ├── news_ep.rs
│ │ │ ├── og_tags.rs
│ │ │ ├── search_ep.rs
│ │ │ ├── search_help.rs
│ │ │ ├── session.rs
│ │ │ ├── templ_utils.rs
│ │ │ ├── unescaped.rs
│ │ │ ├── url_query.rs
│ │ │ ├── user_settings.rs
│ │ │ └── web_error.rs
│ │ └── templates/
│ │ ├── base.rs.html
│ │ ├── base_index.rs.html
│ │ ├── error_page.rs.html
│ │ ├── functional/
│ │ │ └── render_sentence.rs.html
│ │ ├── overlays/
│ │ │ ├── info/
│ │ │ │ ├── collocations.rs.html
│ │ │ │ ├── definitions_jp.rs.html
│ │ │ │ └── inflections.rs.html
│ │ │ ├── mobile_overlays.rs.html
│ │ │ ├── page/
│ │ │ │ ├── decomposition_graph.rs.html
│ │ │ │ ├── image_crop.rs.html
│ │ │ │ ├── loading.rs.html
│ │ │ │ └── settings.rs.html
│ │ │ ├── page_overlays.rs.html
│ │ │ ├── search_overlays.rs.html
│ │ │ └── searchbar/
│ │ │ ├── image_input.rs.html
│ │ │ ├── radicals.rs.html
│ │ │ ├── speech.rs.html
│ │ │ └── suggestions.rs.html
│ │ ├── pages/
│ │ │ ├── about.rs.html
│ │ │ ├── info.rs.html
│ │ │ ├── kanji.rs.html
│ │ │ ├── names.rs.html
│ │ │ ├── news.rs.html
│ │ │ ├── search_help.rs.html
│ │ │ ├── sentences.rs.html
│ │ │ └── words.rs.html
│ │ └── subtemplates/
│ │ ├── footer.rs.html
│ │ ├── head.rs.html
│ │ ├── input_dropdown.rs.html
│ │ ├── main_body.rs.html
│ │ └── paginator.rs.html
│ ├── indexes/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── hashtag.rs
│ │ ├── kanji/
│ │ │ ├── mod.rs
│ │ │ ├── reading.rs
│ │ │ └── reading_freq/
│ │ │ ├── k_freq_item.rs
│ │ │ ├── mod.rs
│ │ │ └── reading.rs
│ │ ├── lib.rs
│ │ ├── names.rs
│ │ ├── ng_freq.rs
│ │ ├── radical.rs
│ │ ├── regex.rs
│ │ ├── sentences.rs
│ │ ├── storage/
│ │ │ ├── kanji.rs
│ │ │ ├── mod.rs
│ │ │ ├── name.rs
│ │ │ ├── radical.rs
│ │ │ ├── sentence.rs
│ │ │ ├── suggestions.rs
│ │ │ ├── utils.rs
│ │ │ └── word.rs
│ │ ├── term_freq.rs
│ │ └── words/
│ │ ├── foreign.rs
│ │ ├── mod.rs
│ │ └── native.rs
│ ├── japanese/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── furigana/
│ │ │ ├── generate/
│ │ │ │ ├── mod.rs
│ │ │ │ └── traits.rs
│ │ │ ├── mod.rs
│ │ │ └── tests.rs
│ │ ├── guessing.rs
│ │ ├── lib.rs
│ │ └── radicals.rs
│ ├── localization/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── error.rs
│ │ ├── language.rs
│ │ ├── lib.rs
│ │ └── traits.rs
│ ├── news/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── lib.rs
│ ├── resources/
│ │ ├── Cargo.toml
│ │ ├── build.rs
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── retrieve/
│ │ │ ├── kanji.rs
│ │ │ ├── mod.rs
│ │ │ ├── name.rs
│ │ │ ├── sentence.rs
│ │ │ └── word.rs
│ │ └── storage/
│ │ ├── feature.rs
│ │ ├── kanji.rs
│ │ ├── mod.rs
│ │ ├── name.rs
│ │ ├── sentence.rs
│ │ └── word.rs
│ ├── search/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── engine/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── names/
│ │ │ │ │ ├── foreign.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── native.rs
│ │ │ │ ├── radical/
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── sentences/
│ │ │ │ │ ├── foreign.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── native.rs
│ │ │ │ └── words/
│ │ │ │ ├── foreign.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── native/
│ │ │ │ ├── k_reading.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── regex.rs
│ │ │ ├── executor/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── out_builder.rs
│ │ │ │ ├── producer.rs
│ │ │ │ ├── search_result.rs
│ │ │ │ └── searchable.rs
│ │ │ ├── kanji/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── order.rs
│ │ │ │ ├── result.rs
│ │ │ │ └── tag_only.rs
│ │ │ ├── lib.rs
│ │ │ ├── name/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── order/
│ │ │ │ │ ├── foreign.rs
│ │ │ │ │ ├── japanese.rs
│ │ │ │ │ └── mod.rs
│ │ │ │ └── producer/
│ │ │ │ ├── foreign.rs
│ │ │ │ ├── kanji_reading.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── native/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── split.rs
│ │ │ │ └── sequence.rs
│ │ │ ├── query/
│ │ │ │ ├── form.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── parser/
│ │ │ │ │ ├── lang.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── prefix.rs
│ │ │ │ │ ├── req_terms.rs
│ │ │ │ │ └── tags.rs
│ │ │ │ ├── prefix.rs
│ │ │ │ ├── regex.rs
│ │ │ │ ├── tags.rs
│ │ │ │ └── user_settings.rs
│ │ │ ├── radical/
│ │ │ │ ├── mod.rs
│ │ │ │ └── word/
│ │ │ │ ├── foreign.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── romaji.rs
│ │ │ ├── sentence/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── order/
│ │ │ │ │ ├── foreign.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── native.rs
│ │ │ │ ├── producer/
│ │ │ │ │ ├── filter.rs
│ │ │ │ │ ├── foreign.rs
│ │ │ │ │ ├── kanji.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── native.rs
│ │ │ │ │ ├── sequence.rs
│ │ │ │ │ └── tag.rs
│ │ │ │ └── result.rs
│ │ │ └── word/
│ │ │ ├── filter.rs
│ │ │ ├── kanji.rs
│ │ │ ├── mod.rs
│ │ │ ├── order/
│ │ │ │ ├── foreign.rs
│ │ │ │ ├── kanji_reading.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── native.rs
│ │ │ │ └── regex.rs
│ │ │ ├── producer/
│ │ │ │ ├── foreign/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── romaji.rs
│ │ │ │ │ └── task.rs
│ │ │ │ ├── japanese/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── number.rs
│ │ │ │ │ ├── sentence_reader.rs
│ │ │ │ │ └── task.rs
│ │ │ │ ├── k_reading.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── regex.rs
│ │ │ │ ├── sequence.rs
│ │ │ │ └── tag.rs
│ │ │ └── result.rs
│ │ └── tests/
│ │ └── search_test.rs
│ ├── sentence_reader/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── analyzer.rs
│ │ ├── grammar/
│ │ │ ├── mod.rs
│ │ │ ├── rule.rs
│ │ │ └── rule_set.rs
│ │ ├── lib.rs
│ │ ├── output.rs
│ │ └── sentence/
│ │ ├── inflection.rs
│ │ ├── mod.rs
│ │ ├── owned_morpheme.rs
│ │ └── part.rs
│ ├── types/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── api/
│ │ │ ├── app/
│ │ │ │ ├── completions/
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── details/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── query.rs
│ │ │ │ │ ├── sentence.rs
│ │ │ │ │ └── word.rs
│ │ │ │ ├── image/
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── kanji/
│ │ │ │ │ ├── ids_tree.rs
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── news/
│ │ │ │ │ ├── long.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── short.rs
│ │ │ │ ├── radical/
│ │ │ │ │ ├── find_kanji.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── search.rs
│ │ │ │ └── search/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── query.rs
│ │ │ │ └── responses/
│ │ │ │ ├── k_compounds.rs
│ │ │ │ ├── kanji.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── names.rs
│ │ │ │ ├── sentences.rs
│ │ │ │ └── words/
│ │ │ │ ├── inflection.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── sentence.rs
│ │ │ │ └── word.rs
│ │ │ ├── internal/
│ │ │ │ ├── info/
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── words.rs
│ │ │ │ └── mod.rs
│ │ │ ├── mod.rs
│ │ │ └── search/
│ │ │ ├── kanji.rs
│ │ │ ├── mod.rs
│ │ │ ├── name.rs
│ │ │ ├── sentence.rs
│ │ │ └── word.rs
│ │ ├── jotoba/
│ │ │ ├── indexes/
│ │ │ │ ├── hashtag.rs
│ │ │ │ └── mod.rs
│ │ │ ├── kanji/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── radical.rs
│ │ │ │ └── reading.rs
│ │ │ ├── language/
│ │ │ │ ├── mod.rs
│ │ │ │ └── param.rs
│ │ │ ├── mod.rs
│ │ │ ├── names/
│ │ │ │ ├── mod.rs
│ │ │ │ └── name_type.rs
│ │ │ ├── pagination/
│ │ │ │ ├── mod.rs
│ │ │ │ └── page.rs
│ │ │ ├── search/
│ │ │ │ ├── guess.rs
│ │ │ │ ├── help.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── query_type.rs
│ │ │ ├── sentences/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── tag.rs
│ │ │ │ └── translation.rs
│ │ │ └── words/
│ │ │ ├── dialect.rs
│ │ │ ├── dict.rs
│ │ │ ├── field.rs
│ │ │ ├── foreign_language.rs
│ │ │ ├── gtype.rs
│ │ │ ├── inflection.rs
│ │ │ ├── information.rs
│ │ │ ├── misc.rs
│ │ │ ├── mod.rs
│ │ │ ├── part_of_speech.rs
│ │ │ ├── pitch/
│ │ │ │ ├── border.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── raw_data.rs
│ │ │ ├── priority.rs
│ │ │ ├── reading/
│ │ │ │ ├── iter.rs
│ │ │ │ └── mod.rs
│ │ │ └── sense.rs
│ │ ├── lib.rs
│ │ └── raw/
│ │ ├── jmdict/
│ │ │ └── mod.rs
│ │ ├── jmnedict/
│ │ │ └── mod.rs
│ │ ├── kanjidict/
│ │ │ └── mod.rs
│ │ └── mod.rs
│ └── utils/
│ ├── Cargo.toml
│ └── src/
│ ├── binary_search.rs
│ ├── korean.rs
│ └── lib.rs
├── locales/
│ ├── de.mo
│ ├── de.po
│ ├── en.mo
│ ├── en.po
│ ├── hu.mo
│ └── hu.po
├── rustfmt.toml
└── scripts/
└── gen_locales.sh
Showing preview only (207K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2470 symbols across 292 files)
FILE: html/assets/js/lib/d3.js
function n (line 1) | function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}
function t (line 1) | function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n...
function e (line 1) | function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}
function r (line 1) | function r(n){return null===n?NaN:+n}
function i (line 1) | function i(n){return!isNaN(n)}
function u (line 1) | function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0...
function o (line 1) | function o(n){return n.length}
function a (line 1) | function a(n){for(var t=1;n*t%1;)t*=10;return t}
function l (line 1) | function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{valu...
function c (line 1) | function c(){this._=Object.create(null)}
function f (line 1) | function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}
function s (line 1) | function s(n){return(n+="")[0]===_o?n.slice(1):n}
function h (line 1) | function h(n){return f(n)in this._}
function p (line 1) | function p(n){return(n=f(n))in this._&&delete this._[n]}
function g (line 1) | function g(){var n=[];for(var t in this._)n.push(s(t));return n}
function v (line 1) | function v(){var n=0;for(var t in this._)++n;return n}
function d (line 1) | function d(){for(var n in this._)return!1;return!0}
function y (line 1) | function y(){this._=Object.create(null)}
function m (line 1) | function m(n){return n}
function M (line 1) | function M(n,t,e){return function(){var r=e.apply(t,arguments);return r=...
function x (line 1) | function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1...
function b (line 1) | function b(){}
function _ (line 1) | function _(){}
function w (line 1) | function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++i<u;)(t=r[i]....
function S (line 1) | function S(){ao.event.preventDefault()}
function k (line 1) | function k(){for(var n,t=ao.event;n=t.sourceEvent;)t=n;return t}
function N (line 1) | function N(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[...
function E (line 1) | function E(n){return ko(n,Co),n}
function A (line 1) | function A(n){return"function"==typeof n?n:function(){return No(n,this)}}
function C (line 1) | function C(n){return"function"==typeof n?n:function(){return Eo(n,this)}}
function z (line 1) | function z(n,t){function e(){this.removeAttribute(n)}function r(){this.r...
function L (line 1) | function L(n){return n.trim().replace(/\s+/g," ")}
function q (line 1) | function q(n){return new RegExp("(?:^|\\s+)"+ao.requote(n)+"(?:\\s+|$)",...
function T (line 1) | function T(n){return(n+"").trim().split(/^|\s+/)}
function R (line 1) | function R(n,t){function e(){for(var e=-1;++e<i;)n[e](this,t)}function r...
function D (line 1) | function D(n){var t=q(n);return function(e,r){if(i=e.classList)return r?...
function P (line 1) | function P(n,t,e){function r(){this.style.removeProperty(n)}function i()...
function U (line 1) | function U(n,t){function e(){delete this[n]}function r(){this[n]=t}funct...
function j (line 1) | function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;...
function F (line 1) | function F(){var n=this.parentNode;n&&n.removeChild(this)}
function H (line 1) | function H(n){return{__data__:n}}
function O (line 1) | function O(n){return function(){return Ao(this,n)}}
function I (line 1) | function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n...
function Y (line 1) | function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var i,u=n[e],o=0,a=u....
function Z (line 1) | function Z(n){return ko(n,qo),n}
function V (line 1) | function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.len...
function X (line 1) | function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListene...
function $ (line 1) | function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this._...
function B (line 1) | function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTa...
function W (line 1) | function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e))...
function J (line 1) | function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerS...
function G (line 1) | function G(){return ao.event.changedTouches[0].identifier}
function K (line 1) | function K(n){return n>0?1:0>n?-1:0}
function Q (line 1) | function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}
function nn (line 1) | function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}
function tn (line 1) | function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}
function en (line 1) | function en(n){return((n=Math.exp(n))-1/n)/2}
function rn (line 1) | function rn(n){return((n=Math.exp(n))+1/n)/2}
function un (line 1) | function un(n){return((n=Math.exp(2*n))-1)/(n+1)}
function on (line 1) | function on(n){return(n=Math.sin(n/2))*n}
function an (line 1) | function an(){}
function ln (line 1) | function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(t...
function cn (line 1) | function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?...
function fn (line 1) | function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(t...
function sn (line 1) | function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math....
function hn (line 1) | function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(t...
function pn (line 1) | function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*n...
function gn (line 1) | function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*...
function vn (line 1) | function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}
function dn (line 1) | function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}
function yn (line 1) | function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n...
function mn (line 1) | function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void...
function Mn (line 1) | function Mn(n){return new mn(n>>16,n>>8&255,255&n)}
function xn (line 1) | function xn(n){return Mn(n)+""}
function bn (line 1) | function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n...
function _n (line 1) | function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=...
function wn (line 1) | function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n...
function Sn (line 1) | function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761...
function kn (line 1) | function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}
function Nn (line 1) | function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math...
function En (line 1) | function En(n){return"function"==typeof n?n:function(){return n}}
function An (line 1) | function An(n){return function(t,e,r){return 2===arguments.length&&"func...
function Cn (line 1) | function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&...
function zn (line 1) | function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}
function Ln (line 1) | function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.re...
function qn (line 1) | function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now())...
function Tn (line 1) | function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),c...
function Rn (line 1) | function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null...
function Dn (line 1) | function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t<e&&(e=t.t),t=(n=t).n):t=n...
function Pn (line 1) | function Pn(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}
function Un (line 1) | function Un(n,t){var e=Math.pow(10,3*xo(8-t));return{scale:t>8?function(...
function jn (line 1) | function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u...
function Fn (line 1) | function Fn(n){return n+""}
function Hn (line 1) | function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arg...
function On (line 1) | function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}...
function In (line 1) | function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,...
function Yn (line 1) | function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;+...
function Zn (line 1) | function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e...
function Vn (line 1) | function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")",...
function Xn (line 1) | function Xn(n){for(var t=new c,e=-1,r=n.length;++e<r;)t.set(n[e].toLower...
function $n (line 1) | function $n(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+1));return r...
function Bn (line 1) | function Bn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n....
function Wn (line 1) | function Wn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n....
function Jn (line 1) | function Jn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+4));return r...
function Gn (line 1) | function Gn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r...
function Kn (line 1) | function Kn(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+...
function Qn (line 1) | function Qn(n){return n+(n>68?1900:2e3)}
function nt (line 1) | function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r...
function tt (line 1) | function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r...
function et (line 1) | function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r...
function rt (line 1) | function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r...
function it (line 1) | function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r...
function ut (line 1) | function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r...
function ot (line 1) | function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r...
function at (line 1) | function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=...
function lt (line 1) | function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r...
function ct (line 1) | function ct(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);retu...
function ft (line 1) | function ft(){}
function st (line 1) | function st(n,t,e){var r=e.s=n+t,i=r-n,u=r-i;e.t=n-u+(t-i)}
function ht (line 1) | function ht(n,t){n&&wa.hasOwnProperty(n.type)&&wa[n.type](n,t)}
function pt (line 1) | function pt(n,t,e){var r,i=-1,u=n.length-e;for(t.lineStart();++i<u;)r=n[...
function gt (line 1) | function gt(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)pt(n[e]...
function vt (line 1) | function vt(){function n(n,t){n*=Yo,t=t*Yo/2+Fo/4;var e=n-r,o=e>=0?1:-1,...
function dt (line 1) | function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Ma...
function yt (line 1) | function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}
function mt (line 1) | function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1...
function Mt (line 1) | function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}
function xt (line 1) | function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}
function bt (line 1) | function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[...
function _t (line 1) | function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}
function wt (line 1) | function wt(n,t){return xo(n[0]-t[0])<Uo&&xo(n[1]-t[1])<Uo}
function St (line 1) | function St(n,t){n*=Yo;var e=Math.cos(t*=Yo);kt(e*Math.cos(n),e*Math.sin...
function kt (line 1) | function kt(n,t,e){++Ea,Ca+=(n-Ca)/Ea,za+=(t-za)/Ea,La+=(e-La)/Ea}
function Nt (line 1) | function Nt(){function n(n,i){n*=Yo;var u=Math.cos(i*=Yo),o=u*Math.cos(n...
function Et (line 1) | function Et(){ja.point=St}
function At (line 1) | function At(){function n(n,t){n*=Yo;var e=Math.cos(t*=Yo),o=e*Math.cos(n...
function Ct (line 1) | function Ct(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.i...
function zt (line 1) | function zt(){return!0}
function Lt (line 1) | function Lt(n,t,e,r,i){var u=[],o=[];if(n.forEach(function(n){if(!((t=n....
function qt (line 1) | function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r<t;)i.n=e=n[r],e...
function Tt (line 1) | function Tt(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this....
function Rt (line 1) | function Rt(n,t,e,r){return function(i,u){function o(t,e){var r=i(t,e);n...
function Dt (line 1) | function Dt(n){return n.length>1}
function Pt (line 1) | function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point...
function Ut (line 1) | function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t...
function jt (line 1) | function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lin...
function Ft (line 1) | function Ft(n,t,e,r){var i,u,o=Math.sin(n-e);return xo(o)>Uo?Math.atan((...
function Ht (line 1) | function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i)...
function Ot (line 1) | function Ot(n,t){var e=n[0],r=n[1],i=[Math.sin(e),-Math.cos(e),0],u=0,o=...
function It (line 1) | function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function...
function Yt (line 1) | function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=...
function Zt (line 1) | function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)<Uo?i>0?0:3:xo(r[0...
function Vt (line 1) | function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=functi...
function Xt (line 1) | function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;re...
function $t (line 1) | function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=f...
function Bt (line 1) | function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}
function Wt (line 1) | function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.pu...
function Jt (line 1) | function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" ...
function Gt (line 1) | function Gt(n,t){Ca+=n,za+=t,++La}
function Kt (line 1) | function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o...
function Qt (line 1) | function Qt(){Wa.point=Gt}
function ne (line 1) | function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o...
function te (line 1) | function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}functio...
function ee (line 1) | function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,...
function re (line 2) | function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return fun...
function ie (line 2) | function ie(n){this.stream=n}
function ue (line 2) | function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:...
function oe (line 2) | function oe(n){return ae(function(){return n})()}
function ae (line 2) | function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1...
function le (line 2) | function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}
function ce (line 2) | function ce(n,t){return[n,t]}
function fe (line 2) | function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}
function se (line 2) | function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}
function he (line 2) | function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,...
function pe (line 2) | function pe(n){var t=he(n);return t.invert=he(-n),t}
function ge (line 2) | function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Mat...
function ve (line 2) | function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a...
function de (line 2) | function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]...
function ye (line 2) | function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n)...
function me (line 2) | function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n)...
function Me (line 2) | function Me(n){return n.source}
function xe (line 2) | function xe(n){return n.target}
function be (line 2) | function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Mat...
function _e (line 2) | function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((...
function we (line 2) | function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i...
function Se (line 2) | function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io...
function ke (line 2) | function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Ma...
function Ne (line 2) | function Ne(n,t){return[n,Math.log(Math.tan(Fo/4+t/2))]}
function Ee (line 2) | function Ee(n){var t,e=oe(n),r=e.scale,i=e.translate,u=e.clipExtent;retu...
function Ae (line 2) | function Ae(n,t){return[Math.log(Math.tan(Fo/4+t/2)),-n]}
function Ce (line 2) | function Ce(n){return n[0]}
function ze (line 2) | function ze(n){return n[1]}
function Le (line 2) | function Le(n){for(var t=n.length,e=[0,1],r=2,i=2;t>i;i++){for(;r>1&&Q(n...
function qe (line 2) | function qe(n,t){return n[0]-t[0]||n[1]-t[1]}
function Te (line 2) | function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}
function Re (line 2) | function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f...
function De (line 2) | function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}
function Pe (line 2) | function Pe(){rr(this),this.edge=this.site=this.circle=null}
function Ue (line 2) | function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}
function je (line 2) | function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}
function Fe (line 2) | function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n]...
function He (line 2) | function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo...
function Oe (line 2) | function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P...
function Ie (line 2) | function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y==...
function Ye (line 2) | function Ye(n){this.site=n,this.edges=[]}
function Ze (line 2) | function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1]...
function Ve (line 2) | function Ve(n,t){return t.angle-n.angle}
function Xe (line 2) | function Xe(){rr(this),this.x=this.y=this.arc=this.site=this.cy=null}
function $e (line 2) | function $e(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,i=n.site,u=e.site;i...
function Be (line 2) | function Be(n){var t=n.circle;t&&(t.P||(al=t.N),ll.remove(t),fl.push(t),...
function We (line 2) | function We(n){for(var t,e=il,r=Yt(n[0][0],n[0][1],n[1][0],n[1][1]),i=e....
function Je (line 2) | function Je(n,t){var e=n.b;if(e)return!0;var r,i,u=n.a,o=t[0][0],a=t[1][...
function Ge (line 2) | function Ge(n,t){this.l=n,this.r=t,this.a=this.b=null}
function Ke (line 2) | function Ke(n,t,e,r){var i=new Ge(n,t);return il.push(i),e&&nr(i,n,t,e),...
function Qe (line 2) | function Qe(n,t,e){var r=new Ge(n,null);return r.a=t,r.b=e,il.push(r),r}
function nr (line 2) | function nr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}
function tr (line 2) | function tr(n,t,e){var r=n.a,i=n.b;this.edge=n,this.site=t,this.angle=e?...
function er (line 2) | function er(){this._=null}
function rr (line 2) | function rr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}
function ir (line 2) | function ir(n,t){var e=t,r=t.R,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e...
function ur (line 2) | function ur(n,t){var e=t,r=t.L,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e...
function or (line 2) | function or(n){for(;n.L;)n=n.L;return n}
function ar (line 2) | function ar(n,t){var e,r,i,u=n.sort(lr).pop();for(il=[],ul=new Array(n.l...
function lr (line 2) | function lr(n,t){return t.y-n.y||t.x-n.x}
function cr (line 2) | function cr(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}
function fr (line 2) | function fr(n){return n.x}
function sr (line 2) | function sr(n){return n.y}
function hr (line 2) | function hr(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}
function pr (line 2) | function pr(n,t,e,r,i,u){if(!n(t,e,r,i,u)){var o=.5*(e+i),a=.5*(r+u),l=t...
function gr (line 2) | function gr(n,t,e,r,i,u,o){var a,l=1/0;return function c(n,f,s,h,p){if(!...
function vr (line 2) | function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o...
function dr (line 2) | function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[...
function yr (line 2) | function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}
function mr (line 2) | function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];...
function Mr (line 2) | function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.inte...
function xr (line 2) | function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.leng...
function br (line 2) | function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}
function _r (line 2) | function _r(n){return function(t){return 1-n(1-t)}}
function wr (line 2) | function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}
function Sr (line 2) | function Sr(n){return n*n}
function kr (line 2) | function kr(n){return n*n*n}
function Nr (line 2) | function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return ...
function Er (line 2) | function Er(n){return function(t){return Math.pow(t,n)}}
function Ar (line 2) | function Ar(n){return 1-Math.cos(n*Io)}
function Cr (line 2) | function Cr(n){return Math.pow(2,10*(n-1))}
function zr (line 2) | function zr(n){return 1-Math.sqrt(1-n*n)}
function Lr (line 2) | function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.leng...
function qr (line 2) | function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}
function Tr (line 2) | function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*...
function Rr (line 2) | function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o...
function Dr (line 2) | function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o...
function Pr (line 2) | function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o...
function Ur (line 2) | function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}
function jr (line 2) | function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t...
function Fr (line 2) | function Fr(n,t){return n[0]*t[0]+n[1]*t[1]}
function Hr (line 2) | function Hr(n){var t=Math.sqrt(Fr(n,n));return t&&(n[0]/=t,n[1]/=t),t}
function Or (line 2) | function Or(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}
function Ir (line 2) | function Ir(n){return n.length?n.pop()+",":""}
function Yr (line 2) | function Yr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push("translat...
function Zr (line 2) | function Zr(n,t,e,r){n!==t?(n-t>180?t+=360:t-n>180&&(n+=360),r.push({i:e...
function Vr (line 2) | function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x...
function Xr (line 2) | function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"sc...
function $r (line 2) | function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t...
function Br (line 2) | function Br(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}
function Wr (line 2) | function Wr(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,M...
function Jr (line 2) | function Jr(n){for(var t=n.source,e=n.target,r=Kr(t,e),i=[t];t!==r;)t=t....
function Gr (line 2) | function Gr(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent...
function Kr (line 2) | function Kr(n,t){if(n===t)return n;for(var e=Gr(n),r=Gr(t),i=e.pop(),u=r...
function Qr (line 2) | function Qr(n){n.fixed|=2}
function ni (line 2) | function ni(n){n.fixed&=-7}
function ti (line 2) | function ti(n){n.fixed|=4,n.px=n.x,n.py=n.y}
function ei (line 2) | function ei(n){n.fixed&=-5}
function ri (line 2) | function ri(n,t,e){var r=0,i=0;if(n.charge=0,!n.leaf)for(var u,o=n.nodes...
function ii (line 2) | function ii(n,t){return ao.rebind(n,t,"sort","children","value"),n.nodes...
function ui (line 2) | function ui(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(i=n.children)...
function oi (line 2) | function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n...
function ai (line 2) | function ai(n){return n.children}
function li (line 2) | function li(n){return n.value}
function ci (line 2) | function ci(n,t){return t.value-n.value}
function fi (line 2) | function fi(n){return ao.merge(n.map(function(n){return(n.children||[])....
function si (line 2) | function si(n){return n.x}
function hi (line 2) | function hi(n){return n.y}
function pi (line 2) | function pi(n,t,e){n.y0=t,n.y=e}
function gi (line 2) | function gi(n){return ao.range(n.length)}
function vi (line 2) | function vi(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}
function di (line 2) | function di(n){for(var t,e=1,r=0,i=n[0][1],u=n.length;u>e;++e)(t=n[e][1]...
function yi (line 2) | function yi(n){return n.reduce(mi,0)}
function mi (line 2) | function mi(n,t){return n+t[1]}
function Mi (line 2) | function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}
function xi (line 2) | function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e...
function bi (line 2) | function bi(n){return[ao.min(n),ao.max(n)]}
function _i (line 2) | function _i(n,t){return n.value-t.value}
function wi (line 2) | function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pac...
function Si (line 2) | function Si(n,t){n._pack_next=t,t._pack_prev=n}
function ki (line 2) | function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}
function Ni (line 2) | function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s)...
function Ei (line 2) | function Ei(n){n._pack_next=n._pack_prev=n}
function Ai (line 2) | function Ai(n){delete n._pack_next,delete n._pack_prev}
function Ci (line 2) | function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=...
function zi (line 2) | function zi(n,t,e){var r=n.r+e.r,i=t.x-n.x,u=t.y-n.y;if(r&&(i||u)){var o...
function Li (line 2) | function Li(n,t){return n.parent==t.parent?1:2}
function qi (line 2) | function qi(n){var t=n.children;return t.length?t[0]:n.t}
function Ti (line 2) | function Ti(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}
function Ri (line 2) | function Ri(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}
function Di (line 2) | function Di(n){for(var t,e=0,r=0,i=n.children,u=i.length;--u>=0;)t=i[u],...
function Pi (line 2) | function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}
function Ui (line 2) | function Ui(n){return 1+ao.max(n,function(n){return n.y})}
function ji (line 2) | function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}
function Fi (line 2) | function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}
function Hi (line 2) | function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}
function Oi (line 2) | function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}
function Ii (line 2) | function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-...
function Yi (line 2) | function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}
function Zi (line 2) | function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}
function Vi (line 2) | function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n...
function Xi (line 2) | function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r...
function $i (line 2) | function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},cei...
function Bi (line 2) | function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;f...
function Wi (line 2) | function Wi(n,t,e,r){function i(){var i=Math.min(n.length,t.length)>2?Bi...
function Ji (line 2) | function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate"...
function Gi (line 2) | function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}
function Ki (line 2) | function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,M...
function Qi (line 2) | function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}
function nu (line 2) | function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"...
function tu (line 2) | function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}
function eu (line 2) | function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo...
function ru (line 2) | function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(...
function iu (line 2) | function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);re...
function uu (line 2) | function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,...
function ou (line 2) | function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set...
function au (line 2) | function au(n,t){function u(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=...
function lu (line 2) | function lu(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.flo...
function cu (line 2) | function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}retu...
function fu (line 2) | function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range...
function su (line 2) | function su(){return 0}
function hu (line 2) | function hu(n){return n.innerRadius}
function pu (line 2) | function pu(n){return n.outerRadius}
function gu (line 2) | function gu(n){return n.startAngle}
function vu (line 2) | function vu(n){return n.endAngle}
function du (line 2) | function du(n){return n&&n.padAngle}
function yu (line 2) | function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}
function mu (line 2) | function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(...
function Mu (line 2) | function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var ...
function xu (line 2) | function xu(n){return n.length>1?n.join("L"):n+"Z"}
function bu (line 2) | function bu(n){return n.join("L")+"Z"}
function _u (line 2) | function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i....
function wu (line 2) | function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i....
function Su (line 2) | function Su(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i....
function ku (line 2) | function ku(n,t){return n.length<4?xu(n):n[1]+Au(n.slice(1,-1),Cu(n,t))}
function Nu (line 2) | function Nu(n,t){return n.length<3?bu(n):n[0]+Au((n.push(n[0]),n),Cu([n[...
function Eu (line 2) | function Eu(n,t){return n.length<3?xu(n):n[0]+Au(n,Cu(n,t))}
function Au (line 2) | function Au(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2...
function Cu (line 2) | function Cu(n,t){for(var e,r=[],i=(1-t)/2,u=n[0],o=n[1],a=1,l=n.length;+...
function zu (line 2) | function zu(n){if(n.length<3)return xu(n);var t=1,e=n.length,r=n[0],i=r[...
function Lu (line 2) | function Lu(n){if(n.length<4)return xu(n);for(var t,e=[],r=-1,i=n.length...
function qu (line 2) | function qu(n){for(var t,e,r=-1,i=n.length,u=i+4,o=[],a=[];++r<4;)e=n[r%...
function Tu (line 2) | function Tu(n,t){var e=n.length-1;if(e)for(var r,i,u=n[0][0],o=n[0][1],a...
function Ru (line 2) | function Ru(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}
function Du (line 2) | function Du(n,t,e){n.push("C",Ru(Rl,t),",",Ru(Rl,e),",",Ru(Dl,t),",",Ru(...
function Pu (line 2) | function Pu(n,t){return(t[1]-n[1])/(t[0]-n[0])}
function Uu (line 2) | function Uu(n){for(var t=0,e=n.length-1,r=[],i=n[0],u=n[1],o=r[0]=Pu(i,u...
function ju (line 2) | function ju(n){for(var t,e,r,i,u=[],o=Uu(n),a=-1,l=n.length-1;++a<l;)t=P...
function Fu (line 2) | function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}
function Hu (line 2) | function Hu(n){for(var t,e,r,i=-1,u=n.length;++i<u;)t=n[i],e=t[0],r=t[1]...
function Ou (line 2) | function Ou(n){function t(t){function l(){v.push("M",a(n(y),s),f,c(n(d.r...
function Iu (line 3) | function Iu(n){return n.radius}
function Yu (line 3) | function Yu(n){return[n.x,n.y]}
function Zu (line 3) | function Zu(n){return function(){var t=n.apply(this,arguments),e=t[0],r=...
function Vu (line 3) | function Vu(){return 64}
function Xu (line 3) | function Xu(){return"circle"}
function $u (line 3) | function $u(n){var t=Math.sqrt(n/Fo);return"M0,"+t+"A"+t+","+t+" 0 1,1 0...
function Bu (line 3) | function Bu(n){return function(){var t,e,r;(t=this[n])&&(r=t[e=t.active]...
function Wu (line 3) | function Wu(n,t,e){return ko(n,Yl),n.namespace=t,n.id=e,n}
function Ju (line 3) | function Ju(n,t,e,r){var i=n.id,u=n.namespace;return Y(n,"function"==typ...
function Gu (line 3) | function Gu(n){return null==n&&(n=""),function(){this.textContent=n}}
function Ku (line 3) | function Ku(n){return null==n?"__transition__":"__transition_"+n+"__"}
function Qu (line 3) | function Qu(n,t,e,r,i){function u(n){var t=v.delay;return f.t=t+l,n>=t?o...
function no (line 3) | function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"tran...
function to (line 3) | function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"tran...
function eo (line 3) | function eo(n){return n.toISOString()}
function ro (line 3) | function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-...
function io (line 3) | function io(n){return new Date(n)}
function uo (line 3) | function uo(n){return JSON.parse(n.responseText)}
function oo (line 3) | function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.cre...
function n (line 3) | function n(t,o,a){if(a>=u.length)return r?r.call(i,o):e?o.sort(e):o;for(...
function t (line 3) | function t(n,e){if(e>=u.length)return n;var r=[],i=o[e++];return n.forEa...
function e (line 3) | function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Ar...
function n (line 3) | function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}
function e (line 3) | function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&...
function n (line 3) | function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}
function e (line 3) | function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}
function r (line 3) | function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}
function i (line 3) | function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}
function u (line 3) | function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}
function o (line 3) | function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d...
function a (line 3) | function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).m...
function l (line 3) | function l(n){z++||n({type:"zoomstart"})}
function c (line 3) | function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}
function f (line 3) | function f(n){--z||(n({type:"zoomend"}),d=null)}
function s (line 3) | function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,...
function h (line 3) | function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(fun...
function p (line 3) | function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this)...
function g (line 3) | function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n)...
function e (line 3) | function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?...
function r (line 3) | function r(n){return e.parse(n.responseText)}
function i (line 3) | function i(n){return function(t){return e.parse(t.responseText,n)}}
function u (line 3) | function u(t){return t.map(o).join(n)}
function o (line 3) | function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}
function e (line 3) | function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charC...
function n (line 4) | function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}
function t (line 4) | function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],...
function e (line 4) | function e(){b.point=t}
function r (line 4) | function r(){x[0]=f,x[1]=h,b.point=n,y=null}
function i (line 4) | function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n...
function u (line 4) | function u(){Na.lineStart()}
function o (line 4) | function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=...
function a (line 4) | function a(n,t){return(t-=n)<0?t+360:t}
function l (line 4) | function l(n,t){return n[0]-t[0]}
function c (line 4) | function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}
function n (line 4) | function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,...
function n (line 4) | function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(th...
function t (line 4) | function t(){return o=null,n}
function t (line 4) | function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}
function n (line 4) | function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-...
function n (line 4) | function n(){return{type:"MultiLineString",coordinates:t()}}
function t (line 4) | function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.rang...
function n (line 4) | function n(){return{type:"LineString",coordinates:[t||r.apply(this,argum...
function t (line 4) | function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=...
function t (line 4) | function t(n){var t=new Array(n.length),r=a[0][0],i=a[0][1],u=a[1][0],o=...
function e (line 4) | function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*...
function u (line 4) | function u(n){function u(n,t,e,r,i,u,o,a){if(!isNaN(e)&&!isNaN(r))if(n.l...
function n (line 4) | function n(){var n,c,s,h,p,g={},v=[],d=ao.range(u),y=[];for(e=[],r=[],n=...
function t (line 4) | function t(){e.sort(function(n,t){return l((n.source.value+n.target.valu...
function n (line 4) | function n(n){return function(t,e,r,i){if(t.point!==n){var u=t.cx-n.x,o=...
function t (line 4) | function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}
function n (line 4) | function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>...
function n (line 4) | function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.pus...
function n (line 4) | function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=...
function t (line 4) | function t(n){var e=n.children,r=0;if(e&&(i=e.length))for(var i,u=-1;++u...
function e (line 4) | function e(e,u){var o=r.call(this,e,u);return n(o[0],0,i[0],i[1]/t(o[0])...
function n (line 4) | function n(o){var a,l=o.length,c=o.map(function(e,r){return+t.call(n,e,r...
function n (line 4) | function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){retu...
function n (line 4) | function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i....
function n (line 4) | function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Ma...
function n (line 4) | function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent...
function t (line 4) | function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());...
function e (line 4) | function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;i...
function r (line 4) | function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}
function i (line 4) | function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i...
function u (line 4) | function u(n){n.x*=l[0],n.y=n.depth*l[1]}
function n (line 4) | function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var...
function n (line 4) | function n(n,t){for(var e,r,i=-1,u=n.length;++i<u;)r=(e=n[i]).value*(0>t...
function t (line 4) | function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u...
function e (line 4) | function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),...
function r (line 4) | function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++o<a;)(e=n...
function i (line 4) | function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0;
function u (line 5) | function u(r){var i=o||a(r),u=i[0];return u.x=u.y=0,u.value?(u.dx=c[0],u...
function t (line 5) | function t(t){var e=n.call(u,t,t.depth);return null==e?Oi(t):Ii(t,"numbe...
function e (line 5) | function e(t){return Ii(t,n)}
function n (line 5) | function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r....
function t (line 5) | function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n...
function n (line 5) | function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r...
function t (line 5) | function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-...
function e (line 5) | function e(n,t){return n.a0==t.a0&&n.a1==t.a1}
function r (line 5) | function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}
function i (line 5) | function i(n,t,e,r){return"Q 0,0 "+r}
function n (line 5) | function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,...
function n (line 5) | function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}
function e (line 5) | function e(){this.removeAttribute(a)}
function r (line 5) | function r(){this.removeAttributeNS(a.space,a.local)}
function i (line 5) | function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribu...
function u (line 5) | function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttribu...
function e (line 5) | function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&fu...
function r (line 5) | function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.loca...
function i (line 5) | function i(){this.style.removeProperty(n)}
function u (line 5) | function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComp...
function i (line 5) | function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null...
function n (line 5) | function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__...
function n (line 5) | function n(t){t.each(function(){var t=ao.select(this).style("pointer-eve...
function e (line 5) | function e(n){n.selectAll(".resize").attr("transform",function(n){return...
function r (line 5) | function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n...
function i (line 5) | function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e...
function u (line 5) | function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L...
FILE: html/assets/js/lib/jc.js
function a (line 1) | function a(){for(var a=0,b={};a<arguments.length;a++){var c=arguments[a]...
function b (line 1) | function b(a){return a.replace(/(%[0-9A-Z]{2})+/g,decodeURIComponent)}
function c (line 1) | function c(d){function e(){}function f(b,c,f){if("undefined"!=typeof doc...
FILE: html/assets/js/locales/collection.js
function getText (line 77) | function getText(identifier) {
FILE: html/assets/js/mobile.js
function markCurrentSearchType (line 17) | function markCurrentSearchType() {
function prepareMobilePageBtn (line 30) | function prepareMobilePageBtn() {
function jumpToTop (line 57) | function jumpToTop() {
function toggleMobileNav (line 67) | function toggleMobileNav() {
FILE: html/assets/js/page/kanjiPage.js
function getPaths (line 79) | function getPaths(kanjiLiteral) {
function refreshAnimations (line 85) | async function refreshAnimations(kanjiLiteral) {
function prepareAutoplay (line 121) | function prepareAutoplay(kanjiLiteral) {
function concludeAutoplay (line 137) | function concludeAutoplay(kanjiLiteral) {
function doOrPauseAnimation (line 148) | async function doOrPauseAnimation(kanjiLiteral) {
function doAnimation (line 164) | async function doAnimation(kanjiLiteral) {
function undoAnimation (line 191) | async function undoAnimation(kanjiLiteral, awaitLast) {
function pauseAnimation (line 219) | async function pauseAnimation(kanjiLiteral) {
function doAnimationStep (line 230) | async function doAnimationStep(kanjiLiteral, path, forward, fastReset) {
function doAnimationStep_onClick (line 246) | async function doAnimationStep_onClick(kanjiLiteral, direction) {
function toggleNumbers (line 270) | function toggleNumbers(kanjiLiteral, visible) {
function toggleCompounds (line 294) | function toggleCompounds(event) {
function generateTreeDiagram (line 315) | async function generateTreeDiagram(kanjiLiteral) {
function getSvgContent (line 427) | function getSvgContent(target, url) {
function onGraphToggleCheckboxClick (line 460) | function onGraphToggleCheckboxClick(event) {
FILE: html/assets/js/page/newsPage.js
function prepareNews (line 5) | function prepareNews() {
FILE: html/assets/js/page/overlay/notifications.js
function requestShortData (line 5) | async function requestShortData() {
function parseShortNotificationResults (line 26) | async function parseShortNotificationResults(results) {
function requestLongData (line 51) | function requestLongData(event, id) {
function parseDetailedNotificationResults (line 75) | async function parseDetailedNotificationResults(result) {
function toggleNotifications (line 83) | function toggleNotifications(event) {
function closeNotifications (line 110) | function closeNotifications() {
function showAllNotifications (line 116) | function showAllNotifications() {
FILE: html/assets/js/page/overlay/settings.js
function Settings (line 5) | function Settings() { }
function prepareSettingsOverlay (line 162) | async function prepareSettingsOverlay() {
function loadAnalytics (line 194) | function loadAnalytics() {
FILE: html/assets/js/page/overlay/settings_overlay.js
function OverlaySettings (line 3) | function OverlaySettings() {}
FILE: html/assets/js/page/sentencePage.js
function toggleTranslation (line 2) | function toggleTranslation(element) {
FILE: html/assets/js/page/wordPage.js
function centerSentenceReaderIfNeeded (line 27) | function centerSentenceReaderIfNeeded() {
function scrollSentenceReaderIntoView (line 40) | function scrollSentenceReaderIntoView() {
function hideUnusedExpanders (line 49) | function hideUnusedExpanders() {
FILE: html/assets/js/qol.js
function shouldCopyFurigana (line 178) | function shouldCopyFurigana(event) {
function shouldCopyKanji (line 193) | function shouldCopyKanji() {
function preventDefaultHighlight (line 199) | function preventDefaultHighlight(event, timeoutDurationMs, disableClick,...
function startEventTimeout (line 206) | function startEventTimeout(targetElement, durationMs, disableClick = tru...
function copyTranslationAndShowMessage (line 228) | function copyTranslationAndShowMessage(textParent) {
function changeSearchType (line 253) | function changeSearchType(html, newType) {
function onBackdropClick (line 261) | function onBackdropClick(event) {
FILE: html/assets/js/search/api.js
function API (line 1) | function API() {}
FILE: html/assets/js/search/overlay/imageSearch.js
function toggleImageSearchOverlay (line 17) | function toggleImageSearchOverlay() {
function imgUploadAltClick (line 31) | function imgUploadAltClick() {
function imgSearchFileSelected (line 36) | function imgSearchFileSelected() {
function resetUploadUrlInput (line 54) | function resetUploadUrlInput() {
function disableUploadUrlInput (line 69) | function disableUploadUrlInput(newMessage) {
function openImageCropOverlay (line 80) | function openImageCropOverlay(pastedFile) {
function uploadCroppedImage (line 103) | function uploadCroppedImage(dataUrl) {
function initCroppie (line 134) | function initCroppie(inputUrl) {
function toggleCroppingModal (line 150) | function toggleCroppingModal() {
FILE: html/assets/js/search/overlay/radicalSearch.js
function toggleRadicalOverlay (line 58) | function toggleRadicalOverlay() {
function resetRadPicker (line 80) | function resetRadPicker() {
function handleKanjiSelect (line 100) | function handleKanjiSelect(event) {
function handleRadicalSelect (line 113) | function handleRadicalSelect(event) {
function openRadicalPage (line 146) | function openRadicalPage(index) {
function clearRadicals (line 175) | function clearRadicals() {
function loadRadicals (line 186) | function loadRadicals(tabIndex) {
function addRadicals (line 209) | function addRadicals(arrayIndex) {
function addRadicalsFromArray (line 221) | function addRadicalsFromArray(index, array) {
function loadRadicalResults (line 238) | function loadRadicalResults(info) {
function iterateMaskAsync (line 289) | function iterateMaskAsync(functionToCall, startIndex, endIndex) {
function updateTabVisuals (line 307) | async function updateTabVisuals() {
function checkRadicalsInTab (line 340) | function checkRadicalsInTab(arrayIndex) {
function resetAllTabs (line 356) | function resetAllTabs() {
function closeAllTabs (line 364) | function closeAllTabs() {
function getSelectedRadicalArray (line 372) | function getSelectedRadicalArray() {
function getRadicalInfo (line 388) | function getRadicalInfo() {
function getRadicalSearchResults (line 430) | function getRadicalSearchResults() {
function loadRadicalSearchResults (line 470) | function loadRadicalSearchResults(results) {
FILE: html/assets/js/search/overlay/speechSearch.js
function recognitionSetup (line 15) | function recognitionSetup() {
function toggleSpeakOverlay (line 62) | function toggleSpeakOverlay() {
function setRecognitionLang (line 80) | function setRecognitionLang(lang) {
FILE: html/assets/js/search/search.js
function toggleSearchIcon (line 11) | function toggleSearchIcon(duration) {
function emptySearchInput (line 22) | function emptySearchInput() {
function getCurrentSubstring (line 30) | function getCurrentSubstring(target) {
function onSearchStart (line 56) | function onSearchStart() {
function scrollSearchIntoView (line 74) | function scrollSearchIntoView() {
function closeAllSubSearchbarOverlays (line 82) | function closeAllSubSearchbarOverlays(overlayToIgnore) {
function openHelpPage (line 92) | function openHelpPage() {
function onHomeClick (line 99) | function onHomeClick(event) {
FILE: html/assets/js/search/suggestions.js
function Suggestions (line 1) | function Suggestions() {}
function setShadowText (line 29) | function setShadowText() {
function loadSuggestionApiData (line 59) | function loadSuggestionApiData(result) {
function removeSuggestions (line 142) | function removeSuggestions() {
FILE: html/assets/js/tools/jotoTools.js
function JotoTools (line 6) | function JotoTools () {}
FILE: html/assets/js/tools/utils.js
function Util (line 9) | function Util () {}
FILE: jotoba_bin/benches/my_benchmark.rs
function get_query (line 12) | fn get_query(inp: &str, query_type: SearchTarget) -> Query {
function load (line 21) | fn load() {
function criterion_benchmark (line 36) | fn criterion_benchmark(c: &mut Criterion) {
function search (line 56) | fn search(query: &Query) {
FILE: jotoba_bin/benches/resources.rs
function load (line 6) | fn load() {
function criterion_benchmark (line 10) | fn criterion_benchmark(c: &mut Criterion) {
FILE: jotoba_bin/src/check.rs
function resources (line 7) | pub fn resources() -> bool {
function check (line 23) | pub fn check() {
function check_all (line 33) | fn check_all() -> bool {
function indexes (line 47) | fn indexes() -> bool {
function sentences (line 51) | fn sentences() -> bool {
function names (line 76) | fn names() -> bool {
function words (line 98) | fn words() -> bool {
function regex (line 127) | fn regex() -> bool {
FILE: jotoba_bin/src/cli.rs
type Options (line 7) | pub struct Options {
function parse (line 15) | pub fn parse() -> Options {
FILE: jotoba_bin/src/main.rs
function main (line 12) | pub async fn main() {
FILE: jotoba_bin/src/webserver.rs
constant ASSET_CACHE_MAX_AGE (line 24) | const ASSET_CACHE_MAX_AGE: u64 = 604800;
function start (line 27) | pub(super) async fn start(options: Options) -> std::io::Result<()> {
function service_worker (line 281) | async fn service_worker(config: Data<Config>, _req: HttpRequest) -> acti...
function privacy (line 285) | async fn privacy(config: Data<Config>, _req: HttpRequest) -> actix_web::...
function sitemap (line 289) | async fn sitemap(config: Data<Config>, _req: HttpRequest) -> actix_web::...
function serve_html_file (line 293) | async fn serve_html_file(config: Data<Config>, file: &str) -> actix_web:...
function robotstxt (line 299) | async fn robotstxt(_req: HttpRequest) -> HttpResponse {
function docs (line 307) | async fn docs(config: Data<Config>, _req: HttpRequest) -> actix_web::Res...
function prepare_data (line 314) | pub(crate) fn prepare_data(ccf: &Config) {
function setup_logger (line 353) | fn setup_logger() {
function load_tokenizer (line 357) | pub fn load_tokenizer(config: &Config) {
function clean_img_scan_dir (line 362) | fn clean_img_scan_dir(config: &Config) {
function debug_info (line 371) | fn debug_info() {
function load_resources (line 377) | pub fn load_resources(src: &str) {
function load_translations (line 383) | fn load_translations(config: &Config) -> Arc<TranslationDict> {
function load_indexes (line 393) | pub fn load_indexes(config: &Config) {
function check (line 397) | fn check() -> bool {
function setup_sentry (line 419) | fn setup_sentry(config: &Config) {
function internal_validator (line 436) | async fn internal_validator(
FILE: lib/api/src/app/completions/kanji/meaning.rs
function suggestions (line 10) | pub fn suggestions(query: &Query) -> Option<Response> {
FILE: lib/api/src/app/completions/kanji/mod.rs
function suggestions (line 9) | pub(crate) fn suggestions(query: Query) -> Option<Response> {
function japanese_suggestions (line 21) | fn japanese_suggestions(query: &Query) -> Option<Response> {
FILE: lib/api/src/app/completions/kanji/reading.rs
function suggestions (line 15) | pub fn suggestions(kanji_reading: kanji::reading::ReadingSearch) -> Opti...
function score (line 49) | fn score(literal: char, reading: &str, query: &str) -> usize {
function starts_with (line 69) | fn starts_with(word: &str, reading: &str) -> bool {
FILE: lib/api/src/app/completions/mod.rs
function suggestion_ep (line 16) | pub async fn suggestion_ep(payload: Json<Request>) -> Result<Json<Respon...
function suggestion_ep_inner (line 21) | pub(crate) fn suggestion_ep_inner(payload: Request) -> Result<Response, ...
function get_suggestions (line 44) | fn get_suggestions(query: Query, radicals: Vec<char>) -> Response {
function as_kanji_reading (line 63) | fn as_kanji_reading(query: &Query) -> Option<ReadingSearch> {
function convert_results (line 85) | pub(crate) fn convert_results(engine_output: Vec<autocompletion::index::...
FILE: lib/api/src/app/completions/names/mod.rs
function suggestions (line 10) | pub(crate) fn suggestions(query: Query) -> Option<Response> {
function transcription_suggestions (line 19) | pub fn transcription_suggestions(query: &Query) -> Option<Response> {
function native_suggestions (line 46) | pub fn native_suggestions(query: &Query) -> Option<Response> {
FILE: lib/api/src/app/completions/opensearch/mod.rs
type EPQuery (line 8) | pub struct EPQuery {
function suggestion_ep (line 12) | pub async fn suggestion_ep(query: web::Query<EPQuery>) -> Result<String,...
function get_suggestions (line 24) | fn get_suggestions(query: Request) -> Result<Vec<String>, actix_web::Err...
function gen_output (line 40) | fn gen_output(suggestions: Vec<String>, raw_query: String) -> String {
function make_request (line 49) | fn make_request(inp: String, search_target: SearchTarget) -> Request {
FILE: lib/api/src/app/completions/opensearch/parse.rs
function parse (line 4) | pub(crate) fn parse(inp: String) -> Parsed {
type Parsed (line 16) | pub(crate) struct Parsed {
method new (line 23) | fn new(query: String) -> Self {
method with_tags (line 31) | fn with_tags(query: String, tags: Vec<Tag>) -> Self {
method search_target (line 36) | pub fn search_target(&self) -> Option<SearchTarget> {
FILE: lib/api/src/app/completions/request.rs
function adjust (line 10) | pub(crate) fn adjust(request: Request) -> Request {
function get_query (line 44) | pub(crate) fn get_query(request: Request) -> Result<(Query, Vec<char>), ...
function get_language (line 64) | pub(crate) fn get_language(request: &Request) -> Language {
function validate (line 69) | pub(crate) fn validate(payload: &Request) -> Result<(), RestError> {
FILE: lib/api/src/app/completions/words/foreign.rs
function suggestions (line 19) | pub fn suggestions(query: &Query, query_str: &str) -> Option<Vec<WordPai...
function new_suggestion_query (line 93) | fn new_suggestion_query(query: &str, lang: Language) -> Option<Suggestio...
function try_romaji (line 113) | pub(crate) fn try_romaji(query_str: &str) -> Option<String> {
function strip_str_end (line 160) | pub fn strip_str_end(inp: &str, len: usize) -> &str {
function end_three_char_kana (line 169) | fn end_three_char_kana(s: &str) -> bool {
function test_strip_end (line 182) | fn test_strip_end() {
FILE: lib/api/src/app/completions/words/hashtag.rs
function suggestions (line 5) | pub fn suggestions(query: &str, search_target: SearchTarget) -> Option<V...
function empty (line 23) | fn empty(search_target: SearchTarget) -> Vec<WordPair> {
FILE: lib/api/src/app/completions/words/kana_end_ext.rs
type KanaEndExtension (line 16) | pub struct KanaEndExtension<'a> {
function new (line 24) | pub fn new(index: &'a JapaneseIndex, max_dist: u32) -> Self {
function run (line 37) | fn run(&self, query: &SuggestionQuery, rel_weight: f64) -> Vec<EngineIte...
function should_run (line 90) | fn should_run(&self, already_found: usize, _query: &SuggestionQuery) -> ...
function get_options (line 95) | fn get_options(&self) -> &ExtensionOptions {
function word_similarity (line 101) | fn word_similarity(
function find_kana_str (line 129) | fn find_kana_str(full_kana: &str, end_sub: &str) -> Option<usize> {
FILE: lib/api/src/app/completions/words/mod.rs
function suggestions (line 15) | pub(crate) fn suggestions(query: Query, radicals: &[char]) -> Option<Res...
function try_word_suggestions (line 29) | fn try_word_suggestions(query: &Query, radicals: &[char]) -> Option<Vec<...
function word_pair_order (line 52) | fn word_pair_order(a: &WordPair, b: &WordPair, query: &str) -> Ordering {
function get_katakana_query (line 57) | fn get_katakana_query(query: &Query) -> Query {
FILE: lib/api/src/app/completions/words/native.rs
constant MAX_SENTENCE_LEN (line 15) | const MAX_SENTENCE_LEN: usize = 15;
function suggestions (line 18) | pub fn suggestions(query: &Query, _romaji_query: &str, radicals: &[char]...
function normalize_inflections (line 112) | pub(crate) fn normalize_inflections(query_str: &str) -> (Option<String>,...
function word_rad_filter (line 136) | fn word_rad_filter(query: &str, word: &types::jotoba::words::Word, radic...
FILE: lib/api/src/app/details/sentences.rs
function details_ep (line 17) | pub async fn details_ep(
function sentence_details (line 26) | fn sentence_details(payload: &DetailsPayload, config: &Config) -> Option...
function get_kanji (line 40) | fn get_kanji(sentence: &Sentence) -> Vec<Kanji> {
function get_words (line 54) | fn get_words(sentence: &Sentence, payload: &DetailsPayload, config: &Con...
function find_word (line 70) | fn find_word(w: &str, payload: &DetailsPayload, config: &Config) -> Opti...
FILE: lib/api/src/app/details/word.rs
function details (line 17) | pub async fn details(
type Details (line 28) | pub(crate) struct Details<'a> {
function new (line 35) | fn new(payload: &'a DetailsPayload) -> Option<Self> {
function get_details (line 40) | fn get_details(&self, config: &Config) -> word::Details {
function get_kanji (line 59) | fn get_kanji(&self) -> Vec<Kanji> {
function has_sentence (line 72) | fn has_sentence(&self) -> bool {
function transitivity_pair (line 77) | fn transitivity_pair(&self) -> Option<TransitivityPair> {
function get_collocations (line 89) | fn get_collocations(&self, config: &Config) -> Vec<Word> {
function get_word (line 106) | fn get_word(&self, config: &Config) -> Word {
function format_word (line 111) | fn format_word(&self, word: &types::jotoba::words::Word, config: &Config...
FILE: lib/api/src/app/img/mod.rs
constant MAX_UPLOAD_SIZE (line 16) | const MAX_UPLOAD_SIZE: usize = 2 * 1024 * 1024;
constant FILTER_JP_REGEX (line 19) | const FILTER_JP_REGEX: Lazy<Regex> =
function scan_ep (line 23) | pub async fn scan_ep(
function scan_image (line 44) | fn scan_image<P: AsRef<Path>>(
function format_text (line 71) | fn format_text(text: String) -> Option<String> {
function read_payload (line 90) | pub(crate) async fn read_payload(
function scan_image (line 100) | fn scan_image<P: AsRef<Path>>(
FILE: lib/api/src/app/img/request.rs
function read_payload (line 17) | pub(crate) async fn read_payload(
function gen_local_file (line 38) | async fn gen_local_file(config: &Config) -> Result<PathBuf, RestError> {
function read_field (line 50) | async fn read_field(mut field: Field, local_file: &PathBuf) -> Result<()...
function check_magic_bytes (line 85) | fn check_magic_bytes(chunk: &[u8]) -> Result<(), RestError> {
function is_supported_format (line 95) | fn is_supported_format(magic_nr: [u8; 4]) -> bool {
FILE: lib/api/src/app/kanji/ids_tree/builder.rs
type KanjiTreeBuilder (line 15) | pub struct KanjiTreeBuilder {
method new (line 22) | pub fn new(build_full: bool) -> Self {
method build (line 27) | pub fn build(&self, c: char) -> Option<OutObject> {
FILE: lib/api/src/app/kanji/ids_tree/mod.rs
function decomp_graph (line 9) | pub async fn decomp_graph(payload: Json<Request>) -> Result<Json<Respons...
FILE: lib/api/src/app/mod.rs
type Result (line 18) | pub type Result<T> = std::result::Result<T, RestError>;
function conv_word (line 20) | pub(crate) fn conv_word(word: jotoba::words::Word, lang: Language, confi...
function conv_ex_sentence (line 75) | pub fn conv_ex_sentence(sense: jotoba::words::sense::Sense, lang: Langua...
function get_example_sentence (line 101) | fn get_example_sentence(id: u32, language: Language) -> Option<(String, ...
FILE: lib/api/src/app/news/detailed.rs
function news (line 6) | pub async fn news(payload: Json<Request>) -> Result<Json<Response>, acti...
FILE: lib/api/src/app/news/mod.rs
function ne_from_resource (line 6) | fn ne_from_resource(src: &news::NewsEntry, short: bool) -> NewsEntry {
FILE: lib/api/src/app/news/short.rs
function news (line 5) | pub async fn news(payload: Json<Request>) -> Result<Json<Response>, acti...
FILE: lib/api/src/app/radical/kanji.rs
function kanji_by_radicals (line 7) | pub async fn kanji_by_radicals(payload: Json<Request>) -> Result<Json<Re...
function find_kanji (line 15) | pub fn find_kanji(rads: &[char]) -> Response {
function push_or_insert (line 50) | fn push_or_insert<T>(map: &mut IntMap<Vec<T>>, key: u32, item: T) {
FILE: lib/api/src/app/radical/search/jp_search.rs
function search (line 7) | pub fn search(query: &str) -> HashSet<char> {
function similar_kanji_search (line 16) | pub fn similar_kanji_search(query: &str) -> Vec<KanjiRads> {
function get_kanji (line 48) | fn get_kanji(lit: char) -> Option<&'static Kanji> {
function into_kanji_rads (line 53) | fn into_kanji_rads(kanji: &Kanji) -> KanjiRads {
function kanji_search (line 67) | fn kanji_search(query: &str) -> HashSet<char> {
function kanji_radicals (line 72) | fn kanji_radicals(kanji: char) -> Vec<char> {
FILE: lib/api/src/app/radical/search/meaning.rs
function search (line 6) | pub fn search(query: &str, language: Language) -> HashSet<char> {
FILE: lib/api/src/app/radical/search/mod.rs
function search_radical (line 18) | pub async fn search_radical(
function user_lang (line 48) | fn user_lang(request: &HttpRequest) -> Language {
function map_radicals (line 56) | fn map_radicals(inp: &HashSet<char>) -> HashMap<u8, BTreeSet<char>> {
function verify_payload (line 70) | fn verify_payload(payload: &mut Request) -> Result<(), RestError> {
FILE: lib/api/src/app/search/kanji.rs
type SearchResp (line 24) | pub type SearchResp = Response<kanji::KanjiResponse>;
function search (line 27) | pub async fn search(payload: Json<SearchPayload>) -> Result<Json<SearchR...
function reading_compounds (line 51) | pub async fn reading_compounds(payload: Json<SearchPayload>) -> Result<J...
function convert_dicts (line 68) | fn convert_dicts(dicts: &Vec<u32>, lang: impl AsLangParam) -> Vec<Compou...
function load_dicts (line 76) | fn load_dicts(dicts: &Vec<u32>, lang: impl AsLangParam) -> Vec<Word> {
FILE: lib/api/src/app/search/mod.rs
constant FIRST_PAGE (line 19) | const FIRST_PAGE: u32 = 1;
constant LAST_PAGE (line 20) | const LAST_PAGE: u32 = 100;
function new_response (line 22) | pub(crate) fn new_response<T: Serialize>(
function new_page (line 35) | pub(crate) fn new_page<V: Serialize + Clone>(
function convert_payload (line 56) | pub(crate) fn convert_payload(pl: &SearchPayload) -> QueryParser {
function convert_user_settings (line 74) | pub(crate) fn convert_user_settings(
FILE: lib/api/src/app/search/names.rs
type Resp (line 17) | pub type Resp = Response<names::Response>;
function search (line 20) | pub async fn search(payload: Json<SearchPayload>) -> Result<Json<Resp>> {
FILE: lib/api/src/app/search/sentences.rs
type Resp (line 16) | pub type Resp = Response<sentences::Response>;
function search (line 19) | pub async fn search(payload: Json<SearchPayload>) -> Result<Json<Resp>> {
function convert_sentence (line 46) | pub(crate) fn convert_sentence(
FILE: lib/api/src/app/search/words.rs
type Resp (line 22) | pub type Resp = Response<words::Response>;
function search (line 25) | pub async fn search(payload: Json<SearchPayload>, config: Data<Config>) ...
function conv_sentence (line 70) | fn conv_sentence(sentence: sentence_reader::Sentence, index: usize) -> S...
function conv_infl_info (line 79) | fn conv_infl_info(infl_info: search::word::result::InflectionInformation...
FILE: lib/api/src/internal/info/words.rs
function word_info (line 11) | pub async fn word_info(payload: Json<Request>) -> Result<HttpResponse, R...
function unique_pos (line 35) | fn unique_pos(word: &Word) -> Vec<PosSimple> {
FILE: lib/api/src/search/kanji/mod.rs
function kanji_search (line 11) | pub async fn kanji_search(
function to_response (line 23) | fn to_response(items: Vec<search::kanji::result::Item>, config: &Config)...
FILE: lib/api/src/search/mod.rs
type Result (line 11) | pub type Result<T> = std::result::Result<T, RestError>;
function parse_query (line 13) | pub(crate) fn parse_query(payload: Json<SearchRequest>, q_type: SearchTa...
FILE: lib/api/src/search/name/mod.rs
function name_search (line 8) | pub async fn name_search(payload: Json<SearchRequest>) -> Result<Json<Re...
FILE: lib/api/src/search/sentence/mod.rs
function sentence_search (line 10) | pub async fn sentence_search(payload: Json<SearchRequest>) -> Result<Jso...
function search_to_sentence (line 27) | fn search_to_sentence(sentence: search::sentence::result::Sentence) -> S...
FILE: lib/api/src/search/word/mod.rs
function word_search (line 14) | pub async fn word_search(
FILE: lib/config/src/lib.rs
type Config (line 14) | pub struct Config {
method get_indexes_source (line 51) | pub fn get_indexes_source(&self) -> &str {
method get_suggestion_sources (line 59) | pub fn get_suggestion_sources(&self) -> &str {
method get_query_report_timeout (line 67) | pub fn get_query_report_timeout(&self) -> Duration {
method get_storage_data_path (line 78) | pub fn get_storage_data_path(&self) -> String {
method get_kreading_freq_path (line 86) | pub fn get_kreading_freq_path(&self) -> String {
method get_unidic_dict (line 95) | pub fn get_unidic_dict(&self) -> String {
method get_img_scan_upload_path (line 104) | pub fn get_img_scan_upload_path(&self) -> String {
method is_debug (line 113) | pub fn is_debug(&self) -> bool {
method new (line 156) | pub fn new(src: Option<PathBuf>) -> Result<Self, String> {
method save (line 192) | fn save(self) -> Result<Self, String> {
method get_config_file (line 203) | pub fn get_config_file() -> Result<PathBuf, String> {
type ServerConfig (line 24) | pub struct ServerConfig {
method get_audio_files (line 137) | pub fn get_audio_files(&self) -> &str {
method get_html_files (line 141) | pub fn get_html_files(&self) -> &str {
method get_locale_path (line 145) | pub fn get_locale_path(&self) -> &str {
method get_news_folder (line 149) | pub fn get_news_folder(&self) -> &str {
type SentryConfig (line 38) | pub struct SentryConfig {
type SearchConfig (line 43) | pub struct SearchConfig {
method default (line 120) | fn default() -> Self {
function variable_asset_hash (line 214) | fn variable_asset_hash(config: &Config) -> std::io::Result<String> {
function dir_content (line 244) | fn dir_content(path: &Path) -> std::io::Result<Vec<PathBuf>> {
function visit_dirs (line 252) | fn visit_dirs(dir: &Path, out: &mut Vec<DirEntry>) -> std::io::Result<()> {
FILE: lib/engine/src/lib.rs
type Engine (line 15) | pub trait Engine<'index> {
method make_query (line 40) | fn make_query<S: AsRef<str>>(inp: S, lang: Option<Language>) -> Option...
method doc_to_output (line 43) | fn doc_to_output(input: &Self::Document) -> Option<Vec<Self::Output>>;
method get_index (line 46) | fn get_index(lang: Option<Language>) -> &'index Self::B;
method retrieve_for (line 49) | fn retrieve_for(
method retrieve (line 57) | fn retrieve(
FILE: lib/engine/src/pushable/counter.rs
type Counter (line 6) | pub struct Counter<T> {
function new (line 13) | pub fn new() -> Self {
function val (line 21) | pub fn val(&self) -> usize {
type Item (line 27) | type Item = T;
method push (line 30) | fn push(&mut self, _: Self::Item) -> bool {
FILE: lib/engine/src/pushable/f_max_cnt.rs
type FilteredMaxCounter (line 6) | pub struct FilteredMaxCounter<'a, T> {
function new (line 15) | pub fn new<F>(max: usize, filter: F) -> Self
function val (line 28) | pub fn val(&self) -> usize {
function inc (line 33) | pub fn inc(&mut self, delta: usize) {
function is_full (line 38) | pub fn is_full(&self) -> bool {
type Item (line 44) | type Item = T;
method push (line 47) | fn push(&mut self, i: Self::Item) -> bool {
FILE: lib/engine/src/pushable/max_cnt.rs
type MaxCounter (line 6) | pub struct MaxCounter<T> {
function new (line 14) | pub fn new(max: usize) -> Self {
function val (line 23) | pub fn val(&self) -> usize {
function inc (line 28) | pub fn inc(&mut self, delta: usize) {
function is_full (line 33) | pub fn is_full(&self) -> bool {
type Item (line 39) | type Item = T;
method push (line 42) | fn push(&mut self, _i: Self::Item) -> bool {
FILE: lib/engine/src/pushable/mod.rs
type Pushable (line 17) | pub trait Pushable {
method push (line 20) | fn push(&mut self, i: Self::Item) -> bool;
type Item (line 27) | type Item = RelItem<T>;
method push (line 30) | fn push(&mut self, i: Self::Item) -> bool {
FILE: lib/engine/src/pushable/push_dbg.rs
type PushDbg (line 5) | pub struct PushDbg<'a, P, I> {
function new (line 15) | pub fn new(output: &'a mut P) -> Self {
type Item (line 28) | type Item = I;
method push (line 31) | fn push(&mut self, i: Self::Item) -> bool {
FILE: lib/engine/src/pushable/push_fn.rs
type PushFn (line 4) | pub struct PushFn<F, T> {
function new (line 14) | pub fn new(f: F) -> Self {
type Item (line 23) | type Item = T;
method push (line 26) | fn push(&mut self, i: Self::Item) -> bool {
FILE: lib/engine/src/pushable/push_mod.rs
type PushMod (line 6) | pub struct PushMod<'a, P, I, O, F> {
function new (line 18) | pub fn new(output: &'a mut P, f: F) -> Self {
type Item (line 33) | type Item = I;
method push (line 36) | fn push(&mut self, i: Self::Item) -> bool {
FILE: lib/engine/src/relevance/data.rs
type SortData (line 6) | pub struct SortData<'item, 'query, T, I, Q> {
function new (line 18) | pub fn new(
function item (line 39) | pub fn item(&self) -> &T {
function rel (line 44) | pub fn rel(&self) -> f32 {
function query_str (line 49) | pub fn query_str(&self) -> &str {
function language (line 54) | pub fn language(&self) -> Option<Language> {
function query (line 59) | pub fn query(&self) -> &'query Q {
function index_item (line 64) | pub fn index_item(&self) -> &I {
function threshold (line 69) | pub fn threshold(&self) -> Option<f32> {
function vec_similarity (line 79) | pub fn vec_similarity(&self) -> f32 {
FILE: lib/engine/src/relevance/item.rs
type RelItem (line 8) | pub struct RelItem<T> {
function new (line 16) | pub fn new(item: T, relevance: f32) -> Self {
function map_item (line 24) | pub fn map_item<F, O>(self, f: F) -> RelItem<O>
method eq (line 38) | fn eq(&self, other: &Self) -> bool {
method hash (line 47) | fn hash<H: Hasher>(&self, state: &mut H) {
method partial_cmp (line 54) | fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
method cmp (line 61) | fn cmp(&self, other: &Self) -> Ordering {
FILE: lib/engine/src/relevance/mod.rs
type RelevanceEngine (line 7) | pub trait RelevanceEngine {
method init (line 12) | fn init(&mut self, _init: RelEngineInit) {}
method score (line 14) | fn score<'item, 'query>(
type RelEngineInit (line 20) | pub struct RelEngineInit {
method new (line 27) | pub(crate) fn new(query: String, language: Option<Language>) -> Self {
FILE: lib/engine/src/result.rs
type SearchResult (line 7) | pub struct SearchResult<T> {
function new (line 15) | pub fn new(items: Vec<RelItem<T>>, total_items: usize) -> Self {
function len (line 24) | pub fn len(&self) -> usize {
function is_empty (line 30) | pub fn is_empty(&self) -> bool {
function iter (line 36) | pub fn iter(&self) -> Iter<'_, RelItem<T>> {
function into_inner (line 41) | pub fn into_inner(self) -> Vec<RelItem<T>> {
function into_iter (line 47) | pub fn into_iter(self) -> impl Iterator<Item = T> {
function get (line 53) | pub fn get(&self, index: usize) -> Option<&RelItem<T>> {
method default (line 60) | fn default() -> Self {
method fmt (line 69) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
FILE: lib/engine/src/task.rs
type SearchTask (line 15) | pub struct SearchTask<'index, E: Engine<'index>> {
function new (line 50) | pub fn new<S: AsRef<str>>(query: S) -> Self {
function with_language (line 58) | pub fn with_language<S: AsRef<str>>(query: S, language: Language) -> Self {
function has_language (line 67) | pub fn has_language(&self) -> bool {
function with_limit (line 73) | pub fn with_limit(mut self, total_limit: usize) -> Self {
function with_max_dist (line 80) | pub fn with_max_dist(mut self, max_dist: f32) -> Self {
function with_threshold (line 88) | pub fn with_threshold(mut self, threshold: f32) -> Self {
function has_threshold (line 95) | pub fn has_threshold(&self) -> bool {
function with_offset (line 101) | pub fn with_offset(mut self, offset: usize) -> Self {
function with_result_filter (line 107) | pub fn with_result_filter<F: 'static>(mut self, res_filter: F) -> Self
function with_custom_order (line 116) | pub fn with_custom_order(
function with_item_filter (line 126) | pub fn with_item_filter<F: 'static>(mut self, item_filter: F) -> Self
function find (line 135) | pub fn find(&mut self) -> SearchResult<E::Output> {
function find_to (line 145) | pub fn find_to<O>(&mut self, out: &mut O) -> Option<usize>
function estimate_result_count (line 160) | pub fn estimate_result_count(&mut self) -> Guess {
function estimate_to (line 189) | pub fn estimate_to<P>(&mut self, out: &mut P)
function find_to_inner (line 200) | fn find_to_inner<O>(&self, out: &mut O, sort: bool) -> Option<usize>
function score (line 240) | fn score(&self, out_item: &E::Output, index_item: &E::Document, query: &...
function make_result (line 258) | fn make_result(
function take_page (line 269) | fn take_page<U: Ord>(&self, pqueue: StableUniquePrioContainerMax<U>) -> ...
function retrieve_next (line 274) | fn retrieve_next(&self, retr: &mut E::Retriever) -> Option<(E::Document,...
function item_filter (line 295) | fn item_filter(&self, item: &E::Document) -> bool {
function rel_init (line 300) | fn rel_init(&mut self) {
function make_rel_init (line 310) | fn make_rel_init(&self) -> RelEngineInit {
method default (line 317) | fn default() -> Self {
FILE: lib/engine/src/utils.rs
function page_from_pqueue (line 5) | pub fn page_from_pqueue<U: Ord>(
function page_from_pqueue_with_max_dist (line 21) | pub fn page_from_pqueue_with_max_dist<I: PartialEq>(
FILE: lib/error/src/api_error.rs
type Origin (line 8) | pub enum Origin {
method fmt (line 15) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type RestError (line 29) | pub enum RestError {
method name (line 67) | pub fn name(&self) -> String {
method from (line 110) | fn from(err: super::Error) -> Self {
method from (line 121) | fn from(_: std::io::Error) -> Self {
method from (line 128) | fn from(_: BlockingError) -> Self {
type ErrorResponse (line 60) | struct ErrorResponse {
method status_code (line 84) | fn status_code(&self) -> StatusCode {
method error_response (line 97) | fn error_response(&self) -> HttpResponse {
FILE: lib/error/src/lib.rs
type Error (line 8) | pub enum Error {
method from (line 20) | fn from(err: std::io::Error) -> Self {
method from (line 26) | fn from(err: FromUtf8Error) -> Self {
method from (line 32) | fn from(err: ParseError) -> Self {
method from (line 40) | fn from(err: ParseIntError) -> Self {
method from (line 46) | fn from(err: std::str::Utf8Error) -> Self {
method fmt (line 52) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
FILE: lib/frontend/src/about.rs
function about (line 13) | pub async fn about(
FILE: lib/frontend/src/actix_ructe.rs
type Render (line 13) | pub struct Render<T: FnOnce(&mut Vec<u8>) -> std::io::Result<()>>(pub T);
function render (line 16) | pub fn render(self) -> Vec<u8> {
FILE: lib/frontend/src/build.rs
function main (line 3) | fn main() -> Result<()> {
FILE: lib/frontend/src/direct.rs
function direct_ep (line 25) | pub async fn direct_ep(
function set_og_tag (line 59) | fn set_og_tag(base_data: &mut BaseData, query_type: SearchTarget) {
function search_res_val (line 81) | fn search_res_val(res: &SearchResult) -> Option<String> {
function find_direct_word (line 90) | pub async fn find_direct_word(id: &str, settings: &UserSettings) -> Resu...
function find_direct_name (line 126) | pub async fn find_direct_name(id: &str) -> Result<ResultData, Error> {
function find_direct_sentence (line 138) | pub async fn find_direct_sentence(id: &str, settings: &UserSettings) -> ...
FILE: lib/frontend/src/help_page.rs
function help (line 13) | pub async fn help(
FILE: lib/frontend/src/index.rs
function index (line 13) | pub async fn index(
FILE: lib/frontend/src/lib.rs
type BaseData (line 44) | pub struct BaseData<'a> {
type Site (line 56) | pub enum Site<'a> {
type SearchResult (line 66) | pub struct SearchResult<'a> {
type ResultData (line 74) | pub enum ResultData {
method is_empty (line 259) | pub fn is_empty(&self) -> bool {
function new (line 83) | pub fn new(
function with_site (line 101) | pub fn with_site(mut self, site: Site<'a>) -> Self {
function with_cust_pages (line 107) | pub fn with_cust_pages(
function with_pages (line 134) | pub fn with_pages(&mut self, items: u32, curr_page: u32) {
function get_search_help (line 139) | pub fn get_search_help(&self) -> Option<&SearchHelp> {
function get_search_site_id (line 145) | pub fn get_search_site_id(&self) -> u8 {
function get_search_site_name (line 159) | pub fn get_search_site_name(&self) -> &str {
function with_search_result (line 173) | pub fn with_search_result(
function get_query_str (line 188) | pub fn get_query_str(&self) -> String {
function sel_str (line 200) | pub fn sel_str(&self, i: SearchTarget) -> &'static str {
function kanji_copounds_collapsed (line 214) | pub fn kanji_copounds_collapsed(&self) -> bool {
function set_og_tags (line 219) | pub fn set_og_tags(&mut self, tags: og_tags::TagSet) {
function get_og_tags (line 224) | pub fn get_og_tags(&self) -> Option<og_tags::TagSet> {
function assets_path (line 232) | pub fn assets_path(&self) -> &str {
function as_search_result (line 239) | pub fn as_search_result(&self) -> Option<&SearchResult<'a>> {
function og_tags (line 248) | pub fn og_tags(&self) -> Option<og_tags::TagSet> {
function og_tags (line 270) | pub fn og_tags(&self) -> og_tags::TagSet {
function og_tag_description (line 287) | pub(crate) fn og_tag_description(&self) -> String {
function search_type_ogg (line 291) | pub(crate) fn search_type_ogg(&self) -> &'static str {
function result_count (line 300) | fn result_count(&self) -> usize {
function default_og_tags (line 310) | fn default_og_tags() -> og_tags::TagSet {
function get_lang (line 327) | pub fn get_lang(&self) -> Language {
function gettext (line 332) | pub fn gettext<T: Translatable>(&self, t: T) -> UnescapedStr<'a> {
function gettext_custom (line 337) | pub fn gettext_custom<T: Translatable>(&self, t: T) -> UnescapedString {
function pgettext (line 342) | pub fn pgettext<T: Translatable>(&self, t: T, context: &'a str) -> Unesc...
function ngettext (line 348) | pub fn ngettext<T: TranslatablePlural>(&self, t: T, n: u64) -> Unescaped...
function pngettext (line 353) | pub fn pngettext<T: TranslatablePlural>(
function gettext_fmt (line 366) | pub fn gettext_fmt<T: Translatable, V: Display + Sized + Clone>(
function pgettext_fmt (line 376) | pub fn pgettext_fmt<T: Translatable, V: Display + Sized + Clone>(
function ngettext_fmt (line 387) | pub fn ngettext_fmt<T: TranslatablePlural, V: Display + Sized + Clone>(
function pngettext_fmt (line 398) | pub fn pngettext_fmt<T: TranslatablePlural, V: Display + Sized + Clone>(
function gt_search_link (line 410) | pub fn gt_search_link<T: Translatable, V: Display + Sized + Clone>(
function gt_search_links (line 421) | pub fn gt_search_links<T: Translatable, V: Display + Sized + Clone>(
function ngt_search_links (line 434) | pub fn ngt_search_links<T: TranslatablePlural, V: Display + Sized + Clone>(
function format_search_link (line 448) | fn format_search_link<V: Display + Sized + Clone>(input: V) -> String {
FILE: lib/frontend/src/liveness.rs
function ready (line 3) | pub async fn ready() -> HttpResponse {
function healthy (line 7) | pub async fn healthy() -> HttpResponse {
FILE: lib/frontend/src/news_ep.rs
function news (line 13) | pub async fn news(
FILE: lib/frontend/src/og_tags.rs
type TagSet (line 6) | pub struct TagSet {
method new (line 34) | pub(crate) fn new() -> Self {
method with_capacity (line 40) | pub(crate) fn with_capacity(cap: usize) -> Self {
method add_og (line 48) | pub fn add_og<S: AsRef<str>>(&mut self, key: TagKeyName, value: S) {
method add_twitter (line 55) | pub fn add_twitter<S: AsRef<str>>(&mut self, key: TagKeyName, value: S) {
method add (line 62) | pub fn add(&mut self, tag: Tag) {
method set_og_tag (line 68) | pub fn set_og_tag<S: AsRef<str>>(&mut self, key: TagKeyName, value: S)...
method set_twitter_tag (line 74) | pub fn set_twitter_tag<S: AsRef<str>>(&mut self, key: TagKeyName, valu...
method set_tag (line 80) | pub fn set_tag<S: AsRef<str>>(&mut self, key: TagKey, value: S) -> Opt...
method render (line 87) | pub fn render(&self) -> String {
method render_unescaped (line 93) | pub fn render_unescaped(&self) -> UnescapedString {
type Tag (line 11) | pub struct Tag {
method new (line 100) | pub fn new<S: AsRef<str>>(key: TagKey, value: S) -> Self {
method render (line 107) | pub fn render(&self) -> String {
type TagKey (line 17) | pub enum TagKey {
method new_og (line 119) | pub fn new_og(tag_name: TagKeyName) -> Self {
method new_twitter (line 125) | pub fn new_twitter(tag_name: TagKeyName) -> Self {
type TagKeyName (line 23) | pub enum TagKeyName {
method as_ref (line 132) | fn as_ref(&self) -> &str {
FILE: lib/frontend/src/search_ep.rs
function search_ep_no_js (line 22) | pub async fn search_ep_no_js(
function search_ep (line 33) | pub async fn search_ep(
function search (line 44) | async fn search(
function do_search (line 79) | async fn do_search<'a>(
type SResult (line 104) | type SResult = Result<ResultData, web_error::Error>;
function sentence_search (line 107) | async fn sentence_search<'a>(base_data: &mut BaseData<'a>, query: &'a Qu...
function kanji_search (line 122) | async fn kanji_search<'a>(base_data: &mut BaseData<'a>, query: &'a Query...
function name_search (line 135) | async fn name_search<'a>(base_data: &mut BaseData<'a>, query: &'a Query)...
function word_search (line 148) | async fn word_search<'a>(base_data: &mut BaseData<'a>, query: &'a Query)...
function redirect_home (line 160) | pub(crate) fn redirect_home() -> HttpResponse {
function report_timeout (line 168) | fn report_timeout(request: &HttpRequest, query: &Query) {
function sentry_request_from_http (line 181) | fn sentry_request_from_http(request: &HttpRequest) -> sentry::protocol::...
function log_duration (line 206) | fn log_duration(search_type: SearchTarget, duration: Duration) {
FILE: lib/frontend/src/search_help.rs
type SearchHelp (line 9) | pub struct SearchHelp {
method is_empty (line 19) | pub fn is_empty(&self) -> bool {
method iter_items (line 24) | pub fn iter_items(&self) -> impl Iterator<Item = (QueryType, Guess)> {
method iter_langs (line 40) | pub fn iter_langs(&self) -> impl Iterator<Item = (ResLanguage, &'stati...
FILE: lib/frontend/src/templ_utils.rs
function get_collocations (line 15) | pub fn get_collocations(word: &Word, lang: impl AsLangParam) -> Vec<(Str...
function unescaped_string (line 54) | pub fn unescaped_string<T: ToString>(s: T) -> UnescapedString {
function get_transitive_counterpart (line 60) | pub fn get_transitive_counterpart(word: &Word) -> Option<Word> {
function get_intransitive_counterpart (line 67) | pub fn get_intransitive_counterpart(word: &Word) -> Option<Word> {
function ext_sentence (line 74) | pub fn ext_sentence(
function get_types_humanized (line 92) | pub fn get_types_humanized(
function word_kanji (line 107) | pub fn word_kanji<O>(res: &SearchResult<Word, O>) -> Vec<Kanji> {
function has_kanji (line 111) | pub fn has_kanji<O>(res: &SearchResult<Word, O>) -> bool {
FILE: lib/frontend/src/unescaped.rs
type UnescapedString (line 9) | pub type UnescapedString = Unescaped<String>;
method from (line 40) | fn from(s: String) -> Self {
type UnescapedStr (line 12) | pub type UnescapedStr<'a> = Unescaped<&'a str>;
type Unescaped (line 15) | pub struct Unescaped<T: Display>(T);
method to_html (line 19) | fn to_html(&self, out: &mut dyn Write) -> io::Result<()> {
method to_html (line 26) | fn to_html(&self, out: &mut dyn Write) -> io::Result<()> {
function from (line 33) | fn from(s: &'a str) -> Self {
function new (line 47) | pub fn new<T: ToString>(t: T) -> Self {
function new (line 54) | pub fn new(t: &'a str) -> Self {
method to_string (line 61) | fn to_string(&self) -> String {
function into (line 68) | fn into(self) -> String {
function into (line 75) | fn into(self) -> String {
function as_ref (line 82) | fn as_ref(&self) -> &str {
function as_str (line 90) | pub fn as_str(&self) -> &'a str {
function as_str (line 98) | pub fn as_str(&self) -> &str {
FILE: lib/frontend/src/url_query.rs
type QueryStruct (line 11) | pub struct QueryStruct {
method adjust (line 29) | pub fn adjust(&self, query_str: String) -> Self {
method as_query_parser (line 49) | pub fn as_query_parser(&self, user_settings: UserSettings) -> QueryPar...
function default_page (line 67) | fn default_page() -> usize {
type NoJSQueryStruct (line 74) | pub struct NoJSQueryStruct {
method to_query_struct (line 90) | pub(crate) fn to_query_struct(self) -> (QueryStruct, String) {
function deserialize_lang (line 105) | fn deserialize_lang<'de, D>(s: D) -> Result<Option<Language>, D::Error>
FILE: lib/frontend/src/user_settings.rs
function parse (line 8) | pub(super) fn parse(request: &HttpRequest) -> UserSettings {
FILE: lib/frontend/src/web_error.rs
type Error (line 9) | pub enum Error {
method fmt (line 17) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
method from (line 30) | fn from(err: error::Error) -> Self {
method from (line 65) | fn from(_: std::str::Utf8Error) -> Self {
method from (line 72) | fn from(_: BlockingError) -> Self {
method get_info_text (line 79) | fn get_info_text(&self) -> InfoText {
type InfoText (line 23) | pub struct InfoText {
method status_code (line 42) | fn status_code(&self) -> StatusCode {
method error_response (line 51) | fn error_response(&self) -> HttpResponse {
function not_found (line 94) | pub async fn not_found() -> Result<HttpResponse, Error> {
FILE: lib/indexes/src/hashtag.rs
type HashTagIndex (line 11) | pub struct HashTagIndex {
method new (line 19) | pub fn new(tags: Vec<RawHashtag>, index: NgramIndex<2, u32>, trie: Tri...
method get (line 24) | pub fn get(&self, pos: usize) -> Option<&RawHashtag> {
method get_filtered (line 29) | pub fn get_filtered(&self, pos: usize, s_targets: &[SearchTarget]) -> ...
method trie_search (line 38) | pub fn trie_search(&self, query: &str, s_targets: &[SearchTarget]) -> ...
method ngram_search (line 51) | pub fn ngram_search(&self, query: &str, s_targets: &[SearchTarget]) ->...
FILE: lib/indexes/src/kanji/reading.rs
type Index (line 4) | pub type Index = Simple<String, u32>;
FILE: lib/indexes/src/kanji/reading_freq/k_freq_item.rs
type KFreqItem (line 6) | pub struct KFreqItem {
method new (line 13) | pub fn new(readings: Vec<String>) -> Self {
method total (line 23) | pub fn total(&self) -> usize {
method inc_total (line 29) | pub fn inc_total(&mut self, add: usize) {
method is_empty (line 34) | pub fn is_empty(&self) -> bool {
method get_readings (line 40) | pub fn get_readings<'a, F: Fn(&str) -> bool>(
method get_reading (line 49) | pub fn get_reading<S: AsRef<str>>(&self, s: S) -> Option<&ReadingFreq> {
FILE: lib/indexes/src/kanji/reading_freq/mod.rs
type FrequencyIndex (line 13) | pub struct FrequencyIndex {
method new (line 19) | pub fn new(all_kanji: &[Kanji]) -> FrequencyIndex {
method add_reading (line 40) | pub fn add_reading<F>(&mut self, kanji_lit: char, matches: F) -> bool
method clear (line 69) | pub fn clear(&mut self) {
method get (line 75) | pub fn get(&self, c: char) -> Option<&KFreqItem> {
method norm_reading_freq (line 81) | pub fn norm_reading_freq(&self, kanji: char, reading: &str) -> Option<...
method norm_reading_freq_th (line 87) | pub fn norm_reading_freq_th(&self, kanji: char, reading: &str, th: usi...
FILE: lib/indexes/src/kanji/reading_freq/reading.rs
type ReadingFreq (line 5) | pub struct ReadingFreq {
method new (line 13) | pub fn new(reading: String) -> Self {
method inc (line 19) | pub fn inc(&mut self, c: u32) {
method is_empty (line 24) | pub fn is_empty(&self) -> bool {
method partial_cmp (line 31) | fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
FILE: lib/indexes/src/names.rs
constant FOREIGN_NGRAM (line 1) | pub const FOREIGN_NGRAM: usize = 3;
type ForeignIndex (line 2) | pub type ForeignIndex = ngindex::NgramIndex<FOREIGN_NGRAM, u32>;
constant NATIVE_NGRAM (line 4) | pub const NATIVE_NGRAM: usize = 3;
type NativeIndex (line 5) | pub type NativeIndex = ngindex::NgramIndex<NATIVE_NGRAM, u32>;
FILE: lib/indexes/src/ng_freq.rs
type NgFreqIndex (line 9) | pub struct NgFreqIndex {
method new (line 15) | pub fn new(n: usize) -> Self {
method len (line 22) | pub fn len(&self) -> usize {
method is_empty (line 27) | pub fn is_empty(&self) -> bool {
method compress (line 31) | pub fn compress(&mut self, threshold: usize) {
method insert (line 35) | pub fn insert(&mut self, gloss: &str) {
method build_vec_cntx (line 49) | pub fn build_vec_cntx<A: AsRef<str>>(&self, builder: &mut VecBuilder, ...
method build_vec (line 54) | pub fn build_vec<A: AsRef<str>>(&self, inp: A) -> SpVec32 {
method vec_builder (line 59) | pub fn vec_builder(&self) -> VecBuilder {
method build_custom_vec (line 63) | pub fn build_custom_vec<A, F>(&self, inp: A, inv_freq: F) -> SpVec32
method build_custom_vec_cntx (line 94) | pub fn build_custom_vec_cntx<A, F>(
method n_for (line 127) | fn n_for(inp: &str, n: usize) -> usize {
method get_padded (line 132) | fn get_padded(&self, inp: &str) -> String {
function term_dist (line 140) | pub fn term_dist(a: &SpVec32, b: &SpVec32) -> f32 {
function test_single (line 167) | fn test_single(term: &str, n: usize) {
function test_freq (line 185) | fn test_freq() {
function test_sim (line 194) | fn test_sim() {
FILE: lib/indexes/src/radical.rs
type RadicalIndex (line 9) | pub struct RadicalIndex {
method new (line 15) | pub fn new(
method has_term (line 27) | pub fn has_term(&self, term: &str) -> bool {
method get (line 33) | pub fn get(&self, term: &str) -> Option<&Vec<SearchRadicalInfo>> {
FILE: lib/indexes/src/regex.rs
type RegexSearchIndex (line 6) | pub struct RegexSearchIndex {
method new (line 13) | pub fn new() -> Self {
method iter (line 21) | pub fn iter(&self) -> Iter<char, HashSet<u32>> {
method get_words_with (line 27) | pub fn get_words_with(&self, character: char) -> Option<&HashSet<u32>> {
method add_term (line 33) | pub fn add_term(&mut self, term: &str, seq_id: u32) {
FILE: lib/indexes/src/sentences.rs
type NativeIndex (line 4) | pub type NativeIndex = VSMIndexSimple<u32>;
type ForeignIndex (line 5) | pub type ForeignIndex = VSMIndexSimple<u32>;
FILE: lib/indexes/src/storage/kanji.rs
constant K_READINGS_FREQ_FILE (line 4) | pub const K_READINGS_FREQ_FILE: &str = "kreading_freq_index";
type KanjiStore (line 7) | pub struct KanjiStore {
method new (line 12) | pub fn new(kread_frequency: FrequencyIndex) -> Self {
method reading_freq (line 17) | pub fn reading_freq(&self) -> &FrequencyIndex {
function load (line 22) | pub(crate) fn load<P: AsRef<Path>>(path: P) -> Result<KanjiStore, Box<dy...
FILE: lib/indexes/src/storage/mod.rs
type IndexStore (line 20) | pub struct IndexStore {
method word (line 30) | pub fn word(&self) -> &WordStore {
method sentence (line 35) | pub fn sentence(&self) -> &SentenceStore {
method name (line 40) | pub fn name(&self) -> &NameStore {
method radical (line 45) | pub fn radical(&self) -> &RadicalStore {
method kanji (line 50) | pub fn kanji(&self) -> &KanjiStore {
method check (line 55) | pub fn check(&self) -> bool {
function get (line 62) | pub fn get() -> &'static IndexStore {
function load (line 67) | pub fn load<P: AsRef<Path>>(index_folder: P) -> Result<bool, Box<dyn Err...
function is_loaded (line 83) | pub fn is_loaded() -> bool {
function wait (line 88) | pub fn wait() {
function load_raw (line 92) | pub fn load_raw<P: AsRef<Path>>(
FILE: lib/indexes/src/storage/name.rs
constant FOREIGN_FILE (line 5) | pub const FOREIGN_FILE: &str = "name_foreign_index";
constant NATIVE_FILE (line 6) | pub const NATIVE_FILE: &str = "name_jp_index";
type NameStore (line 9) | pub struct NameStore {
method new (line 15) | pub(crate) fn new(foreign: ForeignIndex, native: NativeIndex) -> Self {
method foreign (line 20) | pub fn foreign(&self) -> &ForeignIndex {
method native (line 25) | pub fn native(&self) -> &NativeIndex {
method check (line 29) | pub(crate) fn check(&self) -> bool {
function load (line 34) | pub(crate) fn load<P: AsRef<Path>>(path: P) -> Result<NameStore, Box<dyn...
FILE: lib/indexes/src/storage/radical.rs
constant RAD_INDEX_FILE (line 5) | pub const RAD_INDEX_FILE: &str = "radical_index";
type RadicalStore (line 8) | pub struct RadicalStore {
method new (line 13) | pub(crate) fn new(rad_index: RadicalIndex) -> Self {
method meaning_index (line 19) | pub fn meaning_index(&self) -> &RadicalIndex {
method check (line 24) | pub(crate) fn check(&self) -> bool {
function load (line 29) | pub(crate) fn load<P: AsRef<Path>>(path: P) -> Result<RadicalStore, Box<...
FILE: lib/indexes/src/storage/sentence.rs
constant NATIVE_FILE (line 5) | pub const NATIVE_FILE: &str = "sentences_jp_index";
constant FOREIGN_FILE (line 6) | pub const FOREIGN_FILE: &str = "sentences_fg_index";
type SentenceStore (line 9) | pub struct SentenceStore {
method new (line 15) | pub(crate) fn new(native: NativeIndex, foreign: ForeignIndex) -> Self {
method foreign (line 21) | pub fn foreign(&self) -> &ForeignIndex {
method native (line 27) | pub fn native(&self) -> &NativeIndex {
method check (line 31) | pub(crate) fn check(&self) -> bool {
function load (line 36) | pub(crate) fn load<P: AsRef<Path>>(path: P) -> Result<SentenceStore, Box...
FILE: lib/indexes/src/storage/suggestions.rs
constant K_MEANING_NGRAM (line 10) | pub const K_MEANING_NGRAM: usize = 3;
constant FG_WORDS_NGRAM (line 12) | pub const FG_WORDS_NGRAM: usize = 3;
constant JP_WORDS_NGRAM (line 13) | pub const JP_WORDS_NGRAM: usize = 2;
constant FG_NAMES_NGRAM (line 15) | pub const FG_NAMES_NGRAM: usize = 3;
constant JP_NAMES_NGRAM (line 16) | pub const JP_NAMES_NGRAM: usize = 2;
constant SUGGESTION_FILE (line 18) | pub const SUGGESTION_FILE: &str = "suggestions";
type SuggestionStorage (line 25) | pub struct SuggestionStorage {
method new (line 38) | pub fn new(
method jp_words (line 57) | pub fn jp_words(&self) -> &JapaneseIndex {
method foreign_words (line 62) | pub fn foreign_words(&self, language: Language) -> Option<&BasicIndex<...
method kanji_meanings (line 67) | pub fn kanji_meanings(&self) -> &JapaneseIndex<K_MEANING_NGRAM> {
method names_native (line 72) | pub fn names_native(&self) -> &JapaneseIndex<JP_NAMES_NGRAM> {
method names_foreign (line 77) | pub fn names_foreign(&self) -> &BasicIndex<FG_NAMES_NGRAM> {
method hashtags (line 82) | pub fn hashtags(&self) -> &HashTagIndex {
method check (line 86) | pub fn check(&self) -> bool {
function load_raw (line 91) | pub fn load_raw<P: AsRef<Path>>(
function load (line 97) | pub fn load<P: AsRef<Path>>(path: P) -> Result<bool, Box<dyn Error + Syn...
function get_suggestions (line 103) | pub fn get_suggestions() -> &'static SuggestionStorage {
FILE: lib/indexes/src/storage/utils.rs
function deser_file (line 12) | pub fn deser_file<O: DeserializeOwned, P: AsRef<Path>>(
function load_by_language (line 24) | pub fn load_by_language<O, F, P: AsRef<Path>>(
function check_lang_map (line 63) | pub fn check_lang_map<T>(map: &HashMap<Language, T>) -> bool {
function fast_deser (line 68) | fn fast_deser<O: DeserializeOwned, P: AsRef<Path>>(
FILE: lib/indexes/src/storage/word.rs
constant FOREIGN_PREFIX (line 11) | pub const FOREIGN_PREFIX: &str = "word_index_";
constant NATIVE_FILE (line 12) | pub const NATIVE_FILE: &str = "jp_index";
constant REGEX_FILE (line 13) | pub const REGEX_FILE: &str = "regex_index";
constant KANJI_READING_INDEX (line 14) | pub const KANJI_READING_INDEX: &str = "word_kr_index";
type WordStore (line 17) | pub struct WordStore {
method new (line 27) | pub(crate) fn new(
method foreign (line 43) | pub fn foreign(&self, language: Language) -> Option<&ForeignIndex> {
method regex (line 48) | pub fn regex(&self) -> &RegexSearchIndex {
method k_reading (line 53) | pub fn k_reading(&self) -> &kanji::reading::Index {
method native (line 58) | pub fn native(&self) -> &NativeIndex {
method check (line 62) | pub(crate) fn check(&self) -> bool {
function load (line 68) | pub(crate) fn load<P: AsRef<Path>>(path: P) -> Result<WordStore, Box<dyn...
function load (line 79) | pub(crate) fn load<P: AsRef<Path> + Send + Sync>(
function load_foreign (line 109) | fn load_foreign<P: AsRef<Path>>(
FILE: lib/indexes/src/term_freq.rs
type TermFreqIndex (line 6) | pub struct TermFreqIndex {
method new (line 13) | pub fn new() -> Self {
method len (line 23) | pub fn len(&self) -> usize {
method is_empty (line 28) | pub fn is_empty(&self) -> bool {
method insert (line 34) | pub fn insert(&mut self, term: String) {
method compress (line 50) | pub fn compress(&mut self, threshold: usize) {
method vec_builder (line 62) | pub fn vec_builder(&self) -> VecBuilder {
method get_id (line 67) | pub fn get_id(&self, term: &str) -> Option<u32> {
method freq (line 72) | pub fn freq(&self, term: &str) -> Option<u32> {
method freq_by_id (line 78) | pub fn freq_by_id(&self, id: u32) -> Option<u32> {
method inv_freq (line 84) | pub fn inv_freq(&self, term: &str) -> Option<f32> {
method inv_freq_oov (line 92) | pub fn inv_freq_oov(&self, term: &str) -> f32 {
type VecBuilder (line 100) | pub struct VecBuilder<'index> {
function new (line 107) | pub(crate) fn new(index: &'index TermFreqIndex) -> Self {
function get_or_insert_id (line 116) | pub fn get_or_insert_id<S: AsRef<str>>(&mut self, term: S) -> u32 {
FILE: lib/indexes/src/words/foreign.rs
type WordVecIndex (line 7) | pub type WordVecIndex = VSMIndexSimple<u32>;
constant NG_FREQ_N (line 8) | pub const NG_FREQ_N: usize = 3;
type ForeignIndex (line 11) | pub struct ForeignIndex {
method new (line 17) | pub fn new(vsm_index: WordVecIndex, ng_index: NgFreqIndex) -> Self {
method vsm_index (line 25) | pub fn vsm_index(&self) -> &WordVecIndex {
method ng_index (line 30) | pub fn ng_index(&self) -> &NgFreqIndex {
type Target (line 36) | type Target = WordVecIndex;
method deref (line 39) | fn deref(&self) -> &Self::Target {
FILE: lib/indexes/src/words/mod.rs
type ForeignIndex (line 6) | pub type ForeignIndex = foreign::ForeignIndex;
type NativeIndex (line 7) | pub type NativeIndex = native::NativeIndex;
FILE: lib/indexes/src/words/native.rs
constant N (line 6) | pub const N: usize = 3;
type WordVecIndex (line 7) | pub type WordVecIndex = ngindex::NgramIndex<N, u32>;
type NativeIndex (line 11) | pub struct NativeIndex {
method new (line 19) | pub fn new(vsm_index: WordVecIndex, ng_index: NgFreqIndex) -> Self {
method index (line 27) | pub fn index(&self) -> &WordVecIndex {
method tf_index (line 32) | pub fn tf_index(&self) -> &NgFreqIndex {
type Target (line 38) | type Target = WordVecIndex;
method deref (line 41) | fn deref(&self) -> &Self::Target {
FILE: lib/japanese/src/furigana/generate/mod.rs
function checked (line 18) | pub fn checked<R: ReadingRetrieve>(retrieve: R, kanji: &str, kana: &str)...
function check (line 37) | fn check(gen: &str, kana: &str) -> bool {
function unchecked (line 53) | pub fn unchecked<R: ReadingRetrieve>(retrieve: R, kanji: &str, kana: &st...
function gen_iter (line 59) | pub fn gen_iter<'a, R>(
function assign_readings (line 96) | pub fn assign_readings<R: ReadingRetrieve>(
function find_kanji_combo (line 133) | fn find_kanji_combo(
function get_kanji_literals (line 212) | fn get_kanji_literals(inp: &str) -> Vec<char> {
function find_prefix (line 216) | fn find_prefix(prefixe: &HashSet<String>, text: &str) -> Vec<String> {
function format_readings (line 224) | fn format_readings(r: Vec<String>) -> HashSet<String> {
FILE: lib/japanese/src/furigana/generate/traits.rs
type ReadingRetrieve (line 1) | pub trait ReadingRetrieve {
method onyomi (line 2) | fn onyomi(&self, lit: char) -> Vec<String>;
method kunyomi (line 3) | fn kunyomi(&self, lit: char) -> Vec<String>;
method all (line 5) | fn all(&self, lit: char) -> Vec<String> {
method onyomi (line 14) | fn onyomi(&self, lit: char) -> Vec<String> {
method kunyomi (line 18) | fn kunyomi(&self, lit: char) -> Vec<String> {
FILE: lib/japanese/src/furigana/mod.rs
function map_readings (line 10) | fn map_readings(kanji: &str, kana: &str) -> Option<Vec<(String, String)>> {
function has_kanji_after (line 89) | fn has_kanji_after<T>(arr: &[T], offset: usize) -> bool
function starts_with (line 103) | fn starts_with<T>(arr: &[T], a: &[T], b: &[T], last: bool) -> bool
function char_arr_to_string (line 133) | fn char_arr_to_string(vec: &[char]) -> String {
function to_next_kanji (line 138) | fn to_next_kanji<T>(kanji_iter: &mut T) -> (Vec<char>, Vec<char>)
function strip_until_kanji (line 154) | fn strip_until_kanji<T>(mut kanji_iter: T) -> usize
FILE: lib/japanese/src/furigana/tests.rs
function test_map_readings (line 18) | fn test_map_readings(kanji: &str, kana: &str, expected: &[(&str, &str)]) {
FILE: lib/japanese/src/guessing.rs
function test_true (line 10) | fn test_true() {
function test_false (line 38) | fn test_false() {
function test (line 50) | fn test(inp: &str, assert: bool) {
function could_be_romaji (line 61) | pub fn could_be_romaji(inp: &str) -> bool {
function is_romaji_repl (line 65) | pub fn is_romaji_repl(inp: &str) -> Option<String> {
FILE: lib/japanese/src/lib.rs
type ToKanaExt (line 5) | pub trait ToKanaExt {
method to_hiragana (line 6) | fn to_hiragana(&self) -> String;
method to_katakana (line 7) | fn to_katakana(&self) -> String;
method to_hiragana (line 12) | fn to_hiragana(&self) -> String {
method to_katakana (line 17) | fn to_katakana(&self) -> String {
method to_hiragana (line 24) | fn to_hiragana(&self) -> String {
method to_katakana (line 29) | fn to_katakana(&self) -> String {
method to_hiragana (line 36) | fn to_hiragana(&self) -> String {
method to_katakana (line 41) | fn to_katakana(&self) -> String {
function to_kk_fmt (line 46) | pub fn to_kk_fmt(inp: &str) -> String {
function to_hira_fmt (line 52) | pub fn to_hira_fmt(inp: &str) -> String {
function romaji_prefix (line 60) | pub fn romaji_prefix(romaji: &str, hira: &str) -> bool {
FILE: lib/japanese/src/radicals.rs
constant RADICALS (line 15) | pub const RADICALS: &[(u32, &[&str]); 15] = &[
function is_radical (line 89) | pub fn is_radical(lit: char) -> bool {
function get_stroke_count (line 97) | pub fn get_stroke_count(lit: char) -> Option<u32> {
FILE: lib/localization/src/error.rs
type Error (line 2) | pub enum Error {
method from (line 9) | fn from(err: gettext::Error) -> Self {
method from (line 15) | fn from(err: std::io::Error) -> Self {
FILE: lib/localization/src/language.rs
type Language (line 8) | pub enum Language {
method default (line 33) | fn default() -> Self {
method get_id (line 40) | fn get_id(&self) -> &'static str {
FILE: lib/localization/src/lib.rs
type TranslationDict (line 15) | pub struct TranslationDict {
method new (line 23) | pub fn new(path: &str, default_lang: Language) -> Result<TranslationDi...
method gettext (line 67) | pub fn gettext<'a>(&'a self, msg_id: &'a str, language: Option<Languag...
method ngettext (line 75) | pub fn ngettext<'a>(
method pgettext (line 89) | pub fn pgettext<'a>(
method npgettext (line 102) | pub fn npgettext<'a>(
method gettext_fmt (line 116) | pub fn gettext_fmt<T: Display + Sized + Clone>(
method ngettext_fmt (line 129) | pub fn ngettext_fmt<T: Display + Sized + Clone>(
method pgettext_fmt (line 143) | pub fn pgettext_fmt<T: Display + Sized + Clone>(
method npgettext_fmt (line 157) | pub fn npgettext_fmt<T: Display + Sized + Clone>(
method get_catalog (line 173) | pub fn get_catalog(&self, language: Option<Language>) -> &Catalog {
method get_default_catalog (line 181) | pub fn get_default_catalog(&self) -> &Catalog {
function format (line 189) | fn format<T: Display + Sized + Clone>(inp: &str, values: &[T]) -> String {
function count_placeholder (line 207) | fn count_placeholder(inp: &str) -> usize {
FILE: lib/localization/src/traits.rs
type Translatable (line 21) | pub trait Translatable {
method get_id (line 8) | fn get_id(&self) -> &'static str {
method get_id (line 23) | fn get_id(&self) -> &'static str;
method gettext (line 27) | fn gettext<'a>(&self, dict: &'a TranslationDict, language: Option<Lang...
method pgettext (line 33) | fn pgettext<'a>(
method gettext_fmt (line 44) | fn gettext_fmt<'a, T: Display + Sized + Clone>(
method pgettext_fmt (line 55) | fn pgettext_fmt<T: Display + Sized + Clone>(
method gettext_custom (line 66) | fn gettext_custom(&self, dict: &TranslationDict, language: Option<Lang...
type TranslatablePlural (line 72) | pub trait TranslatablePlural: Translatable {
method get_plural_id (line 15) | fn get_plural_id(&self) -> &'static str {
method get_plural_id (line 74) | fn get_plural_id(&self) -> &'static str;
method ngettext (line 78) | fn ngettext<'a>(
method npgettext (line 89) | fn npgettext<'a>(
method ngettext_fmt (line 101) | fn ngettext_fmt<'a, T: Display + Sized + Clone>(
method npgettext_fmt (line 113) | fn npgettext_fmt<T: Display + Sized + Clone>(
FILE: lib/news/src/lib.rs
type News (line 19) | pub struct News {
method init (line 35) | pub fn init<P: AsRef<Path>>(path: P) -> Result<(), Box<dyn std::error:...
method load (line 50) | pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, Box<dyn std::erro...
method last_entries (line 92) | pub fn last_entries(&self, limit: usize) -> impl Iterator<Item = &News...
method by_id (line 99) | pub fn by_id(&self, id: u32) -> Option<&NewsEntry> {
type NewsEntry (line 24) | pub struct NewsEntry {
function get (line 106) | pub fn get() -> Arc<News> {
function parse_markdown (line 110) | fn parse_markdown<P: AsRef<Path>>(file: P) -> Result<(String, String), B...
function shorten_markdown (line 127) | fn shorten_markdown(full: &str) -> String {
FILE: lib/resources/build.rs
function main (line 3) | fn main() {
FILE: lib/resources/src/lib.rs
constant GIT_HASH (line 15) | pub const GIT_HASH: &str = env!("GIT_HASH");
constant REQUIRED_FEATURES (line 18) | pub const REQUIRED_FEATURES: &[Feature] = &[
function get (line 38) | pub fn get() -> &'static ResourceStorage {
function is_loaded (line 47) | pub fn is_loaded() -> bool {
function load_raw (line 52) | pub fn load_raw<P: AsRef<Path>>(path: P) -> Result<ResourceStorage, Box<...
function load (line 58) | pub fn load<P: AsRef<Path>>(path: P) -> Result<bool, Box<dyn Error>> {
function store (line 66) | pub fn store<W: Write>(output: W, storage: &ResourceStorage) -> Result<(...
function set (line 71) | pub fn set(res_storage: ResourceStorage) {
function wait (line 75) | pub fn wait() {
FILE: lib/resources/src/retrieve/kanji.rs
type KanjiRetrieve (line 8) | pub struct KanjiRetrieve<'a> {
function new (line 14) | pub(crate) fn new(storage: &'a KanjiStorage) -> Self {
function by_literal (line 20) | pub fn by_literal(&self, literal: char) -> Option<&'a Kanji> {
function has_literal (line 26) | pub fn has_literal(&self, literal: char) -> bool {
function by_radicals (line 32) | pub fn by_radicals(&self, radicals: &[char]) -> Vec<&'a Kanji> {
function by_jlpt (line 51) | pub fn by_jlpt(&self, jlpt: u8) -> Option<&'a Vec<char>> {
function radicals (line 57) | pub fn radicals(&self) -> impl Iterator<Item = &'a DetailedRadical> {
function by_genki_lesson (line 63) | pub fn by_genki_lesson(&self, genki_lektion: u8) -> Option<&'a Vec<char>> {
function iter (line 68) | pub fn iter(&self) -> impl Iterator<Item = &'a Kanji> {
function all (line 73) | pub fn all(&self) -> Vec<Kanji> {
function ids (line 78) | pub fn ids(&self, kanji_lit: char) -> Option<&'a IDS> {
function count (line 84) | pub fn count(&self) -> usize {
function onyomi (line 91) | fn onyomi(&self, lit: char) -> Vec<String> {
function kunyomi (line 98) | fn kunyomi(&self, lit: char) -> Vec<String> {
FILE: lib/resources/src/retrieve/name.rs
type NameRetrieve (line 5) | pub struct NameRetrieve<'a> {
function new (line 11) | pub(crate) fn new(storage: &'a NameStorage) -> Self {
function by_sequence (line 17) | pub fn by_sequence(&self, seq_id: u32) -> Option<&'a Name> {
function count (line 23) | pub fn count(&self) -> usize {
function iter (line 29) | pub fn iter(&self) -> impl Iterator<Item = &'a Name> {
FILE: lib/resources/src/retrieve/sentence.rs
type SentenceRetrieve (line 5) | pub struct SentenceRetrieve<'a> {
function new (line 11) | pub(crate) fn new(storage: &'a SentenceStorage) -> Self {
function by_id (line 17) | pub fn by_id(&self, id: u32) -> Option<&'a Sentence> {
function ids_by_jlpt (line 23) | pub fn ids_by_jlpt(&self, jlpt: u8) -> impl Iterator<Item = u32> + 'a {
function by_tag (line 34) | pub fn by_tag<'b>(&'b self, tag: &Tag) -> impl Iterator<Item = &'a Sente...
function by_jlpt (line 45) | pub fn by_jlpt<'b>(&'b self, jlpt: u8) -> impl Iterator<Item = &'a Sente...
function count (line 55) | pub fn count(&self) -> usize {
function iter (line 60) | pub fn iter(&self) -> impl Iterator<Item = &'a Sentence> {
FILE: lib/resources/src/retrieve/word.rs
type WordRetrieve (line 5) | pub struct WordRetrieve<'a> {
function new (line 11) | pub(crate) fn new(storage: &'a WordStorage) -> Self {
function by_sequence (line 17) | pub fn by_sequence(&self, seq_id: u32) -> Option<&'a Word> {
function iter (line 23) | pub fn iter(&self) -> impl Iterator<Item = &'a Word> {
function katakana (line 28) | pub fn katakana<'b>(&'b self) -> impl Iterator<Item = &'a Word> + 'b + D...
function irregular_ichidan (line 37) | pub fn irregular_ichidan<'b>(
function irregular_ichidan_len (line 49) | pub fn irregular_ichidan_len(&self) -> usize {
function katakana_len (line 55) | pub fn katakana_len(&self) -> usize {
function by_jlpt (line 61) | pub fn by_jlpt<'b>(
function jlpt_len (line 75) | pub fn jlpt_len(&self, jlpt: u8) -> Option<usize> {
function by_pos_simple (line 81) | pub fn by_pos_simple<'b>(
function pos_simple_len (line 95) | pub fn pos_simple_len(&self, pos: &PosSimple) -> Option<usize> {
function by_misc (line 101) | pub fn by_misc<'b>(
function misc_len (line 115) | pub fn misc_len(&self, misc: &Misc) -> Option<usize> {
function count (line 121) | pub fn count(&self) -> usize {
FILE: lib/resources/src/storage/feature.rs
type Feature (line 4) | pub enum Feature {
method all (line 37) | pub fn all() -> Vec<Feature> {
FILE: lib/resources/src/storage/kanji.rs
type KanjiStorage (line 10) | pub struct KanjiStorage {
method new (line 33) | pub fn new() -> Self {
method insert_kanji (line 38) | pub fn insert_kanji(&mut self, kanji: Vec<Kanji>) {
method insert_radicals (line 55) | pub fn insert_radicals(&mut self, radicals: Vec<DetailedRadical>) {
method get_features (line 62) | pub fn get_features(&self) -> Vec<Feature> {
FILE: lib/resources/src/storage/mod.rs
type ResourceStorage (line 20) | pub struct ResourceStorage {
method new (line 29) | pub fn new() -> Self {
method check (line 34) | pub fn check(&self) -> bool {
method missing_but_required (line 38) | pub fn missing_but_required(&self) -> Vec<Feature> {
method missing_features (line 52) | pub fn missing_features(&self) -> Vec<Feature> {
method has_feature (line 68) | pub fn has_feature(&self, feature: Feature) -> bool {
method get_features (line 73) | pub fn get_features(&self) -> Vec<Feature> {
method words (line 89) | pub fn words<'a>(&'a self) -> WordRetrieve<'a> {
method kanji (line 95) | pub fn kanji(&self) -> KanjiRetrieve {
method names (line 101) | pub fn names(&self) -> NameRetrieve {
method sentences (line 107) | pub fn sentences(&self) -> SentenceRetrieve {
FILE: lib/resources/src/storage/name.rs
type NameStorage (line 9) | pub struct NameStorage {
method new (line 15) | pub fn new() -> Self {
method insert_names (line 20) | pub fn insert_names(&mut self, names: Vec<Name>) {
method get_features (line 28) | pub fn get_features(&self) -> Vec<Feature> {
FILE: lib/resources/src/storage/sentence.rs
type SentenceStorage (line 9) | pub struct SentenceStorage {
method new (line 21) | pub fn new() -> Self {
method get_features (line 25) | pub fn get_features(&self) -> Vec<Feature> {
FILE: lib/resources/src/storage/word.rs
type WordStorage (line 10) | pub struct WordStorage {
method new (line 28) | pub fn new() -> Self {
method count (line 34) | pub fn count(&self) -> usize {
method insert_words (line 39) | pub fn insert_words(&mut self, words: Vec<Word>) {
method update_sentence_mapping (line 63) | pub fn update_sentence_mapping(&mut self) {
method get_features (line 67) | pub fn get_features(&self) -> Vec<Feature> {
method clear_words (line 97) | fn clear_words(&mut self) {
FILE: lib/search/src/engine/names/foreign.rs
type Engine (line 9) | pub struct Engine;
type B (line 12) | type B = NGIndex<FOREIGN_NGRAM, Self::Document>;
type DictItem (line 13) | type DictItem = String;
type Document (line 14) | type Document = IndexItem<u32>;
type Retriever (line 15) | type Retriever = DefaultRetrieve<'static, Self::B, Self::DictItem, Sel...
type Output (line 18) | type Output = &'static Name;
type Query (line 19) | type Query = TermSet;
method make_query (line 21) | fn make_query<S: AsRef<str>>(inp: S, _: Option<Language>) -> Option<Se...
method doc_to_output (line 37) | fn doc_to_output(input: &Self::Document) -> Option<Vec<Self::Output>> {
method get_index (line 45) | fn get_index(_: Option<Language>) -> &'static Self::B {
method retrieve_for (line 50) | fn retrieve_for(
function format_word (line 60) | fn format_word(inp: &str) -> String {
FILE: lib/search/src/engine/names/native.rs
type Engine (line 10) | pub struct Engine;
type B (line 13) | type B = NGIndex<NATIVE_NGRAM, Self::Document>;
type DictItem (line 14) | type DictItem = String;
type Document (line 15) | type Document = IndexItem<u32>;
type Retriever (line 16) | type Retriever = DefaultRetrieve<'static, Self::B, Self::DictItem, Sel...
type Output (line 19) | type Output = &'static Name;
type Query (line 20) | type Query = TermSet;
method make_query (line 22) | fn make_query<S: AsRef<str>>(inp: S, _: Option<Language>) -> Option<Se...
method doc_to_output (line 36) | fn doc_to_output(input: &Self::Document) -> Option<Vec<Self::Output>> {
method get_index (line 44) | fn get_index(_: Option<Language>) -> &'static Self::B {
method retrieve_for (line 49) | fn retrieve_for(
FILE: lib/search/src/engine/radical/mod.rs
function find (line 6) | pub fn find(query_str: &str) -> Vec<&'static SearchRadicalInfo> {
function add_similar (line 24) | fn add_similar(query_str: &str, out: &mut Vec<&str>) {
FILE: lib/search/src/engine/sentences/foreign.rs
type Engine (line 13) | pub struct Engine {}
type B (line 16) | type B = MemBackend<
type DictItem (line 23) | type DictItem = DictTerm;
type Document (line 24) | type Document = DocVector<u32>;
type Retriever (line 25) | type Retriever = DefaultRetrieve<'static, Self::B, Self::DictItem, Sel...
type Output (line 26) | type Output = &'static Sentence;
type Query (line 27) | type Query = SpVec32;
method make_query (line 29) | fn make_query<S: AsRef<str>>(inp: S, _lang: Option<Language>) -> Optio...
method doc_to_output (line 46) | fn doc_to_output(input: &Self::Document) -> Option<Vec<Self::Output>> {
method get_index (line 54) | fn get_index(_lang: Option<Language>) -> &'static Self::B {
method retrieve_for (line 59) | fn retrieve_for(
function all_terms (line 75) | pub(crate) fn all_terms(i: &str) -> Vec<String> {
function format_word (line 89) | fn format_word(inp: &str) -> String {
FILE: lib/search/src/engine/sentences/native.rs
type Engine (line 16) | pub struct Engine {}
type B (line 19) | type B = MemBackend<
type DictItem (line 26) | type DictItem = DictTerm;
type Document (line 27) | type Document = DocVector<u32>;
type Retriever (line 28) | type Retriever = DefaultRetrieve<'static, Self::B, Self::DictItem, Sel...
type Output (line 29) | type Output = &'static Sentence;
type Query (line 30) | type Query = SpVec32;
method make_query (line 32) | fn make_query<S: AsRef<str>>(inp: S, _lang: Option<Language>) -> Optio...
method doc_to_output (line 73) | fn doc_to_output(input: &Self::Document) -> Option<Vec<Self::Output>> {
method get_index (line 81) | fn get_index(_lang: Option<Language>) -> &'static Self::B {
method retrieve_for (line 86) | fn retrieve_for(
function format_query (line 106) | fn format_query(inp: &str) -> String {
FILE: lib/search/src/engine/words/foreign.rs
type Engine (line 16) | pub struct Engine;
type B (line 21) | type B = MemBackend<
type DictItem (line 28) | type DictItem = DictTerm;
type Document (line 29) | type Document = DocVector<u32>;
type Retriever (line 30) | type Retriever = DefaultRetrieve<'static, Self::B, Self::DictItem, Sel...
type Output (line 31) | type Output = &'static Word;
type Query (line 32) | type Query = SpVec32;
method make_query (line 34) | fn make_query<S: AsRef<str>>(inp: S, lang: Option<Language>) -> Option...
method doc_to_output (line 62) | fn doc_to_output(input: &Self::Document) -> Option<Vec<Self::Output>> {
method get_index (line 70) | fn get_index(lang: Option<Language>) -> &'static Self::B {
method retrieve_for (line 75) | fn retrieve_for(
constant FORMAT_REGEX (line 18) | const FORMAT_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new("^to ").unwrap...
function format_word (line 86) | fn format_word(inp: &str) -> String {
FILE: lib/search/src/engine/words/native/k_reading.rs
type Engine (line 5) | pub struct Engine;
type B (line 8) | type B = indexes::kanji::reading::Index;
type DictItem (line 9) | type DictItem = String;
type Document (line 10) | type Document = u32;
type Retriever (line 11) | type Retriever = DefaultRetrieve<'static, Self::B, Self::DictItem, Sel...
type Output (line 12) | type Output = &'static Word;
type Query (line 13) | type Query = String;
method make_query (line 15) | fn make_query<S: AsRef<str>>(inp: S, _lang: Option<Language>) -> Optio...
method doc_to_output (line 20) | fn doc_to_output(input: &Self::Document) -> Option<Vec<Self::Output>> {
method get_index (line 28) | fn get_index(_lang: Option<Language>) -> &'static Self::B {
method retrieve_for (line 32) | fn retrieve_for(
FILE: lib/search/src/engine/words/native/mod.rs
type Engine (line 12) | pub struct Engine {}
type B (line 15) | type B = NGIndex<NATIVE_NGRAM, Self::Document>;
type DictItem (line 16) | type DictItem = String;
type Document (line 17) | type Document = IndexItem<u32>;
type Retriever (line 18) | type Retriever = DefaultRetrieve<'static, Self::B, Self::DictItem, Sel...
type Output (line 21) | type Output = &'static Word;
type Query (line 22) | type Query = TermSet;
method make_query (line 24) | fn make_query<S: AsRef<str>>(inp: S, _: Option<Language>) -> Option<Se...
method doc_to_output (line 38) | fn doc_to_output(input: &Self::Document) -> Option<Vec<Self::Output>> {
method get_index (line 46) | fn get_index(_: Option<Language>) -> &'static Self::B {
method retrieve_for (line 51) | fn retrieve_for(
FILE: lib/search/src/engine/words/native/regex.rs
type RegexSearchResult (line 11) | pub struct RegexSearchResult {
function search (line 18) | pub fn search<F>(query: &RegexSQuery, sort: F, limit: usize, offset: usi...
function find_words (line 55) | pub(crate) fn find_words(index: &RegexSearchIndex, chars: &[char]) -> In...
FILE: lib/search/src/executor/mod.rs
constant MAX_ESTIMATE (line 18) | pub const MAX_ESTIMATE: usize = 100;
type SearchExecutor (line 21) | pub struct SearchExecutor<S: Searchable> {
function new (line 28) | pub fn new(search: S) -> Self {
function run (line 33) | pub fn run(self) -> SearchResult<S::OutItem, S::ResAdd> {
function guess (line 84) | pub fn guess(&self) -> Option<Guess> {
FILE: lib/search/src/executor/out_builder.rs
type OutputBuilder (line 5) | pub struct OutputBuilder<'a, I, OA> {
function new (line 15) | pub(crate) fn new<F: Fn(&I) -> bool + 'a>(filter: F, len: usize) -> Self {
function len (line 26) | pub fn len(&self) -> usize {
function is_empty (line 31) | pub fn is_empty(&self) -> bool {
function push (line 37) | pub fn push(&mut self, item: RelItem<I>) -> bool {
type Item (line 56) | type Item = RelItem<I>;
method push (line 60) | fn push(&mut self, i: Self::Item) -> bool {
type OutputAddable (line 65) | pub trait OutputAddable: Default {
method is_empty (line 67) | fn is_empty(&self) -> bool {
FILE: lib/search/src/executor/producer.rs
type Producer (line 5) | pub trait Producer {
method produce (line 8) | fn produce(
method should_run (line 16) | fn should_run(&self, _already_found: usize) -> bool {
method estimate_to (line 20) | fn estimate_to(&self, _out: &mut FilteredMaxCounter<<Self::Target as S...
method name (line 22) | fn name(&self) -> String {
function format_debug_name (line 27) | fn format_debug_name<T: ?Sized>() -> String {
FILE: lib/search/src/executor/search_result.rs
type SearchResult (line 5) | pub struct SearchResult<T, O = ()> {
function from_vec (line 14) | pub fn from_vec(items: Vec<T>) -> Self {
function new (line 25) | pub fn new(items: Vec<T>, total: usize) -> Self {
function with_other_data (line 37) | pub fn with_other_data(items: Vec<T>, total: usize, other_data: O) -> Se...
function len (line 46) | pub fn len(&self) -> usize {
function is_empty (line 51) | pub fn is_empty(&self) -> bool {
function iter (line 56) | pub fn iter(&self) -> impl Iterator<Item = &T> {
function with_other_default (line 63) | pub fn with_other_default(items: Vec<T>, total: usize) -> Self {
method default (line 77) | fn default() -> Self {
type Target (line 87) | type Target = O;
method deref (line 90) | fn deref(&self) -> &Self::Target {
FILE: lib/search/src/executor/searchable.rs
type Searchable (line 8) | pub trait Searchable {
method get_producer (line 13) | fn get_producer<'s>(&'s self) -> &Vec<Box<dyn Producer<Target = Self> ...
method get_query (line 15) | fn get_query(&self) -> &Query;
method to_output_item (line 18) | fn to_output_item(&self, item: Self::Item) -> Self::OutItem;
method mod_output (line 21) | fn mod_output(&self, _out: &mut OutputBuilder<Self::Item, Self::ResAdd...
method filter (line 24) | fn filter(&self, _item: &Self::Item) -> bool {
method max_top_dist (line 29) | fn max_top_dist(&self) -> Option<f32> {
FILE: lib/search/src/kanji/mod.rs
function search (line 18) | pub fn search(query: &Query) -> Result<KanjiResult, Error> {
function by_japanese_query (line 53) | fn by_japanese_query(query: &str) -> Vec<Kanji> {
function kana_search (line 65) | fn kana_search(query: &str) -> Vec<Kanji> {
function by_korean_reading (line 83) | fn by_korean_reading(query: &str) -> Vec<Kanji> {
function from_char (line 93) | fn from_char(c: char) -> Option<Kanji> {
function kanji_from_str (line 97) | fn kanji_from_str(text: &str) -> Vec<Kanji> {
function guess_result (line 106) | pub fn guess_result(query: &Query) -> Option<Guess> {
function by_meaning (line 122) | fn by_meaning(meaning: &str) -> Vec<Kanji> {
function to_item (line 134) | fn to_item(items: Vec<Kanji>, query: &Query) -> Vec<Item> {
function format_query (line 142) | fn format_query(query: &str) -> String {
FILE: lib/search/src/kanji/order.rs
function default (line 7) | pub(crate) fn default(a: &Item, b: &Item) -> Ordering {
FILE: lib/search/src/kanji/result.rs
type KanjiResult (line 10) | pub struct KanjiResult {
type Item (line 16) | pub struct Item {
method load_words (line 24) | pub fn load_words(k: Kanji, lang: impl AsLangParam) -> Self {
method get_frames (line 58) | pub fn get_frames<P: AsRef<Path>>(&self, assets_path: P) -> Option<Str...
method get_animation (line 63) | pub fn get_animation<P: AsRef<Path>>(&self, assets_path: P) -> Option<...
method get_korean (line 68) | pub fn get_korean(&self) -> Option<Vec<String>> {
method get_parts_count (line 87) | pub fn get_parts_count(&self) -> usize {
method get_radical (line 92) | pub fn get_radical(&self) -> String {
method get_rad_len (line 101) | pub fn get_rad_len(&self) -> usize {
function load_dicts (line 39) | fn load_dicts(dicts: &Vec<u32>, lang: impl AsLangParam) -> Option<Vec<Wo...
FILE: lib/search/src/kanji/tag_only.rs
function search (line 5) | pub fn search(query: &Query) -> Result<KanjiResult, Error> {
function genki_search (line 19) | fn genki_search(query: &Query, genki_lesson: u8) -> Result<KanjiResult, ...
function jlpt_search (line 49) | fn jlpt_search(query: &Query, jlpt: u8) -> Result<KanjiResult, Error> {
FILE: lib/search/src/lib.rs
function build_help (line 16) | pub fn build_help(querytype: SearchTarget, query: &Query) -> Option<Sear...
FILE: lib/search/src/name/mod.rs
type Search (line 16) | pub struct Search<'a> {
function new (line 22) | pub fn new(query: &'a Query) -> Self {
type Item (line 34) | type Item = &'static Name;
type OutItem (line 35) | type OutItem = &'static Name;
type ResAdd (line 36) | type ResAdd = ();
method to_output_item (line 39) | fn to_output_item(&self, item: Self::Item) -> Self::OutItem {
method get_producer (line 44) | fn get_producer<'s>(&'s self) -> &Vec<Box<dyn Producer<Target = Self> + ...
method get_query (line 49) | fn get_query(&self) -> &Query {
FILE: lib/search/src/name/order/foreign.rs
type ForeignOrder (line 5) | pub struct ForeignOrder;
type OutItem (line 8) | type OutItem = &'static Name;
type IndexItem (line 9) | type IndexItem = IndexItem<u32>;
type Query (line 10) | type Query = TermSet;
method score (line 13) | fn score<'item, 'query>(
FILE: lib/search/src/name/order/japanese.rs
type NativeOrder (line 5) | pub struct NativeOrder;
type OutItem (line 8) | type OutItem = &'static Name;
type IndexItem (line 9) | type IndexItem = IndexItem<u32>;
type Query (line 10) | type Query = TermSet;
method score (line 13) | fn score<'item, 'query>(
FILE: lib/search/src/name/producer/foreign.rs
type ForeignProducer (line 10) | pub struct ForeignProducer<'a> {
function new (line 15) | pub fn new(query: &'a Query) -> Self {
function foreign_task (line 19) | fn foreign_task(&self) -> SearchTask<'static, Engine> {
type Target (line 28) | type Target = Search<'a>;
method produce (line 30) | fn produce(
method should_run (line 40) | fn should_run(&self, _already_found: usize) -> bool {
method estimate_to (line 44) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
function format_word (line 50) | fn format_word(inp: &str) -> String {
FILE: lib/search/src/name/producer/kanji_reading.rs
type KreadingProducer (line 12) | pub struct KreadingProducer<'a> {
function new (line 17) | pub fn new(query: &'a Query) -> Self {
function search_task (line 21) | fn search_task(&self) -> Option<SearchTask<'static, Engine>> {
type Target (line 35) | type Target = Search<'a>;
method produce (line 37) | fn produce(
method should_run (line 49) | fn should_run(&self, _already_found: usize) -> bool {
method estimate_to (line 53) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
function filter (line 61) | fn filter(name: &Name, reading: &str, literal: char) -> Option<bool> {
type NanoriRetrieve (line 76) | struct NanoriRetrieve<'a> {
function new (line 81) | fn new(kanji_retrieve: KanjiRetrieve<'a>) -> Self {
method onyomi (line 88) | fn onyomi(&self, lit: char) -> Vec<String> {
method kunyomi (line 93) | fn kunyomi(&self, lit: char) -> Vec<String> {
method all (line 97) | fn all(&self, lit: char) -> Vec<String> {
FILE: lib/search/src/name/producer/native/mod.rs
type NativeProducer (line 11) | pub struct NativeProducer<'a> {
function new (line 17) | pub fn new(query: &'a Query) -> Self {
function jp_task (line 22) | fn jp_task(&self) -> SearchTask<'static, Engine> {
type Target (line 30) | type Target = Search<'a>;
method produce (line 32) | fn produce(
method should_run (line 42) | fn should_run(&self, _already_found: usize) -> bool {
method estimate_to (line 46) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
FILE: lib/search/src/name/producer/native/split.rs
type SplitProducer (line 17) | pub struct SplitProducer<'a> {
function new (line 22) | pub fn new(query: &'a Query) -> Self {
function queries (line 26) | fn queries(&self) -> Vec<String> {
function run (line 35) | fn run<C, P, O>(&self, cb: C, out: &mut P)
function find_to (line 51) | fn find_to<P>(&self, out: &mut P)
type Target (line 65) | type Target = Search<'a>;
method produce (line 67) | fn produce(
method should_run (line 77) | fn should_run(&self, already_found: usize) -> bool {
method estimate_to (line 82) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
type SplitOrder (line 87) | struct SplitOrder {
method new (line 94) | fn new(q_count: usize, pos: usize) -> Self {
type OutItem (line 100) | type OutItem = &'static Name;
type IndexItem (line 101) | type IndexItem = IndexItem<u32>;
type Query (line 102) | type Query = TermSet;
method score (line 105) | fn score<'item, 'query>(
FILE: lib/search/src/name/producer/sequence.rs
type SeqProducer (line 12) | pub struct SeqProducer<'a> {
function new (line 17) | pub fn new(query: &'a Query) -> Self {
function name (line 21) | fn name(&self) -> Option<&'static Name> {
type Target (line 28) | type Target = Search<'a>;
method produce (line 30) | fn produce(
method estimate_to (line 42) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
method should_run (line 48) | fn should_run(&self, _already_found: usize) -> bool {
FILE: lib/search/src/query/form.rs
type Form (line 5) | pub enum Form {
method as_kanji_reading (line 28) | pub fn as_kanji_reading(&self) -> Option<&kanji::reading::ReadingSearc...
method is_kanji_reading (line 38) | pub fn is_kanji_reading(&self) -> bool {
method is_tag_only (line 46) | pub fn is_tag_only(&self) -> bool {
method is_normal (line 52) | pub fn is_normal(&self) -> bool {
method is_sequence (line 63) | pub fn is_sequence(&self) -> bool {
method as_sequence (line 67) | pub fn as_sequence(&self) -> Option<&u32> {
FILE: lib/search/src/query/mod.rs
constant QUERY_ENCODE_SET (line 21) | const QUERY_ENCODE_SET: &AsciiSet = &NON_ALPHANUMERIC.add(b'/');
type Query (line 25) | pub struct Query {
method has_part_of_speech_tags (line 67) | pub fn has_part_of_speech_tags(&self) -> bool {
method get_search_type_tags (line 73) | pub fn get_search_type_tags(&self) -> impl Iterator<Item = &SearchTarg...
method get_part_of_speech_tags (line 79) | pub fn get_part_of_speech_tags(&self) -> impl Iterator<Item = &PosSimp...
method get_misc_tags (line 85) | pub fn get_misc_tags(&self) -> impl Iterator<Item = &Misc> + '_ {
method page_offset (line 91) | pub fn page_offset(&self, page_size: usize) -> usize {
method has_tag (line 97) | pub fn has_tag(&self, tag: Tag) -> bool {
method add_page (line 102) | pub fn add_page(&mut self, n: usize) {
method without_search_type_tags (line 109) | pub fn without_search_type_tags(&self) -> String {
method get_query_encoded (line 122) | pub fn get_query_encoded(&self) -> String {
method get_search_lang (line 127) | pub fn get_search_lang(&self) -> Language {
method lang (line 133) | pub fn lang(&self) -> Language {
method lang_param (line 139) | pub fn lang_param(&self) -> LangParam {
method show_english (line 145) | pub fn show_english(&self) -> bool {
method is_regex (line 151) | pub fn is_regex(&self) -> bool {
method as_regex_query (line 156) | pub fn as_regex_query(&self) -> Option<&RegexSQuery> {
type QueryLang (line 56) | pub enum QueryLang {
FILE: lib/search/src/query/parser/lang.rs
function parse (line 8) | pub fn parse(query: &str) -> QueryLang {
function get_jp_part (line 22) | fn get_jp_part(inp: &str) -> usize {
function strip_regex (line 36) | fn strip_regex(query: &str) -> Option<String> {
FILE: lib/search/src/query/parser/mod.rs
constant MAX_QUERY_LEN (line 11) | pub const MAX_QUERY_LEN: usize = 400;
constant JAPANESE_THRESHOLD (line 15) | pub const JAPANESE_THRESHOLD: usize = 40;
type QueryParser (line 18) | pub struct QueryParser {
method new (line 37) | pub fn new(
method with_lang_overwrite (line 54) | pub fn with_lang_overwrite(mut self, lang: ContentLanguage) -> Self {
method with_word_index (line 60) | pub fn with_word_index(mut self, word_index: usize) -> Self {
method with_page (line 66) | pub fn with_page(mut self, page: usize) -> Self {
method parse (line 73) | pub fn parse(mut self) -> Option<Query> {
method extract_tags (line 118) | fn extract_tags(query_str: &str) -> (String, Vec<Tag>) {
method get_search_target (line 127) | fn get_search_target(&self, tags: &[Tag]) -> SearchTarget {
method parse_form (line 135) | fn parse_form(&self, query: &str, tags: &[Tag], s_prefix: Option<Searc...
method parse_kanji_reading (line 171) | fn parse_kanji_reading(&self, query: &str) -> Option<kanji::reading::R...
function format_kanji_reading (line 198) | pub fn format_kanji_reading(s: &str) -> String {
function calc_page_offset (line 202) | pub fn calc_page_offset(page: usize, page_size: usize) -> usize {
FILE: lib/search/src/query/parser/prefix.rs
function parse_prefix (line 6) | pub fn parse_prefix(query: &str) -> (&str, Option<SearchPrefix>) {
function try_lang_prefix (line 18) | fn try_lang_prefix(query: &str) -> (&str, Option<Language>) {
function try_sequence (line 41) | fn try_sequence(query: &str) -> Option<u32> {
function test_lang_override_split (line 55) | fn test_lang_override_split() {
function test_lang_override_split_invalid (line 63) | fn test_lang_override_split_invalid() {
FILE: lib/search/src/query/parser/req_terms.rs
constant QUOTS_CONTENT (line 4) | pub const QUOTS_CONTENT: Lazy<Regex> = Lazy::new(|| Regex::new(r#""[^"]+...
function parse (line 6) | pub fn parse(inp: &str) -> (String, Vec<String>) {
function test_parse_quote_cnt (line 42) | fn test_parse_quote_cnt() {
FILE: lib/search/src/query/parser/tags.rs
function extract_parse (line 16) | pub fn extract_parse<'a, F>(inp: &'a str, parse: F) -> (String, Vec<Tag>)
function parse (line 58) | pub fn parse(s: &str) -> Vec<Tag> {
function parse_jlpt_tag (line 95) | fn parse_jlpt_tag(s: &str) -> Option<Tag> {
function parse_genki_tag (line 107) | fn parse_genki_tag(s: &str) -> Option<Tag> {
function parse_search_type (line 113) | fn parse_search_type(s: &str) -> Option<Tag> {
function test_parse_jlpt_tag_parsing (line 130) | fn test_parse_jlpt_tag_parsing() {
function test_parse_genki_tag_parsing (line 135) | fn test_parse_genki_tag_parsing() {
FILE: lib/search/src/query/prefix.rs
type SearchPrefix (line 5) | pub enum SearchPrefix {
FILE: lib/search/src/query/regex.rs
constant REGEX_CHARS (line 21) | pub const REGEX_CHARS: &[char] = &['*', '?', '?'];
type RegexSQuery (line 25) | pub struct RegexSQuery {
method new (line 32) | pub fn new(query: &str) -> Option<Self> {
method matches (line 45) | pub fn matches(&self, word: &str) -> bool {
method get_chars (line 50) | pub fn get_chars(&self) -> Vec<char> {
method convert_regex (line 61) | fn convert_regex(query: &str) -> String {
method is_regex (line 78) | fn is_regex(query: &str) -> bool {
method query (line 84) | pub fn query(&self) -> &str {
function adjust_regex (line 91) | fn adjust_regex(query: &str) -> String {
method hash (line 100) | fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
method eq (line 107) | fn eq(&self, other: &Self) -> bool {
FILE: lib/search/src/query/tags.rs
type Tag (line 9) | pub enum Tag {
method is_producer (line 27) | pub fn is_producer(&self) -> bool {
method is_search_type (line 33) | pub fn is_search_type(&self) -> bool {
method is_part_of_speech (line 39) | pub fn is_part_of_speech(&self) -> bool {
method as_search_type (line 44) | pub fn as_search_type(&self) -> Option<&SearchTarget> {
method as_part_of_speech (line 53) | pub fn as_part_of_speech(&self) -> Option<&PosSimple> {
method is_misc (line 65) | pub fn is_misc(&self) -> bool {
method as_misc (line 70) | pub fn as_misc(&self) -> Option<&Misc> {
method is_jlpt (line 82) | pub fn is_jlpt(&self) -> bool {
method as_jlpt (line 87) | pub fn as_jlpt(&self) -> Option<u8> {
method is_genki_lesson (line 99) | pub fn is_genki_lesson(&self) -> bool {
method as_genki_lesson (line 104) | pub fn as_genki_lesson(&self) -> Option<u8> {
method is_irregular_iru_eru (line 115) | pub fn is_irregular_iru_eru(&self) -> bool {
method is_hidden (line 123) | pub fn is_hidden(&self) -> bool {
method is_sentence_tag (line 132) | pub fn is_sentence_tag(&self) -> bool {
method as_sentence_tag (line 137) | pub fn as_sentence_tag(&self) -> Option<&sentences::Tag> {
method is_katakana (line 149) | pub fn is_katakana(&self) -> bool {
FILE: lib/search/src/query/user_settings.rs
type UserSettings (line 6) | pub struct UserSettings {
method show_english (line 21) | pub fn show_english(&self) -> bool {
method language (line 26) | pub fn language(&self) -> Language {
method lang_param (line 32) | pub fn lang_param(&self) -> LangParam {
method default (line 39) | fn default() -> Self {
method eq (line 54) | fn eq(&self, other: &Self) -> bool {
method hash (line 61) | fn hash<H: Hasher>(&self, state: &mut H) {
FILE: lib/search/src/radical/mod.rs
function meaning_search (line 7) | pub fn meaning_search(query: &str) -> HashSet<char> {
FILE: lib/search/src/radical/word/foreign.rs
constant WORD_LIMIT (line 9) | const WORD_LIMIT: usize = 3;
type Search (line 12) | pub struct Search<'a> {
function new (line 19) | pub fn new(query: &'a str, lang: Language) -> Self {
function run (line 25) | pub fn run(&self) -> HashSet<char> {
function search_task (line 31) | fn search_task(&self) -> SearchTask<'static, Engine> {
function select_kanji (line 37) | fn select_kanji(&self, res: SearchResult<&Word>) -> HashSet<char> {
FILE: lib/search/src/radical/word/romaji.rs
constant WORD_LIMIT (line 8) | const WORD_LIMIT: usize = 3;
type Search (line 11) | pub struct Search<'a> {
function new (line 17) | pub fn new(query: &'a str) -> Self {
function run (line 23) | pub fn run(&self) -> HashSet<char> {
function search_task (line 29) | fn search_task(&self) -> SearchTask<'static, Engine> {
function select_kanji (line 36) | fn select_kanji(&self, res: SearchResult<&Word>) -> HashSet<char> {
FILE: lib/search/src/sentence/mod.rs
type Search (line 16) | pub struct Search<'a> {
function new (line 22) | pub fn new(query: &'a Query) -> Self {
type ResAdd (line 40) | type ResAdd = ResData;
type OutItem (line 41) | type OutItem = result::Sentence;
type Item (line 42) | type Item = &'static Sentence;
method get_producer (line 44) | fn get_producer<'s>(&'s self) -> &Vec<Box<dyn Producer<Target = Self> + ...
method mod_output (line 48) | fn mod_output(&self, out: &mut OutputBuilder<Self::Item, Self::ResAdd>) {
method to_output_item (line 53) | fn to_output_item(&self, item: Self::Item) -> Self::OutItem {
method get_query (line 57) | fn get_query(&self) -> &Query {
method filter (line 62) | fn filter(&self, item: &Self::Item) -> bool {
method max_top_dist (line 67) | fn max_top_dist(&self) -> Option<f32> {
FILE: lib/search/src/sentence/order/foreign.rs
type ForeignOrder (line 6) | pub struct ForeignOrder {
method new (line 11) | pub fn new(lang: Language) -> Self {
type OutItem (line 17) | type OutItem = &'static Sentence;
type IndexItem (line 18) | type IndexItem = DocVector<u32>;
type Query (line 19) | type Query = SpVec32;
method score (line 21) | fn score<'item, 'query>(
FILE: lib/search/src/sentence/order/native.rs
constant QUERY_WEIGHT (line 6) | pub const QUERY_WEIGHT: f32 = 100.0;
type NativeOrder (line 8) | pub struct NativeOrder {
method new (line 13) | pub fn new(lang: Language) -> Self {
type OutItem (line 19) | type OutItem = &'static Sentence;
type IndexItem (line 20) | type IndexItem = DocVector<u32>;
type Query (line 21) | type Query = SpVec32;
method score (line 24) | fn score<'item, 'query>(
function sim (line 44) | fn sim(vec_a: &SpVec32, vec_b: &SpVec32, a_weight: f32) -> f32 {
FILE: lib/search/src/sentence/producer/filter.rs
function filter_sentence (line 9) | pub(crate) fn filter_sentence(query: &Query, sentence: &Sentence) -> bool {
function by_quot_marks (line 41) | fn by_quot_marks(query: &Query, sentence: &Sentence) -> bool {
function by_quot_marks_jp (line 73) | fn by_quot_marks_jp(query: &Query, sentence: &Sentence) -> bool {
type FeQotTermsVecFilter (line 95) | pub struct FeQotTermsVecFilter {
method new (line 101) | pub fn new(query: &Query) -> Self {
method filter (line 129) | pub fn filter(&self, sentence: &DocVector<u32>) -> bool {
FILE: lib/search/src/sentence/producer/foreign.rs
type ForeignProducer (line 12) | pub struct ForeignProducer<'a> {
function new (line 18) | pub fn new(query: &'a Query, language: Language) -> Self {
function task (line 22) | fn task(&self) -> SearchTask<'static, foreign::Engine> {
type Target (line 36) | type Target = Search<'a>;
method produce (line 38) | fn produce(
method should_run (line 48) | fn should_run(&self, _already_found: usize) -> bool {
method estimate_to (line 52) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
FILE: lib/search/src/sentence/producer/kanji.rs
function sentence_matches (line 12) | pub(crate) fn sentence_matches(sentence: &Sentence, reading: &Reading) -...
function get_reading (line 46) | pub(crate) fn get_reading(reading: &ReadingSearch) -> Option<Reading> {
FILE: lib/search/src/sentence/producer/native.rs
type NativeProducer (line 12) | pub struct NativeProducer<'a> {
function new (line 18) | pub fn new(query: &'a Query, lang: Language) -> Self {
function task (line 22) | fn task(&self) -> SearchTask<'static, native::Engine> {
function jp_reading (line 31) | fn jp_reading(&self) -> String {
type Target (line 43) | type Target = Search<'a>;
method produce (line 45) | fn produce(
method should_run (line 55) | fn should_run(&self, _already_found: usize) -> bool {
method estimate_to (line 59) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
FILE: lib/search/src/sentence/producer/sequence.rs
type SequenceProducer (line 13) | pub struct SequenceProducer<'a> {
function new (line 18) | pub fn new(query: &'a Query) -> Self {
function sentence (line 22) | fn sentence(&self) -> Option<&'static Sentence> {
type Target (line 29) | type Target = Search<'a>;
method produce (line 31) | fn produce(
method estimate_to (line 43) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
method should_run (line 49) | fn should_run(&self, _already_found: usize) -> bool {
FILE: lib/search/src/sentence/producer/tag.rs
type TagProducer (line 14) | pub struct TagProducer<'a> {
function new (line 19) | pub fn new(query: &'a Query) -> Self {
function find_to (line 23) | fn find_to<P>(&self, out: &mut P)
function push_tag (line 37) | pub fn push_tag<P>(&self, tag: &Tag, out: &mut P)
function push_iter (line 50) | fn push_iter<P, I>(&self, iter: I, out: &mut P)
type Target (line 69) | type Target = Search<'a>;
method produce (line 71) | fn produce(
method estimate_to (line 81) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
method should_run (line 86) | fn should_run(&self, _already_found: usize) -> bool {
FILE: lib/search/src/sentence/result.rs
type ResData (line 8) | pub struct ResData {
method new (line 13) | pub fn new(hidden: bool) -> Self {
type Sentence (line 22) | pub struct Sentence {
method furigana_pairs (line 33) | pub fn furigana_pairs<'a>(&'a self) -> Vec<SegmentRef<'a>> {
method get_english (line 39) | pub fn get_english(&self) -> Option<&str> {
method from_m_sentence (line 44) | pub fn from_m_sentence(
FILE: lib/search/src/word/filter.rs
type WordFilter (line 6) | pub struct WordFilter {
method new (line 12) | pub fn new(query: Query) -> Self {
method filter_word (line 19) | pub fn filter_word<W: Borrow<Word>>(&self, word: W) -> bool {
method by_language (line 37) | fn by_language(&self, w: &Word) -> Option<()> {
method by_katakana_tag (line 42) | fn by_katakana_tag(&self, w: &Word) -> Option<()> {
method by_jlpt (line 48) | fn by_jlpt(&self, w: &Word) -> Option<()> {
method by_pos_tags (line 58) | fn by_pos_tags(&self, w: &Word) -> Option<()> {
method by_misc_tags (line 64) | fn by_misc_tags(&self, w: &Word) -> Option<()> {
method by_quot_marks (line 71) | fn by_quot_marks(&self, w: &Word) -> Option<()> {
method by_quot_marks_jp (line 103) | fn by_quot_marks_jp(&self, w: &Word, q_term: &str) -> Option<()> {
FILE: lib/search/src/word/kanji.rs
function load_word_kanji_info (line 6) | pub fn load_word_kanji_info(words: &[Word]) -> Vec<Kanji> {
FILE: lib/search/src/word/mod.rs
type Search (line 24) | pub struct Search<'a> {
function new (line 31) | pub fn new(query: &'a Query) -> Self {
type Item (line 54) | type Item = &'static Word;
type OutItem (line 55) | type OutItem = Word;
type ResAdd (line 56) | type ResAdd = result::AddResData;
method get_producer (line 58) | fn get_producer<'s>(&'s self) -> &Vec<Box<dyn Producer<Target = Self> + ...
method get_query (line 62) | fn get_query(&self) -> &Query {
method mod_output (line 66) | fn mod_output(&self, out: &mut OutputBuilder<Self::Item, Self::ResAdd>) {
method to_output_item (line 73) | fn to_output_item(&self, item: Self::Item) -> Self::OutItem {
method filter (line 80) | fn filter(&self, word: &Self::Item) -> bool {
method max_top_dist (line 85) | fn max_top_dist(&self) -> Option<f32> {
function max_top_dist_filter (line 95) | fn max_top_dist_filter(query: &Query) -> bool {
FILE: lib/search/src/word/order/foreign.rs
type ForeignOrder (line 11) | pub struct ForeignOrder {
method new (line 20) | pub fn new() -> Self {
method get_query_vec (line 29) | fn get_query_vec(&self, lang: Language) -> &SpVec32 {
method text_sim (line 46) | fn text_sim(&self, word: &Word, lang: Language) -> f32 {
type OutItem (line 70) | type OutItem = &'static Word;
type IndexItem (line 71) | type IndexItem = DocVector<u32>;
type Query (line 72) | type Query = SpVec32;
method score (line 75) | fn score<'item, 'query>(
method init (line 94) | fn init(&mut self, init: engine::relevance::RelEngineInit) {
function get_ng_index (line 109) | fn get_ng_index(lang: Language) -> &'static NgFreqIndex {
function build_vec (line 114) | pub fn build_vec(index: &NgFreqIndex, term: &str) -> SpVec32 {
FILE: lib/search/src/word/order/kanji_reading.rs
type KanjiReadingRelevance (line 4) | pub struct KanjiReadingRelevance;
type OutItem (line 7) | type OutItem = &'static Word;
type IndexItem (line 8) | type IndexItem = u32;
type Query (line 9) | type Query = String;
method score (line 12) | fn score<'item, 'query>(
FILE: lib/search/src/word/order/native.rs
type NativeOrder (line 9) | pub struct NativeOrder {
method new (line 23) | pub fn new(orig_query: String) -> Self {
method with_w_index (line 34) | pub fn with_w_index(mut self, index: usize) -> Self {
method with_oquery_ts (line 39) | pub fn with_oquery_ts(mut self, ts: TermSet) -> Self {
method exceeded_threshold (line 45) | fn exceeded_threshold<'i, 'q, A, B, C>(item: &SortData<'i, 'q, A, B, C...
method text_sim (line 50) | fn text_sim(&self, word: &Word) -> f32 {
method reading_sim (line 58) | fn reading_sim(&self, reading: &str) -> f32 {
type OutItem (line 65) | type OutItem = &'static Word;
type IndexItem (line 66) | type IndexItem = IndexItem<u32>;
type Query (line 67) | type Query = TermSet;
method score (line 69) | fn score<'item, 'query>(
method init (line 142) | fn init(&mut self, init: engine::relevance::RelEngineInit) {
function ng_freq_index (line 149) | fn ng_freq_index() -> &'static NgFreqIndex {
function build_ng_vec (line 154) | fn build_ng_vec(term: &str) -> SpVec32 {
FILE: lib/search/src/word/order/regex.rs
function regex_order (line 6) | pub fn regex_order(word: &Word, found_in: &str, _query: &RegexSQuery) ->...
FILE: lib/search/src/word/producer/foreign/mod.rs
type ForeignProducer (line 14) | pub struct ForeignProducer<'a> {
function new (line 19) | pub fn new(query: &'a Query) -> Self {
type Target (line 25) | type Target = Search<'a>;
method produce (line 27) | fn produce(
method estimate_to (line 52) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
method should_run (line 68) | fn should_run(&self, _already_found: usize) -> bool {
FILE: lib/search/src/word/producer/foreign/romaji.rs
type RomajiProducer (line 11) | pub struct RomajiProducer<'a> {
function new (line 16) | pub fn new(query: &'a Query) -> Self {
function hira_query (line 20) | fn hira_query(&self) -> String {
function kk_query (line 24) | fn kk_query(&self) -> String {
function kk_task (line 28) | fn kk_task(&self) -> SearchTask<'static, Engine> {
function hira_task (line 33) | fn hira_task(&self) -> SearchTask<'static, Engine> {
type Target (line 42) | type Target = Search<'a>;
method produce (line 44) | fn produce(
method estimate_to (line 55) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
method should_run (line 60) | fn should_run(&self, already_found: usize) -> bool {
FILE: lib/search/src/word/producer/foreign/task.rs
type ForeignSearch (line 11) | pub struct ForeignSearch<'a> {
function new (line 18) | pub(crate) fn new(query: &'a Query, query_str: &'a str, language: Langua...
function task (line 26) | pub fn task(&self) -> SearchTask<'static, Engine> {
FILE: lib/search/src/word/producer/japanese/mod.rs
type NativeProducer (line 16) | pub struct NativeProducer<'a> {
function new (line 21) | pub fn new(query: &'a Query) -> Self {
function task (line 25) | fn task(&self) -> SearchTask<'static, Engine> {
type Target (line 31) | type Target = Search<'a>;
method produce (line 33) | fn produce(
method estimate_to (line 43) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
method should_run (line 47) | fn should_run(&self, already_found: usize) -> bool {
FILE: lib/search/src/word/producer/japanese/number.rs
type NumberProducer (line 13) | pub struct NumberProducer<'a> {
function new (line 19) | pub fn new(query: &'a Query) -> Self {
type Target (line 25) | type Target = Search<'a>;
method produce (line 27) | fn produce(
method estimate_to (line 41) | fn estimate_to(&self, _out: &mut FilteredMaxCounter<<Self::Target as Sea...
method should_run (line 43) | fn should_run(&self, _already_found: usize) -> bool {
FILE: lib/search/src/word/producer/japanese/sentence_reader.rs
type SReaderProducer (line 28) | pub struct SReaderProducer<'a> {
function new (line 34) | pub fn new(query: &'a Query) -> Self {
function infl_task (line 40) | fn infl_task(&self) -> Option<SearchTask<'static, Engine>> {
function sentence_index (line 55) | fn sentence_index(&self) -> usize {
function sentence_word (line 64) | fn sentence_word(&self) -> Option<&Part> {
function snt_task_normalized (line 71) | fn snt_task_normalized(&self) -> Option<SearchTask<'static, Engine>> {
function snt_task_infl (line 85) | fn snt_task_infl(&self) -> Option<SearchTask<'static, Engine>> {
type Target (line 96) | type Target = Search<'a>;
method produce (line 98) | fn produce(
method should_run (line 131) | fn should_run(&self, already_found: usize) -> bool {
method estimate_to (line 155) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
function word_exists (line 172) | fn word_exists(term: &str) -> bool {
function set_furigana (line 189) | fn set_furigana(s: &mut Sentence) {
function furigana_by_reading (line 197) | fn furigana_by_reading(morpheme: &str, part: &sentence_reader::Part) -> ...
function name_furi (line 201) | fn name_furi(morpheme: &str) -> Option<String> {
function word_furi (line 219) | fn word_furi(morpheme: &str, part: &sentence_reader::Part) -> Option<Str...
type WordFuriOrder (line 237) | struct WordFuriOrder {
method new (line 244) | fn new(pos: Option<PosSimple>, morph: String) -> Self {
type OutItem (line 250) | type OutItem = &'static Word;
type IndexItem (line 251) | type IndexItem = IndexItem<u32>;
type Query (line 252) | type Query = TermSet;
method score (line 254) | fn score<'item, 'query>(
FILE: lib/search/src/word/producer/japanese/task.rs
type NativeSearch (line 11) | pub struct NativeSearch<'a> {
function new (line 20) | pub(crate) fn new(query: &'a Query, query_str: &'a str) -> Self {
function with_custom_original_query (line 39) | pub fn with_custom_original_query(mut self, query: &'a str) -> Self {
function with_threshold (line 44) | pub fn with_threshold(mut self, threshold: f32) -> Self {
function task (line 49) | pub fn task(&self) -> SearchTask<'static, Engine> {
function original_query (line 60) | pub fn original_query(&self) -> &str {
FILE: lib/search/src/word/producer/k_reading.rs
type KReadingProducer (line 17) | pub struct KReadingProducer<'a> {
function new (line 22) | pub fn new(query: &'a Query) -> Self {
function get_kanji (line 28) | fn get_kanji(&self) -> Option<&'static Kanji> {
function kr_query (line 37) | fn kr_query(&self) -> Option<String> {
function find_to (line 43) | fn find_to<P>(&self, out: &mut P)
type Target (line 59) | type Target = Search<'a>;
method produce (line 61) | fn produce(
method should_run (line 71) | fn should_run(&self, _already_found: usize) -> bool {
method estimate_to (line 75) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
FILE: lib/search/src/word/producer/regex.rs
type RegexProducer (line 16) | pub struct RegexProducer<'a> {
function new (line 21) | pub fn new(query: &'a Query) -> Self {
function find_to_unsorted (line 25) | fn find_to_unsorted<P: Pushable<Item = RelItem<&'static Word>>>(
function find_to (line 34) | fn find_to<P: Pushable<Item = RelItem<&'static Word>>>(&self, out: &mut ...
type Target (line 42) | type Target = Search<'a>;
method produce (line 44) | fn produce(
method should_run (line 54) | fn should_run(&self, _already_found: usize) -> bool {
method estimate_to (line 58) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
function search (line 64) | pub fn search<'a, F, P>(query: &'a RegexSQuery, sort: F, out: &mut P)
FILE: lib/search/src/word/producer/sequence.rs
type SeqProducer (line 10) | pub struct SeqProducer<'a> {
function new (line 15) | pub fn new(query: &'a Query) -> Self {
function word (line 20) | pub fn word(&self) -> Option<&'static Word> {
type Target (line 27) | type Target = Search<'a>;
method produce (line 29) | fn produce(
method should_run (line 41) | fn should_run(&self, _already_found: usize) -> bool {
method estimate_to (line 45) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
FILE: lib/search/src/word/producer/tag.rs
type TagProducer (line 14) | pub struct TagProducer<'a> {
function new (line 19) | pub fn new(query: &'a Query) -> Self {
function get_producer_tag (line 23) | fn get_producer_tag(&self) -> Option<&Tag> {
function find_to (line 34) | fn find_to<P>(&self, out: &mut P)
function find_words (line 43) | fn find_words<P>(&self, out: &mut P, tag: &Tag)
function push_iter (line 58) | fn push_iter<P, I>(&self, iter: I, out: &mut P)
function tag_len (line 77) | fn tag_len(&self, tag: &Tag) -> Option<usize> {
type Target (line 91) | type Target = Search<'a>;
method produce (line 93) | fn produce(
method should_run (line 103) | fn should_run(&self, _already_found: usize) -> bool {
method estimate_to (line 108) | fn estimate_to(&self, out: &mut FilteredMaxCounter<<Self::Target as Sear...
FILE: lib/search/src/word/result.rs
type AddResData (line 6) | pub struct AddResData {
method has_sentence (line 36) | pub fn has_sentence(&self) -> bool {
method has_inflection (line 40) | pub fn has_inflection(&self) -> bool {
method sentence_parts (line 44) | pub fn sentence_parts(&self) -> Option<&sentence_reader::Sentence> {
method sentence_index (line 48) | pub fn sentence_index(&self) -> usize {
method is_empty (line 15) | fn is_empty(&self) -> bool {
type SentenceInfo (line 21) | pub struct SentenceInfo {
type InflectionInformation (line 28) | pub struct InflectionInformation {
method from_part (line 54) | pub fn from_part(part: &sentence_reader::Part) -> Option<Self> {
function selected (line 66) | pub fn selected(curr: usize, selected: usize) -> &'static str {
FILE: lib/search/tests/search_test.rs
function search (line 15) | fn search(query: &Query) -> SearchResult<Word, AddResData> {
function inflections (line 30) | fn inflections(query_str: &str, exp_infl: &[Inflection]) {
function sentence_reader_test (line 44) | fn sentence_reader_test(query_str: &str, exp_parts: &[&str]) {
function correct_kanji_shown (line 68) | fn correct_kanji_shown(query_str: &str) {
function word_search (line 111) | fn word_search(query_str: &str, language: Language, first_res: &str) {
function pos_tag_test (line 131) | fn pos_tag_test(query_str: &str, exp_pos: &[PosSimple], exp_res: &[&str]) {
function test_jp_search (line 149) | fn test_jp_search() {
function test_romaji (line 173) | fn test_romaji(query_str: &str, expected: &[&str]) {
function make_query (line 184) | fn make_query(query_str: &str, language: Language) -> Query {
function parse_query (line 195) | fn parse_query(query_str: &str, language: Language, q_type: SearchTarget...
function load_data (line 203) | fn load_data() {
function wait (line 220) | fn wait() {
FILE: lib/sentence_reader/src/analyzer.rs
function get_grammar_analyzer (line 7) | pub(crate) fn get_grammar_analyzer() -> &'static Analyzer {
function get_rules (line 12) | fn get_rules() -> RuleSet {
FILE: lib/sentence_reader/src/grammar/mod.rs
type Analyzer (line 13) | pub struct Analyzer {
method new (line 19) | pub fn new(rules: RuleSet) -> Self {
method check (line 26) | pub fn check<T: ToRule>(&self, inp: &[T]) -> usize {
method has_rule (line 59) | pub fn has_rule(&self, rule: &str) -> bool {
method check_full (line 65) | pub fn check_full<T: ToRule>(&self, inp: &[T]) -> bool {
method resolve_to_rule (line 71) | fn resolve_to_rule<T: ToRule>(&self, tr: T) -> Option<&Rule> {
method rules (line 77) | pub fn rules(&self) -> &RuleSet {
FILE: lib/sentence_reader/src/grammar/rule.rs
type Rule (line 6) | pub struct Rule {
method new (line 13) | pub fn new(name: &'static str, rhs: &'static [&'static str]) -> Self {
method name (line 19) | pub fn name(&self) -> &'static str {
method rhs (line 25) | pub fn rhs(&self) -> &'static [&'static str] {
method has_dst (line 31) | pub fn has_dst(&self, name: &str) -> bool {
type ToRule (line 36) | pub trait ToRule {
method to_rule (line 37) | fn to_rule(&self) -> Option<&str>;
method to_rule (line 42) | fn to_rule(&self) -> Option<&str> {
method to_rule (line 49) | fn to_rule(&self) -> Option<&str> {
FILE: lib/sentence_reader/src/grammar/rule_set.rs
constant ALL_WILDCARD (line 4) | pub const ALL_WILDCARD: &str = "*";
type RuleSet (line 7) | pub struct RuleSet {
method new (line 13) | pub fn new(rules: &[Rule]) -> Self {
method add (line 22) | pub fn add(&mut self, rule: Rule) -> bool {
method has_rule (line 37) | pub fn has_rule(&self, name: &str) -> bool {
method check (line 42) | pub fn check(&self) -> bool {
method get_rule (line 60) | pub fn get_rule(&self, name: &str) -> Option<&Rule> {
method add_all_wildcard (line 64) | fn add_all_wildcard(&mut self) {
method fmt (line 76) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
FILE: lib/sentence_reader/src/lib.rs
function load_parser (line 19) | pub fn load_parser<P: AsRef<Path>>(path: P) {
function wait (line 24) | pub fn wait() {
function is_loaded (line 28) | pub fn is_loaded() -> bool {
type Parser (line 33) | pub struct Parser<'input> {
function new (line 39) | pub fn new(original: &'input str) -> Self {
function parse (line 49) | pub fn parse(&self) -> ParseResult {
FILE: lib/sentence_reader/src/output.rs
type ParseResult (line 5) | pub enum ParseResult {
method is_sentence (line 16) | pub fn is_sentence(&self) -> bool {
method is_inflected_word (line 24) | pub fn is_inflected_word(&self) -> bool {
method is_none (line 32) | pub fn is_none(&self) -> bool {
method as_sentence (line 37) | pub fn as_sentence(&self) -> Option<&Sentence> {
method as_inflected_word (line 46) | pub fn as_inflected_word(&self) -> Option<&Part> {
type Sentence (line 57) | pub struct Sentence {
method new (line 63) | pub fn new(parts: Vec<Part>) -> Self {
method get_at (line 69) | pub fn get_at(&self, pos: usize) -> Option<&Part> {
method get_at_mut (line 75) | pub fn get_at_mut(&mut self, pos: usize) -> Option<&mut Part> {
method iter_mut (line 80) | pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Part> {
method iter (line 85) | pub fn iter(&self) -> impl Iterator<Item = &Part> {
method word_count (line 91) | pub fn word_count(&self) -> usize {
method into_parts (line 97) | pub fn into_parts(self) -> Vec<Part> {
FILE: lib/sentence_reader/src/sentence/inflection.rs
method from (line 37) | fn from(parts: Vec<igo_unidic::Morpheme<'static, 'b>>, _pos: usize) -> O...
function parse_inflections (line 79) | pub(crate) fn parse_inflections(morph: &[Morpheme<'static, '_>]) -> Vec<...
function get_rules (line 86) | fn get_rules() -> RuleSet {
FILE: lib/sentence_reader/src/sentence/mod.rs
type FromMorphemes (line 10) | pub trait FromMorphemes<'a, 'b>: Sized {
method from (line 11) | fn from(parts: Vec<Morpheme<'a, 'b>>, pos: usize) -> Option<Self>;
function from (line 16) | fn from(parts: Vec<Morpheme<'static, 'b>>, pos: usize) -> Option<Self> {
type SentenceAnalyzer (line 26) | pub struct SentenceAnalyzer<'input> {
function new (line 33) | pub fn new(
function is_empty (line 41) | pub fn is_empty(&self) -> bool {
function analyze (line 46) | pub fn analyze<O: FromMorphemes<'static, 'input>>(&self) -> Vec<O> {
function morphemes (line 90) | pub fn morphemes(&self) -> &Vec<Morpheme<'_, '_>> {
function debug (line 94) | pub fn debug(&self) {
function map_morph_to_rule (line 114) | pub(crate) fn map_morph_to_rule(pos: usize, morph: &Morpheme<'_, '_>) ->...
FILE: lib/sentence_reader/src/sentence/owned_morpheme.rs
type OwnedMorpheme (line 4) | pub struct OwnedMorpheme<'dict> {
function from (line 16) | fn from(m: Morpheme<'dict, '_>) -> Self {
function reading (line 31) | pub fn reading(&self) -> &str {
FILE: lib/sentence_reader/src/sentence/part.rs
type Part (line 17) | pub struct Part {
method new (line 27) | pub fn new(morphemes: Vec<Morpheme<'static, '_>>, pos: usize) -> Optio...
method has_inflections (line 47) | pub fn has_inflections(&self) -> bool {
method morphemes (line 52) | pub fn morphemes(&self) -> &[OwnedMorpheme] {
method inflections (line 57) | pub fn inflections(&self) -> &[Inflection] {
method get_inflected (line 64) | pub fn get_inflected(&self) -> String {
method get_normalized (line 73) | pub fn get_normalized(&self) -> String {
method pos (line 78) | pub fn pos(&self) -> usize {
method set_furigana (line 83) | pub fn set_furigana<F>(&mut self, add_fn: F)
method furigana (line 120) | pub fn furigana(&self) -> Option<&str> {
method word_class (line 125) | pub fn word_class(&self) -> Option<&'static str> {
method word_class_raw (line 150) | pub fn word_class_raw(&self) -> &WordClass<'_> {
method word_class_lower (line 155) | pub fn word_class_lower(&self) -> Option<String> {
method get_main_morpheme (line 160) | fn get_main_morpheme(&self) -> &OwnedMorpheme {
method main_lexeme (line 165) | fn main_lexeme(&self) -> &str {
method from (line 172) | fn from(parts: Vec<Morpheme<'static, 'b>>, pos: usize) -> Option<Self> {
method into (line 243) | fn into(self) -> SentencePart {
function merge_furigana (line 182) | fn merge_furigana(src: &str, furi: &str) -> Option<String> {
function can_merge_furi (line 212) | fn can_merge_furi(src: &str, furi: &str) -> bool {
function wc_to_simple_pos (line 253) | pub fn wc_to_simple_pos(wc: &WordClass) -> Option<PosSimple> {
FILE: lib/types/src/api/app/completions/mod.rs
type Request (line 6) | pub struct Request {
type Response (line 28) | pub struct Response {
method new (line 35) | pub fn new(suggestions: Vec<WordPair>) -> Self {
method with_type (line 43) | pub fn with_type(suggestions: Vec<WordPair>, suggestion_type: Suggesti...
type SuggestionType (line 54) | pub enum SuggestionType {
type WordPair (line 66) | pub struct WordPair {
method new (line 75) | pub fn new(primary: String) -> Self {
method with_secondary (line 83) | pub fn with_secondary(primary: String, secondary: String) -> Self {
method has_reading (line 92) | pub fn has_reading(&self, reading: &str) -> bool {
method secondary_preferred (line 102) | pub fn secondary_preferred(&self) -> &String {
method from (line 110) | fn from(word: &crate::jotoba::words::Word) -> Self {
FILE: lib/types/src/api/app/details/query.rs
type DetailsPayload (line 8) | pub struct DetailsPayload {
method lang_param (line 17) | pub fn lang_param(&self) -> LangParam {
FILE: lib/types/src/api/app/details/sentence.rs
type Details (line 6) | pub struct Details {
method new (line 15) | pub fn new(sentence: Sentence, words: Vec<Word>, kanji: Vec<Kanji>) ->...
FILE: lib/types/src/api/app/details/word.rs
type Details (line 9) | pub struct Details {
method new (line 31) | pub fn new(
type TransitivityPair (line 24) | pub enum TransitivityPair {
FILE: lib/types/src/api/app/image/mod.rs
type Response (line 5) | pub struct Response {
type Request (line 11) | pub struct Request {
function default_conf_threshold (line 20) | fn default_conf_threshold() -> i32 {
FILE: lib/types/src/api/app/kanji/ids_tree.rs
type Request (line 4) | pub struct Request {
type Response (line 10) | pub struct Response {
method new (line 16) | pub fn new(tree: OutObject, has_big: bool) -> Self {
type OutObject (line 22) | pub struct OutObject {
method new (line 31) | pub fn new(name: char) -> Self {
method with_children (line 40) | pub fn with_children(name: char, children: Vec<OutObject>) -> Self {
method add_child (line 49) | pub fn add_child(&mut self, child: Self) {
method set_literal_available (line 54) | pub fn set_literal_available(&mut self, literal_available: bool) {
FILE: lib/types/src/api/app/mod.rs
function deserialize_lang_option (line 16) | pub fn deserialize_lang_option<'de, D>(s: D) -> Result<Option<Language>,...
function deserialize_lang (line 30) | pub fn deserialize_lang<'de, D>(s: D) -> Result<Language, D::Error>
FILE: lib/types/src/api/app/news/long.rs
type Request (line 6) | pub struct Request {
type Response (line 11) | pub struct Response {
FILE: lib/types/src/api/app/news/mod.rs
type NewsEntry (line 7) | pub struct NewsEntry {
FILE: lib/types/src/api/app/news/short.rs
type Request (line 6) | pub struct Request {
type Response (line 11) | pub struct Response {
FILE: lib/types/src/api/app/radical/find_kanji.rs
type Request (line 6) | pub struct Request {
type Response (line 12) | pub struct Response {
FILE: lib/types/src/api/app/radical/search.rs
type Request (line 6) | pub struct Request {
type Response (line 12) | pub struct Response {
type KanjiRads (line 19) | pub struct KanjiRads {
method new (line 26) | pub fn new(kanji: char, rads: HashMap<u32, Vec<char>>) -> Self {
FILE: lib/types/src/api/app/search/query.rs
type SearchPayload (line 8) | pub struct SearchPayload {
method lang_param (line 30) | pub fn lang_param(&self) -> LangParam {
type UserSettings (line 37) | pub struct UserSettings {
method lang_param (line 49) | pub fn lang_param(&self) -> LangParam {
FILE: lib/types/src/api/app/search/responses/k_compounds.rs
type CompoundResponse (line 5) | pub struct CompoundResponse {
method new (line 11) | pub fn new(compounds: Vec<CompoundSet>) -> Self {
type CompoundSet (line 18) | pub struct CompoundSet {
method new (line 27) | pub fn new(on: Vec<CompoundWord>, kun: Vec<CompoundWord>) -> Self {
type CompoundWord (line 34) | pub struct CompoundWord {
method new (line 42) | pub fn new(jp: String, kana: String, translations: Vec<String>) -> Self {
method from_word (line 52) | pub fn from_word(word: &crate::jotoba::words::Word) -> Self {
FILE: lib/types/src/api/app/search/responses/kanji.rs
type KanjiResponse (line 7) | pub struct KanjiResponse {
method new (line 13) | pub fn new(kanji: Vec<Kanji>) -> Self {
type Kanji (line 20) | pub struct Kanji {
method from (line 57) | fn from(k: crate::jotoba::kanji::Kanji) -> Self {
FILE: lib/types/src/api/app/search/responses/mod.rs
type Response (line 12) | pub struct Response<T: Serialize> {
function new (line 20) | pub fn new(inner: Page<T>) -> Self {
function with_help (line 27) | pub fn with_help(inner: Page<T>, search_help: SearchHelp) -> Self {
function with_help_fn (line 34) | pub fn with_help_fn<S>(inner: Page<T>, help_fn: S) -> Self
function set_search_help (line 44) | pub fn set_search_help(&mut self, search_help: SearchHelp) -> &mut Self {
FILE: lib/types/src/api/app/search/responses/names.rs
type Response (line 7) | pub struct Response {
method new (line 13) | pub fn new(names: Vec<Name>) -> Self {
FILE: lib/types/src/api/app/search/responses/sentences.rs
type Response (line 5) | pub struct Response {
method new (line 11) | pub fn new(sentences: Vec<Sentence>) -> Self {
type Sentence (line 17) | pub struct Sentence {
method new (line 26) | pub fn new(sequence: u32, content: String, translation: String) -> Self {
FILE: lib/types/src/api/app/search/responses/words/inflection.rs
type InflectionInfo (line 6) | pub struct InflectionInfo {
method new (line 16) | pub fn new(inflection: Vec<Inflection>, lexeme: String) -> Self {
FILE: lib/types/src/api/app/search/responses/words/mod.rs
type Response (line 14) | pub struct Response {
method new (line 39) | pub fn new(
FILE: lib/types/src/api/app/search/responses/words/sentence.rs
type Sentence (line 4) | pub struct Sentence {
method new (line 13) | pub fn new(curr_index: usize, parts: Vec<SentencePart>) -> Self {
type SentencePart (line 19) | pub struct SentencePart {
method new (line 35) | pub fn new(
FILE: lib/types/src/api/app/search/responses/words/word.rs
type Word (line 13) | pub struct Word {
type Sense (line 36) | pub struct Sense {
FILE: lib/types/src/api/internal/info/words.rs
type Request (line 12) | pub struct Request {
method new (line 21) | pub fn new(ids: Vec<u32>, language: Language, show_english: bool) -> S...
method lang_param (line 30) | pub fn lang_param(&self) -> LangParam {
type Response (line 36) | pub struct Response {
method new (line 66) | pub fn new(items: Vec<WordItem>) -> Self {
type WordItem (line 41) | pub struct WordItem {
method new (line 49) | pub fn new(
FILE: lib/types/src/api/search/kanji.rs
type Response (line 6) | pub struct Response {
type Kanji (line 11) | pub struct Kanji {
method from (line 41) | pub fn from<P: AsRef<Path>>(kanji: &crate::jotoba::kanji::Kanji, asset...
FILE: lib/types/src/api/search/mod.rs
type SearchRequest (line 12) | pub struct SearchRequest {
FILE: lib/types/src/api/search/name.rs
type Response (line 6) | pub struct Response {
method from (line 34) | fn from(name: Vec<&crate::jotoba::names::Name>) -> Self {
type Name (line 11) | pub struct Name {
method from (line 22) | fn from(name: &crate::jotoba::names::Name) -> Self {
FILE: lib/types/src/api/search/sentence.rs
type Response (line 6) | pub struct Response {
method from (line 22) | fn from(sentences: Vec<Sentence>) -> Self {
type Sentence (line 11) | pub struct Sentence {
FILE: lib/types/src/api/search/word.rs
type Response (line 18) | pub struct Response {
method new (line 24) | pub fn new(words: Vec<Word>, kanji: Vec<Kanji>) -> Self {
method from (line 29) | pub fn from<P: AsRef<Path>>(
type Word (line 45) | pub struct Word {
method from (line 112) | fn from(word: &crate::jotoba::words::Word) -> Self {
type Reading (line 58) | pub struct Reading {
type Sense (line 67) | pub struct Sense {
method from (line 86) | fn from(sense: &crate::jotoba::words::sense::Sense) -> Self {
function convert_kanji (line 138) | fn convert_kanji<P: AsRef<std::path::Path>>(
function convert_words (line 149) | fn convert_words(wres: Vec<&crate::jotoba::words::Word>) -> Vec<Word> {
FILE: lib/types/src/jotoba/indexes/hashtag.rs
type RawHashtag (line 7) | pub struct RawHashtag {
method new (line 14) | pub fn new(tag: String, s_targets: Vec<SearchTarget>, freq: f32) -> Se...
type Err (line 24) | type Err = ();
method from_str (line 26) | fn from_str(s: &str) -> Result<Self, Self::Err> {
FILE: lib/types/src/jotoba/kanji/mod.rs
type Kanji (line 17) | pub struct Kanji {
method get_reading_type (line 42) | pub fn get_reading_type(&self, reading: &str) -> Option<ReadingType> {
method in_kun_reading (line 57) | pub fn in_kun_reading(&self, reading: &str) -> bool {
method in_on_reading (line 63) | pub fn in_on_reading(&self, reading: &str) -> bool {
method find_reading (line 69) | pub fn find_reading(&self, reading: &str) -> Option<Reading> {
method reading_iter (line 85) | pub fn reading_iter(&self) -> impl Iterator<Item = (&String, u32)> {
method reading_from_pos (line 93) | pub fn reading_from_pos(&self, pos: usize) -> Option<Reading> {
method get_literal_reading (line 114) | pub fn get_literal_reading(&self, reading: &str) -> Option<String> {
method has_reading (line 123) | pub fn has_reading(&self, reading: &str) -> bool {
method has_stroke_frames (line 129) | pub fn has_stroke_frames<P: AsRef<Path>>(&self, assets_path: P) -> bool {
method get_stroke_frames_url (line 135) | pub fn get_stroke_frames_url(&self) -> String {
method get_stroke_frames_path (line 141) | pub fn get_stroke_frames_path<P: AsRef<Path>>(&self, assets_path: P) -...
method get_animation_path (line 150) | pub fn get_animation_path<P: AsRef<Path>>(&self, assets_path: P) -> Pa...
method has_animation_file (line 159) | pub fn has_animation_file<P: AsRef<Path>>(&self, assets_path: P) -> bo...
method has_compounds (line 166) | pub fn has_compounds(&self) -> bool {
function format_reading (line 173) | pub fn format_reading(reading: &str) -> String {
function literal_kun_reading (line 179) | pub fn literal_kun_reading(kun: &str) -> String {
function format_reading_with_literal (line 191) | pub fn format_reading_with_literal(literal: char, reading: &str, r_type:...
function reading_on1 (line 210) | fn reading_on1() -> Reading {
function reading_kun (line 214) | fn reading_kun() -> Reading {
function reading_kun2 (line 218) | fn reading_kun2() -> Reading {
function reading_kun3 (line 222) | fn reading_kun3() -> Reading {
function test_reading (line 227) | fn test_reading() {
FILE: lib/types/src/jotoba/kanji/radical.rs
type DetailedRadical (line 5) | pub struct DetailedRadical {
type SearchRadicalInfo (line 15) | pub struct SearchRadicalInfo {
type SearchRadical (line 23) | pub struct SearchRadical {
FILE: lib/types/src/jotoba/kanji/reading.rs
type ReadingType (line 9) | pub enum ReadingType {
type Reading (line 15) | pub struct Reading {
method format_reading_with_literal (line 26) | pub fn format_reading_with_literal(&self) -> String {
method new (line 43) | pub(crate) fn new(r_type: ReadingType, literal: char, inner: String) -...
method get_type (line 53) | pub fn get_type(&self) -> ReadingType {
method get_literal (line 59) | pub fn get_literal(&self) -> &char {
method get_raw (line 65) | pub fn get_raw(&self) -> &str {
method matches_kanji (line 71) | pub fn matches_kanji(&self, kanji: &Kanji) -> bool {
method get_lit_str (line 77) | pub fn get_lit_str(&self) -> String {
method is_full_reading (line 83) | pub fn is_full_reading(&self) -> bool {
function eq (line 90) | fn eq(&self, other: &ReadingType) -> bool {
type ReadingSearch (line 97) | pub struct ReadingSearch {
method new (line 106) | pub fn new(literal: &str, reading: &str) -> Self {
FILE: lib/types/src/jotoba/language/mod.rs
type Language (line 16) | pub enum Language {
method iter (line 42) | pub fn iter() -> IntoIter<Language, 10> {
method iter_word (line 60) | pub fn iter_word() -> IntoIter<Language, 9> {
method to_query_format (line 75) | pub fn to_query_format(&self) -> &'static str {
type Error (line 99) | type Error = ();
method try_from (line 101) | fn try_from(i: i32) -> Result<Self, Self::Error> {
method into (line 120) | fn into(self) -> i32 {
method default (line 93) | fn default() -> Self {
method get_id (line 139) | fn get_id(&self) -> &'static str {
FILE: lib/types/src/jotoba/language/param.rs
type LangParam (line 7) | pub struct LangParam {
method new (line 15) | pub fn new(lang: Language) -> Self {
method with_en (line 21) | pub fn with_en(lang: Language) -> Self {
method with_en_raw (line 27) | pub fn with_en_raw(lang: Language, use_en: bool) -> Self {
method en_fallback (line 33) | pub fn en_fallback(&self) -> bool {
method is_english (line 39) | pub fn is_english(&self) -> bool {
method language (line 45) | pub fn language(&self) -> Language {
method eq_to_lang (line 52) | pub fn eq_to_lang(&self, lang: &Language) -> bool {
method from (line 80) | fn from(lang: &Language) -> Self {
method from (line 87) | fn from(lang: Language) -> Self {
method from (line 94) | fn from(lang: (Language, bool)) -> Self {
type Target (line 58) | type Target = Language;
method deref (line 61) | fn deref(&self) -> &Self::Target {
type AsLangParam (line 67) | pub trait AsLangParam: Copy {
method as_lang (line 68) | fn as_lang(self) -> LangParam;
method as_lang (line 73) | fn as_lang(self) -> LangParam {
FILE: lib/types/src/jotoba/names/mod.rs
type Name (line 8) | pub struct Name {
method is_gendered (line 19) | pub fn is_gendered(&self) -> bool {
method get_gender (line 27) | pub fn get_gender(&self) -> Option<NameType> {
method has_non_gender_tags (line 34) | pub fn has_non_gender_tags(&self) -> bool {
method get_reading (line 42) | pub fn get_reading(&self) -> &str {
method has_kanji (line 47) | pub fn has_kanji(&self) -> bool {
method eq (line 54) | fn eq(&self, other: &Self) -> bool {
method hash (line 63) | fn hash<H: Hasher>(&self, state: &mut H) {
FILE: lib/types/src/jotoba/names/name_type.rs
type NameType (line 9) | pub enum NameType {
method is_gender (line 66) | pub fn is_gender(&self) -> bool {
method get_id (line 74) | fn get_id(&self) -> &'static str {
FILE: lib/types/src/jotoba/pagination/mod.rs
constant BUTTONS_TO_DISPLAY (line 8) | const BUTTONS_TO_DISPLAY: u8 = 5;
type Pagination (line 12) | pub struct Pagination {
method new (line 21) | pub fn new(curr_page: u32, items: u32, items_per_page: u32, max_pages:...
method new_page (line 31) | pub fn new_page<T: Serialize + Clone>(
method get_last (line 43) | pub fn get_last(&self) -> u32 {
method is_first (line 49) | pub fn is_first(&self) -> bool {
method is_last (line 55) | pub fn is_last(&self) -> bool {
method with_value (line 59) | pub fn with_value<T: Serialize + Clone>(&self, v: T) -> Page<T> {
method gen_page_buttons (line 67) | pub fn gen_page_buttons(&self) -> impl Iterator<Item = PaginationButto...
type PaginationButton (line 86) | pub struct PaginationButton {
method new (line 94) | fn new(page: u32, active: bool) -> PaginationButton {
FILE: lib/types/src/jotoba/pagination/page.rs
type Page (line 6) | pub struct Page<T: Serialize> {
function new (line 19) | pub fn new(content: T) -> Self {
function with_pages (line 32) | pub fn with_pages(content: T, current_page: u32, pages: u32) -> Self {
function set_current_page (line 46) | pub fn set_current_page(&mut self, current_page: u32) {
function set_pages (line 56) | pub fn set_pages(&mut self, pages: u32) {
function pages (line 62) | pub fn pages(&self) -> u32 {
function is_empty (line 68) | pub fn is_empty(&self) -> bool {
function current_page (line 73) | pub fn current_page(&self) -> u32 {
FILE: lib/types/src/jotoba/search/guess.rs
type Guess (line 6) | pub struct Guess {
method new (line 23) | pub fn new(value: u32, guess_type: GuessType) -> Self {
method with_limit (line 29) | pub fn with_limit(value: u32, limit: u32) -> Self {
method format (line 44) | pub fn format(&self) -> String {
type GuessType (line 13) | pub enum GuessType {
method get_prefix (line 52) | pub fn get_prefix(&self) -> &'static str {
FILE: lib/types/src/jotoba/search/help.rs
type SearchHelp (line 10) | pub struct SearchHelp {
method new (line 24) | pub fn new(
method is_empty (line 41) | pub fn is_empty(&self) -> bool {
method iter_items (line 46) | pub fn iter_items(&self) -> impl Iterator<Item = (SearchTarget, Guess)> {
method iter_langs (line 62) | pub fn iter_langs(&self) -> impl Iterator<Item = (Language, &'static s...
FILE: lib/types/src/jotoba/search/query_type.rs
type SearchTarget (line 7) | pub enum SearchTarget {
method iterate (line 22) | pub fn iterate() -> impl Iterator<Item = Self> {
method get_translated (line 27) | pub fn get_translated<'a>(
method get_type_id (line 36) | pub fn get_type_id(&self) -> u8 {
type Error (line 47) | type Error = ();
method try_from (line 50) | fn try_from(value: u8) -> Result<Self, Self::Error> {
method get_id (line 64) | fn get_id(&self) -> &'static str {
FILE: lib/types/src/jotoba/sentences/mod.rs
type Sentence (line 18) | pub struct Sentence {
method new (line 31) | pub fn new(
method has_tag (line 51) | pub fn has_tag(&self, tag: &Tag) -> bool {
method has_translation (line 57) | pub fn has_translation(&self, lang: impl AsLangParam) -> bool {
method translation_for (line 66) | pub fn translation_for(&self, language: Language) -> Option<&str> {
method get_translation (line 73) | pub fn get_translation(&self, lang: impl AsLangParam) -> Option<&str> {
method set_jlpt_guess (line 87) | pub fn set_jlpt_guess(&mut self, guess: u8) {
method calc_lang_mask (line 96) | pub fn calc_lang_mask(&self) -> u16 {
method level (line 101) | pub fn level(&self) -> Option<i8> {
method get_kana (line 112) | pub fn get_kana(&self) -> String {
method fmt (line 160) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function lang_mask (line 117) | pub fn lang_mask<I>(langs: I) -> u16
function parse_lang_mask (line 129) | pub fn parse_lang_mask(mask: u16) -> Vec<Language> {
method eq (line 146) | fn eq(&self, other: &Self) -> bool {
method hash (line 153) | fn hash<H: Hasher>(&self, state: &mut H) {
FILE: lib/types/src/jotoba/sentences/tag.rs
type Tag (line 9) | pub enum Tag {
method iter (line 63) | pub fn iter() -> impl Iterator<Item = Tag> {
method as_str (line 68) | pub fn as_str(&self) -> &str {
FILE: lib/types/src/jotoba/sentences/translation.rs
type Translation (line 6) | pub struct Translation {
method from (line 13) | fn from((text, language): (String, Language)) -> Self {
FILE: lib/types/src/jotoba/words/dialect.rs
type Dialect (line 11) | pub enum Dialect {
method into (line 47) | fn into(self) -> &'static str {
method fmt (line 40) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
method get_id (line 68) | fn get_id(&self) -> &'static str {
method gettext_custom (line 73) | fn gettext_custom(&self, dict: &TranslationDict, language: Option<Langua...
FILE: lib/types/src/jotoba/words/dict.rs
type Dict (line 7) | pub struct Dict {
method len (line 19) | pub fn len(&self) -> usize {
method is_empty (line 26) | pub fn is_empty(&self) -> bool {
FILE: lib/types/src/jotoba/words/field.rs
type Field (line 9) | pub enum Field {
method get_id (line 184) | fn get_id(&self) -> &'static str {
method gettext_custom (line 275) | fn gettext_custom(&self, dict: &TranslationDict, language: Option<Langua...
FILE: lib/types/src/jotoba/words/foreign_language.rs
type ForeignLanguage (line 9) | pub enum ForeignLanguage {
method get_id (line 128) | fn get_id(&self) -> &'static str {
method default (line 193) | fn default() -> Self {
FILE: lib/types/src/jotoba/words/gtype.rs
type GType (line 7) | pub enum GType {
type Error (line 17) | type Error = ();
method try_from (line 20) | fn try_from(i: i32) -> Result<Self, Self::Error> {
method into (line 32) | fn into(self) -> i32 {
FILE: lib/types/src/jotoba/words/inflection.rs
type Inflection (line 8) | pub enum Inflection {
method get_id (line 35) | fn get_id(&self) -> &'static str {
method gettext (line 62) | fn gettext<'a>(
type Inflections (line 73) | pub struct Inflections {
type InflectionPair (line 91) | pub struct InflectionPair {
function build_inflections (line 98) | pub fn build_inflections(
function of_word (line 151) | pub fn of_word(word: &super::Word) -> Option<Inflections> {
function get_jp_verb (line 164) | pub fn get_jp_verb(word: &super::Word) -> Option<Verb> {
FILE: lib/types/src/jotoba/words/information.rs
type Information (line 9) | pub enum Information {
method get_id (line 36) | fn get_id(&self) -> &'static str {
FILE: lib/types/src/jotoba/words/misc.rs
type Misc (line 12) | pub enum Misc {
method iter (line 193) | pub fn iter() -> impl Iterator<Item = Misc> {
method as_str (line 198) | pub fn as_str(&self) -> &str {
method get_id (line 129) | fn get_id(&self) -> &'static str {
FILE: lib/types/src/jotoba/words/mod.rs
type Word (line 38) | pub struct Word {
method is_common (line 55) | pub fn is_common(&self) -> bool {
method get_jlpt_lvl (line 61) | pub fn get_jlpt_lvl(&self) -> Option<u8> {
method get_reading (line 68) | pub fn get_reading(&self) -> &Dict {
method get_reading_str (line 75) | pub fn get_reading_str(&self) -> &str {
method sense_gloss_iter (line 81) | pub fn sense_gloss_iter(&self) -> SenseGlossIter {
method senses_by_lang (line 87) | pub fn senses_by_lang(&self, language: impl AsLangParam) -> Vec<&Sense> {
method get_senses_orderd (line 96) | pub fn get_senses_orderd(&self, english_on_top: bool, _language: Langu...
method get_senses_with_en (line 111) | pub fn get_senses_with_en(&self) -> Vec<Vec<Sense>> {
method senses (line 123) | pub fn senses(&self) -> &[Sense] {
method sense_by_id (line 128) | pub fn sense_by_id(&self, id: u8) -> Option<&Sense> {
method get_sense_gloss (line 132) | pub fn get_sense_gloss(&self, id: u16) -> Option<(&Sense, &sense::Glos...
method gloss_iter_by_lang (line 140) | pub fn gloss_iter_by_lang(&self, lang_param: impl AsLangParam) -> impl...
method get_word_tag_count (line 148) | pub fn get_word_tag_count(&self) -> u8 {
method has_sentence (line 156) | pub fn has_sentence(&self, lang: impl AsLangParam) -> bool {
method has_misc (line 169) | pub fn has_misc(&self, misc: &Misc) -> bool {
method has_pos (line 177) | pub fn has_pos(&self, pos_filter: &[PosSimple]) -> bool {
method has_all_pos (line 189) | pub fn has_all_pos(&self, pos_filter: &[PosSimple]) -> bool {
method has_all_pos_iter (line 195) | pub fn has_all_pos_iter<'a, I>(&self, mut pos_filter: I) -> bool
method has_language (line 205) | pub fn has_language(&self, language: impl AsLangParam) -> bool {
method has_collocations (line 212) | pub fn has_collocations(&self) -> bool {
method reading_iter (line 218) | pub fn reading_iter(&self, allow_kana: bool) -> ReadingIter<'_> {
method has_reading (line 224) | pub fn has_reading(&self, reading: &str) -> bool {
method has_kanji (line 230) | pub fn has_kanji(&self) -> bool {
method has_main_reading (line 235) | pub fn has_main_reading(&self, reading: &str) -> bool {
method get_pos (line 247) | pub fn get_pos(&self) -> impl Iterator<Item = &PartOfSpeech> {
method get_kana (line 255) | pub fn get_kana(&self) -> &str {
method has_pitch (line 260) | pub fn has_pitch(&self) -> bool {
method get_pitches (line 265) | pub fn get_pitches(&self) -> Vec<Pitch> {
method get_first_pitch (line 274) | pub fn get_first_pitch(&self) -> Option<Pitch> {
method is_katakana_word (line 281) | pub fn is_katakana_word(&self) -> bool {
method adjust_language (line 287) | pub fn adjust_language(&mut self, lang: impl AsLangParam) {
method get_furigana (line 294) | pub fn get_furigana(&self) -> Option<Vec<SegmentRef>> {
method audio_file_name (line 307) | pub fn audio_file_name(&self) -> Option<String> {
method audio_file_name_old (line 316) | pub fn audio_file_name_old(&self) -> Option<String> {
method audio_file (line 331) | pub fn audio_file<P: AsRef<Path>>(&self, _assets_path: P) -> Option<St...
method alt_readings_beautified (line 342) | pub fn alt_readings_beautified(&self) -> String {
method glosses_pretty (line 350) | pub fn glosses_pretty(&self) -> String {
method pretty_print_senses (line 362) | fn pretty_print_senses(senses: &[Sense]) -> String {
method get_inflections (line 374) | pub fn get_inflections(&self) -> Option<inflection::Inflections> {
method fmt (line 406) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function filter_languages (line 382) | pub fn filter_languages<'a, I: 'a + Iterator<Item = &'a mut Word>>(
method hash (line 393) | fn hash<H: Hasher>(&self, state: &mut H) {
method eq (line 400) | fn eq(&self, other: &Self) -> bool {
FILE: lib/types/src/jotoba/words/part_of_speech.rs
type PosSimple (line 26) | pub enum PosSimple {
method iter (line 67) | pub fn iter() -> impl Iterator<Item = PosSimple> {
method as_str (line 72) | pub fn as_str(&self) -> &str {
type Error (line 78) | type Error = ();
method try_from (line 79) | fn try_from(i: i32) -> Result<Self, Self::Error> {
method into (line 105) | fn into(self) -> i32 {
type PartOfSpeech (line 172) | pub enum PartOfSpeech {
method to_pos_simple (line 131) | pub fn to_pos_simple(&self) -> Vec<PosSimple> {
method is_godan (line 208) | pub fn is_godan(&self) -> bool {
method is_ichidan (line 217) | pub fn is_ichidan(&self) -> bool {
method into (line 740) | fn into(self) -> String {
type Error (line 775) | type Error = ();
method try_from (line 777) | fn try_from(value: &str) -> Result<Self, Self::Error> {
type VerbType (line 231) | pub enum VerbType {
method into (line 451) | fn into(self) -> String {
type Error (line 479) | type Error = ();
method try_from (line 481) | fn try_from(value: &str) -> Result<Self, Self::Error> {
type AdjectiveType (line 247) | pub enum AdjectiveType {
method into (line 701) | fn into(self) -> String {
type Error (line 720) | type Error = ();
method try_from (line 722) | fn try_from(value: &str) -> Result<Self, Self::Error> {
type NounType (line 264) | pub enum NounType {
method into (line 673) | fn into(self) -> String {
type Error (line 687) | type Error = ();
method try_from (line 689) | fn try_from(value: &str) -> Result<Self, Self::Error> {
type IrregularVerb (line 274) | pub enum IrregularVerb {
type Error (line 508) | type Error = ();
method try_from (line 509) | fn try_from(value: &str) -> Result<Self, Self::Error> {
method into (line 524) | fn into(self) -> String {
type NidanVerb (line 284) | pub struct NidanVerb {
method into (line 633) | fn into(self) -> String {
type Error (line 645) | type Error = ();
method try_from (line 647) | fn try_from(value: &str) -> Result<Self, Self::Error> {
type VerbClass (line 291) | pub enum VerbClass {
type VerbEnding (line 299) | pub enum VerbEnding {
method into (line 588) | fn into(self) -> String {
type Error (line 610) | type Error = ();
method try_from (line 611) | fn try_from(value: &str) -> Result<Self, Self::Error> {
type GodanVerbEnding (line 317) | pub enum GodanVerbEnding {
method into (line 539) | fn into(self) -> String {
type Error (line 562) | type Error = ();
method try_from (line 563) | fn try_from(value: &str) -> Result<Self, Self::Error> {
method get_id (line 337) | fn get_id(&self) -> &'static str {
method gettext_custom (line 361) | fn gettext_custom(&self, dict: &TranslationDict, language: Option<Langua...
method get_id (line 371) | fn get_id(&self) -> &'static str {
method get_id (line 389) | fn get_id(&self) -> &'static str {
method get_id (line 402) | fn get_id(&self) -> &'static str {
method gettext_custom (line 416) | fn gettext_custom(&self, dict: &TranslationDict, language: Option<Langua...
method get_id (line 426) | fn get_id(&self) -> &'static str {
method gettext_custom (line 437) | fn gettext_custom(&self, dict: &TranslationDict, language: Option<Langua...
FILE: lib/types/src/jotoba/words/pitch/border.rs
type Border (line 3) | pub enum Border {
method get_class (line 12) | pub fn get_class(&self) -> char {
method horizontal (line 22) | pub fn horizontal(high: bool) -> Border {
type BorderBuilder (line 32) | pub struct BorderBuilder {
method new (line 38) | pub fn new(initial: Border) -> Self {
method add (line 45) | pub fn add(&mut self, border: Border) {
method build (line 51) | pub fn build(self) -> String {
FILE: lib/types/src/jotoba/words/pitch/mod.
Condensed preview — 435 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,391K chars).
[
{
"path": ".dockerignore",
"chars": 309,
"preview": "/html/assets/js/lib/loadAnalytics.js\n/html/assets/svg\n/html/audio\n/html/*.html\n!/html/docs.html\n/target\nout\n*.old\n.env\ni"
},
{
"path": ".github/FUNDING.yml",
"chars": 120,
"preview": "# These are supported funding model platforms\n\ncustom: [\"https://paypal.me/JojiiOfficial\", \"https://paypal.me/yukaru1\"]\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 968,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve. Check the trello board first!\ntitle: ''\nlabels: ''\nassig"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 595,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
},
{
"path": ".github/workflows/docker-image.yml",
"chars": 781,
"preview": "name: Docker Image CI\n\non:\n push:\n branches: [ master ]\n workflow_dispatch:\n\njobs:\n build:\n runs-on: ubuntu-lat"
},
{
"path": ".gitignore",
"chars": 373,
"preview": "/html/assets/js/lib/loadAnalytics.js\n/html/assets/svg\n/html/audio\n/html/assets/sitemap.xml\n/html/assets/*.html\n!/html/as"
},
{
"path": "Cargo.toml",
"chars": 165,
"preview": "[workspace]\n\nmembers = [\"jotoba_bin\", \"lib/*\"]\n\n[profile.dev]\nopt-level = 2\nincremental = true\nlto = false\nstrip = false"
},
{
"path": "Dockerfile",
"chars": 929,
"preview": "FROM rust:1.70.0-bullseye as build\n\nWORKDIR app\n\nCOPY ./lib ./lib\nCOPY ./.git ./.git\nCOPY ./locales ./locales\nCOPY ./Car"
},
{
"path": "LICENSE",
"chars": 34524,
"preview": " GNU AFFERO GENERAL PUBLIC LICENSE\n Version 3, 19 November 2007\n\n Copyright (C)"
},
{
"path": "README.md",
"chars": 2913,
"preview": "# Jotoba <img width=\"30\" align=\"center\" src=\"/html/assets/jotokun/JotoBook.svg\">\nJotoba is a free online multi-language "
},
{
"path": "deny.toml",
"chars": 9839,
"preview": "# This template contains all of the possible sections and their default values\n\n# Note that all fields that take a lint "
},
{
"path": "docker-compose.yaml",
"chars": 247,
"preview": "version: \"3.7\"\n\nservices:\n app:\n image: ghcr.io/wedontpanic/jotoba:latest\n restart: always\n ports:\n - 808"
},
{
"path": "html/assets/css/main.css",
"chars": 17566,
"preview": "/* ----------------- Color Themes ----------------- */\r\n\r\n:root,\r\n:root.light {\r\n --background: #f2f1f0;\r\n --overl"
},
{
"path": "html/assets/css/mobile.css",
"chars": 7148,
"preview": "/*\n Used to make mobile stuff less ugly. Will be transfered into the others file bit-by-bit.\n*/\n\n@media only screen a"
},
{
"path": "html/assets/css/overlay/croppingOverlay.css",
"chars": 1308,
"preview": ".modal.fade .modal-dialog.crop {\n transition: unset;\n transform: unset;\n}\n\n.cropping-target-border {\n position:"
},
{
"path": "html/assets/css/overlay/footerOverlay.css",
"chars": 818,
"preview": ".cookie-footer {\n display: block;\n position: fixed;\n bottom: 5%;\n padding: 10px;\n background: var(--overl"
},
{
"path": "html/assets/css/overlay/imgUploadOverlay.css",
"chars": 700,
"preview": ".image-search-input {\n width: 50%;\n padding: 0px 39px 0px 8px;\n margin-top: 4px;\n display: block;\n border"
},
{
"path": "html/assets/css/overlay/notificationOverlay.css",
"chars": 1813,
"preview": "#notifications-container {\n position: absolute;\n top: 60px;\n right: 55px;\n width: 16rem;\n z-index: 10;\n "
},
{
"path": "html/assets/css/overlay/overlayBase.css",
"chars": 1903,
"preview": ".overlay {\n z-index: 1;\n margin-top: 2px;\n position: absolute;\n width: 100%;\n height: -webkit-max-content"
},
{
"path": "html/assets/css/overlay/radicalOverlay.css",
"chars": 5875,
"preview": "/*\n Used by the radical picker only.\n*/\n\n.rad-results {\n padding-left: 5px;\n padding-top: 10px;\n min-height:"
},
{
"path": "html/assets/css/overlay/settingsOverlay.css",
"chars": 3368,
"preview": "#settingsModal .modal-body {\n height: 600px;\n margin: 0;\n padding: 0;\n}\n\n#settingsModal .choices__list--dropdow"
},
{
"path": "html/assets/css/overlay/suggestionOverlay.css",
"chars": 1034,
"preview": "\n#search::-moz-selection {\n color: var(--primaryTextColor);\n background-color: var(--secondaryColor);\n}\n\n#search::"
},
{
"path": "html/assets/css/page/aboutPage.css",
"chars": 236,
"preview": "article {\n padding-left: 10px;\n}\n\n.about-title {\n font-size: 22px;\n font-weight: bold;\n color: var(--primary"
},
{
"path": "html/assets/css/page/errorPage.css",
"chars": 1913,
"preview": "body {\n\tbackground: #f2f1f0;\n\tcolor: #222222;\n\tfont-family: 'Open Sans', sans-serif;\n\tmax-height: 700px;\n\toverflow: hidd"
},
{
"path": "html/assets/css/page/footer.css",
"chars": 1562,
"preview": "footer {\n margin: auto;\n width: 50%;\n padding-top: 50px;\n padding-bottom: 15px;\n max-width: 1150px;\n w"
},
{
"path": "html/assets/css/page/helpPage.css",
"chars": 200,
"preview": ".help-joto {\n width: 100px;\n position: relative;\n margin-top: -320px;\n margin-left: 530px;\n}\n\ndiv > .fat:not"
},
{
"path": "html/assets/css/page/indexPage.css",
"chars": 4407,
"preview": "/* ----------------- Index Page ----------------- */\n\n.title {\n padding-top: 5%;\n padding-bottom: 1.25%;\n margi"
},
{
"path": "html/assets/css/page/infoPage.css",
"chars": 287,
"preview": ".help-cat {\n padding-top: 25px;\n}\n\n.table {\n display: flex;\n flex-direction: column;\n margin-left: 25px;\n}\n\n"
},
{
"path": "html/assets/css/page/kanjiPage.css",
"chars": 6982,
"preview": ".kanji-entry.left.detail {\n width: 155px;\n padding-left: 25px;\n}\n\n.kanji-entry.right.detail {\n overflow-x: hidd"
},
{
"path": "html/assets/css/page/multiPage/kana.css",
"chars": 94,
"preview": ".inline-kana-preview {\n line-height: 1.1;\n font-size: xx-large;\n padding-top: 24px;\n}"
},
{
"path": "html/assets/css/page/multiPage/kanji.css",
"chars": 986,
"preview": ".kanji-entry {\n height: -webkit-fit-content;\n height: -moz-fit-content;\n height: fit-content;\n padding-botto"
},
{
"path": "html/assets/css/page/multiPage/markdown.css",
"chars": 172,
"preview": "h1 {\n font-size: 1.5rem;\n}\n\nh2 {\n font-size: 1rem;\n}\n\np {\n font-size: 14px;\n}\n\n.md-center {\n display: flex;\n"
},
{
"path": "html/assets/css/page/namePage.css",
"chars": 48,
"preview": ".kanji-preview.small {\n font-size: x-large;\n}"
},
{
"path": "html/assets/css/page/newsPage.css",
"chars": 1028,
"preview": "#news-list {\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.news-container {\n display: b"
},
{
"path": "html/assets/css/page/sentencePage.css",
"chars": 924,
"preview": ".furigana-kanji-container {\n text-align: left;\n}\n\n.inline-kana-preview.small, .kanji-preview.small, .inline-kana-prev"
},
{
"path": "html/assets/css/page/wordExtensions/searchAnnotation.css",
"chars": 731,
"preview": ".search-annotation {\n color: var(--tagColor);\n max-height: 150px;\n margin-bottom: 15px;\n overflow: auto;\n "
},
{
"path": "html/assets/css/page/wordExtensions/sentenceReader.css",
"chars": 1463,
"preview": "#sr {\n justify-content: center;\n}\n\n.sentence-part {\n color: var(--primaryTextColor) !important;\n border-bottom:"
},
{
"path": "html/assets/css/page/wordPage.css",
"chars": 5291,
"preview": ".title-div {\n text-align: center;\n text-align: -webkit-center;\n width: 80%;\n}\n\n.title-div h1 {\n font-weight:"
},
{
"path": "html/assets/css/search/choices.css",
"chars": 9242,
"preview": "/*\n Used by the search bar only. So much css for a damn text field..\n*/\n\n.choices {\n position: relative;\n margin-bo"
},
{
"path": "html/assets/css/search/searchRow.css",
"chars": 2903,
"preview": "#search-row {\n padding-top: 10px;\n padding-left: 10px;\n padding-right: 10px;\n}\n\n#emptyInput {\n position: abs"
},
{
"path": "html/assets/css/tools/alerts.css",
"chars": 348,
"preview": "/* ----------------- Alerts Color Design ----------------- */\n.msg-message {\n border: none !important;\n border-rad"
},
{
"path": "html/assets/css/tools/pagination.css",
"chars": 1351,
"preview": ".pagination {\n display: flex;\n list-style: none;\n justify-content: center;\n padding: 0px 0 25px 0;\n margi"
},
{
"path": "html/assets/css/tools/ripple.css",
"chars": 616,
"preview": ".has-ripple{position:relative;overflow:hidden;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);trans"
},
{
"path": "html/assets/docs.html",
"chars": 27224,
"preview": "<html>\n <head>\n <meta charset=\"utf-8\">\n <script type=\"module\" src=\"https://unpkg.com/rapidoc/dist/rapidoc-min.js\""
},
{
"path": "html/assets/fonts/fonts.css",
"chars": 814,
"preview": "@font-face {\n font-family: 'Roboto';\n font-style: normal;\n font-weight: 300;\n font-display: swap;\n src: url(\"roboto"
},
{
"path": "html/assets/js/lib/d3.js",
"chars": 151725,
"preview": "!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDoc"
},
{
"path": "html/assets/js/lib/jc.js",
"chars": 1611,
"preview": "!function(a){var b;if(\"function\"==typeof define&&define.amd&&(define(a),b=!0),\"object\"==typeof exports&&(module.exports="
},
{
"path": "html/assets/js/lib/jotobaChoices.js",
"chars": 920,
"preview": "document.querySelectorAll(\".choices__item--choice.choices__item--selectable\").forEach(e=>{e.addEventListener(\"click\",t=>"
},
{
"path": "html/assets/js/locales/collection.js",
"chars": 3615,
"preview": "const locales = {\n \"en-US\": {\n \"LANG_JAP\": \"Japanese\",\n \"LANG_GER\": \"German\",\n \"LANG_ENG\": \"Engl"
},
{
"path": "html/assets/js/mobile.js",
"chars": 2213,
"preview": "/**\n * This JS-File contains some Improvements specifically for mobile views\n */\n\n// Mark the currently selected search "
},
{
"path": "html/assets/js/page/infoPage.js",
"chars": 335,
"preview": "\n// On load, check if Shortcuts should be shown. They are useless for mobile devices\nif( /Android|webOS|iPhone|iPad|iPod"
},
{
"path": "html/assets/js/page/kanjiPage.js",
"chars": 15994,
"preview": "/**\n * This JS-File implements the Kanji Animation and compound dropdown features\n */\n\n// Kanji settings\nvar kanjiSettin"
},
{
"path": "html/assets/js/page/newsPage.js",
"chars": 581,
"preview": "// [news] is declared directly in the html\n\nprepareNews();\n\nfunction prepareNews() {\n let list = document.getElementB"
},
{
"path": "html/assets/js/page/overlay/notifications.js",
"chars": 3835,
"preview": "// On Start -> Try and load the latest data\nrequestShortData();\n\n// Start a query to receive current notifications\nasync"
},
{
"path": "html/assets/js/page/overlay/settings.js",
"chars": 7541,
"preview": "/*\n* This JS-File everything related to the settings overlay\n*/\n\nfunction Settings() { }\n\n// Analytics. Use your own or "
},
{
"path": "html/assets/js/page/overlay/settings_overlay.js",
"chars": 3617,
"preview": "/** This JS file is used for the connection between the settings \"backend\" and \"frontend\" */\n\nfunction OverlaySettings()"
},
{
"path": "html/assets/js/page/sentencePage.js",
"chars": 307,
"preview": "// Toggles the given translation visible / invisible\nfunction toggleTranslation(element) {\n let parent = $(element.pa"
},
{
"path": "html/assets/js/page/wordPage.js",
"chars": 1925,
"preview": "// Object reference for sentence reader\nconst sr = document.getElementById(\"sr\");\n\n// Enable sentence-example expander\n$"
},
{
"path": "html/assets/js/qol.js",
"chars": 11258,
"preview": "/**\n * This JS-File contains some Quality of Life improvements for the website\n */\n\nvar shiftPressed = false;\n\n// Preven"
},
{
"path": "html/assets/js/search/api.js",
"chars": 3172,
"preview": "function API() {};\n\n// Used to store old Requests so they can be cancelled when no longer needed\nAPI.lastRequest = undef"
},
{
"path": "html/assets/js/search/eventHandler.js",
"chars": 2946,
"preview": "/*\n* Made to Handle search related events. Loads after search.js!\n*/\n\n// Key Events focussing on the search\n$(document"
},
{
"path": "html/assets/js/search/overlay/imageSearch.js",
"chars": 4941,
"preview": "/**\n * This file handles everything related to image-search requests\n */ \n\n// Quick image search for STRG + V\ndocument."
},
{
"path": "html/assets/js/search/overlay/radicalSearch.js",
"chars": 15017,
"preview": "/**\n * Used to handle the radical search\n*/\nconst radicals = [\n [\"一\", \"|\", \"丶\", \"ノ\", \"乙\", \"亅\"],\n [\"二\", \"亠\", \"人\", "
},
{
"path": "html/assets/js/search/overlay/speechSearch.js",
"chars": 3885,
"preview": "/**\n * This JS-File implements the Speech to Text functionality for text input\n */\n\nvar SpeechRecognition, recognition;\n"
},
{
"path": "html/assets/js/search/overlay/suggestionOverlay.js",
"chars": 2049,
"preview": "/*\n* Handles functions related to the suggestion Overlay. Load before search.js!\n*/\n\nSuggestions.overlay = function ()"
},
{
"path": "html/assets/js/search/search.js",
"chars": 3186,
"preview": "/**\n * This JS-File contains functions handling the website search (e.g. Search suggestions)\n */\n\n// Prepare Search / Vo"
},
{
"path": "html/assets/js/search/shared.js",
"chars": 1584,
"preview": "/**\n * This JS-File contains variables shared between files to improve performance\n */\n\nconst kanjiRegEx = '([一-龯|々|𥝱|𩺊]"
},
{
"path": "html/assets/js/search/suggestions.js",
"chars": 5066,
"preview": "function Suggestions() {};\n\n/**\n * Updates the suggestions help and respects selected radicals if given some\n * \n * @par"
},
{
"path": "html/assets/js/tools/jotoTools.js",
"chars": 2889,
"preview": "/*\n* Collection-File like utils.js but that are made specifically for Jotoba\n*/\n\n// The JotoTools \"parent\"\nfunction Jo"
},
{
"path": "html/assets/js/tools/ripple.js",
"chars": 2219,
"preview": "!function(a,b,c){a.ripple=function(d,e){var f=this,g=f.log=function(){f.defaults.debug&&console&&console.log&&console.lo"
},
{
"path": "html/assets/js/tools/service-worker.js",
"chars": 167,
"preview": "// Currently unused.\n\nself.addEventListener('install', event => {\n});\n\nself.addEventListener('activate', event => {\n});\n"
},
{
"path": "html/assets/js/tools/theme.js",
"chars": 1058,
"preview": "const themeEvent = new Event(\"theme-changed\");\n\n// Sets the color Theme to the given Value by passing a class to the :ro"
},
{
"path": "html/assets/js/tools/utils.js",
"chars": 2815,
"preview": "/**\n * This JS-File contains some functions that are commonly used\n */\n\n// Constants\nconst dateSettings = { year: 'numer"
},
{
"path": "html/assets/js/tools/utils2.js",
"chars": 8444,
"preview": "/**\n * This JS-File contains some functions that are commonly used\n * This file is supposed to be loaded asynchronously."
},
{
"path": "html/assets/settings/manifest.json",
"chars": 442,
"preview": "{\n \"name\": \"Jotoba\",\n \"short_name\": \"Jotoba\",\n \"start_url\": \"/\",\n \"display\": \"standalone\",\n \"background_c"
},
{
"path": "html/assets/settings/opensearch.xml",
"chars": 789,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<OpenSearchDescription xmlns=\"http://a9.com/-/spec/opensearch/1.1/\"\n xmlns"
},
{
"path": "jotoba_bin/Cargo.toml",
"chars": 1276,
"preview": "[package]\nname = \"jotoba\"\nversion = \"0.1.0\"\nauthors = [\"jojii <jojii@gmx.net>\"]\nedition = \"2021\"\nlicense = \"GPLv3\"\n\n# Se"
},
{
"path": "jotoba_bin/benches/my_benchmark.rs",
"chars": 1717,
"preview": "use criterion::{criterion_group, criterion_main, Criterion};\nuse search::{\n executor::SearchExecutor,\n query::{par"
},
{
"path": "jotoba_bin/benches/resources.rs",
"chars": 1009,
"preview": "use criterion::{black_box, criterion_group, criterion_main, Criterion};\n\n#[global_allocator]\nstatic ALLOC: snmalloc_rs::"
},
{
"path": "jotoba_bin/src/check.rs",
"chars": 3653,
"preview": "use crate::webserver::prepare_data;\nuse config::Config;\nuse ngindex::index_framework::traits::{backend::Backend, storage"
},
{
"path": "jotoba_bin/src/cli.rs",
"chars": 1180,
"preview": "use std::process::exit;\n\nuse argparse::{ArgumentParser, Print, StoreTrue};\n\n/// Command line arguments\n#[derive(Default)"
},
{
"path": "jotoba_bin/src/main.rs",
"chars": 643,
"preview": "#![allow(irrefutable_let_patterns)]\n\n// Benchmarks say this is up to 50% faster\n#[global_allocator]\nstatic ALLOC: snmall"
},
{
"path": "jotoba_bin/src/webserver.rs",
"chars": 16558,
"preview": "use actix_files::NamedFile;\nuse actix_web_httpauth::{extractors::bearer::BearerAuth, middleware::HttpAuthentication};\nus"
},
{
"path": "lib/api/Cargo.toml",
"chars": 1855,
"preview": "[package]\nname = \"api\"\nversion = \"0.1.0\"\nauthors = [\"jojii <jojii@gmx.net>\"]\nedition = \"2021\"\n\n[dependencies]\njapanese ="
},
{
"path": "lib/api/src/app/completions/kanji/meaning.rs",
"chars": 1369,
"preview": "use super::super::{convert_results, words::foreign::try_romaji, Response};\nuse autocompletion::suggest::{\n extension:"
},
{
"path": "lib/api/src/app/completions/kanji/mod.rs",
"chars": 890,
"preview": "pub mod meaning;\npub mod reading;\n\nuse search::query::{Query, QueryLang};\nuse types::api::app::completions::Response;\nus"
},
{
"path": "lib/api/src/app/completions/kanji/reading.rs",
"chars": 2102,
"preview": "use engine::Engine;\nuse index_framework::traits::{\n backend::Backend, dictionary::IndexDictionary, postings::IndexPos"
},
{
"path": "lib/api/src/app/completions/mod.rs",
"chars": 2954,
"preview": "mod kanji;\nmod names;\npub mod opensearch;\nmod request;\nmod words;\n\nuse actix_web::web::Json;\nuse jp_utils::JapaneseExt;\n"
},
{
"path": "lib/api/src/app/completions/names/mod.rs",
"chars": 2319,
"preview": "use super::{convert_results, Response};\nuse autocompletion::suggest::{\n extension::ngram::NGramExtension, query::Sugg"
},
{
"path": "lib/api/src/app/completions/opensearch/mod.rs",
"chars": 1617,
"preview": "mod parse;\n\nuse actix_web::web;\nuse serde::Deserialize;\nuse types::{api::app::completions::Request, jotoba::search::Sear"
},
{
"path": "lib/api/src/app/completions/opensearch/parse.rs",
"chars": 992,
"preview": "use search::query::{parser::QueryParser, Tag, UserSettings};\nuse types::jotoba::search::SearchTarget;\n\npub(crate) fn par"
},
{
"path": "lib/api/src/app/completions/request.rs",
"chars": 2422,
"preview": "use std::str::FromStr;\n\nuse error::api_error::RestError;\nuse jp_utils::JapaneseExt;\nuse search::query::{self, parser::Qu"
},
{
"path": "lib/api/src/app/completions/words/foreign.rs",
"chars": 5975,
"preview": "use autocompletion::suggest::{\n extension::{\n kanji_align::KanjiAlignExtension, ngram::NGramExtension,\n "
},
{
"path": "lib/api/src/app/completions/words/hashtag.rs",
"chars": 1304,
"preview": "use index_framework::traits::{backend::Backend, storage::IndexStorage};\nuse std::ops::Deref;\nuse types::{api::app::compl"
},
{
"path": "lib/api/src/app/completions/words/kana_end_ext.rs",
"chars": 3992,
"preview": "use autocompletion::{\n index::{\n japanese::{Item, JapaneseIndex},\n IndexItem,\n },\n relevance::{it"
},
{
"path": "lib/api/src/app/completions/words/mod.rs",
"chars": 2082,
"preview": "pub mod foreign;\npub mod hashtag;\npub mod kana_end_ext;\npub mod native;\n\nuse std::{cmp::Ordering, time::Instant};\n\nuse j"
},
{
"path": "lib/api/src/app/completions/words/native.rs",
"chars": 5226,
"preview": "use super::{super::*, kana_end_ext::KanaEndExtension};\nuse autocompletion::{\n index::{str_item::StringItem, IndexItem"
},
{
"path": "lib/api/src/app/details/mod.rs",
"chars": 33,
"preview": "pub mod sentences;\npub mod word;\n"
},
{
"path": "lib/api/src/app/details/sentences.rs",
"chars": 2712,
"preview": "use crate::app::{search::sentences::convert_sentence, Result};\nuse actix_web::web::{Data, Json};\nuse config::Config;\nuse"
},
{
"path": "lib/api/src/app/details/word.rs",
"chars": 3295,
"preview": "use crate::app::Result;\nuse actix_web::web::{Data, Json};\nuse config::Config;\nuse error::api_error::RestError;\nuse jp_ut"
},
{
"path": "lib/api/src/app/img/mod.rs",
"chars": 2923,
"preview": "#![allow(unused)]\n#[cfg(feature = \"img_scan\")]\npub mod request;\n\nuse actix_multipart::Multipart;\nuse actix_web::web::{se"
},
{
"path": "lib/api/src/app/img/request.rs",
"chars": 2660,
"preview": "use std::{\n convert::TryInto,\n fs::{create_dir, File},\n io::Write,\n path::{Path, PathBuf},\n};\n\nuse actix_mul"
},
{
"path": "lib/api/src/app/kanji/ids_tree/builder.rs",
"chars": 2051,
"preview": "use ids_parser::Origin;\nuse once_cell::sync::Lazy;\nuse std::collections::HashSet;\nuse types::api::app::kanji::ids_tree::"
},
{
"path": "lib/api/src/app/kanji/ids_tree/mod.rs",
"chars": 628,
"preview": "pub mod builder;\n\nuse actix_web::web::Json;\nuse builder::KanjiTreeBuilder;\nuse error::api_error::RestError;\nuse types::a"
},
{
"path": "lib/api/src/app/kanji/mod.rs",
"chars": 18,
"preview": "pub mod ids_tree;\n"
},
{
"path": "lib/api/src/app/mod.rs",
"chars": 2881,
"preview": "pub mod completions;\npub mod details;\npub mod img;\npub mod kanji;\npub mod news;\npub mod radical;\npub mod search;\n\nuse st"
},
{
"path": "lib/api/src/app/news/detailed.rs",
"chars": 432,
"preview": "use actix_web::web::Json;\nuse error::api_error;\nuse types::api::app::news::long::{Request, Response};\n\n/// Get detailed "
},
{
"path": "lib/api/src/app/news/mod.rs",
"chars": 420,
"preview": "pub mod detailed;\npub mod short;\n\nuse types::api::app::news::NewsEntry;\n\nfn ne_from_resource(src: &news::NewsEntry, shor"
},
{
"path": "lib/api/src/app/news/short.rs",
"chars": 449,
"preview": "use actix_web::web::Json;\nuse types::api::app::news::short::{Request, Response};\n\n/// Get short news endpoint\npub async "
},
{
"path": "lib/api/src/app/radical/kanji.rs",
"chars": 1964,
"preview": "use actix_web::web::Json;\nuse intmap::{int_set::IntSet, IntMap};\nuse std::{collections::HashMap, time::Instant};\nuse typ"
},
{
"path": "lib/api/src/app/radical/mod.rs",
"chars": 66,
"preview": "pub mod kanji;\npub mod search;\n\npub use kanji::kanji_by_radicals;\n"
},
{
"path": "lib/api/src/app/radical/search/jp_search.rs",
"chars": 2967,
"preview": "use jp_utils::JapaneseExt;\nuse search::radical::word::RomajiSearch;\nuse std::collections::{HashMap, HashSet};\nuse types:"
},
{
"path": "lib/api/src/app/radical/search/meaning.rs",
"chars": 657,
"preview": "use std::collections::HashSet;\n\nuse japanese::ToKanaExt;\nuse types::jotoba::language::Language;\n\npub fn search(query: &s"
},
{
"path": "lib/api/src/app/radical/search/mod.rs",
"chars": 2032,
"preview": "mod jp_search;\nmod meaning;\n\nuse std::{\n collections::{BTreeSet, HashMap, HashSet},\n str::FromStr,\n};\n\nuse actix_w"
},
{
"path": "lib/api/src/app/search/kanji.rs",
"chars": 2462,
"preview": "use super::new_page;\n\nuse super::convert_payload;\nuse crate::app::Result;\nuse actix_web::web::{self, Json};\nuse error::a"
},
{
"path": "lib/api/src/app/search/mod.rs",
"chars": 2085,
"preview": "pub mod kanji;\npub mod names;\npub mod sentences;\npub mod words;\n\nuse search::{\n query::UserSettings,\n query::{pars"
},
{
"path": "lib/api/src/app/search/names.rs",
"chars": 1063,
"preview": "use super::new_page;\n\nuse super::convert_payload;\nuse crate::app::Result;\nuse actix_web::web::{self, Json};\nuse error::a"
},
{
"path": "lib/api/src/app/search/sentences.rs",
"chars": 1419,
"preview": "use super::new_page;\n\nuse super::convert_payload;\nuse crate::app::Result;\nuse actix_web::web::{self, Json};\nuse error::a"
},
{
"path": "lib/api/src/app/search/words.rs",
"chars": 2332,
"preview": "use super::new_page;\n\nuse super::convert_payload;\nuse crate::app::Result;\nuse actix_web::web::Data;\nuse actix_web::web::"
},
{
"path": "lib/api/src/internal/info/mod.rs",
"chars": 15,
"preview": "pub mod words;\n"
},
{
"path": "lib/api/src/internal/info/words.rs",
"chars": 1244,
"preview": "use std::collections::HashSet;\n\nuse actix_web::{web::Json, HttpResponse};\nuse error::api_error::RestError;\nuse types::{\n"
},
{
"path": "lib/api/src/internal/mod.rs",
"chars": 14,
"preview": "pub mod info;\n"
},
{
"path": "lib/api/src/lib.rs",
"chars": 151,
"preview": "/// API endpoints for the webapp\npub mod app;\n\n/// API endpoints for internal communication\npub mod internal;\n\n/// Searc"
},
{
"path": "lib/api/src/search/kanji/mod.rs",
"chars": 808,
"preview": "use actix_web::web::{self, Data, Json};\nuse config::Config;\nuse types::{\n api::search::kanji::{Kanji, Response},\n "
},
{
"path": "lib/api/src/search/mod.rs",
"chars": 742,
"preview": "pub mod kanji;\npub mod name;\npub mod sentence;\npub mod word;\n\nuse actix_web::web::Json;\nuse error::api_error::RestError;"
},
{
"path": "lib/api/src/search/name/mod.rs",
"chars": 543,
"preview": "use actix_web::web::{self, Json};\nuse search::SearchExecutor;\nuse types::{api::search::name::Response, jotoba::search::S"
},
{
"path": "lib/api/src/search/sentence/mod.rs",
"chars": 1010,
"preview": "use actix_web::web::{self, Json};\nuse types::{\n api::search::sentence::{Response, Sentence},\n jotoba::search::Sear"
},
{
"path": "lib/api/src/search/word/mod.rs",
"chars": 946,
"preview": "use super::{Result, SearchRequest};\nuse actix_web::web::{self, Data, Json};\nuse config::Config;\nuse search::{word::Searc"
},
{
"path": "lib/config/Cargo.toml",
"chars": 338,
"preview": "[package]\nname = \"config\"\nversion = \"0.1.0\"\nauthors = [\"jojii <jojii@gmx.net>\"]\nedition = \"2021\"\n\n# See more keys and th"
},
{
"path": "lib/config/src/lib.rs",
"chars": 7760,
"preview": "use std::{\n fs::DirEntry,\n io::{BufReader, Read, Write},\n time::Duration,\n};\n\nuse serde::{Deserialize, Serializ"
},
{
"path": "lib/engine/Cargo.toml",
"chars": 715,
"preview": "[package]\nname = \"engine\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n# See more keys and their definitions at https://doc.rust-"
},
{
"path": "lib/engine/src/lib.rs",
"chars": 1557,
"preview": "pub mod pushable;\npub mod relevance;\npub mod result;\npub mod task;\npub mod utils;\n\nuse index_framework::{\n retrieve::"
},
{
"path": "lib/engine/src/pushable/counter.rs",
"chars": 538,
"preview": "use std::marker::PhantomData;\n\nuse super::Pushable;\n\n/// Counts all push calls without storing the items\npub struct Coun"
},
{
"path": "lib/engine/src/pushable/f_max_cnt.rs",
"chars": 1155,
"preview": "use super::Pushable;\nuse std::marker::PhantomData;\n\n/// A counter that Implements CancelPushable which counts up to a fi"
},
{
"path": "lib/engine/src/pushable/max_cnt.rs",
"chars": 921,
"preview": "use super::Pushable;\nuse std::marker::PhantomData;\n\n/// A counter that Implements CancelPushable which counts up to a fi"
},
{
"path": "lib/engine/src/pushable/mod.rs",
"chars": 661,
"preview": "pub mod counter;\npub mod f_max_cnt;\npub mod max_cnt;\npub mod push_dbg;\npub mod push_fn;\npub mod push_mod;\n\npub use count"
},
{
"path": "lib/engine/src/pushable/push_dbg.rs",
"chars": 691,
"preview": "use super::Pushable;\nuse std::{fmt::Debug, marker::PhantomData};\n\n/// Allows debugging pushed items\npub struct PushDbg<'"
},
{
"path": "lib/engine/src/pushable/push_fn.rs",
"chars": 440,
"preview": "use super::Pushable;\nuse std::marker::PhantomData;\n\npub struct PushFn<F, T> {\n f: F,\n p: PhantomData<T>,\n}\n\nimpl<F"
},
{
"path": "lib/engine/src/pushable/push_mod.rs",
"chars": 721,
"preview": "use std::marker::PhantomData;\n\nuse super::Pushable;\n\n/// Allows modifying pushed data\npub struct PushMod<'a, P, I, O, F>"
},
{
"path": "lib/engine/src/relevance/data.rs",
"chars": 1613,
"preview": "use sparse_vec::{SpVec32, VecExt};\nuse types::jotoba::language::Language;\n\n/// Item to sort stuff\n#[derive(Debug)]\npub s"
},
{
"path": "lib/engine/src/relevance/item.rs",
"chars": 1398,
"preview": "use std::{\n cmp::Ordering,\n hash::{Hash, Hasher},\n};\n\n/// A single item (result) in a set of search results\n#[deri"
},
{
"path": "lib/engine/src/relevance/mod.rs",
"chars": 607,
"preview": "pub mod data;\npub mod item;\n\nuse data::SortData;\nuse types::jotoba::language::Language;\n\npub trait RelevanceEngine {\n "
},
{
"path": "lib/engine/src/result.rs",
"chars": 2051,
"preview": "use super::relevance::item::RelItem;\nuse std::{fmt::Debug, slice::Iter};\n\n/// A result from a search. Contains informati"
},
{
"path": "lib/engine/src/task.rs",
"chars": 10194,
"preview": "use crate::{\n pushable::{MaxCounter, PushMod, Pushable},\n relevance::{data::SortData, RelevanceEngine},\n releva"
},
{
"path": "lib/engine/src/utils.rs",
"chars": 1279,
"preview": "use crate::relevance::item::RelItem;\nuse priority_container::StableUniquePrioContainerMax;\n\n/// Takes the correct \"limit"
},
{
"path": "lib/error/Cargo.toml",
"chars": 368,
"preview": "[package]\nname = \"error\"\nversion = \"0.1.0\"\nauthors = [\"jojii <jojii@gmx.net>\"]\nedition = \"2021\"\n\n# See more keys and the"
},
{
"path": "lib/error/src/api_error.rs",
"chars": 3389,
"preview": "#![allow(dead_code, unreachable_patterns)]\n\nuse actix_web::{error::BlockingError, http::StatusCode, HttpResponse, Respon"
},
{
"path": "lib/error/src/lib.rs",
"chars": 1197,
"preview": "#[cfg(feature = \"web_error\")]\npub mod api_error;\n\nuse std::{fmt::Display, num::ParseIntError, string::FromUtf8Error};\nus"
},
{
"path": "lib/frontend/Cargo.toml",
"chars": 918,
"preview": "[package]\nname = \"frontend\"\nversion = \"0.1.0\"\nauthors = [\"jojii <jojii@gmx.net>\"]\nedition = \"2021\"\nbuild = \"src/build.rs"
},
{
"path": "lib/frontend/src/about.rs",
"chars": 739,
"preview": "use std::sync::Arc;\n\n//use actix_session::Session;\nuse actix_web::{web, HttpRequest, HttpResponse};\nuse config::Config;\n"
},
{
"path": "lib/frontend/src/actix_ructe.rs",
"chars": 641,
"preview": "macro_rules! render {\n ($template:path) => (super::actix_ructe::Render(|o| $template(o)));\n ($template:path, $($ar"
},
{
"path": "lib/frontend/src/build.rs",
"chars": 138,
"preview": "use ructe::{Result, Ructe};\n\nfn main() -> Result<()> {\n let mut ructe = Ructe::from_env()?;\n ructe.compile_templat"
},
{
"path": "lib/frontend/src/direct.rs",
"chars": 5076,
"preview": "use std::sync::Arc;\n\nuse actix_web::{web, HttpRequest, HttpResponse};\nuse config::Config;\nuse localization::TranslationD"
},
{
"path": "lib/frontend/src/help_page.rs",
"chars": 741,
"preview": "use std::sync::Arc;\n\n//use actix_session::Session;\nuse actix_web::{web, HttpRequest, HttpResponse};\nuse config::Config;\n"
},
{
"path": "lib/frontend/src/index.rs",
"chars": 743,
"preview": "use std::sync::Arc;\n\n//use actix_session::Session;\nuse actix_web::{web, HttpRequest, HttpResponse};\nuse config::Config;\n"
},
{
"path": "lib/frontend/src/lib.rs",
"chars": 12461,
"preview": "include!(concat!(env!(\"OUT_DIR\"), \"/templates.rs\"));\n\n#[macro_use]\nmod actix_ructe;\n\npub mod about;\npub mod direct;\npub "
},
{
"path": "lib/frontend/src/liveness.rs",
"chars": 179,
"preview": "use actix_web::HttpResponse;\n\npub async fn ready() -> HttpResponse {\n HttpResponse::Ok().finish()\n}\n\npub async fn hea"
},
{
"path": "lib/frontend/src/news_ep.rs",
"chars": 816,
"preview": "use std::sync::Arc;\n\n//use actix_session::Session;\nuse actix_web::{web, HttpRequest, HttpResponse};\nuse config::Config;\n"
},
{
"path": "lib/frontend/src/og_tags.rs",
"chars": 3651,
"preview": "use crate::unescaped::UnescapedString;\nuse itertools::Itertools;\n\n/// Set of tags which can be rendered as HTML\n#[derive"
},
{
"path": "lib/frontend/src/search_ep.rs",
"chars": 6607,
"preview": "use super::user_settings;\nuse super::web_error;\nuse crate::{\n templates,\n url_query::{NoJSQueryStruct, QueryStruct"
},
{
"path": "lib/frontend/src/search_help.rs",
"chars": 1386,
"preview": "use types::jotoba::{\n language::Language as ResLanguage,\n search::{guess::Guess, QueryType},\n};\n\n/// Structure con"
},
{
"path": "lib/frontend/src/session.rs",
"chars": 661,
"preview": "/*\nuse actix_session::Session;\nuse search::query::UserSettings;\n\n// Initializes the session. Returns a session id if use"
},
{
"path": "lib/frontend/src/templ_utils.rs",
"chars": 3314,
"preview": "use itertools::Itertools;\nuse jp_utils::furi::{parse::FuriParser, segment::SegmentRef};\nuse localization::{traits::Trans"
},
{
"path": "lib/frontend/src/unescaped.rs",
"chars": 1955,
"preview": "use std::{\n fmt::Display,\n io::{self, Write},\n};\n\nuse crate::templates::ToHtml;\n\n/// Unescaped owned String\npub ty"
},
{
"path": "lib/frontend/src/url_query.rs",
"chars": 3155,
"preview": "use std::str::FromStr;\n\nuse search::{\n self,\n query::{parser::QueryParser, UserSettings},\n};\nuse serde::{Deseriali"
},
{
"path": "lib/frontend/src/user_settings.rs",
"chars": 1774,
"preview": "use std::str::FromStr;\n\nuse actix_web::HttpRequest;\nuse search::query::UserSettings;\nuse types::jotoba::language::Langua"
},
{
"path": "lib/frontend/src/web_error.rs",
"chars": 2424,
"preview": "use actix_web::{error::BlockingError, http::StatusCode, HttpResponse, ResponseError};\n\n#[cfg(not(feature = \"sentry_error"
},
{
"path": "lib/frontend/templates/base.rs.html",
"chars": 3420,
"preview": "@use super::subtemplates::{head_html, input_dropdown_html, main_body_html, footer_html};\r\n@use super::overlays::{page_ov"
},
{
"path": "lib/frontend/templates/base_index.rs.html",
"chars": 6199,
"preview": "@use super::subtemplates::{head_html, input_dropdown_html, footer_html};\n@use super::overlays::{page_overlays_html, sear"
},
{
"path": "lib/frontend/templates/error_page.rs.html",
"chars": 1608,
"preview": "@use crate::web_error::InfoText;\n@(status_code: u16, info: InfoText)\n\n<html lang=\"en\"></html>\n <title>Jotoba</title>\n"
},
{
"path": "lib/frontend/templates/functional/render_sentence.rs.html",
"chars": 1224,
"preview": "@use jp_utils::furi::segment::SegmentRef;\n@use jp_utils::furi::segment::AsSegment;\n@* TODO Figure out how to use Iterato"
},
{
"path": "lib/frontend/templates/overlays/info/collocations.rs.html",
"chars": 1002,
"preview": "@use crate::BaseData;\n@use types::jotoba::words::Word;\n@use crate::{templ_utils::*};\n\n@(data: &BaseData, word: &Word)\n\n<"
},
{
"path": "lib/frontend/templates/overlays/info/definitions_jp.rs.html",
"chars": 400,
"preview": "@use crate::BaseData;\n@use types::jotoba::words::Word;\n\n@(_data: &BaseData, word: &Word)\n\n<div class=\"modal fade\" id=\"jd"
},
{
"path": "lib/frontend/templates/overlays/info/inflections.rs.html",
"chars": 3023,
"preview": "@use crate::BaseData;\n@use types::jotoba::words::{Word, inflection::Inflections};\n\n@(data: &BaseData, word: &Word, infle"
},
{
"path": "lib/frontend/templates/overlays/mobile_overlays.rs.html",
"chars": 1143,
"preview": "@use crate::BaseData;\n@(_data: &BaseData)\n\n<div class=\"mobile-nav d-flex flex-column-reverse hidden\">\n <!-- Settings "
},
{
"path": "lib/frontend/templates/overlays/page/decomposition_graph.rs.html",
"chars": 288,
"preview": "@use crate::BaseData;\n@(_data: &BaseData)\n\n<div id=\"backdrop\" class=\"hidden\" onclick='onBackdropClick(event)'>\n <div "
},
{
"path": "lib/frontend/templates/overlays/page/image_crop.rs.html",
"chars": 808,
"preview": "@use crate::BaseData;\n@(data: &BaseData)\n\n<div class=\"modal fade\" id=\"imageCroppingModal\">\n <div class=\"modal-body cr"
},
{
"path": "lib/frontend/templates/overlays/page/loading.rs.html",
"chars": 118,
"preview": "@use crate::BaseData;\n@(_data: &BaseData)\n\n<div id=\"loading-screen\">\n <div class=\"loading-animation\"></div>\n</div> "
},
{
"path": "lib/frontend/templates/overlays/page/settings.rs.html",
"chars": 18046,
"preview": "@use crate::BaseData;\n@(data: &BaseData)\n\n<div class=\"modal fade\" id=\"settingsModal\">\n <div class=\"modal-dialog\">\n "
},
{
"path": "lib/frontend/templates/overlays/page_overlays.rs.html",
"chars": 175,
"preview": "@use super::page::{image_crop_html, loading_html, settings_html};\n\n@use crate::BaseData;\n@(data: &BaseData)\n\n@:image_cro"
},
{
"path": "lib/frontend/templates/overlays/search_overlays.rs.html",
"chars": 223,
"preview": "@use super::searchbar::{image_input_html, radicals_html, speech_html, suggestions_html};\n\n@use crate::BaseData;\n@(data: "
},
{
"path": "lib/frontend/templates/overlays/searchbar/image_input.rs.html",
"chars": 1037,
"preview": "@use crate::BaseData;\n@(data: &BaseData)\n\n<div class=\"overlay image hidden\">\n <span class=\"x-button noselect\" onclick"
},
{
"path": "lib/frontend/templates/overlays/searchbar/radicals.rs.html",
"chars": 2340,
"preview": "@use crate::BaseData;\n@(data: &BaseData)\n\n<div class=\"overlay radical noselect hidden\">\n <span class=\"x-button nosele"
},
{
"path": "lib/frontend/templates/overlays/searchbar/speech.rs.html",
"chars": 1805,
"preview": "@use crate::BaseData;\n@(data: &BaseData)\n\n<div class=\"overlay speech hidden\">\n <span class=\"x-button noselect\" onclic"
},
{
"path": "lib/frontend/templates/overlays/searchbar/suggestions.rs.html",
"chars": 167,
"preview": "@use crate::BaseData;\n@(_data: &BaseData)\n\n<div class=\"overlay suggestion noselect hidden\">\n <div id=\"suggestion-cont"
},
{
"path": "lib/frontend/templates/pages/about.rs.html",
"chars": 6511,
"preview": "@use crate::BaseData;\n@(data: &BaseData)\n\n<link rel=\"stylesheet\" type=\"text/css\" href=\"/variable_assets/@data.asset_hash"
},
{
"path": "lib/frontend/templates/pages/info.rs.html",
"chars": 7377,
"preview": "@use crate::BaseData;\n@(data: &BaseData)\n\n\n<link rel=\"stylesheet\" type=\"text/css\" href=\"/variable_assets/@data.asset_has"
},
{
"path": "lib/frontend/templates/pages/kanji.rs.html",
"chars": 11139,
"preview": "@use search::kanji::result::Item;\n@use crate::BaseData;\n@use super::search_help;\n@use crate::templ_utils::*;\n@use crate:"
},
{
"path": "lib/frontend/templates/pages/names.rs.html",
"chars": 1961,
"preview": "@use types::jotoba::names::Name;\n@use super::search_help;\n@use crate::templ_utils::get_types_humanized;\n@use crate::Base"
},
{
"path": "lib/frontend/templates/pages/news.rs.html",
"chars": 718,
"preview": "@use crate::BaseData;\n@use news::NewsEntry;\n@type News = Vec<NewsEntry>;\n@(data: &BaseData, news: News)\n\n<link rel=\"styl"
},
{
"path": "lib/frontend/templates/pages/search_help.rs.html",
"chars": 2588,
"preview": "@use crate::BaseData;\n@(data: &BaseData, title: &str)\n\n<link rel=\"stylesheet\" type=\"text/css\" href=\"/variable_assets/@da"
},
{
"path": "lib/frontend/templates/pages/sentences.rs.html",
"chars": 2443,
"preview": "@use search::sentence::result::{Sentence, ResData};\n@use search::executor::search_result::SearchResult;\n@use super::sear"
},
{
"path": "lib/frontend/templates/pages/words.rs.html",
"chars": 18822,
"preview": "@use search::word::result::{selected, AddResData};\n@use types::jotoba::words::Word;\n@use types::jotoba::language::Langua"
},
{
"path": "lib/frontend/templates/subtemplates/footer.rs.html",
"chars": 1421,
"preview": "@use super::{paginator};\n@use crate::BaseData;\n@use resources::GIT_HASH;\n@(data: &BaseData, show_ref: bool)\n\n<footer>\n\n "
},
{
"path": "lib/frontend/templates/subtemplates/head.rs.html",
"chars": 6769,
"preview": "@use crate::BaseData;\n@(data: &BaseData)\n\n<head>\n <!-- Meta Info -->\n <title>@data.gettext(\"Jotoba\")</title>\n <"
},
{
"path": "lib/frontend/templates/subtemplates/input_dropdown.rs.html",
"chars": 1502,
"preview": "@use crate::BaseData;\n@(data: &BaseData)\n\n<div class=\"index-btn-container\">\n <div class=\"input-field first-wrap\">\n "
},
{
"path": "lib/frontend/templates/subtemplates/main_body.rs.html",
"chars": 1343,
"preview": "@use crate::templates::pages::{words_html, kanji_html, names_html, sentences_html, about_html, info_html, news_html};\n\n@"
},
{
"path": "lib/frontend/templates/subtemplates/paginator.rs.html",
"chars": 1244,
"preview": "@use crate::BaseData;\n@(data: &BaseData)\n\n@if let Some(pagination) = data.pagination {\n <nav>\n <ul class=\"paginatio"
},
{
"path": "lib/indexes/Cargo.toml",
"chars": 1338,
"preview": "[package]\nname = \"indexes\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n# See more keys and their definitions at https://doc.rust"
},
{
"path": "lib/indexes/src/hashtag.rs",
"chars": 2312,
"preview": "use ngindex::{\n index_framework::retrieve::retriever::{ngram::NGramRetriever, Retriever},\n NgramIndex,\n};\nuse qp_t"
}
]
// ... and 235 more files (download for full content)
About this extraction
This page contains the full source code of the WeDontPanic/Jotoba GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 435 files (1.2 MB), approximately 367.9k tokens, and a symbol index with 2470 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.