From de89c130c60c610a8f3f58c83238754fa2ac0c56 Mon Sep 17 00:00:00 2001 From: Mathias Nater Date: Mon, 27 Apr 2015 16:53:21 +0200 Subject: [PATCH 01/86] Removes comments from bower.json --- bower.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bower.json b/bower.json index e6dcabd..5283527 100644 --- a/bower.json +++ b/bower.json @@ -1,5 +1,3 @@ -//use the following command to install Hyphenator.js: -//bower install git://github.com/mnater/Hyphenator { "name": "Hyphenator", "version": "5.0.0", @@ -8,4 +6,4 @@ "favicon.ico", "Hyphenator_observable.js" ] -} \ No newline at end of file +} From 15cfd3395b1f9aa50d4681188656ed3c55148686 Mon Sep 17 00:00:00 2001 From: Lars Moelleken Date: Wed, 24 Jun 2015 11:10:21 +0200 Subject: [PATCH 02/86] Update README.md --- README.md | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d410107..4bc548a 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,71 @@ This repository replaces https://code.google.com/p/hyphenator/ -Please see the projects page on http://mnater.github.io/Hyphenator/ for instructions and further reading. \ No newline at end of file +## Overview + +Hyphenator.js is a free open source Javascript library that automatically hyphenates text on websites. It comes in handy as a _polyfill_ for legacy browsers that don't support CSS 3 hyphation at all or for modern browsers that do hyphenation, but do not provide hyphenation dictionaries for a particular language. + +Hyphenator.js … + +* can be [included by the creator of the website](https://github.com/mnater/Hyphenator/blob/wiki/en_HowToUseHyphenator.md#using-hyphenator-on-your-website). +* can be used [as bookmarklet on any website](https://github.com/mnater/Hyphenator/blob/wiki/en_HowToUseHyphenator.md#using-hyphenator-as-a-bookmarklet). +* is [unobtrusive](http://en.wikipedia.org/wiki/Unobtrusive_JavaScript). +* steps behind CSS 3 hyphenation if supported ([how to use Hyphenator_Loader](https://github.com/mnater/Hyphenator/blob/wiki/en_HowToUseHyphenator.md#hyphenator_loaderjs)). +* runs on the client in order that the HTML source of the website may be served clean and svelte and that it can respond to text resizings by the user. +* is highly configurable and has a well [documented API](https://github.com/mnater/Hyphenator/blob/wiki/en_PublicAPI.md#public-api). +* relies on Franklin M. Liangs hyphenation algorithm ([PDF](http://www.tug.org/docs/liang/liang-thesis.pdf)) commonly known from LaTeX and OpenOffice. +* supports a [large set of different languages](https://github.com/mnater/Hyphenator/blob/wiki/en_AddNewLanguage.md#what-we-have-now). +* provides services for [customizing, merging and packing script and patterns](http://mnater.github.io/Hyphenator/mergeAndPack.html). +* also wraps URLs and Email-adresses. +* is free software licensed under [MIT License](http://mnater.github.io/Hyphenator/LICENSE.txt) (Version 5.0.0 and above). + +## Quick links + +* [Code](https://github.com/mnater/Hyphenator) +* [Download](https://github.com/mnater/Hyphenator/releases/latest) +* [Documentation](https://github.com/mnater/Hyphenator/blob/wiki/en_TableOfContents.md#table-of-contents) + +## Quick guide + +1. [Download](https://github.com/mnater/Hyphenator/releases/latest) the recent version of Hyphenator.js +2. Use [mergeAndPack.html](http://mnater.github.io/Hyphenator/mergeAndPack.html) to configure and minify Hyphenator.js and hyphenation patterns. +3. Prepare your .html documents (i.e. add `hyphenate`-classes, set `lang` and add Hyphenator.js) +4. Test it! + +Get [detailed instructions](https://github.com/mnater/Hyphenator/blob/wiki/en_HowToUseHyphenator.md#using-hyphenator-on-your-website). + +## The bad parts + +As with most things, there's a downside, too. Consider the following drawbacks before using Hyphenator.js: + +* Hyphenator.js and the hyphenation patterns are quite large. A good compression and caching is vital. +* Automatic hyphenation can not be perfect: it may lead to misleading hyphenation like leg-ends (depends on the pattern quality) +* There's no support for special (aka non-standard) hyphenation (e.g. omaatje->oma-tje) +* There's no way for Javascript to influence the algorithm for laying out text in the browser. Thus we can't control how many hyphens occur on subsequent lines nor can we know which words have actually to be hyphenated. Hyphenator.js just hyphenates all of them. + +## Philosophy + +### There is text and there is beautiful text + +This beauty becomes manifest in content and representation. I'm firmly convinced that all written text (well, most of it) deserves fine typography, that we deserve it. While hyphenation is just one of many tesserae that forms the appearance of text, it may be an important one. + +### There is code and there is sound code + +In code there is readability, maintainability, performance and genius – and some constraints of technology. As a hobbyist programmer I often feel like a hobbit surrounded by wizards who campaign for these values. But being an agile hobbit gives me the freedom to find my own way through the woods (thankfully free from evil in this area). I'm constantly in search of the most performant path to circumvent the constraints of technology while maintaining readability and maintainability of my code. Sometimes this path is illuminated by a wizard[1](#fn1). + +## Issues and Requests + +Each release is tested in various browsers with an [automated testsuite](./testsuite/). Nevertheless, there will always be bugs. Please don't hesitate to [submit them](https://github.com/mnater/Hyphenator/issues). + +If you have a special use case and Hyphenator.js doesn't provide a solution, feel free to [submit a feature request](https://github.com/mnater/Hyphenator/issues). + +And please, be patient. Hyphenator.js is a hobby of mine and sometimes other things have precedence… + +* * * + +(1) Some of my coding wizards are: + +* Franklin Mark Liang for his beautiful [hyphenation algorithm](http://www.tug.org/docs/liang/) +* [Douglas Crockford](http://www.crockford.com) for making Javascript a programming language +* Vyacheslav Egorov for his [deep insights to V8](http://mrale.ph/) +* Bram Stein for his [initiative on web typography](http://stateofwebtype.com) From 9746af33c88a8fddeed841b8413c89fa359eb5bc Mon Sep 17 00:00:00 2001 From: Lars Moelleken Date: Wed, 24 Jun 2015 11:14:25 +0200 Subject: [PATCH 03/86] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4bc548a..a61421a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Hyphenator.js -This repository replaces https://code.google.com/p/hyphenator/ +- This repository replaces https://code.google.com/p/hyphenator/ +- Demo: http://mnater.github.io/Hyphenator/ ## Overview From 36cd5db6eac9691b8530cb061ad8cde0d40f0e06 Mon Sep 17 00:00:00 2001 From: mnater Date: Wed, 24 Jun 2015 12:29:48 +0200 Subject: [PATCH 04/86] fix link --- mergeAndPack.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mergeAndPack.html b/mergeAndPack.html index 5bbe06f..9974707 100644 --- a/mergeAndPack.html +++ b/mergeAndPack.html @@ -930,7 +930,7 @@

mergeAndPack https://github.com/mnater/Hyphenator.js/blob/wiki/en_PublicAPI.md.

- Since this page uses XMLHttpRequests to load the script and pattern files, it will not work if you call it with the file:// protocol. Instead put it on your server or go to http://code.google.com/p/hyphenator/. + Since this page uses XMLHttpRequests to load the script and pattern files, it will not work if you call it with the file:// protocol. Instead put it on your server or go to http://mnater.github.io/Hyphenator/mergeAndPack.html.

The script loads the versions of Hyphenator.js (and Hyphenator_Loader.js and the patterns) that resides in the same directory like this page. From 8fb686ef8f3e8f1187d7771db7165bd987e5b4a7 Mon Sep 17 00:00:00 2001 From: mnater Date: Wed, 24 Jun 2015 12:33:07 +0200 Subject: [PATCH 05/86] update version number --- Hyphenator.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index d856e3a..b35c5ed 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -1,4 +1,4 @@ -/** @license Hyphenator 5.0.1(devel) - client side hyphenation for webbrowsers +/** @license Hyphenator 5.2.0(devel) - client side hyphenation for webbrowsers * Copyright (C) 2015 Mathias Nater, Zürich (mathiasnater at gmail dot com) * https://github.com/mnater/Hyphenator * @@ -19,7 +19,7 @@ * @global * @namespace Hyphenator * @author Mathias Nater, - * @version 5.0.1(devel) + * @version 5.2.0(devel) * @example * <script src = "Hyphenator.js" type = "text/javascript"></script> * <script type = "text/javascript"> @@ -2814,7 +2814,7 @@ var Hyphenator = (function (window) { * minor release: new languages, improvements * @access public */ - version: '5.0.0(devel)', + version: '5.2.0(devel)', /** * @member {boolean} Hyphenator.doHyphenation From 310908a80efd42333e5c1971352a2ae9744d3189 Mon Sep 17 00:00:00 2001 From: mnater Date: Wed, 24 Jun 2015 17:38:17 +0200 Subject: [PATCH 06/86] Load Hyphenator as soon as one lang isn't supported --- Hyphenator_Loader.js | 101 +++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 61 deletions(-) diff --git a/Hyphenator_Loader.js b/Hyphenator_Loader.js index 903af5d..1e50c82 100644 --- a/Hyphenator_Loader.js +++ b/Hyphenator_Loader.js @@ -43,6 +43,37 @@ var Hyphenator_Loader = (function (window) { return r; }, + /** + * @name Hyphenator-loadNrunHyphenator + * @description Loads Hyphenator.js and runs it with the given configuration + * @type {function({object})} + * @param {object} config the configuration object for Hyphenator.js + * @private + */ + loadNrunHyphenator = function (config) { + var head, script, done = false; + + head = window.document.getElementsByTagName('head').item(0); + script = createElem('script'); + script.src = path; + script.type = 'text/javascript'; + script.onload = script.onreadystatechange = function () { + if (!done && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) { + done = true; + + Hyphenator.config(config); + Hyphenator.run(); + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + if (head && script.parentNode) { + head.removeChild(script); + } + } + }; + head.appendChild(script); + }, + /** * @name Hyphenator-checkLangSupport * @description @@ -56,15 +87,8 @@ var Hyphenator_Loader = (function (window) { checkLangSupport = function () { var shadowContainer, shadow, - shadows = [], lang, - i, - r = true, - bdy = window.document.getElementsByTagName('body')[0], - fakeBdy = false; - if (!bdy) { fakeBdy = createElem('body'); - } shadowContainer = createElem('div'); shadowContainer.style.MozHyphens = 'auto'; shadowContainer.style['-webkit-hyphens'] = 'auto'; @@ -75,6 +99,9 @@ var Hyphenator_Loader = (function (window) { shadowContainer.style.wordWrap = 'normal'; shadowContainer.style.visibility = 'hidden'; + fakeBdy.appendChild(shadowContainer); + window.document.documentElement.appendChild(fakeBdy); + for (lang in languages) { if (languages.hasOwnProperty(lang)) { shadow = createElem('div'); @@ -83,62 +110,14 @@ var Hyphenator_Loader = (function (window) { shadow.style['-webkit-locale'] = "'" + lang + "'"; shadow.appendChild(window.document.createTextNode(languages[lang])); shadowContainer.appendChild(shadow); - shadows.push(shadow); - } - } - if (fakeBdy) { - fakeBdy.appendChild(shadowContainer); - window.document.documentElement.appendChild(fakeBdy); - } else { - bdy.appendChild(shadowContainer); - } - for (i = 0; i < shadows.length; i += 1) { - r = (shadows[i].offsetHeight > 12) && r; - } - if (fakeBdy) { - fakeBdy.parentNode.removeChild(fakeBdy); - } else { - bdy.removeChild(shadowContainer); - } - return r; - }, - - /** - * @name Hyphenator-loadNrunHyphenator - * @description Loads Hyphenator.js and runs it with the given configuration - * @type {function({object})} - * @param {object} config the configuration object for Hyphenator.js - * @private - */ - loadNrunHyphenator = function (config) { - var head, script, done = false; - - head = window.document.getElementsByTagName('head').item(0); - script = createElem('script'); - script.src = path; - script.type = 'text/javascript'; - script.onload = script.onreadystatechange = function () { - if (!done && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) { - done = true; - - Hyphenator.config(config); - Hyphenator.run(); - - // Handle memory leak in IE - script.onload = script.onreadystatechange = null; - if (head && script.parentNode) { - head.removeChild(script); + if (shadow.offsetHeight === 12) { + loadNrunHyphenator(config); + break; } } - }; - head.appendChild(script); - }, - - runner = function () { - var allLangsSupported = checkLangSupport(); - if (!allLangsSupported) { - loadNrunHyphenator(config); } + + fakeBdy.parentNode.removeChild(fakeBdy); }; return { @@ -153,7 +132,7 @@ var Hyphenator_Loader = (function (window) { languages = langs; path = p; config = configs || {}; - runner(); + checkLangSupport(); } }; }(window)); \ No newline at end of file From f0f1b5be631cccd91797ca62ec2ac19c27f0ffda Mon Sep 17 00:00:00 2001 From: mnater Date: Fri, 26 Jun 2015 13:07:08 +0200 Subject: [PATCH 07/86] Make vars private --- Hyphenator.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index b35c5ed..1a79d10 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -1664,6 +1664,9 @@ var Hyphenator = (function (window) { * @access private */ ValueStore = function (len) { + var startIndex = 1, + actualIndex = 2, + lastValueIndex = 2; this.keys = (function () { var i, r; if (Object.prototype.hasOwnProperty.call(window, "Uint8Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) @@ -1676,23 +1679,20 @@ var Hyphenator = (function (window) { } return r; }()); - this.startIndex = 1; - this.actualIndex = 2; - this.lastValueIndex = 2; this.add = function (p) { - this.keys[this.actualIndex] = p; - this.lastValueIndex = this.actualIndex; - this.actualIndex += 1; + this.keys[actualIndex] = p; + lastValueIndex = actualIndex; + actualIndex += 1; }; this.add0 = function () { //just do a step, since array is initialized with zeroes - this.actualIndex += 1; + actualIndex += 1; }; this.finalize = function () { - var start = this.startIndex; - this.keys[start] = this.lastValueIndex - start; - this.startIndex = this.lastValueIndex + 1; - this.actualIndex = this.lastValueIndex + 2; + var start = startIndex; + this.keys[start] = lastValueIndex - start; + startIndex = lastValueIndex + 1; + actualIndex = lastValueIndex + 2; return start; }; }, From 37427d1c6b3d49d47c8bd84f68fac125eff6c5e5 Mon Sep 17 00:00:00 2001 From: mnater Date: Sat, 25 Jul 2015 23:54:48 +0200 Subject: [PATCH 08/86] Fixes #226 --- Hyphenator.js | 4 ++-- testsuite/index.html | 3 ++- testsuite/test118.html | 2 +- testsuite/test119.html | 53 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 testsuite/test119.html diff --git a/Hyphenator.js b/Hyphenator.js index 1a79d10..e38e7e7 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -2182,7 +2182,7 @@ var Hyphenator = (function (window) { */ wwAsMappedCharCodeStore = (function () { if (Object.prototype.hasOwnProperty.call(window, "Int32Array")) { - return new window.Int32Array(32); + return new window.Int32Array(64); } return []; }()), @@ -2197,7 +2197,7 @@ var Hyphenator = (function (window) { wwhpStore = (function () { var r; if (Object.prototype.hasOwnProperty.call(window, "Uint8Array")) { - r = new window.Uint8Array(32); + r = new window.Uint8Array(64); } else { r = []; } diff --git a/testsuite/index.html b/testsuite/index.html index 70213a5..929128a 100644 --- a/testsuite/index.html +++ b/testsuite/index.html @@ -192,7 +192,8 @@

The Hyphenator Testsuite

{exec: true, path: 'test115.html'}, {exec: true, path: 'test116.html'}, {exec: true, path: 'test117.html'}, - {exec: true, path: 'test118.html'} + {exec: true, path: 'test118.html'}, + {exec: true, path: 'test119.html'} diff --git a/testsuite/test118.html b/testsuite/test118.html index 74ba58b..c242376 100644 --- a/testsuite/test118.html +++ b/testsuite/test118.html @@ -43,7 +43,7 @@ -

<<- index | <- Prev | Next ->

+

<<- index | <- Prev | Next ->

Test 118

Hyphenate words in french with rare caracters

diff --git a/testsuite/test119.html b/testsuite/test119.html new file mode 100644 index 0000000..a1a6600 --- /dev/null +++ b/testsuite/test119.html @@ -0,0 +1,53 @@ + + + + Hyphenator.js – Test 119 + + + + + + +

<<- index | <- Prev | Next ->

+

Test 119

+

Hyphenate p45.

+ +

pneumonoultramicroscopicsilicovolcanoconiosis

+

pneu·mo·noul·tra·mi·cro·scop·ic·sil·i·co·vol·canoco·nio·sis

+ + \ No newline at end of file From c58a4f470168c451ff34aa770468a1c7682bf772 Mon Sep 17 00:00:00 2001 From: mnater Date: Sun, 26 Jul 2015 00:02:26 +0200 Subject: [PATCH 09/86] Fix links --- testsuite/test119.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/test119.html b/testsuite/test119.html index a1a6600..23721c5 100644 --- a/testsuite/test119.html +++ b/testsuite/test119.html @@ -43,7 +43,7 @@ -

<<- index | <- Prev | Next ->

+

<<- index | <- Prev | Next ->

Test 119

Hyphenate p45.

From b2dfb9c424bb15433675a95f3e2ad91419d131ef Mon Sep 17 00:00:00 2001 From: mnater Date: Sun, 26 Jul 2015 00:05:34 +0200 Subject: [PATCH 10/86] Fix «» --- testsuite/test40.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/test40.html b/testsuite/test40.html index f6048d5..0dde132 100644 --- a/testsuite/test40.html +++ b/testsuite/test40.html @@ -48,6 +48,6 @@

Test 40

Using charset=ISO-8859-1 instead of utf8. IE fails here! (if Latin-1 has to be used replace all non ascii-chars in the pattern files with unicode escapes.)

Das englische Wort “Hyphenation” lsst sich nicht unbedingt wrtlich mit «Silbentrennung» bersetzen.

-

Das eng|li|sche Wort “Hy|phen|ation” lsst sich nicht un|be|dingt wrt|lich mit Sil|ben|tren|nung ber|set|zen.

+

Das eng|li|sche Wort “Hy|phen|ation” lsst sich nicht un|be|dingt wrt|lich mit «Sil|ben|tren|nung» ber|set|zen.

\ No newline at end of file From d9f8c774b3e2704a68284f2cff794b5791145ae9 Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 13 Aug 2015 13:37:50 +0200 Subject: [PATCH 11/86] Reset style on shadow. Fixes #231 The function measuring the text height in Hyphenator_Loader and Hyphenator.js can yield wrong results if some text-height-changing styles are defined for divs. These styles are now resetted for each measured div. --- Hyphenator.js | 3 +++ Hyphenator_Loader.js | 18 +++++++++--------- testsuite/test95.html | 8 ++++++++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index e38e7e7..568d2eb 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -403,10 +403,13 @@ var Hyphenator = (function (window) { shadow = createElem('div', window); shadow.id = 'Hyphenator_LanguageChecker'; shadow.style.width = '5em'; + shadow.style.padding = '0'; + shadow.style.border = 'none'; shadow.style[prefix] = 'auto'; shadow.style.hyphens = 'auto'; shadow.style.fontSize = '12px'; shadow.style.lineHeight = '12px'; + shadow.style.wordWrap = 'normal'; shadow.style.visibility = 'hidden'; shadow.lang = lang; shadow.style['-webkit-locale'] = "'" + lang + "'"; diff --git a/Hyphenator_Loader.js b/Hyphenator_Loader.js index 1e50c82..d7a5527 100644 --- a/Hyphenator_Loader.js +++ b/Hyphenator_Loader.js @@ -60,7 +60,6 @@ var Hyphenator_Loader = (function (window) { script.onload = script.onreadystatechange = function () { if (!done && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) { done = true; - Hyphenator.config(config); Hyphenator.run(); @@ -90,13 +89,6 @@ var Hyphenator_Loader = (function (window) { lang, fakeBdy = createElem('body'); shadowContainer = createElem('div'); - shadowContainer.style.MozHyphens = 'auto'; - shadowContainer.style['-webkit-hyphens'] = 'auto'; - shadowContainer.style['-ms-hyphens'] = 'auto'; - shadowContainer.style.hyphens = 'auto'; - shadowContainer.style.fontSize = '12px'; - shadowContainer.style.lineHeight = '12px'; - shadowContainer.style.wordWrap = 'normal'; shadowContainer.style.visibility = 'hidden'; fakeBdy.appendChild(shadowContainer); @@ -105,9 +97,17 @@ var Hyphenator_Loader = (function (window) { for (lang in languages) { if (languages.hasOwnProperty(lang)) { shadow = createElem('div'); + shadow.style.MozHyphens = 'auto'; + shadow.style['-webkit-hyphens'] = 'auto'; + shadow.style['-ms-hyphens'] = 'auto'; + shadow.style.hyphens = 'auto'; shadow.style.width = '5em'; - shadow.lang = lang; + shadow.style.lineHeight = '12px'; + shadow.style.border = 'none'; + shadow.style.padding = '0'; + shadow.style.wordWrap = 'normal'; shadow.style['-webkit-locale'] = "'" + lang + "'"; + shadow.lang = lang; shadow.appendChild(window.document.createTextNode(languages[lang])); shadowContainer.appendChild(shadow); if (shadow.offsetHeight === 12) { diff --git a/testsuite/test95.html b/testsuite/test95.html index ca0eb5c..2f95494 100644 --- a/testsuite/test95.html +++ b/testsuite/test95.html @@ -10,6 +10,14 @@ margin-left:25%; margin-right:25%; } + div { + line-height: 100px; + border: 10px solid red; + padding: 100px; + font-size: 100px; + word-wrap: break-word; + -webkit-hyphens: none; + } #test1, #test2 { background-color: #ffd6d6; } From fea169418fc928d25d13e337f2ff4f7a926cb841 Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 3 Sep 2015 22:47:59 +0200 Subject: [PATCH 12/86] =?UTF-8?q?add=20=C3=A6=20to=20french=20specialChars?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- testsuite/test118.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testsuite/test118.html b/testsuite/test118.html index c242376..b6b5bf4 100644 --- a/testsuite/test118.html +++ b/testsuite/test118.html @@ -45,9 +45,9 @@

<<- index | <- Prev | Next ->

Test 118

-

Hyphenate words in french with rare caracters

+

Hyphenate words in french with rare caracters (check)

-

noël vurës aiguë ambiguë béguë besaiguë ciguë suraiguë capharnaüm Emmaüs vergeüre Vogüé

-

noël vurës aiguë ambi|guë béguë besai|guë ciguë sur|ai|guë caphar|naüm Emmaüs ver|geüre Vogüé

+

noël vurës aiguë ambiguë béguë besaiguë ciguë suraiguë capharnaüm Emmaüs vergeüre Vogüé supernovæ

+

noël vurës aiguë ambi|guë béguë besai|guë ciguë sur|ai|guë caphar|naüm Emmaüs ver|geüre Vogüé super|novæ

\ No newline at end of file From 5b1425af31240825747de747a2cc116cc63346d3 Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 3 Sep 2015 22:52:17 +0200 Subject: [PATCH 13/86] fix links --- patterns/fr.js | 2 +- testsuite/test115.html | 2 +- testsuite/test117.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/patterns/fr.js b/patterns/fr.js index 4845933..49a7f59 100644 --- a/patterns/fr.js +++ b/patterns/fr.js @@ -4,7 +4,7 @@ Hyphenator.languages['fr'] = { leftmin: 3, rightmin: 3, - specialChars: "àâçèéêëîïôûüœ’'", + specialChars: "àâçèéêëîïôûüœæ’'", patterns: { 2: "1ç1j1q", 3: "1gè’â41zu1zo1zi1zè1zé1ze1za’y4_y41wu1wo1wi1we1wa1vy1vû1vu1vô1vo1vî1vi1vê1vè1vé1ve1vâ1va’û4_û4’u4_u41ba1bâ1ty1be1bé1bè1bê1tû1tu1tô1bi1bî1to1tî1ti1tê1tè1té1te1tà1tâ1ta1bo1bô1sy1sû1su1sœ1bu1bû1by2’21ca1câ1sô1ce1cé1cè1cê1so1sî1si1sê1sè1sé1se1sâ1sa1ry1rû1ru1rô1ro1rî1ri1rê1rè1ré1re1râ1ra’a41py1pû1pu1pô1po1pî1pi1pê1pè1pé1pe1pâ1pa_ô41ci1cî’ô4’o4_o41nyn1x1nû1nu1nœ1nô1no1nî1ni1nê1nè1né1ne1nâ1co1cô1na1my1mû1mu1mœ1mô1mo1mî1mi1cœ1mê1mè1mé1me1mâ1ma1ly1lû1lu1lô1lo1lî1li1lê1lè1cu1cû1cy1lé1d’1da1dâ1le1là1de1dé1dè1dê1lâ1la1ky1kû1ku1kô1ko1kî1ki1kê1kè1ké1ke1kâ1ka2jk_a4’î4_î4’i4_i41hy1hû1hu1hô1ho1hî1hi1hê1hè1hé1he1hâ1ha1gy1gû1gu1gô1go1gî1gi1gê_â41gé1ge1gâ1ga1fy1di1dî1fû1fu1fô1fo’e41fî1fi1fê1fè1do1dô1fé1fe1fâ1fa’è41du1dû1dy_è4’é4_é4’ê4_ê4_e41zy", diff --git a/testsuite/test115.html b/testsuite/test115.html index 87d0c17..2097014 100644 --- a/testsuite/test115.html +++ b/testsuite/test115.html @@ -57,7 +57,7 @@ -

<<- index | <- Prev | Next ->

+

<<- index | <- Prev | Next ->

Test 115

Use Hyphenator_Loader.js, while word-wrap is set to break-word.

diff --git a/testsuite/test117.html b/testsuite/test117.html index a7b3d59..7d9e73d 100644 --- a/testsuite/test117.html +++ b/testsuite/test117.html @@ -43,7 +43,7 @@ -

<<- index | <- Prev | Next ->

+

<<- index | <- Prev | Next ->

Test 117

Check hyphenation on compound characters (ñ). Fails if String().normalize not supported.

From 6e929b4a22fa0e1d80d849e4c26145d39e4c3d39 Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 14 Sep 2015 10:16:39 +0200 Subject: [PATCH 14/86] fix links --- testsuite/test85.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/test85.html b/testsuite/test85.html index e99f672..d8f1203 100644 --- a/testsuite/test85.html +++ b/testsuite/test85.html @@ -43,7 +43,7 @@ -

<<- index | <- Prev | Next ->

+

<<- index | <- Prev | Next ->

Test 85

Hyphenate and display text as soon as pattern is available. Don't wait for other patterns to be loaded

From 2dcd8c413867ac477257da7e64501ed991c969dd Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 24 Sep 2015 16:55:10 +0200 Subject: [PATCH 15/86] Sort patterns upon creation to gain better performance --- compressor.html | 90 ++++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 34 deletions(-) diff --git a/compressor.html b/compressor.html index d7341b6..918fd2a 100644 --- a/compressor.html +++ b/compressor.html @@ -86,13 +86,15 @@ @@ -399,7 +421,7 @@

Compressor for

- + <
From f9eae9d67d0b6503f46c29bf0ce942b582a4a44d Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 24 Sep 2015 16:59:54 +0200 Subject: [PATCH 16/86] remove < --- compressor.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compressor.html b/compressor.html index 918fd2a..ac9a41d 100644 --- a/compressor.html +++ b/compressor.html @@ -421,7 +421,7 @@

Compressor for

- < +

From 21d5a9d23f3eb724046f4837784ea47384969a82 Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 24 Sep 2015 17:01:16 +0200 Subject: [PATCH 17/86] remove < --- compressor.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compressor.html b/compressor.html index 918fd2a..ac9a41d 100644 --- a/compressor.html +++ b/compressor.html @@ -421,7 +421,7 @@

Compressor for

- < +

From 362a4012ce255dbaeb8c786a8c40d032375977d5 Mon Sep 17 00:00:00 2001 From: Mathias Nater Date: Fri, 9 Oct 2015 22:18:46 +0200 Subject: [PATCH 18/86] remove unnecessary code --- compressor.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/compressor.html b/compressor.html index ac9a41d..dcd7659 100644 --- a/compressor.html +++ b/compressor.html @@ -159,9 +159,6 @@ i; for (i = 0; i < patterns.length; i += 1) { chr = patterns.charAt(i); - if (chr === ".") { - chr = "_"; - } if (!chr.match(/\d/) && chr !== " " && !collected.hasOwnProperty(chr)) { collected[chr] = true; } From 8a19fe4c2cab031b1fee7c1fb0afa1d8997c7fee Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 19 Oct 2015 11:15:19 +0200 Subject: [PATCH 19/86] Add tests 120 and 121 --- testsuite/index.html | 7 ++-- testsuite/test120.html | 86 ++++++++++++++++++++++++++++++++++++++++++ testsuite/test121.html | 57 ++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 testsuite/test120.html create mode 100644 testsuite/test121.html diff --git a/testsuite/index.html b/testsuite/index.html index 929128a..25f2181 100644 --- a/testsuite/index.html +++ b/testsuite/index.html @@ -193,10 +193,9 @@

The Hyphenator Testsuite

{exec: true, path: 'test116.html'}, {exec: true, path: 'test117.html'}, {exec: true, path: 'test118.html'}, - {exec: true, path: 'test119.html'} - - - + {exec: true, path: 'test119.html'}, + {exec: true, path: 'test120.html'}, + {exec: true, path: 'test121.html'} ], testframe = document.getElementById('testframe'), currentTest = 1, total = 'passed'; diff --git a/testsuite/test120.html b/testsuite/test120.html new file mode 100644 index 0000000..cd04cb2 --- /dev/null +++ b/testsuite/test120.html @@ -0,0 +1,86 @@ + + + + Hyphenator.js – Test 120 + + + + + + +

<<- index | <- Prev | Next ->

+

Test 120

+

Use multiple class names

+ +

Class "text"

+

Hyphenation

+

Hy|phen|ation

+ +

Class "content"

+

Hyphenation

+

Hy|phen|ation

+ +

Class "blocktext"

+

Hyphenation

+

Hy|phen|ation

+ +

Nested classes

+

Hyphenation Example

+

Hy|phen|ation Ex|am|ple

+ + \ No newline at end of file diff --git a/testsuite/test121.html b/testsuite/test121.html new file mode 100644 index 0000000..060271a --- /dev/null +++ b/testsuite/test121.html @@ -0,0 +1,57 @@ + + + + + Test 121 + + + + + + +

<<- index | <- Prev | Next ->

+

Test 121

+

Check issue with ligatures in OpenType-Fonts (issue #239)

+ +
+

Hyphenator.js and ligatures in OpenType-Font enabled:

+

ff – ligature sometimes corrupts hyphenation

+

ft – ligature sometimes corrupts hyphenation

+
+
+

Hyphenator.js and ligatures in OpenType-Font disabled:

+

ff – ligature sometimes corrupts hyphenation

+

ft – ligature sometimes corrupts hyphenation

+
+ + + \ No newline at end of file From 86bbd5283472f849f9b15db791750bfdeacbbec6 Mon Sep 17 00:00:00 2001 From: Sam Umbach Date: Sat, 14 Nov 2015 16:32:08 -0500 Subject: [PATCH 20/86] Minor improvements to README --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a61421a..a459e13 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## Overview -Hyphenator.js is a free open source Javascript library that automatically hyphenates text on websites. It comes in handy as a _polyfill_ for legacy browsers that don't support CSS 3 hyphation at all or for modern browsers that do hyphenation, but do not provide hyphenation dictionaries for a particular language. +Hyphenator.js is a free open source Javascript library that automatically hyphenates text on websites. It comes in handy as a _polyfill_ for legacy browsers that don't support CSS 3 hyphenation at all or for modern browsers that do hyphenation, but do not provide hyphenation dictionaries for a particular language. Hyphenator.js … @@ -14,11 +14,11 @@ Hyphenator.js … * is [unobtrusive](http://en.wikipedia.org/wiki/Unobtrusive_JavaScript). * steps behind CSS 3 hyphenation if supported ([how to use Hyphenator_Loader](https://github.com/mnater/Hyphenator/blob/wiki/en_HowToUseHyphenator.md#hyphenator_loaderjs)). * runs on the client in order that the HTML source of the website may be served clean and svelte and that it can respond to text resizings by the user. -* is highly configurable and has a well [documented API](https://github.com/mnater/Hyphenator/blob/wiki/en_PublicAPI.md#public-api). +* is highly configurable and has a [well-documented API](https://github.com/mnater/Hyphenator/blob/wiki/en_PublicAPI.md#public-api). * relies on Franklin M. Liangs hyphenation algorithm ([PDF](http://www.tug.org/docs/liang/liang-thesis.pdf)) commonly known from LaTeX and OpenOffice. * supports a [large set of different languages](https://github.com/mnater/Hyphenator/blob/wiki/en_AddNewLanguage.md#what-we-have-now). * provides services for [customizing, merging and packing script and patterns](http://mnater.github.io/Hyphenator/mergeAndPack.html). -* also wraps URLs and Email-adresses. +* also wraps URLs and Email adresses. * is free software licensed under [MIT License](http://mnater.github.io/Hyphenator/LICENSE.txt) (Version 5.0.0 and above). ## Quick links @@ -40,10 +40,10 @@ Get [detailed instructions](https://github.com/mnater/Hyphenator/blob/wiki/en_Ho As with most things, there's a downside, too. Consider the following drawbacks before using Hyphenator.js: -* Hyphenator.js and the hyphenation patterns are quite large. A good compression and caching is vital. +* Hyphenator.js and the hyphenation patterns are quite large. Good compression and caching is vital. * Automatic hyphenation can not be perfect: it may lead to misleading hyphenation like leg-ends (depends on the pattern quality) * There's no support for special (aka non-standard) hyphenation (e.g. omaatje->oma-tje) -* There's no way for Javascript to influence the algorithm for laying out text in the browser. Thus we can't control how many hyphens occur on subsequent lines nor can we know which words have actually to be hyphenated. Hyphenator.js just hyphenates all of them. +* There's no way for Javascript to influence the algorithm for laying out text in the browser. Thus we can't control how many hyphens occur on subsequent lines nor can we know which words have actually been hyphenated. Hyphenator.js just hyphenates all of them. ## Philosophy From 79ee045701505d99c041f6c705aa6cbfbaea899d Mon Sep 17 00:00:00 2001 From: mnater Date: Sun, 15 Nov 2015 19:58:16 +0100 Subject: [PATCH 21/86] Fix test121.html --- testsuite/test121.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testsuite/test121.html b/testsuite/test121.html index 060271a..89b05c5 100644 --- a/testsuite/test121.html +++ b/testsuite/test121.html @@ -43,12 +43,12 @@

Test 121

Check issue with ligatures in OpenType-Fonts (issue #239)

-

Hyphenator.js and ligatures in OpenType-Font enabled:

+

Hyphenator.js and ligatures in OpenType-Font enabled: issues

ff – ligature sometimes corrupts hyphenation

ft – ligature sometimes corrupts hyphenation

-

Hyphenator.js and ligatures in OpenType-Font disabled:

+

Hyphenator.js and ligatures in OpenType-Font disabled: no issues

ff – ligature sometimes corrupts hyphenation

ft – ligature sometimes corrupts hyphenation

From 05759e8674f30935bab4114b5f4719baf2d7de23 Mon Sep 17 00:00:00 2001 From: faiwer Date: Tue, 24 Nov 2015 15:41:44 +0600 Subject: [PATCH 22/86] Fix doCharSubst https://github.com/mnater/Hyphenator/issues/246 --- Hyphenator.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index 568d2eb..d62937b 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -2167,10 +2167,10 @@ var Hyphenator = (function (window) { * @access private */ doCharSubst = function (loCharSubst, w) { - var subst, r; + var subst, r = w; for (subst in loCharSubst) { if (loCharSubst.hasOwnProperty(subst)) { - r = w.replace(new RegExp(subst, 'g'), loCharSubst[subst]); + r = r.replace(new RegExp(subst, 'g'), loCharSubst[subst]); } } return r; @@ -3280,4 +3280,4 @@ if (Hyphenator.isBookmarklet()) { Hyphenator.config({displaytogglebox: true, intermediatestate: 'visible', storagetype: 'local', doframes: true, useCSS3hyphenation: true}); Hyphenator.config(Hyphenator.getConfigFromURI()); Hyphenator.run(); -} \ No newline at end of file +} From d56f41d2f1f228bee332c398fbc04e6cee51765f Mon Sep 17 00:00:00 2001 From: mnater Date: Wed, 25 Nov 2015 22:34:06 +0100 Subject: [PATCH 23/86] Update JSLint --- testsuite/files/jslint.js | 7666 +++++++++++++++++++------------------ testsuite/test16.html | 44 +- 2 files changed, 3950 insertions(+), 3760 deletions(-) diff --git a/testsuite/files/jslint.js b/testsuite/files/jslint.js index 193ec5c..5ad98b7 100755 --- a/testsuite/files/jslint.js +++ b/testsuite/files/jslint.js @@ -1,7 +1,6 @@ // jslint.js -// 2014-07-08 - -// Copyright (c) 2002 Douglas Crockford (www.JSLint.com) +// 2015-11-16 +// Copyright (c) 2015 Douglas Crockford (www.JSLint.com) // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -23,4266 +22,4479 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +// jslint is a function that takes 3 arguments: + +// source A text to analyze, a string or an array of strings. +// option_object An object whose keys correspond to option names. +// global_array An array of strings containing global variables that +// the file is allowed readonly access. + +// jslint returns an object containing its results. The object contains a lot +// of valuable information. It can be used to generate reports. The object +// contains: + +// edition: the version of JSLint that did the analysis. +// functions: an array of objects that represent all of the functions +// declared in the file. +// global: an object representing the global object. Its .context property +// is an object containing a property for each global variable. +// id: "(JSLint)" +// imports: an array of strings representing each of the imports. +// json: true if the file is a JSON text. +// lines: an array of strings, the source. +// module: true if an import or export statement was used. +// ok: true if no warnings were generated. This is what you want. +// option: the option argument. +// property: a property object. +// stop: true if JSLint was unable to finish. You don't want this. +// tokens: an array of objects representing the tokens in the file. +// tree: the token objects arranged in a tree. +// warnings: an array of warning objects. A warning object can contain: +// name: 'JSLintError' +// column: A column number in the file. +// line: A line number in the file. +// code: A warning code string. +// message: The warning message string. +// a: Exhibit A. +// b: Exhibit B. +// c: Exhibit C. +// d: Exhibit D. + +// jslint works in several phases. In any of these phases, errors might be +// found. Sometimes JSLint is able to recover from an error and continue +// parsing. In some cases, it cannot and will stop early. If that should happen, +// repair your code and try again. + +// Phases: + +// 1. If the source is a single string, split it into an array of strings. +// 2. Turn the source into an array of tokens. +// 3. Furcate the tokens into a parse tree. +// 4. Walk the tree, traversing all of the nodes of the tree. It is a +// recursive traversal. Each node may be processed on the way down +// (preaction) and on the way up (postaction). +// 5. Check the whitespace between the tokens. + +// jslint can also examine JSON text. It decides that a file is JSON text if +// the first token is '[' or '{'. Processing of JSON text is much simpler than +// the processing of JavaScript programs. Only the first three phases are +// required. + // WARNING: JSLint will hurt your feelings. -// JSLINT is a global function. It takes two parameters. - -// var myResult = JSLINT(source, option); - -// The first parameter is either a string or an array of strings. If it is a -// string, it will be split on '\n' or '\r'. If it is an array of strings, it -// is assumed that each string represents one line. The source can be a -// JavaScript text or a JSON text. - -// The second parameter is an optional object of options that control the -// operation of JSLINT. Most of the options are booleans: They are all -// optional and have a default value of false. One of the options, predef, -// can be an array of names, which will be used to declare global variables, -// or an object whose keys are used as global names, with a boolean value -// that determines if they are assignable. - -// If it checks out, JSLINT returns true. Otherwise, it returns false. - -// If false, you can inspect JSLINT.errors to find out the problems. -// JSLINT.errors is an array of objects containing these properties: - -// { -// line : The line (relative to 0) at which the lint was found -// character : The character (relative to 0) at which the lint was found -// reason : The problem -// evidence : The text line in which the problem occurred -// raw : The raw message before the details were inserted -// a : The first detail -// b : The second detail -// c : The third detail -// d : The fourth detail -// } - -// If a stopping error was found, a null will be the last element of the -// JSLINT.errors array. A stopping error means that JSLint was not confident -// enough to continue. It does not necessarily mean that the error was -// especially heinous. - -// You can request a data structure that contains JSLint's results. - -// var myData = JSLINT.data(); - -// It returns a structure with this form: - -// { -// errors: [ -// { -// line: NUMBER, -// character: NUMBER, -// reason: STRING, -// evidence: STRING -// } -// ], -// functions: [ -// { -// name: STRING, -// line: NUMBER, -// level: NUMBER, -// parameter: [ -// STRING -// ], -// var: [ -// STRING -// ], -// exception: [ -// STRING -// ], -// closure: [ -// STRING -// ], -// outer: [ -// STRING -// ], -// global: [ -// STRING -// ], -// label: [ -// STRING -// ] -// } -// ], -// global: [ -// STRING -// ], -// member: { -// STRING: NUMBER -// }, -// json: BOOLEAN -// } - -// You can request a Function Report, which shows all of the functions -// and the parameters and vars that they use. This can be used to find -// implied global variables and other problems. The report is in HTML and -// can be inserted into an HTML . It should be given the result of the -// JSLINT.data function. - -// var myReport = JSLINT.report(data); - -// You can request an HTML error report. - -// var myErrorReport = JSLINT.error_report(data); - -// You can obtain an object containing all of the properties found in the -// file. JSLINT.property contains an object containing a key for each -// property used in the program, the value being the number of times that -// property name was used in the file. - -// You can request a properties report, which produces a list of the program's -// properties in the form of a /*properties*/ declaration. - -// var myPropertyReport = JSLINT.properties_report(JSLINT.property); - -// You can obtain the parse tree that JSLint constructed while parsing. The -// latest tree is kept in JSLINT.tree. A nice stringification can be produced -// with - -// JSON.stringify(JSLINT.tree, [ -// 'string', 'arity', 'name', 'first', -// 'second', 'third', 'block', 'else' -// ], 4)); - -// You can request a context coloring table. It contains information that can be -// applied to the file that was analyzed. Context coloring colors functions -// based on their nesting level, and variables on the color of the functions -// in which they are defined. - -// var myColorization = JSLINT.color(data); - -// It returns an array containing objects of this form: - -// { -// from: COLUMN, -// thru: COLUMN, -// line: ROW, -// level: 0 or higher -// } - -// JSLint provides three inline directives. They look like slashstar comments, -// and allow for setting options, declaring global variables, and establishing a -// set of allowed property names. - -// These directives respect function scope. - -// The jslint directive is a special comment that can set one or more options. -// For example: - -/*jslint - evil: true, nomen: true, regexp: true, todo: true +/*property + a, and, arity, b, bad_assignment_a, bad_character_number_a, + bad_directive_a, bad_get, bad_module_name_a, bad_option_a, bad_property_a, + bad_set, bitwise, block, body, browser, c, calls, catch, charAt, + charCodeAt, closer, closure, code, column, concat, constant, context, + couch, create, d, dead, devel, directive, disrupt, dot, duplicate_a, + edition, ellipsis, else, empty_block, es6, eval, every, expected_a_at_b_c, + expected_a_b, expected_a_b_from_c_d, expected_a_before_b, + expected_digits_after_a, expected_four_digits, expected_identifier_a, + expected_line_break_a_b, expected_regexp_factor_a, expected_space_a_b, + expected_statements_a, expected_string_a, expected_type_string_a, + expression, extra, flag, for, forEach, free, from, fud, fudge, function, + function_in_loop, functions, g, global, i, id, identifier, import, imports, + inc, indexOf, infix_in, init, initial, isArray, isNaN, join, json, keys, + label, label_a, lbp, led, length, level, line, lines, live, loop, m, + margin, match, maxerr, maxlen, message, misplaced_a, misplaced_directive_a, + module, naked_block, name, names, nested_comment, new, node, not_label_a, + nud, ok, open, option, out_of_scope_a, parameters, pop, property, push, + qmark, quote, redefinition_a_b, replace, reserved_a, role, search, + signature, slash_equal, slice, some, sort, split, statement, stop, strict, + subscript_a, switch, test, this, thru, toString, todo_comment, tokens, + too_long, too_many, tree, type, u, unclosed_comment, unclosed_mega, + unclosed_string, undeclared_a, unexpected_a, unexpected_a_after_b, + unexpected_at_top_level_a, unexpected_char_a, unexpected_comment, + unexpected_directive_a, unexpected_expression_a, unexpected_label_a, + unexpected_parens, unexpected_space_a_b, + unexpected_statement_a, unexpected_trailing_space, unexpected_typeof_a, + uninitialized_a, unreachable_a, unregistered_property_a, unsafe, unused_a, + use_spaces, used, value, var_loop, var_switch, variable, warning, warnings, + weird_condition_a, weird_expression_a, weird_loop, weird_relation_a, white, + wrap_assignment, wrap_condition, wrap_immediate, wrap_regexp, wrap_unary, + wrapped, writable, y */ -// The current option set is - -// ass true, if assignment expressions should be allowed -// bitwise true, if bitwise operators should be allowed -// browser true, if the standard browser globals should be predefined -// closure true, if Google Closure idioms should be tolerated -// continue true, if the continuation statement should be tolerated -// debug true, if debugger statements should be allowed -// devel true, if logging should be allowed (console, alert, etc.) -// eqeq true, if == should be allowed -// evil true, if eval should be allowed -// forin true, if for in statements need not filter -// indent the indentation factor -// maxerr the maximum number of errors to allow -// maxlen the maximum length of a source line -// newcap true, if constructor names capitalization is ignored -// node true, if Node.js globals should be predefined -// nomen true, if names may have dangling _ -// passfail true, if the scan should stop on first error -// plusplus true, if increment/decrement should be allowed -// properties true, if all property names must be declared with /*properties*/ -// regexp true, if the . should be allowed in regexp literals -// rhino true, if the Rhino environment globals should be predefined -// unparam true, if unused parameters should be tolerated -// sloppy true, if the 'use strict'; pragma is optional -// stupid true, if really stupid practices are tolerated -// sub true, if all forms of subscript notation are tolerated -// todo true, if TODO comments are tolerated -// vars true, if multiple var statements per function should be allowed -// white true, if sloppy whitespace is tolerated - -// The properties directive declares an exclusive list of property names. -// Any properties named in the program that are not in the list will -// produce a warning. - -// For example: - -/*properties - '\b', '\t', '\n', '\f', '\r', '!', '!=', '!==', '"', '%', '\'', '(begin)', - '(error)', '*', '+', '-', '/', '<', '<=', '==', '===', '>', '>=', '\\', a, - a_label, a_scope, already_defined, and, apply, arguments, arity, ass, - assign, assignment_expression, assignment_function_expression, at, avoid_a, - b, bad_assignment, bad_constructor, bad_in_a, bad_invocation, bad_new, - bad_number, bad_operand, bad_wrap, bitwise, block, break, breakage, browser, - c, call, charAt, charCodeAt, character, closure, code, color, combine_var, - comments, conditional_assignment, confusing_a, confusing_regexp, - constructor_name_a, continue, control_a, couch, create, d, dangling_a, data, - dead, debug, deleted, devel, disrupt, duplicate_a, edge, edition, elif, - else, empty_block, empty_case, empty_class, entityify, eqeq, error_report, - errors, evidence, evil, exception, exec, expected_a_at_b_c, expected_a_b, - expected_a_b_from_c_d, expected_id_a, expected_identifier_a, - expected_identifier_a_reserved, expected_number_a, expected_operator_a, - expected_positive_a, expected_small_a, expected_space_a_b, - expected_string_a, f, first, flag, floor, forEach, for_if, forin, from, - fromCharCode, fud, function, function_block, function_eval, function_loop, - function_statement, function_strict, functions, global, hasOwnProperty, id, - identifier, identifier_function, immed, implied_evil, indent, indexOf, - infix_in, init, insecure_a, isAlpha, isArray, isDigit, isNaN, join, jslint, - json, keys, kind, label, labeled, lbp, leading_decimal_a, led, left, length, - level, line, loopage, master, match, maxerr, maxlen, message, missing_a, - missing_a_after_b, missing_property, missing_space_a_b, missing_use_strict, - mode, move_invocation, move_var, n, name, name_function, nested_comment, - newcap, node, nomen, not, not_a_constructor, not_a_defined, not_a_function, - not_a_label, not_a_scope, not_greater, nud, number, octal_a, open, outer, - parameter, parameter_a_get_b, parameter_arguments_a, parameter_set_a, - params, paren, passfail, plusplus, pop, postscript, predef, properties, - properties_report, property, prototype, push, quote, r, radix, raw, - read_only, reason, redefinition_a_b, regexp, relation, replace, report, - reserved, reserved_a, rhino, right, scanned_a_b, scope, search, second, - shift, slash_equal, slice, sloppy, sort, split, statement, statement_block, - stop, stopping, strange_loop, strict, string, stupid, sub, subscript, - substr, supplant, sync_a, t, tag_a_in_b, test, third, thru, toString, todo, - todo_comment, token, tokens, too_long, too_many, trailing_decimal_a, tree, - unclosed, unclosed_comment, unclosed_regexp, unescaped_a, unexpected_a, - unexpected_char_a, unexpected_comment, unexpected_label_a, - unexpected_property_a, unexpected_space_a_b, unexpected_typeof_a, - uninitialized_a, unnecessary_else, unnecessary_initialize, unnecessary_use, - unparam, unreachable_a_b, unsafe, unused_a, url, use_array, use_braces, - use_nested_if, use_object, use_or, use_param, use_spaces, used, - used_before_a, var, var_a_not, var_loop, vars, varstatement, warn, warning, - was, weird_assignment, weird_condition, weird_new, weird_program, - weird_relation, weird_ternary, white, wrap, wrap_immediate, wrap_regexp, - write_is_wrong, writeable -*/ +var jslint = (function JSLint() { + 'use strict'; -// The global directive is used to declare global variables that can -// be accessed by the program. If a declaration is true, then the variable -// is writeable. Otherwise, it is read-only. + function empty() { -// We build the application inside a function so that we produce only a single -// global variable. That function will be invoked immediately, and its return -// value is the JSLINT function itself. That function is also an object that -// can contain data and other functions. +// The empty function produces a new empty object that inherits nothing. This is +// much better than {} because confusions around accidental method names like +// 'constructor' are completely avoided. -var JSLINT = (function () { - 'use strict'; + return Object.create(null); + } - function array_to_object(array, value) { + function populate(object, array, value) { -// Make an object from an array of keys and a common value. +// Augment an object by taking property names from an array of strings. - var i, length = array.length, object = Object.create(null); - for (i = 0; i < length; i += 1) { - object[array[i]] = value; - } - return object; + array.forEach(function (name) { + object[name] = value; + }); } - var allowed_option = { - ass : true, - bitwise : true, - browser : true, - closure : true, - continue : true, - couch : true, - debug : true, - devel : true, - eqeq : true, - evil : true, - forin : true, - indent : 10, - maxerr : 1000, - maxlen : 256, - newcap : true, - node : true, - nomen : true, - passfail : true, - plusplus : true, - properties: true, - regexp : true, - rhino : true, - unparam : true, - sloppy : true, - stupid : true, - sub : true, - todo : true, - vars : true, - white : true - }, - anonname, // The guessed name for anonymous functions. - -// These are operators that should not be used with the ! operator. - - bang = { - '<' : true, - '<=' : true, - '==' : true, - '===': true, - '!==': true, - '!=' : true, - '>' : true, - '>=' : true, - '+' : true, - '-' : true, - '*' : true, - '/' : true, - '%' : true - }, - begin, // The root token - block_var, // vars defined in the current block - -// browser contains a set of global names that are commonly provided by a -// web browser environment. - - browser = array_to_object([ - 'clearInterval', 'clearTimeout', 'document', 'event', 'FormData', - 'frames', 'history', 'Image', 'localStorage', 'location', 'name', - 'navigator', 'Option', 'parent', 'screen', 'sessionStorage', - 'setInterval', 'setTimeout', 'Storage', 'window', 'XMLHttpRequest' - ], false), - -// bundle contains the text messages. - - bundle = { - a_label: "'{a}' is a statement label.", - a_scope: "'{a}' used out of scope.", - already_defined: "'{a}' is already defined.", - and: "The '&&' subexpression should be wrapped in parens.", - assignment_expression: "Unexpected assignment expression.", - assignment_function_expression: "Expected an assignment or " + - "function call and instead saw an expression.", - avoid_a: "Avoid '{a}'.", - bad_assignment: "Bad assignment.", - bad_constructor: "Bad constructor.", - bad_in_a: "Bad for in variable '{a}'.", - bad_invocation: "Bad invocation.", - bad_new: "Do not use 'new' for side effects.", - bad_number: "Bad number '{a}'.", - bad_operand: "Bad operand.", - bad_wrap: "Do not wrap function literals in parens unless they " + - "are to be immediately invoked.", - combine_var: "Combine this with the previous 'var' statement.", - conditional_assignment: "Expected a conditional expression and " + - "instead saw an assignment.", - confusing_a: "Confusing use of '{a}'.", - confusing_regexp: "Confusing regular expression.", - constructor_name_a: "A constructor name '{a}' should start with " + - "an uppercase letter.", - control_a: "Unexpected control character '{a}'.", - dangling_a: "Unexpected dangling '_' in '{a}'.", - deleted: "Only properties should be deleted.", - duplicate_a: "Duplicate '{a}'.", - empty_block: "Empty block.", - empty_case: "Empty case.", - empty_class: "Empty class.", - evil: "eval is evil.", - expected_a_b: "Expected '{a}' and instead saw '{b}'.", - expected_a_b_from_c_d: "Expected '{a}' to match '{b}' from line " + - "{c} and instead saw '{d}'.", - expected_a_at_b_c: "Expected '{a}' at column {b}, not column {c}.", - expected_id_a: "Expected an id, and instead saw #{a}.", - expected_identifier_a: "Expected an identifier and instead saw '{a}'.", - expected_identifier_a_reserved: "Expected an identifier and " + - "instead saw '{a}' (a reserved word).", - expected_number_a: "Expected a number and instead saw '{a}'.", - expected_operator_a: "Expected an operator and instead saw '{a}'.", - expected_positive_a: "Expected a positive number and instead saw '{a}'", - expected_small_a: "Expected a small positive integer and instead saw '{a}'", - expected_space_a_b: "Expected exactly one space between '{a}' and '{b}'.", - expected_string_a: "Expected a string and instead saw '{a}'.", - for_if: "The body of a for in should be wrapped in an if " + - "statement to filter unwanted properties from the prototype.", - function_block: "Function statements should not be placed in blocks." + - "Use a function expression or move the statement to the top of " + - "the outer function.", - function_eval: "The Function constructor is eval.", - function_loop: "Don't make functions within a loop.", - function_statement: "Function statements are not invocable. " + - "Wrap the whole function invocation in parens.", - function_strict: "Use the function form of 'use strict'.", - identifier_function: "Expected an identifier in an assignment " + - "and instead saw a function invocation.", - implied_evil: "Implied eval is evil. Pass a function instead of a string.", - infix_in: "Unexpected 'in'. Compare with undefined, or use the " + - "hasOwnProperty method instead.", - insecure_a: "Insecure '{a}'.", - isNaN: "Use the isNaN function to compare with NaN.", - leading_decimal_a: "A leading decimal point can be confused with a dot: '.{a}'.", - missing_a: "Missing '{a}'.", - missing_a_after_b: "Missing '{a}' after '{b}'.", - missing_property: "Missing property name.", - missing_space_a_b: "Missing space between '{a}' and '{b}'.", - missing_use_strict: "Missing 'use strict' statement.", - move_invocation: "Move the invocation into the parens that " + - "contain the function.", - move_var: "Move 'var' declarations to the top of the function.", - name_function: "Missing name in function statement.", - nested_comment: "Nested comment.", - not: "Nested not.", - not_a_constructor: "Do not use {a} as a constructor.", - not_a_defined: "'{a}' has not been fully defined yet.", - not_a_function: "'{a}' is not a function.", - not_a_label: "'{a}' is not a label.", - not_a_scope: "'{a}' is out of scope.", - not_greater: "'{a}' should not be greater than '{b}'.", - octal_a: "Don't use octal: '{a}'. Use '\\u....' instead.", - parameter_arguments_a: "Do not mutate parameter '{a}' when using 'arguments'.", - parameter_a_get_b: "Unexpected parameter '{a}' in get {b} function.", - parameter_set_a: "Expected parameter (value) in set {a} function.", - radix: "Missing radix parameter.", - read_only: "Read only.", - redefinition_a_b: "Redefinition of '{a}' from line {b}.", - reserved_a: "Reserved name '{a}'.", - scanned_a_b: "{a} ({b}% scanned).", - slash_equal: "A regular expression literal can be confused with '/='.", - statement_block: "Expected to see a statement and instead saw a block.", - stopping: "Stopping.", - strange_loop: "Strange loop.", - strict: "Strict violation.", - subscript: "['{a}'] is better written in dot notation.", - sync_a: "Unexpected sync method: '{a}'.", - tag_a_in_b: "A '<{a}>' must be within '<{b}>'.", - todo_comment: "Unexpected TODO comment.", - too_long: "Line too long.", - too_many: "Too many errors.", - trailing_decimal_a: "A trailing decimal point can be confused " + - "with a dot: '.{a}'.", - unclosed: "Unclosed string.", - unclosed_comment: "Unclosed comment.", - unclosed_regexp: "Unclosed regular expression.", - unescaped_a: "Unescaped '{a}'.", - unexpected_a: "Unexpected '{a}'.", - unexpected_char_a: "Unexpected character '{a}'.", - unexpected_comment: "Unexpected comment.", - unexpected_label_a: "Unexpected label '{a}'.", - unexpected_property_a: "Unexpected /*property*/ '{a}'.", - unexpected_space_a_b: "Unexpected space between '{a}' and '{b}'.", - unexpected_typeof_a: "Unexpected 'typeof'. " + - "Use '===' to compare directly with {a}.", - uninitialized_a: "Uninitialized '{a}'.", - unnecessary_else: "Unnecessary 'else' after disruption.", - unnecessary_initialize: "It is not necessary to initialize '{a}' " + - "to 'undefined'.", - unnecessary_use: "Unnecessary 'use strict'.", - unreachable_a_b: "Unreachable '{a}' after '{b}'.", - unsafe: "Unsafe character.", - unused_a: "Unused '{a}'.", - url: "JavaScript URL.", - use_array: "Use the array literal notation [].", - use_braces: "Spaces are hard to count. Use {{a}}.", - use_nested_if: "Expected 'else { if' and instead saw 'else if'.", - use_object: "Use the object literal notation {} or Object.create(null).", - use_or: "Use the || operator.", - use_param: "Use a named parameter.", - use_spaces: "Use spaces, not tabs.", - used_before_a: "'{a}' was used before it was defined.", - var_a_not: "Variable {a} was not declared correctly.", - var_loop: "Don't declare variables in a loop.", - weird_assignment: "Weird assignment.", - weird_condition: "Weird condition.", - weird_new: "Weird construction. Delete 'new'.", - weird_program: "Weird program.", - weird_relation: "Weird relation.", - weird_ternary: "Weird ternary.", - wrap_immediate: "Wrap an immediate function invocation in " + - "parentheses to assist the reader in understanding that the " + - "expression is the result of a function, and not the " + - "function itself.", - wrap_regexp: "Wrap the /regexp/ literal in parens to " + - "disambiguate the slash operator.", - write_is_wrong: "document.write can be a form of eval." - }, - closure = array_to_object([ - 'goog' - ], false), - comments, - comments_off, - couch = array_to_object([ + +// These are the options that are recognized in the option object or that may +// appear in a /*jslint*/ directive. Most options will have a boolean value, +// usually true. Some options will also predefine some number of global +// variables. + + bitwise: true, + browser: [ + 'Audio', 'clearInterval', 'clearTimeout', 'document', 'event', + 'FormData', 'history', 'Image', 'localStorage', 'location', 'name', + 'navigator', 'Option', 'screen', 'sessionStorage', 'setInterval', + 'setTimeout', 'Storage', 'XMLHttpRequest' + ], + couch: [ 'emit', 'getRow', 'isArray', 'log', 'provides', 'registerType', 'require', 'send', 'start', 'sum', 'toJSON' - ], false), - - descapes = { - 'b': '\b', - 't': '\t', - 'n': '\n', - 'f': '\f', - 'r': '\r', - '"': '"', - '/': '/', - '\\': '\\', - '!': '!' - }, - - devel = array_to_object([ + ], + devel: [ 'alert', 'confirm', 'console', 'Debug', 'opera', 'prompt', 'WSH' - ], false), - directive, - escapes = { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '\'': '\\\'', - '"' : '\\"', - '/' : '\\/', - '\\': '\\\\' - }, - - funct, // The current function - - functions, // All of the functions - global_funct, // The global body - global_scope, // The global scope - in_block, // Where function statements are not allowed - indent, - itself, // JSLINT itself - json_mode, - lex, // the tokenizer - lines, - lookahead, - node = array_to_object([ + ], + es6: [ + 'ArrayBuffer', 'DataView', 'Float32Array', 'Float64Array', + 'Generator', 'GeneratorFunction', 'Int8Array', 'Int16Array', + 'Int32Array', 'Intl', 'Map', 'Promise', 'Proxy', 'Reflect', + 'Set', 'Symbol', 'System', 'Uint8Array', 'Uint8ClampedArray', + 'Uint16Array', 'Uint32Array', 'WeakMap', 'WeakSet' + ], + eval: true, + for: true, + fudge: true, + maxerr: 10000, + maxlen: 10000, + node: [ 'Buffer', 'clearImmediate', 'clearInterval', 'clearTimeout', 'console', 'exports', 'global', 'module', 'process', 'require', 'setImmediate', 'setInterval', 'setTimeout', '__dirname', '__filename' - ], false), - node_js, - numbery = array_to_object(['indexOf', 'lastIndexOf', 'search'], true), - next_token, - option, - predefined, // Global variables defined by option - prereg, - prev_token, - property, - protosymbol, - regexp_flag = array_to_object(['g', 'i', 'm'], true), - return_this = function return_this() { - return this; - }, - rhino = array_to_object([ - 'defineClass', 'deserialize', 'gc', 'help', 'load', 'loadClass', - 'print', 'quit', 'readFile', 'readUrl', 'runCommand', 'seal', - 'serialize', 'spawn', 'sync', 'toint32', 'version' - ], false), - - scope, // An object containing an object for each variable in scope - semicolon_coda = array_to_object([';', '"', '\'', ')'], true), - -// standard contains the global names that are provided by the -// ECMAScript standard. - - standard = array_to_object([ - 'Array', 'Boolean', 'Date', 'decodeURI', 'decodeURIComponent', - 'encodeURI', 'encodeURIComponent', 'Error', 'eval', 'EvalError', - 'Function', 'isFinite', 'isNaN', 'JSON', 'Map', 'Math', 'Number', - 'Object', 'parseInt', 'parseFloat', 'Promise', 'Proxy', - 'RangeError', 'ReferenceError', 'Reflect', 'RegExp', 'Set', - 'String', 'Symbol', 'SyntaxError', 'System', 'TypeError', - 'URIError', 'WeakMap', 'WeakSet' - ], false), - - strict_mode, - syntax = Object.create(null), - token, - tokens, - var_mode, - warnings, - -// Regular expressions. Some of these are stupidly long. + ], + this: true, + white: true + }; + + var spaceop = { + +// This is the set of infix operators that require a space on each side. + + '!=': true, + '!==': true, + '%': true, + '%=': true, + '&': true, + '&=': true, + '&&': true, + '*': true, + '*=': true, + '+=': true, + '-=': true, + '/': true, + '/=': true, + '<': true, + '<=': true, + '<<': true, + '<<=': true, + '=': true, + '==': true, + '===': true, + '=>': true, + '>': true, + '>=': true, + '>>': true, + '>>=': true, + '>>>': true, + '>>>=': true, + '^': true, + '^=': true, + '|': true, + '|=': true, + '||': true + }; + + var bitwiseop = { + +// These are the bitwise operators. + + '~': true, + '^': true, + '^=': true, + '&': true, + '&=': true, + '|': true, + '|=': true, + '<<': true, + '<<=': true, + '>>': true, + '>>=': true, + '>>>': true, + '>>>=': true + }; + + var opener = { + +// The open and close pairs. + + '(': ')', // paren + '[': ']', // bracket + '{': '}', // brace + '${': '}' // mega + }; + + var relationop = { + +// The relational operators. + + '!=': true, + '!==': true, + '==': true, + '===': true, + '<': true, + '<=': true, + '>': true, + '>=': true + }; + + var standard = [ + +// These are the globals that are provided by the ES5 language standard. + + 'Array', 'Boolean', 'Date', 'decodeURI', 'decodeURIComponent', + 'encodeURI', 'encodeURIComponent', 'Error', 'EvalError', 'Function', + 'isFinite', 'isNaN', 'JSON', 'Math', 'Number', 'Object', 'parseInt', + 'parseFloat', 'RangeError', 'ReferenceError', 'RegExp', 'String', + 'SyntaxError', 'TypeError', 'URIError' + ]; + + var bundle = { + +// The bundle contains the raw text messages that are generated by jslint. It +// seems that they are all error messages and warnings. There are no "Atta +// boy!" or "You are so awesome!" messages. There is no positive reinforcement +// or encouragement. This relentless negativity can undermine self-esteem and +// wound the inner child. But if you accept it as sound advice rather than as +// personal criticism, it can make your programs better. + + and: "The '&&' subexpression should be wrapped in parens.", + bad_assignment_a: "Bad assignment to '{a}'.", + bad_character_number_a: "Bad character code: '{a}'", + bad_directive_a: "Bad directive '{a}'.", + bad_get: "A get function takes no parameters.", + bad_module_name_a: "Bad module name '{a}'.", + bad_option_a: "Bad option '{a}'.", + bad_property_a: "Bad property name '{a}'.", + bad_set: "A set function takes one parameter.", + duplicate_a: "Duplicate '{a}'.", + empty_block: "Empty block.", + es6: "Unexpected ES6 feature.", + expected_a_at_b_c: "Expected '{a}' at column {b}, not column {c}.", + expected_a_b: "Expected '{a}' and instead saw '{b}'.", + expected_a_b_from_c_d: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", + expected_a_before_b: "Expected '{a}' before '{b}'.", + expected_digits_after_a: "Expected digits after '{a}'.", + expected_four_digits: "Expected four digits after '\\u'.", + expected_identifier_a: "Expected an identifier and instead saw '{a}'.", + expected_line_break_a_b: "Expected a line break between '{a}' and '{b}'.", + expected_regexp_factor_a: "Expected a regexp factor and instead saw '{a}'.", + expected_space_a_b: "Expected one space between '{a}' and '{b}'.", + expected_statements_a: "Expected statements before '{a}'.", + expected_string_a: "Expected a string and instead saw '{a}'.", + expected_type_string_a: "Expected a type string and instead saw '{a}'.", + function_in_loop: "Don't make functions within a loop.", + infix_in: "Unexpected 'in'. Compare with undefined, or use the hasOwnProperty method instead.", + isNaN: "Use the isNaN function to compare with NaN.", + label_a: "'{a}' is a statement label.", + misplaced_a: "Place '{a}' at the outermost level.", + misplaced_directive_a: "Place the '/*{a}*/' directive before the first statement.", + naked_block: "Naked block.", + nested_comment: "Nested comment.", + not_label_a: "'{a}' is not a label.", + out_of_scope_a: "'{a}' is out of scope.", + redefinition_a_b: "Redefinition of '{a}' from line {b}.", + reserved_a: "Reserved name '{a}'.", + slash_equal: "A regular expression literal can be confused with '/='.", + subscript_a: "['{a}'] is better written in dot notation.", + todo_comment: "Unexpected TODO comment.", + too_long: "Line too long.", + too_many: "Too many warnings.", + unclosed_comment: "Unclosed comment.", + unclosed_mega: "Unclosed mega literal.", + unclosed_string: "Unclosed string.", + undeclared_a: "Undeclared '{a}'.", + unexpected_a: "Unexpected '{a}'.", + unexpected_a_after_b: "Unexpected '{a}' after '{b}'.", + unexpected_at_top_level_a: "Unexpected '{a}' at top level.", + unexpected_char_a: "Unexpected character '{a}'.", + unexpected_comment: "Unexpected comment.", + unexpected_directive_a: "When using modules, don't use directive '/*{a}'.", + unexpected_expression_a: "Unexpected expression '{a}' in statement position.", + unexpected_label_a: "Unexpected label '{a}'.", + unexpected_parens: "Don't wrap function literals in parens.", + unexpected_space_a_b: "Unexpected space between '{a}' and '{b}'.", + unexpected_statement_a: "Unexpected statement '{a}' in expression position.", + unexpected_trailing_space: "Unexpected trailing space.", + unexpected_typeof_a: "Unexpected 'typeof'. Use '===' to compare directly with {a}.", + uninitialized_a: "Uninitialized '{a}'.", + unreachable_a: "Unreachable '{a}'.", + unregistered_property_a: "Unregistered property name '{a}'.", + unsafe: "Unsafe character '{a}'.", + unused_a: "Unused '{a}'.", + use_spaces: "Use spaces, not tabs.", + var_loop: "Don't declare variables in a loop.", + var_switch: "Don't declare variables in a switch.", + weird_condition_a: "Weird condition '{a}'.", + weird_expression_a: "Weird expression '{a}'.", + weird_loop: "Weird loop.", + weird_relation_a: "Weird relation '{a}'.", + wrap_assignment: "Don't wrap assignment statements in parens.", + wrap_condition: "Wrap the condition in parens.", + wrap_immediate: "Wrap an immediate function invocation in " + + "parentheses to assist the reader in understanding that the " + + "expression is the result of a function, and not the " + + "function itself.", + wrap_regexp: "Wrap this regexp in parens to avoid confusion.", + wrap_unary: "Wrap the unary expression in parens." + }; + +// Regular expression literals: +// supplant {variables} + var rx_supplant = /\{([^{}]*)\}/g, // carriage return, carriage return linefeed, or linefeed - crlfx = /\r\n?|\n/, + rx_crlf = /\n|\r\n?/, // unsafe characters that are silently deleted by one or more browsers - cx = /[\u0000-\u0008\u000a-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/, + rx_unsafe = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/, // identifier - ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/, -// javascript url - jx = /^(?:javascript|jscript|ecmascript|vbscript)\s*:/i, + rx_identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/, + rx_bad_property = /^_|\$|Sync$|_$/, // star slash - lx = /\*\/|\/\*/, -// characters in strings that need escapement - nx = /[\u0000-\u001f'\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, -// sync - syx = /Sync$/, -// comment todo - tox = /^\W*to\s*do(?:\W|$)/i, -// token - tx = /^\s*([(){}\[\]\?.,:;'"~#@`]|={1,3}|\/(\*(jslint|properties|property|members?|globals?)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|[\^%]=?|&[&=]?|\|[|=]?|>{1,3}=?|<(?:[\/=!]|\!(\[|--)?|<=?)?|\!(\!|==?)?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+(?:[xX][0-9a-fA-F]+|\.[0-9]*)?(?:[eE][+\-]?[0-9]+)?)/; - - - if (typeof String.prototype.entityify !== 'function') { - String.prototype.entityify = function () { - return this - .replace(/&/g, '&') - .replace(//g, '>'); - }; - } - - if (typeof String.prototype.isAlpha !== 'function') { - String.prototype.isAlpha = function () { - return (this >= 'a' && this <= 'z\uffff') || - (this >= 'A' && this <= 'Z\uffff'); - }; + rx_star_slash = /\*\//, +// slash star + rx_slash_star = /\/\*/, +// slash star or ending slash + rx_slash_star_or_slash = /\/\*|\/$/, +// uncompleted work comment + rx_todo = /\b(?:todo|TO\s?DO|HACK)\b/, +// tab + rx_tab = /\t/g, +// directive + rx_directive = /^(jslint|property|global)\s*(.*)$/, + rx_directive_part = /^([a-zA-Z$_][a-zA-Z0-9$_]*)\s*(?::\s*(true|false|[0-9]+)\s*)?(?:,\s*)?(.*)$/, +// token (sorry it is so long) + rx_token = /^((\s+)|([a-zA-Z_$][a-zA-Z0-9_$]*)|[(){}\[\]\?,:;'"~`]|=(?:==?|>)?|\.+|\/[=*\/]?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|[\^%]=?|&[&=]?|\|[\|=]?|>{1,3}=?|<= 'a' && string <= 'z\uffff') || + (string >= 'A' && string <= 'Z\uffff'); } - if (typeof String.prototype.isDigit !== 'function') { - String.prototype.isDigit = function () { - return (this >= '0' && this <= '9'); - }; + function supplant(string, object) { + return string.replace(rx_supplant, function (found, filling) { + var replacement = object[filling]; + return (replacement !== undefined) + ? replacement + : found; + }); } - if (typeof String.prototype.supplant !== 'function') { - String.prototype.supplant = function (o) { - return this.replace(/\{([^{}]*)\}/g, function (a, b) { - var replacement = o[b]; - return typeof replacement === 'string' || - typeof replacement === 'number' ? replacement : a; - }); - }; + var anon = "anonymous", // The guessed name for anonymous functions. + blockage, // The current block. + block_stack, // The stack of blocks. + declared_globals, // The object containing the global declarations. + directive_mode, // true if directives are still allowed. + early_stop, // true if JSLint cannot finish. + export_mode, // true if an export statement was seen. + fudge, // true if the natural numbers start with 1. + functionage, // The current function. + functions, // The array containing all of the functions. + global, // The global object, the outermost context. + imports, // The array collecting all import-from strings. + json_mode, // true if parsing JSON. + lines, // The array containing source lines. + module_mode, // true if import or export was used. + next_token, // The next token to be examined in the parse. + option, // The options parameter. + property, // The object containing the tallied property names. + mega_mode, // true if currently parsing a megastring literal. + stack, // The stack of functions. + syntax, // The object containing the parser. + token, // The current token being examined in the parse. + token_nr, // The number of the next token. + tokens, // The array of tokens. + tenure, // The predefined property registry. + tree, // The abstract parse tree. + var_mode, // true if using var, false if using let. + warnings; // The array collecting all generated warnings. + +// Error reportage functions: + + function artifact(the_token) { + +// Return a string representing an artifact. + + if (the_token === undefined) { + the_token = next_token; + } + return (the_token.id === '(string)' || the_token.id === '(number)') + ? String(the_token.value) + : the_token.id; } + function artifact_line(the_token) { - function sanitize(a) { +// Return the fudged line number of an artifact. -// Escapify a troublesome character. - - return escapes[a] || - '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4); + if (the_token === undefined) { + the_token = next_token; + } + return the_token.line + fudge; } + function artifact_column(the_token) { - function add_to_predefined(group) { - Object.keys(group).forEach(function (name) { - predefined[name] = group[name]; - }); +// Return the fudged column number of an artifact. + + if (the_token === undefined) { + the_token = next_token; + } + return the_token.from + fudge; } + function warn_at(code, line, column, a, b, c, d) { - function assume() { - if (option.browser) { - add_to_predefined(browser); - option.browser = false; - } - if (option.closure) { - add_to_predefined(closure); - } - if (option.couch) { - add_to_predefined(couch); - option.couch = false; +// Report an error at some line and column of the program. The warning object +// resembles an exception. + + var warning = { // ~~ + name: 'JSLintError', + column: column, + line: line, + code: code + }; + if (a !== undefined) { + warning.a = a; } - if (option.devel) { - add_to_predefined(devel); - option.devel = false; + if (b !== undefined) { + warning.b = b; } - if (option.node) { - add_to_predefined(node); - option.node = false; - node_js = true; + if (c !== undefined) { + warning.c = c; } - if (option.rhino) { - add_to_predefined(rhino); - option.rhino = false; + if (d !== undefined) { + warning.d = d; } + warning.message = supplant(bundle[code] || code, warning); + warnings.push(warning); + return (typeof option.maxerr === 'number' && + warnings.length === option.maxerr) + ? stop_at('too_many', line, column) + : warning; } + function stop_at(code, line, column, a, b, c, d) { -// Produce an error warning. +// Same as warn_at, except that it stops the analysis. - function artifact(tok) { - if (!tok) { - tok = next_token; - } - return tok.id === '(number)' ? tok.number : tok.string; + throw warn_at(code, line, column, a, b, c, d); } - function quit(message, line, character) { - throw { - name: 'JSLintError', - line: line, - character: character, - message: bundle.scanned_a_b.supplant({ - a: bundle[message] || message, - b: Math.floor((line / lines.length) * 100) - }) - }; - } + function warn(code, the_token, a, b, c, d) { - function warn(code, line, character, a, b, c, d) { - var warning = { // ~~ - id: '(error)', - raw: bundle[code] || code, - code: code, - evidence: lines[line - 1] || '', - line: line, - character: character, - a: a || artifact(this), - b: b, - c: c, - d: d - }; - warning.reason = warning.raw.supplant(warning); - itself.errors.push(warning); - if (option.passfail) { - quit('stopping', line, character); +// Same as warn_at, except the warning will be associated with a specific token. +// If there is already a warning on this token, suppress the new one. It is +// likely that the first warning will be the most meaningful. + + if (the_token === undefined) { + the_token = next_token; } - warnings += 1; - if (warnings >= option.maxerr) { - quit('too_many', line, character); + if (the_token.warning === undefined) { + the_token.warning = warn_at( + code, + the_token.line, + the_token.from, + a || artifact(the_token), + b, + c, + d + ); + return the_token.warning; } - return warning; } - function stop(code, line, character, a, b, c, d) { - var warning = warn(code, line, character, a, b, c, d); - quit('stopping', warning.line, warning.character); - } + function stop(code, the_token, a, b, c, d) { + +// Similar to warn and stop_at. If the token already had a warning, that +// warning will be replaced with this new one. It is likely that the stopping +// warning will be the most meaningful. - function expected_at(at) { - if (!option.white && next_token.from !== at) { - next_token.warn('expected_a_at_b_c', '', at, next_token.from); + if (the_token === undefined) { + the_token = next_token; } + the_token.warning = undefined; + throw warn(code, the_token, a, b, c, d); } -// lexical analysis and token construction +// Tokenize: + + function tokenize(source) { + +// tokenize takes a source and produces from it an array of token objects. +// JavaScript is notoriously difficult to tokenize because of the horrible +// interactions between automatic semicolon insertion, regular expression +// literals, and now megastring literals. JSLint benefits from eliminating +// automatic semicolon insertion and nested megastring literals, which allows +// full tokenization to precede parsing. - lex = (function lex() { - var character, c, from, length, line, pos, source_row; +// If the source is not an array, then it is split into lines at the +// carriage return/linefeed. -// Private lex methods + lines = (Array.isArray(source)) + ? source + : source.split(rx_crlf); + tokens = []; + + var char, // a popular character + column = 0, // the column number of the next character + from, // the starting column number of the token + line = -1, // the line number of the next character + previous = global, // the previous token including comments + prior = global, // the previous token excluding comments + mega_from, // the starting column of megastring + mega_line, // the starting line of megastring + snippet, // a piece of string + source_line; // the current line source string function next_line() { + +// Put the next line of source in source_line. If the line contains tabs, +// replace them with spaces and give a warning. Also warn if the line contains +// unsafe characters or is too damn long. + var at; - character = 1; - source_row = lines[line]; + column = 0; line += 1; - if (source_row === undefined) { - return false; - } - at = source_row.search(/\t/); - if (at >= 0) { - if (option.white) { - source_row = source_row.replace(/\t/g, ' '); - } else { - warn('use_spaces', line, at + 1); + source_line = lines[line]; + if (source_line !== undefined) { + at = source_line.search(rx_tab); + if (at >= 0) { + if (!option.white) { + warn_at('use_spaces', line, at + 1); + } + source_line = source_line.replace(rx_tab, ' '); + } + at = source_line.search(rx_unsafe); + if (at >= 0) { + warn_at( + 'unsafe', + line, + column + at, + 'U+' + source_line.charCodeAt(at).toString(16) + ); + } + if (option.maxlen && option.maxlen < source_line.length) { + warn_at('too_long', line, source_line.length); + } else if (!option.white && source_line.slice(-1) === ' ') { + warn_at( + 'unexpected_trailing_space', + line, + source_line.length - 1 + ); } } - at = source_row.search(cx); - if (at >= 0) { - warn('unsafe', line, at); - } - if (option.maxlen && option.maxlen < source_row.length) { - warn('too_long', line, source_row.length); - } - return true; + return source_line; } -// Produce a token object. The token inherits from a syntax symbol. +// Most tokens, including the identifiers, operators, and punctuators, can be +// found with a regular expression. Regular expressions cannot correctly match +// regular expression literals, so we will match those the hard way. String +// literals and number literals can be matched by regular expressions, but they +// don't provide good warnings. The functions snip, next_char, prev_char, +// some_digits, and escape help in the parsing of literals. - function it(type, value) { - var id, the_token; - if (type === '(string)') { - if (jx.test(value)) { - warn('url', line, from); - } - } - the_token = Object.create(syntax[( - type === '(punctuator)' || (type === '(identifier)' && - Object.prototype.hasOwnProperty.call(syntax, value)) - ? value - : type - )] || syntax['(error)']); - if (type === '(identifier)') { - the_token.identifier = true; - if (value === '__iterator__' || value === '__proto__') { - stop('reserved_a', line, from, value); - } else if (!option.nomen && - (value.charAt(0) === '_' || - value.charAt(value.length - 1) === '_')) { - warn('dangling_a', line, from, value); - } + function snip() { + +// Remove the last character from snippet. + + snippet = snippet.slice(0, -1); + } + + function next_char(match) { + +// Get the next character from the source line. Remove it from the source_line, +// and append it to the snippet. Optionally check that the previous character +// matched an expected value. + + if (match !== undefined && char !== match) { + return stop_at('expected_a_b', line, column, match, char); } - if (type === '(number)') { - the_token.number = +value; - } else if (value !== undefined) { - the_token.string = String(value); + if (source_line) { + char = source_line.charAt(0); + source_line = source_line.slice(1); + snippet += char; + } else { + char = ''; + snippet += ' '; } - the_token.line = line; - the_token.from = from; - the_token.thru = character; - if (comments.length) { - the_token.comments = comments; - comments = []; + column += 1; + return char; + } + + function back_char() { + +// Back up one character by moving a character from the end of the snippet to +// the front of the source_line. + + if (snippet) { + char = snippet.slice(-1); + source_line = char + source_line; + column -= 1; + snip(); + } else { + char = ''; } - id = the_token.id; - prereg = id && ( - ('(,=:[!&|?{};~+-*%^<>'.indexOf(id.charAt(id.length - 1)) >= 0) || - id === 'return' || id === 'case' - ); - return the_token; + return char; } - function match(x) { - var exec = x.exec(source_row), first; - if (exec) { - length = exec[0].length; - first = exec[1]; - c = first.charAt(0); - source_row = source_row.slice(length); - from = character + length - first.length; - character += length; - return first; + function some_digits(rx, quiet) { + var result = source_line.match(rx); + if (result) { + char = result[1]; + column += char.length; + source_line = result[2]; + snippet += char; + } else { + char = ''; + if (!quiet) { + warn_at( + 'expected_digits_after_a', + line, + column, + snippet + ); + } } - for (;;) { - if (!source_row) { - if (!option.white) { - warn('unexpected_char_a', line, character - 1, '(space)'); + return char.length; + } + + function escape(extra) { + switch (next_char('\\')) { + case '\\': + case '\'': + case '"': + case '/': + case ':': + case '=': + case '|': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + case ' ': + break; + case 'u': + if (next_char('u') === '{') { + if (some_digits(rx_hexs) > 5) { + warn_at('too_many_digits', line, column - 1); + } + if (!option.es6) { + warn_at('es6', line, column); + } + if (next_char() !== '}') { + stop_at('expected_a_before_b', line, column, '}', char); } return; } - c = source_row.charAt(0); - if (c !== ' ') { - break; + back_char(); + if (some_digits(rx_hexs, true) < 4) { + warn_at('expected_four_digits', line, column - 1); + } + break; + case '': + return stop_at('unclosed_string', line, column); + default: + if (extra && extra.indexOf(char) < 0) { + warn_at('unexpected_a_after_b', line, column, char, '\\'); } - source_row = source_row.slice(1); - character += 1; } - stop('unexpected_char_a', line, character, c); - + next_char(); } - function string(x) { - var ch, at = 0, r = '', result; + function make(id, value, identifier) { - function hex(n) { - var i = parseInt(source_row.substr(at + 1, n), 16); - at += n; - if (i >= 32 && i <= 126 && - i !== 34 && i !== 92 && i !== 39) { - warn('unexpected_a', line, character, '\\'); - } - character += n; - ch = String.fromCharCode(i); - } +// Make the token object and append it to the tokens list. - if (json_mode && x !== '"') { - warn('expected_a_b', line, character, '"', x); - } + var the_token = { + id: id, + identifier: !!identifier, + from: from, + thru: column, + line: line + }; + tokens.push(the_token); - for (;;) { - while (at >= source_row.length) { - at = 0; - if (!next_line()) { - stop('unclosed', line - 1, from); - } - } - ch = source_row.charAt(at); - if (ch === x) { - character += 1; - source_row = source_row.slice(at + 1); - result = it('(string)', r); - result.quote = x; - return result; - } - if (ch < ' ') { - if (ch === '\n' || ch === '\r') { - break; - } - warn('control_a', line, character + at, - source_row.slice(0, at)); - } else if (ch === '\\') { - at += 1; - character += 1; - ch = source_row.charAt(at); - switch (ch) { - case '': - warn('unexpected_a', line, character, '\\'); - next_line(); - at = -1; - break; - case '\'': - if (json_mode) { - warn('unexpected_a', line, character, '\\\''); - } - break; - case 'u': - hex(4); - break; - case 'v': - if (json_mode) { - warn('unexpected_a', line, character, '\\v'); - } - ch = '\v'; - break; - case 'x': - if (json_mode) { - warn('unexpected_a', line, character, '\\x'); - } - hex(2); - break; - default: - if (typeof descapes[ch] !== 'string') { - warn(ch >= '0' && ch <= '7' ? 'octal_a' : 'unexpected_a', - line, character, '\\' + ch); - } else { - ch = descapes[ch]; - } - } - } - r += ch; - character += 1; - at += 1; +// Directives must appear before the first statement. + + if (id !== '(comment)') { + directive_mode = false; } - } - function number(snippet) { - var digit; - if (source_row.charAt(0).isAlpha()) { - warn('expected_space_a_b', - line, character, c, source_row.charAt(0)); +// If the token is to have a value, give it one. + + if (value !== undefined) { + the_token.value = value; } - if (c === '0') { - digit = snippet.charAt(1); - if (digit.isDigit()) { - if (token.id !== '.') { - warn('unexpected_a', line, character, snippet); - } - } else if (json_mode && (digit === 'x' || digit === 'X')) { - warn('unexpected_a', line, character, '0x'); - } + +// If this token is an identifier that touches a preceding number, or +// a '/', comment, or regular expression literal that touches a preceding +// comment or regular expression literal, then give a missing space warning. +// This warning is not suppressed by option.white. + + if ( + previous.line === line && + previous.thru === from && + ( + (id === '(comment)' || id === '(regexp)' || id === '/') && + ( + previous.id === '(comment)' || + previous.id === '(regexp)' + ) + ) + ) { + warn( + 'expected_space_a_b', + the_token, + artifact(previous), + artifact(the_token) + ); } - if (snippet.slice(snippet.length - 1) === '.') { - warn('trailing_decimal_a', line, character, snippet); + if (previous.id === '.' && id === '(number)') { + warn('expected_a_before_b', previous, '0', '.'); } - digit = +snippet; - if (!isFinite(digit)) { - warn('bad_number', line, character, snippet); + if (prior.id === '.' && the_token.identifier) { + the_token.dot = true; } - snippet = digit; - return it('(number)', snippet); - } - function comment(snippet, type) { - if (comments_off) { - warn('unexpected_comment', line, character); - } else if (!option.todo && tox.test(snippet)) { - warn('todo_comment', line, character); +// The previous token is used to detect adjacency problems. + + previous = the_token; + +// The prior token is a previous token that was not a comment. The prior token +// is used to disambiguate '/', which can mean division or regular expression +// literal. + + if (previous.id !== '(comment)') { + prior = previous; } - comments.push({ - id: type, - from: from, - thru: character, - line: line, - string: snippet - }); + return the_token; } - function regexp() { - var at = 0, - b, - bit, - depth = 0, - flag = '', - high, - letter, - low, - potential, - quote, - result; - for (;;) { - b = true; - c = source_row.charAt(at); - at += 1; - switch (c) { - case '': - stop('unclosed_regexp', line, from); - return; - case '/': - if (depth > 0) { - warn('unescaped_a', line, from + at, '/'); - } - c = source_row.slice(0, at - 1); - potential = Object.create(regexp_flag); - for (;;) { - letter = source_row.charAt(at); - if (potential[letter] !== true) { - break; - } - potential[letter] = false; - at += 1; - flag += letter; - } - if (source_row.charAt(at).isAlpha()) { - stop('unexpected_a', line, from, source_row.charAt(at)); - } - character += at; - source_row = source_row.slice(at); - quote = source_row.charAt(0); - if (quote === '/' || quote === '*') { - stop('confusing_regexp', line, from); - } - result = it('(regexp)', c); - result.flag = flag; - return result; - case '\\': - c = source_row.charAt(at); - if (c < ' ') { - warn('control_a', line, from + at, String(c)); - } else if (c === '<') { - warn('unexpected_a', line, from + at, '\\'); - } - at += 1; - break; - case '(': - depth += 1; - b = false; - if (source_row.charAt(at) === '?') { - at += 1; - switch (source_row.charAt(at)) { - case ':': - case '=': - case '!': - at += 1; - break; - default: - warn('expected_a_b', line, from + at, - ':', source_row.charAt(at)); - } - } - break; - case '|': - b = false; - break; - case ')': - if (depth === 0) { - warn('unescaped_a', line, from + at, ')'); - } else { - depth -= 1; - } - break; - case ' ': - pos = 1; - while (source_row.charAt(at) === ' ') { - at += 1; - pos += 1; - } - if (pos > 1) { - warn('use_braces', line, from + at, pos); - } - break; - case '[': - c = source_row.charAt(at); - if (c === '^') { - at += 1; - if (!option.regexp) { - warn('insecure_a', line, from + at, c); - } else if (source_row.charAt(at) === ']') { - stop('unescaped_a', line, from + at, '^'); - } - } - bit = false; - if (c === ']') { - warn('empty_class', line, from + at - 1); - bit = true; - } -klass: do { - c = source_row.charAt(at); - at += 1; - switch (c) { - case '[': - case '^': - warn('unescaped_a', line, from + at, c); - bit = true; - break; - case '-': - if (bit) { - bit = false; - } else { - warn('unescaped_a', line, from + at, '-'); - bit = true; - } - break; - case ']': - if (!bit) { - warn('unescaped_a', line, from + at - 1, '-'); - } - break klass; - case '\\': - c = source_row.charAt(at); - if (c < ' ') { - warn('control_a', line, from + at, String(c)); - } else if (c === '<') { - warn('unexpected_a', line, from + at, '\\'); + function directive(the_comment, body) { + +// JSLint recognizes three directives that can be encoded in comments. This +// function processes one item, and calls itself recursively to process the +// next one. + + var result = body.match(rx_directive_part); + if (result) { + var allowed, + name = result[1], + value = result[2]; + switch (the_comment.directive) { + case 'jslint': + allowed = allowed_option[name]; + switch (typeof allowed) { + case 'boolean': + case 'object': + switch (value) { + case 'true': + case '': + case undefined: + option[name] = true; + if (Array.isArray(allowed)) { + populate(declared_globals, allowed, false); } - at += 1; - bit = true; break; - case '/': - warn('unescaped_a', line, from + at - 1, '/'); - bit = true; + case 'false': + option[name] = false; break; default: - bit = true; - } - } while (c); - break; - case '.': - if (!option.regexp) { - warn('insecure_a', line, from + at, c); - } - break; - case ']': - case '?': - case '{': - case '}': - case '+': - case '*': - warn('unescaped_a', line, from + at, c); - break; - } - if (b) { - switch (source_row.charAt(at)) { - case '?': - case '+': - case '*': - at += 1; - if (source_row.charAt(at) === '?') { - at += 1; + warn('bad_option_a', the_comment, name + ':' + value); } break; - case '{': - at += 1; - c = source_row.charAt(at); - if (c < '0' || c > '9') { - warn('expected_number_a', line, - from + at, c); - } - at += 1; - low = +c; - for (;;) { - c = source_row.charAt(at); - if (c < '0' || c > '9') { - break; - } - at += 1; - low = +c + (low * 10); - } - high = low; - if (c === ',') { - at += 1; - high = Infinity; - c = source_row.charAt(at); - if (c >= '0' && c <= '9') { - at += 1; - high = +c; - for (;;) { - c = source_row.charAt(at); - if (c < '0' || c > '9') { - break; - } - at += 1; - high = +c + (high * 10); - } - } - } - if (source_row.charAt(at) !== '}') { - warn('expected_a_b', line, from + at, - '}', c); + case 'number': + if (isFinite(+value)) { + option[name] = +value; } else { - at += 1; - } - if (source_row.charAt(at) === '?') { - at += 1; - } - if (low > high) { - warn('not_greater', line, from + at, - low, high); + warn('bad_option_a', the_comment, name + ':' + value); } break; + default: + warn('bad_option_a', the_comment, name); + } + break; + case 'property': + if (tenure === undefined) { + tenure = empty(); } + tenure[name] = true; + break; + case 'global': + if (value) { + warn('bad_option_a', the_comment, name + ':' + value); + } + declared_globals[name] = false; + module_mode = the_comment; + break; } + return directive(the_comment, result[3]); + } + if (body) { + return stop('bad_directive_a', the_comment, body); } - c = source_row.slice(0, at - 1); - character += at; - source_row = source_row.slice(at); - return it('(regexp)', c); } -// Public lex methods + function comment(snippet) { - return { - init: function (source) { - if (typeof source === 'string') { - lines = source.split(crlfx); +// Make a comment object. Comments are not allowed in JSON text. Comments can +// include directives and notices of incompletion. + + var the_comment = make('(comment)', snippet); + if (Array.isArray(snippet)) { + snippet = snippet.join(' '); + } + if (!option.devel && rx_todo.test(snippet)) { + warn('todo_comment', the_comment); + } + var result = snippet.match(rx_directive); + if (result) { + if (!directive_mode) { + warn_at('misplaced_directive_a', line, from, result[1]); } else { - lines = source; + the_comment.directive = result[1]; + directive(the_comment, result[2]); } - line = 0; - next_line(); - from = 1; - }, + } + return the_comment; + } -// token -- this is called by advance to get the next token. + function regexp() { - token: function () { - var first, i, snippet; +// Parse a regular expression literal. - for (;;) { - while (!source_row) { - if (!next_line()) { - return it('(end)'); - } - } - snippet = match(tx); - if (snippet) { + var result, + u_mode = false, + value; -// identifier + function quantifier() { - first = snippet.charAt(0); - if (first.isAlpha() || first === '_' || first === '$') { - return it('(identifier)', snippet); - } +// Match an optional quantifier. -// number + switch (char) { + case '?': + case '*': + case '+': + next_char(); + break; + case '{': + if (some_digits(rx_digits, true) === 0) { + warn_at('expected_a', line, column, '0'); + } + if (next_char() === ',') { + some_digits(rx_digits, true); + next_char(); + } + next_char('}'); + break; + default: + return; + } + if (char === '?') { + next_char('?'); + } + } - if (first.isDigit()) { - return number(snippet); - } - switch (snippet) { + function subklass() { -// string +// Match a character in a character class. - case '"': - case "'": - return string(snippet); + switch (char) { + case '\\': + escape(); + return true; + case '[': + case ']': + case '/': + case '^': + case '-': + case '|': + case '': + return false; + case '`': + if (mega_mode) { + warn_at('unexpected_a', line, column, '`'); + } + next_char(); + return true; + case ' ': + warn_at('expected_a_before_b', line, column, '\\', ' '); + next_char(); + return true; + default: + next_char(); + return true; + } + } -// // comment + function range() { - case '//': - comment(source_row, '//'); - source_row = ''; - break; - -// /* comment - - case '/*': - for (;;) { - i = source_row.search(lx); - if (i >= 0) { - break; - } - character = source_row.length; - comment(source_row); - from = 0; - if (!next_line()) { - stop('unclosed_comment', line, character); - } - } - comment(source_row.slice(0, i), '/*'); - character += i + 2; - if (source_row.charAt(i) === '/') { - stop('nested_comment', line, character); - } - source_row = source_row.slice(i + 2); - break; +// Match a range of subclasses. - case '': - break; -// / - case '/': - if (token.id === '/=') { - stop('slash_equal', line, from); - } - return prereg - ? regexp() - : it('(punctuator)', snippet); - -// punctuator - default: - return it('(punctuator)', snippet); + if (subklass()) { + if (char === '-') { + next_char('-'); + if (!subklass()) { + return stop_at('unexpected_a', line, column - 1, '-'); } } + return range(); } } - }; - }()); - function define(kind, token) { + function klass() { -// Define a name. +// Match a class. - var name = token.string, - master = scope[name]; // The current definition of the name + next_char('['); + if (char === '^') { + next_char('^'); + } + range(); + next_char(']'); + } -// vars are created with a deadzone, so that the expression that initializes -// the var cannot access the var. Functions are not writeable. + function choice() { - token.dead = false; - token.init = false; - token.kind = kind; - token.master = master; - token.used = 0; - token.writeable = true; + function group() { -// Global variables are a little weird. They can be defined multiple times. -// Some predefined global vars are (or should) not be writeable. +// Match a group that starts with left paren. - if (kind === 'var' && funct === global_funct) { - if (!master) { - if (predefined[name] === false) { - token.writeable = false; + next_char('('); + if (char === '?') { + next_char('?'); + switch (char) { + case ':': + case '=': + case '!': + next_char(); + break; + default: + next_char(':'); + } + } else if (char === ':') { + warn_at('expected_a_before_b', line, column, '?', ':'); + } + choice(); + next_char(')'); } - global_scope[name] = token; - } - } else { -// It is an error if the name has already been defined in this scope, except -// when reusing an exception variable name. + function factor() { + switch (char) { + case '[': + klass(); + return true; + case '\\': + escape('BbDdSsWw^${}[]().|*+?'); + return true; + case '(': + group(); + return true; + case '/': + case '|': + case ']': + case ')': + case '}': + case '{': + case '?': + case '+': + case '*': + case '': + return false; + case '`': + if (mega_mode) { + warn_at('unexpected_a', line, column, '`'); + } + break; + case ' ': + warn_at('expected_a_before_b', line, column, '\\', ' '); + break; + } + next_char(); + return true; + } - if (master) { - if (master.function === funct) { - if (master.kind !== 'exception' || kind !== 'exception' || - !master.dead) { - token.warn('already_defined', name); + function sequence(follow) { + if (factor()) { + quantifier(); + return sequence(true); } - } else if (master.function !== global_funct) { - if (kind === 'var') { - token.warn('redefinition_a_b', name, master.line); + if (!follow) { + warn_at('expected_regexp_factor_a', line, column, char); } } - } - scope[name] = token; - if (kind === 'var') { - block_var.push(name); - } - } - } - function peek(distance) { +// Match a choice (a sequence that can be followed by | and another choice). -// Peek ahead to a future token. The distance is how far ahead to look. The -// default is the next token. - - var found, slot = 0; - - distance = distance || 0; - while (slot <= distance) { - found = lookahead[slot]; - if (!found) { - found = lookahead[slot] = lex.token(); + sequence(); + if (char === '|') { + next_char('|'); + return choice(); + } } - slot += 1; - } - return found; - } +// Scan the regexp literal. Give a warning if the first character is = because +// /= looks like a division assignment operator. - function advance(id, match) { + snippet = ''; + next_char(); + if (char === '=') { + warn_at('expected_a_before_b', line, column, '\\', '='); + } + choice(); -// Produce the next token, also looking for programming errors. +// Make sure there is a closing slash. - if (indent) { + snip(); + value = snippet; + next_char('/'); -// If indentation checking was requested, then inspect all of the line breakings. -// The var statement is tricky because the names might be aligned or not. We -// look at the first line break after the var to determine the programmer's -// intention. +// Process dangling flag letters. - if (var_mode && next_token.line !== token.line) { - if ((var_mode !== indent || !next_token.edge) && - next_token.from === indent.at - - (next_token.edge ? option.indent : 0)) { - var dent = indent; - for (;;) { - dent.at -= option.indent; - if (dent === var_mode) { - break; - } - dent = dent.was; + var allowed = { + g: true, + i: true, + m: true, + u: u_mode, + y: option.es6 + }, + flag = empty(); + (function make_flag() { + if (is_letter(char)) { + if (allowed[char] !== true) { + warn_at('unexpected_a', line, column, char); } - dent.open = false; + allowed[char] = false; + flag[char] = true; + next_char(); + return make_flag(); } - var_mode = null; + }()); + if (u_mode && !flag.u) { + warn_at('expected_a_before_b', line, column, 'u', char); } - if (next_token.id === '?' && indent.mode === ':' && - token.line !== next_token.line) { - indent.at -= option.indent; + back_char(); + if (char === '/' || char === '*') { + return stop_at('unexpected_a', line, from, char); } - if (indent.open) { + result = make('(regexp)', char); + result.flag = flag; + result.value = value; + return result; + } -// If the token is an edge. + function string(quote) { - if (next_token.edge) { - if (next_token.edge === 'label') { - expected_at(1); - } else if (next_token.edge === 'case' || indent.mode === 'statement') { - expected_at(indent.at - option.indent); - } else if (indent.mode !== 'array' || next_token.line !== token.line) { - expected_at(indent.at); - } +// Make a string token. -// If the token is not an edge, but is the first token on the line. + var the_token; + snippet = ''; + next_char(); - } else if (next_token.line !== token.line) { - if (next_token.from < indent.at + (indent.mode === - 'expression' ? 0 : option.indent)) { - expected_at(indent.at + option.indent); - } - indent.wrap = true; - } - } else if (next_token.line !== token.line) { - if (next_token.edge) { - expected_at(indent.at); - } else { - indent.wrap = true; - if (indent.mode === 'statement' || indent.mode === 'var') { - expected_at(indent.at + option.indent); - } else if (next_token.from < indent.at + (indent.mode === - 'expression' ? 0 : option.indent)) { - expected_at(indent.at + option.indent); + return (function next() { + switch (char) { + case quote: + snip(); + the_token = make('(string)', snippet); + the_token.quote = quote; + return the_token; + case '\\': + escape(); + break; + case '': + return stop_at('unclosed_string', line, column); + case '`': + if (mega_mode) { + warn_at('unexpected_a', line, column, '`'); } + next_char('`'); + break; + default: + next_char(); } - } + return next(); + }()); } - switch (token.id) { - case '(number)': - if (next_token.id === '.') { - next_token.warn('trailing_decimal_a'); - } - break; - case '-': - if (next_token.id === '-' || next_token.id === '--') { - next_token.warn('confusing_a'); + function frack() { + if (char === '.') { + some_digits(rx_digits); + next_char(); } - break; - case '+': - if (next_token.id === '+' || next_token.id === '++') { - next_token.warn('confusing_a'); - } - break; - } - if (token.id === '(string)' || token.identifier) { - anonname = token.string; - } - - if (id && next_token.id !== id) { - if (match) { - next_token.warn('expected_a_b_from_c_d', id, - match.id, match.line, artifact()); - } else if (!next_token.identifier || next_token.string !== id) { - next_token.warn('expected_a_b', id, artifact()); + if (char === 'E' || char === 'e') { + next_char(); + if (char !== '+' && char !== '-') { + back_char(); + } + some_digits(rx_digits); + next_char(); } } - prev_token = token; - token = next_token; - next_token = lookahead.shift() || lex.token(); - next_token.function = funct; - tokens.push(next_token); - } - - function do_globals() { - var name, writeable; - for (;;) { - if (next_token.id !== '(string)' && !next_token.identifier) { - return; - } - name = next_token.string; - advance(); - writeable = false; - if (next_token.id === ':') { - advance(':'); - switch (next_token.id) { - case 'true': - writeable = predefined[name] !== false; - advance('true'); + function number() { + if (snippet === '0') { + switch (next_char()) { + case '.': + frack(); break; - case 'false': - advance('false'); + case 'b': + some_digits(rx_bits); + next_char(); + break; + case 'o': + some_digits(rx_octals); + next_char(); + break; + case 'x': + some_digits(rx_hexs); + next_char(); break; - default: - next_token.stop('unexpected_a'); } + } else { + next_char(); + frack(); } - predefined[name] = writeable; - if (next_token.id !== ',') { - return; - } - advance(','); - } - } +// If the next character after a number is a digit or letter, then something +// unexpected is going on. - function do_jslint() { - var name, value; - while (next_token.id === '(string)' || next_token.identifier) { - name = next_token.string; - if (!allowed_option[name]) { - next_token.stop('unexpected_a'); - } - advance(); - if (next_token.id !== ':') { - next_token.stop('expected_a_b', ':', artifact()); - } - advance(':'); - if (typeof allowed_option[name] === 'number') { - value = next_token.number; - if (value > allowed_option[name] || value <= 0 || - Math.floor(value) !== value) { - next_token.stop('expected_small_a'); - } - option[name] = value; - } else { - if (next_token.id === 'true') { - option[name] = true; - } else if (next_token.id === 'false') { - option[name] = false; - } else { - next_token.stop('unexpected_a'); - } - } - advance(); - if (next_token.id === ',') { - advance(','); + if ( + (char >= '0' && char <= '9') || + (char >= 'a' && char <= 'z') || + (char >= 'A' && char <= 'Z') + ) { + return stop_at( + 'unexpected_a_after_b', + line, + column - 1, + snippet.slice(-1), + snippet.slice(0, -1) + ); } + back_char(); + return make('(number)', snippet); } - assume(); - } - - function do_properties() { - var name; - option.properties = true; - for (;;) { - if (next_token.id !== '(string)' && !next_token.identifier) { - return; - } - name = next_token.string; - advance(); - if (next_token.id === ':') { - for (;;) { - advance(); - if (next_token.id !== '(string)' && !next_token.identifier) { - break; - } - } - } - property[name] = 0; - if (next_token.id !== ',') { - return; + function lex() { + var array, + i = 0, + j = 0, + last, + result, + the_token; + if (!source_line) { + source_line = next_line(); + from = 0; + return (source_line === undefined) + ? (mega_mode) + ? stop_at('unclosed_mega', mega_line, mega_from) + : make('(end)') + : lex(); } - advance(','); - } - } + from = column; + result = source_line.match(rx_token); +// result[1] token +// result[2] whitespace +// result[3] identifier +// result[4] number +// result[5] rest - directive = function directive() { - var command = this.id, - old_comments_off = comments_off, - old_indent = indent; - comments_off = true; - indent = null; - if (next_token.line === token.line && next_token.from === token.thru) { - next_token.warn('missing_space_a_b', artifact(token), artifact()); - } - if (lookahead.length > 0) { - this.warn('unexpected_a'); - } - switch (command) { - case '/*properties': - case '/*property': - case '/*members': - case '/*member': - do_properties(); - break; - case '/*jslint': - do_jslint(); - break; - case '/*globals': - case '/*global': - do_globals(); - break; - default: - this.stop('unexpected_a'); - } - comments_off = old_comments_off; - advance('*/'); - indent = old_indent; - }; + if (!result) { + return stop_at('unexpected_char_a', line, column, source_line.charAt(0)); + } + snippet = result[1]; + column += snippet.length; + source_line = result[5]; -// Indentation intention +// Whitespace was matched. Call lex again to get more. - function edge(mode) { - next_token.edge = indent ? indent.open && (mode || 'edge') : ''; - } + if (result[2]) { + return lex(); + } +// The token is an identifier. - function step_in(mode) { - var open; - if (typeof mode === 'number') { - indent = { - at: +mode, - open: true, - was: indent - }; - } else if (!indent) { - indent = { - at: 1, - mode: 'statement', - open: true - }; - } else if (mode === 'statement') { - indent = { - at: indent.at, - open: true, - was: indent - }; - } else { - open = mode === 'var' || next_token.line !== token.line; - indent = { - at: (open || mode === 'control' - ? indent.at + option.indent - : indent.at) + (indent.wrap ? option.indent : 0), - mode: mode, - open: open, - was: indent - }; - if (mode === 'var' && open) { - var_mode = indent; + if (result[3]) { + return make(snippet, undefined, true); } - } - } - function step_out(id, symbol) { - if (id) { - if (indent && indent.open) { - indent.at -= option.indent; - edge(); +// The token is a number. + + if (result[4]) { + return number(snippet); } - advance(id, symbol); - } - if (indent) { - indent = indent.was; - } - } -// Functions for conformance of whitespace. +// The token is something miscellaneous. - function one_space(left, right) { - left = left || token; - right = right || next_token; - if (right.id !== '(end)' && !option.white && - (token.line !== right.line || - token.thru + 1 !== right.from)) { - right.warn('expected_space_a_b', artifact(token), artifact(right)); - } - } + switch (snippet) { - function one_space_only(left, right) { - left = left || token; - right = right || next_token; - if (right.id !== '(end)' && (left.line !== right.line || - (!option.white && left.thru + 1 !== right.from))) { - right.warn('expected_space_a_b', artifact(left), artifact(right)); - } - } +// The token is a single or double quote string. - function no_space(left, right) { - left = left || token; - right = right || next_token; - if ((!option.white) && - left.thru !== right.from && left.line === right.line) { - right.warn('unexpected_space_a_b', artifact(left), artifact(right)); - } - } + case '\'': + case '"': + return string(snippet); - function no_space_only(left, right) { - left = left || token; - right = right || next_token; - if (right.id !== '(end)' && (left.line !== right.line || - (!option.white && left.thru !== right.from))) { - right.warn('unexpected_space_a_b', artifact(left), artifact(right)); - } - } +// The token is a megastring. We don't allow any kind if mega nesting. - function spaces(left, right) { - if (!option.white) { - left = left || token; - right = right || next_token; - if (left.thru === right.from && left.line === right.line) { - right.warn('missing_space_a_b', artifact(left), artifact(right)); - } - } - } + case '`': + if (mega_mode) { + return stop_at('expected_a_b', line, column, '}', '`'); + } + snippet = ''; + mega_from = from; + mega_line = line; + mega_mode = true; - function comma() { - if (next_token.id !== ',') { - warn('expected_a_b', token.line, token.thru, ',', artifact()); - } else { - if (!option.white) { - no_space_only(); - } - advance(','); - spaces(); - } - } +// Parsing a mega literal is tricky. First make a ` token. + make('`'); + from += 1; - function semicolon() { - if (next_token.id !== ';') { - warn('expected_a_b', token.line, token.thru, ';', artifact()); - } else { - if (!option.white) { - no_space_only(); - } - advance(';'); - if (semicolon_coda[next_token.id] !== true) { - spaces(); - } - } - } +// Then loop, building up a string, possibly from many lines, until seeing +// the end of file, a closing `, or a ${ indicting an expression within the +// string. - function use_strict() { - if (next_token.string === 'use strict') { - if (strict_mode) { - next_token.warn('unnecessary_use'); - } - edge(); - advance(); - semicolon(); - strict_mode = true; - return true; - } - return false; - } + (function part() { + var at = source_line.search(rx_mega); +// If neither ` nor ${ is seen, then the whole line joins the snippet. - function are_similar(a, b) { - if (a === b) { - return true; - } - if (Array.isArray(a)) { - if (Array.isArray(b) && a.length === b.length) { - var i; - for (i = 0; i < a.length; i += 1) { - if (!are_similar(a[i], b[i])) { - return false; + if (at < 0) { + snippet += source_line + '\n'; + return (next_line() === undefined) + ? stop_at('unclosed_mega', mega_line, mega_from) + : part(); + } + +// if either ` or ${ was found, then the preceding joins the snippet to become +// a string token. + + snippet += source_line.slice(0, at); + column += at; + source_line = source_line.slice(at); + make('(string)', snippet).quote = '`'; + snippet = ''; + +// If ${, then make tokens that will become part of an expression until +// a } token is made. + + if (source_line.charAt(0) === '$') { + column += 2; + make('${'); + source_line = source_line.slice(2); + (function expr() { + var id = lex().id; + if (id === '{') { + return stop_at( + 'expected_a_b', + line, + column, + '}', + '{' + ); + } + if (id !== '}') { + return expr(); + } + }()); + return part(); } + }()); + source_line = source_line.slice(1); + column += 1; + mega_mode = false; + return make('`'); + +// The token is a // comment. + + case '//': + snippet = source_line; + source_line = ''; + the_token = comment(snippet); + if (mega_mode) { + warn('unexpected_comment', the_token, '`'); } - return true; + return the_token; + +// The token is a /* comment. + + case '/*': + array = []; + if (source_line.charAt(0) === '/') { + warn_at('unexpected_a', line, column + i, '/'); + } + (function next() { + if (source_line > '') { + i = source_line.search(rx_star_slash); + if (i >= 0) { + return; + } + j = source_line.search(rx_slash_star); + if (j >= 0) { + warn_at('nested_comment', line, column + j); + } + } + array.push(source_line); + source_line = next_line(); + if (source_line === undefined) { + return stop_at('unclosed_comment', line, column); + } + return next(); + }()); + snippet = source_line.slice(0, i); + j = snippet.search(rx_slash_star_or_slash); + if (j >= 0) { + warn_at('nested_comment', line, column + j); + } + array.push(snippet); + column += i + 2; + source_line = source_line.slice(i + 2); + return comment(array); + +// The token is a slash. + + case '/': + +// The / can be a division operator or the beginning of a regular expression +// literal. It is not possible to know which without doing a complete parse. +// We want to complete the tokenization before we begin to parse, so we will +// estimate. This estimator can fail in some cases. For example, it cannot +// know if '}' is ending a block or ending an object literal, so it can +// behave incorrectly in that case; it is not meaningful to divide an +// object, so it is likely that we can get away with it. We avoided the worst +// cases by eliminating automatic semicolon insertion. + + if (prior.identifier) { + if (!prior.dot) { + switch (prior.id) { + case 'return': + return regexp(); + case '(begin)': + case 'case': + case 'delete': + case 'in': + case 'instanceof': + case 'new': + case 'typeof': + case 'void': + case 'yield': + the_token = regexp(); + return stop('unexpected_a', the_token); + } + } + } else { + last = prior.id.charAt(prior.id.length - 1); + if ('(,=:?['.indexOf(last) >= 0) { + return regexp(); + } + if ('!&|{};~+-*%/^<>'.indexOf(last) >= 0) { + the_token = regexp(); + warn('wrap_regexp', the_token); + return the_token; + } + } + if (source_line.charAt(0) === '/') { + column += 1; + source_line = source_line.slice(1); + snippet = '/='; + warn_at('unexpected_a', line, column, '/='); + } + break; } - return false; + return make(snippet); } - if (Array.isArray(b)) { - return false; - } - if (a.id === '(number)' && b.id === '(number)') { - return a.number === b.number; - } - if (a.arity === b.arity && a.string === b.string) { - switch (a.arity) { - case undefined: - return a.string === b.string; - case 'prefix': - case 'suffix': - return a.id === b.id && are_similar(a.first, b.first) && - a.id !== '{' && a.id !== '['; - case 'infix': - return are_similar(a.first, b.first) && - are_similar(a.second, b.second); - case 'ternary': - return are_similar(a.first, b.first) && - are_similar(a.second, b.second) && - are_similar(a.third, b.third); - case 'function': - case 'regexp': - return false; - default: - return true; + +// This is the only loop in JSLint. It will turn into a recursive call to lex +// when ES6 has been finished and widely deployed and adopted. + + while (true) { + if (lex().id === '(end)') { + break; } } - if (a.id === '.' && b.id === '[' && b.arity === 'infix') { - return a.second.string === b.second.string && b.second.id === '(string)'; - } - if (a.id === '[' && a.arity === 'infix' && b.id === '.') { - return a.second.string === b.second.string && a.second.id === '(string)'; - } - return false; } +// Parsing: -// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it -// is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is -// like .nud except that it is only used on the first token of a statement. -// Having .fud makes it much easier to define statement-oriented languages like -// JavaScript. I retained Pratt's nomenclature. +// Parsing weaves the tokens into an abstract syntax tree. During that process, +// a token may be given any of these properties: -// .nud Null denotation -// .fud First null denotation -// .led Left denotation -// lbp Left binding power -// rbp Right binding power +// arity string +// label identifier +// name identifier +// expression expressions +// block statements +// else statements (else, default, catch) -// They are elements of the parsing method called Top Down Operator Precedence. +// Specialized tokens may have additional properties. - function expression(rbp, initial) { + function survey(name) { + var id = name.id; -// rbp is the right binding power. -// initial indicates that this is the first expression of a statement. +// Tally the property name. If it is a string, only tally strings that conform +// to the identifier rules. - var left; - if (next_token.id === '(end)') { - token.stop('unexpected_a', next_token.id); - } - advance(); - if (initial) { - anonname = 'anonymous'; + if (id === '(string)') { + id = name.value; + if (!rx_identifier.test(id)) { + return id; + } + } else { + if (!name.identifier) { + return stop('expected_identifier_a', name); + } } - if (initial === true && token.fud) { - left = token.fud(); + +// If we have seen this name before, increment its count. + + if (typeof property[id] === 'number') { + property[id] += 1; + +// If this is the first time seeing this property name, and if there is a +// tenure list, then it must be on the list. Otherwise, it must conform to +// the rules for good property names. + } else { - if (token.nud) { - left = token.nud(); + if (tenure !== undefined) { + if (tenure[id] !== true) { + warn('unregistered_property_a', name); + } } else { - if (next_token.id === '(number)' && token.id === '.') { - token.warn('leading_decimal_a', artifact()); - advance(); - return token; + if (name.identifier && rx_bad_property.test(id)) { + warn('bad_property_a', name); } - token.stop('expected_identifier_a', artifact(token)); - } - while (rbp < next_token.lbp) { - advance(); - left = token.led(left); - } - } - if (left && left.assign && !initial) { - if (!option.ass) { - left.warn('assignment_expression'); - } - if (left.id !== '=' && left.first.master) { - left.first.master.used = true; } + property[id] = 1; } - return left; + return id; } - protosymbol = { - nud: function () { - this.stop('unexpected_a'); - }, - led: function () { - this.stop('expected_operator_a'); - }, - warn: function (code, a, b, c, d) { - if (!this.warning) { - this.warning = warn(code, this.line || 0, this.from || 0, - a || artifact(this), b, c, d); - } - }, - stop: function (code, a, b, c, d) { - this.warning = undefined; - this.warn(code, a, b, c, d); - return quit('stopping', this.line, this.character); - }, - lbp: 0 - }; + function dispense() { -// Functional constructors for making the symbols that will be inherited by -// tokens. +// Deliver the next token, skipping the comments. - function symbol(s, bp) { - var x = syntax[s]; - if (!x) { - x = Object.create(protosymbol); - x.id = x.string = s; - x.lbp = bp || 0; - syntax[s] = x; + var cadet = tokens[token_nr]; + token_nr += 1; + if (cadet.id === '(comment)') { + if (json_mode) { + warn('unexpected_a', cadet); + } + return dispense(); + } else { + return cadet; } - return x; } - function postscript(x) { - x.postscript = true; - return x; - } + function lookahead() { - function ultimate(s) { - var x = symbol(s, 0); - x.from = 1; - x.thru = 1; - x.line = 0; - x.edge = 'edge'; - x.string = s; - return postscript(x); +// Look ahead one token without advancing. + + var old_token_nr = token_nr, + cadet = dispense(true); + token_nr = old_token_nr; + return cadet; } - function reserve_name(x) { - var c = x.id.charAt(0); - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { - x.identifier = x.reserved = true; + function advance(id, match) { + +// Produce the next token. + +// Attempt to give helpful names to anonymous functions. + + if (token.identifier && token.id !== 'function') { + anon = token.id; + } else if (token.id === '(string)' && rx_identifier.test(token.value)) { + anon = token.value; } - return x; - } - function stmt(s, f) { - var x = symbol(s); - x.fud = f; - return reserve_name(x); - } +// Attempt to match next_token with an expected id. - function disrupt_stmt(s, f) { - var x = stmt(s, f); - x.disrupt = true; - } + if (id !== undefined && next_token.id !== id) { + return (match === undefined) + ? stop('expected_a_b', next_token, id, artifact()) + : stop( + 'expected_a_b_from_c_d', + next_token, + id, + artifact(match), + artifact_line(match), + artifact(next_token) + ); + } - function labeled_stmt(s, f) { - var x = stmt(s, function labeled() { - var the_statement; - if (funct.breakage) { - funct.breakage.push(this); - } else { - funct.breakage = [this]; - } - the_statement = f.apply(this); - if (funct.breakage.length > 1) { - funct.breakage.pop(); - } else { - delete funct.breakage; - } - return the_statement; - }); - x.labeled = true; - } - - function prefix(s, f) { - var x = symbol(s, 150); - reserve_name(x); - x.nud = function () { - var that = this; - that.arity = 'prefix'; - if (typeof f === 'function') { - that = f(that); - if (that.arity !== 'prefix') { - return that; - } - } else { - if (s === 'typeof') { - one_space(); - } else { - no_space_only(); - } - that.first = expression(150); - } - switch (that.id) { - case '++': - case '--': - if (!option.plusplus) { - that.warn('unexpected_a'); - } else if ((!that.first.identifier || that.first.reserved) && - that.first.id !== '.' && that.first.id !== '[') { - that.warn('bad_operand'); - } - break; - default: - if (that.first.arity === 'prefix' || - that.first.arity === 'function') { - that.warn('unexpected_a'); - } - } - return that; - }; - return x; - } - - - function type(s, t, nud) { - var x = symbol(s); - x.arity = t; - if (nud) { - x.nud = nud; - } - return x; +// Promote the tokens, skipping comments. + + token = next_token; + next_token = dispense(); + if (next_token.id === '(end)') { + token_nr -= 1; + } } +// Parsing of JSON is simple: - function reserve(s, f) { - var x = symbol(s); - x.identifier = x.reserved = true; - if (typeof f === 'function') { - x.nud = f; - } - return x; - } - - - function constant(name) { - var x = reserve(name); - x.string = name; - x.nud = return_this; - return x; - } - + function json_value() { - function reservevar(s, v) { - return reserve(s, function () { - if (typeof v === 'function') { - v(this); + function json_object() { + var brace = next_token, + object = empty(); + advance('{'); + if (next_token.id !== '}') { + (function next() { + if (next_token.quote !== '"') { + warn('unexpected_a', next_token, next_token.quote); + } + advance('(string)'); + if (object[token.value] !== undefined) { + warn('duplicate_a', token); + } else if (token.value === '__proto__') { + warn('bad_property_name_a', token); + } else { + object[token.value] = token; + } + advance(':'); + json_value(); + if (next_token.id === ',') { + advance(','); + return next(); + } + }()); } - return this; - }); - } - + advance('}', brace); + } - function infix(s, p, f, w) { - var x = symbol(s, p); - reserve_name(x); - x.led = function (left) { - this.arity = 'infix'; - if (!w) { - spaces(prev_token, token); - spaces(); - } - if (!option.bitwise && this.bitwise) { - this.warn('unexpected_a'); - } - if (typeof f === 'function') { - return f(left, this); + function json_array() { + var bracket = next_token; + advance('['); + if (next_token.id !== ']') { + (function next() { + json_value(); + if (next_token.id === ',') { + advance(','); + return next(); + } + }()); } - this.first = left; - this.second = expression(p); - return this; - }; - return x; - } - - function expected_relation(node, message) { - if (node.assign) { - node.warn(message || 'conditional_assignment'); + advance(']', bracket); } - return node; - } - function expected_condition(node, message) { - switch (node.id) { + switch (next_token.id) { + case '{': + json_object(); + break; case '[': - case '-': - if (node.arity !== 'infix') { - node.warn(message || 'weird_condition'); - } + json_array(); break; + case 'true': case 'false': - case 'function': - case 'Infinity': - case 'NaN': case 'null': - case 'true': - case 'undefined': - case 'void': - case '(number)': - case '(regexp)': - case '(string)': - case '{': - case '?': - case '~': - node.warn(message || 'weird_condition'); + advance(); break; - case '(': - if (node.first.id === 'new' || - (node.first.string === 'Boolean') || - (node.first.id === '.' && - numbery[node.first.second.string] === true)) { - node.warn(message || 'weird_condition'); + case '(number)': + if (!rx_JSON_number.test(next_token.value)) { + warn('unexpected_a'); } + advance(); break; - } - return node; - } - - function check_relation(node) { - switch (node.arity) { - case 'prefix': - switch (node.id) { - case '{': - case '[': - node.warn('unexpected_a'); - break; - case '!': - node.warn('confusing_a'); - break; + case '(string)': + if (next_token.quote !== '"') { + warn('unexpected_a', next_token, next_token.quote); } + advance(); break; - case 'function': - case 'regexp': - node.warn('unexpected_a'); + case '-': + advance('-'); + advance('(number)'); break; default: - if (node.id === 'NaN') { - node.warn('isNaN'); - } else if (node.relation) { - node.warn('weird_relation'); - } + stop('unexpected_a'); } - return node; } +// Now we parse JavaScript. - function relation(s, eqeq) { - var x = infix(s, 100, function (left, that) { - check_relation(left); - if (eqeq && !option.eqeq) { - that.warn('expected_a_b', eqeq, that.id); - } - var right = expression(100); - if (are_similar(left, right) || - ((left.id === '(string)' || left.id === '(number)') && - (right.id === '(string)' || right.id === '(number)'))) { - that.warn('weird_relation'); - } else if (left.id === 'typeof') { - if (right.id !== '(string)') { - right.warn("expected_string_a", artifact(right)); - } else if (right.string === 'undefined' || - right.string === 'null') { - left.warn("unexpected_typeof_a", right.string); - } - } else if (right.id === 'typeof') { - if (left.id !== '(string)') { - left.warn("expected_string_a", artifact(left)); - } else if (left.string === 'undefined' || - left.string === 'null') { - right.warn("unexpected_typeof_a", left.string); - } - } - that.first = left; - that.second = check_relation(right); - return that; - }); - x.relation = true; - return x; - } + function enroll(name, role, readonly) { - function lvalue(that, s) { - var master; - if (that.identifier) { - master = scope[that.string]; - if (master) { - if (scope[that.string].writeable !== true) { - that.warn('read_only'); - } - master.used -= 1; - if (s === '=') { - master.init = true; - } - } else if (that.reserved) { - that.warn('expected_identifier_a_reserved'); - } - } else if (that.id === '.' || that.id === '[') { - if (!that.first || that.first.string === 'arguments') { - that.warn('bad_assignment'); - } +// Enroll a name into the current function context. The role can be exception, +// function, label, parameter, or variable. We look for variable redefinition +// because it causes confusion. + + var id = name.id; + +// Reserved words may not be enrolled. + + if (syntax[id] !== undefined && id !== 'ignore') { + warn('reserved_a', name); } else { - that.warn('bad_assignment'); - } - } +// Has the name been enrolled in this context? - function assignop(s, op) { - var x = infix(s, 20, function (left, that) { - var next; - that.first = left; - lvalue(left, s); - that.second = expression(20); - if (that.id === '=' && are_similar(that.first, that.second)) { - that.warn('weird_assignment'); - } - next = that; - while (next_token.id === '=') { - lvalue(next.second, '='); - next_token.first = next.second; - next.second = next_token; - next = next_token; - advance('='); - next.second = expression(20); - } - return that; - }); - x.assign = true; - if (op) { - if (syntax[op].bitwise) { - x.bitwise = true; + var earlier = functionage.context[id]; + if (earlier) { + warn( + 'redefinition_a_b', + name, + name.id, + earlier.line + fudge + ); + +// Has the name been enrolled in an outer context? + + } else { + stack.forEach(function (value) { + var item = value.context[id]; + if (item !== undefined) { + earlier = item; + } + }); + if (earlier) { + if (id === 'ignore') { + if (earlier.role === 'variable') { + warn('unexpected_a', name); + } + } else { + if (( + role !== 'exception' || + earlier.role !== 'exception' + ) && role !== 'parameter') { + warn( + 'redefinition_a_b', + name, + name.id, + earlier.line + fudge + ); + } + } + } + +// Enroll it. + + functionage.context[id] = name; + name.dead = true; + name.function = functionage; + name.init = false; + name.role = role; + name.used = 0; + name.writable = !readonly; } } - return x; } + function expression(rbp, initial) { - function bitwise(s, p) { - var x = infix(s, p, 'number'); - x.bitwise = true; - return x; - } +// This is the heart of the Pratt parser. I retained Pratt's nomenclature. +// They are elements of the parsing method called Top Down Operator Precedence. +// nud Null denotation +// led Left denotation +// lbp Left binding power +// rbp Right binding power - function suffix(s) { - var x = symbol(s, 150); - x.led = function (left) { - no_space_only(prev_token, token); - if (!option.plusplus) { - this.warn('unexpected_a'); - } else if ((!left.identifier || left.reserved) && - left.id !== '.' && left.id !== '[') { - this.warn('bad_operand'); - } - this.first = left; - this.arity = 'suffix'; - return this; - }; - return x; - } +// It processes a nud (variable, constant, prefix operator). It will then +// process leds (infix operators) until the bind powers cause it to stop. It +// returns the expression's parse tree. + + var left, the_symbol; +// Statements will have already advanced, so advance now only if the token is +// not the first of a statement, - function optional_identifier(variable) { - if (next_token.identifier) { + if (!initial) { advance(); - if (token.reserved && variable) { - token.warn('expected_identifier_a_reserved'); - } - return token.string; } + the_symbol = syntax[token.id]; + if (the_symbol !== undefined && the_symbol.nud !== undefined) { + left = the_symbol.nud(); + } else if (token.identifier) { + left = token; + left.arity = 'variable'; + } else { + return stop('unexpected_a', token); + } + (function right() { + the_symbol = syntax[next_token.id]; + if ( + the_symbol !== undefined && + the_symbol.led !== undefined && + rbp < the_symbol.lbp + ) { + advance(); + left = the_symbol.led(left); + return right(); + } + }()); + return left; } + function condition() { + +// Parse the condition part of a do, if, while. - function identifier(variable) { - var i = optional_identifier(variable); - if (!i) { - next_token.stop(token.id === 'function' && next_token.id === '(' - ? 'name_function' - : 'expected_identifier_a'); + var the_paren = next_token, + the_value; + the_paren.free = true; + advance('('); + the_value = expression(0); + advance(')'); + if (the_value.wrapped === true) { + warn('unexpected_a', the_paren); + } + switch (the_value.id) { + case '?': + case '~': + case '&': + case '|': + case '^': + case '<<': + case '>>': + case '>>>': + case '+': + case '-': + case '*': + case '/': + case '%': + case 'typeof': + case '(number)': + case '(string)': + warn('unexpected_a', the_value); + break; } - return i; + return the_value; } + function is_weird(thing) { + return ( + thing.id === '(regexp)' || + thing.id === '{' || + thing.id === '=>' || + thing.id === 'function' || + (thing.id === '[' && thing.arity === 'unary') + ); + } - function statement() { + function are_similar(a, b) { + if (a === b) { + return true; + } + if (Array.isArray(a)) { + return ( + Array.isArray(b) && + a.length === b.length && + a.every(function (value, index) { + return are_similar(value, b[index]); + }) + ); + } + if (Array.isArray(b)) { + return false; + } + if (a.id === '(number)' && b.id === '(number)') { + return a.value === b.value; + } + var a_string, b_string; + if (a.id === '(string)') { + a_string = a.value; + } else if (a.id === '`' && a.constant) { + a_string = a.value[0]; + } + if (b.id === '(string)') { + b_string = b.value; + } else if (b.id === '`' && b.constant) { + b_string = b.value[0]; + } + if (typeof a_string === 'string') { + return a_string === b_string; + } + if (is_weird(a) || is_weird(b)) { + return false; + } + if (a.arity === b.arity && a.id === b.id) { + if (a.id === '.') { + return are_similar(a.expression, b.expression) && + are_similar(a.name, b.name); + } + switch (a.arity) { + case 'unary': + return are_similar(a.expression, b.expression); + case 'binary': + return a.id !== '(' && + are_similar(a.expression[0], b.expression[0]) && + are_similar(a.expression[1], b.expression[1]); + case 'ternary': + return are_similar(a.expression[0], b.expression[0]) && + are_similar(a.expression[1], b.expression[1]) && + are_similar(a.expression[2], b.expression[2]); + case 'function': + case 'regexp': + return false; + default: + return true; + } + } + return false; + } - var label, preamble, the_statement; + function semicolon() { -// We don't like the empty statement. +// Try to match a semicolon. if (next_token.id === ';') { - next_token.warn('unexpected_a'); - semicolon(); - return; + advance(';'); + } else { + warn_at( + 'expected_a_b', + token.line, + token.thru, + ';', + artifact(next_token) + ); } + anon = 'anonymous'; + } -// Is this a labeled statement? + function statement() { - if (next_token.identifier && !next_token.reserved && peek().id === ':') { - edge('label'); - label = next_token; - advance(); +// Parse a statement. Any statement may have a label, but only four statements +// have use for one. A statement can be one of the standard statements, or +// an assignment expression, or an invocation expression. + + var first, + the_label, + the_statement, + the_symbol; + advance(); + if (token.identifier && next_token.id === ':') { + the_label = token; + if (the_label.id === 'ignore') { + warn('unexpected_a', the_label); + } advance(':'); - define('label', label); - if (next_token.labeled !== true || funct === global_funct) { - label.stop('unexpected_label_a'); - } else if (jx.test(label.string + ':')) { - label.warn('url'); + switch (next_token.id) { + case 'do': + case 'for': + case 'switch': + case 'while': + enroll(the_label, 'label', true); + the_label.init = true; + the_label.dead = false; + the_statement = statement(); + the_statement.label = the_label; + the_statement.statement = true; + return the_statement; + default: + advance(); + warn('unexpected_label_a', the_label); } - next_token.label = label; - label.init = true; - label.statement = next_token; } // Parse the statement. - preamble = next_token; - if (token.id !== 'else') { - edge(); - } - step_in('statement'); - the_statement = expression(0, true); - if (the_statement) { - -// Look for the final semicolon. - - if (the_statement.arity === 'statement') { - if (the_statement.id === 'switch' || - (the_statement.block && the_statement.id !== 'do')) { - spaces(); - } else { - semicolon(); - } - } else { + first = token; + first.statement = true; + the_symbol = syntax[first.id]; + if (the_symbol !== undefined && the_symbol.fud !== undefined) { + the_symbol.disrupt = false; + the_symbol.statement = true; + the_statement = the_symbol.fud(); + } else { -// If this is an expression statement, determine if it is acceptable. -// We do not like -// new Blah; -// statements. If it is to be used at all, new should only be used to make -// objects, not side effects. The expression statements we do like do -// assignment or invocation or delete. +// It is an expression statement. - if (the_statement.id === '(') { - if (the_statement.first.id === 'new') { - next_token.warn('bad_new'); - } - } else if (the_statement.id === '++' || - the_statement.id === '--') { - lvalue(the_statement.first); - } else if (!the_statement.assign && - the_statement.id !== 'delete') { - if (!option.closure || !preamble.comments) { - preamble.warn('assignment_function_expression'); - } - } - semicolon(); + the_statement = expression(0, true); + if (the_statement.wrapped && the_statement.id !== '(') { + warn('unexpected_a', first); } + semicolon(); } - step_out(); - if (label) { - label.dead = true; + if (the_label !== undefined) { + the_label.dead = true; } return the_statement; } - function statements() { - var array = [], disruptor, the_statement; -// A disrupt statement may not be followed by any other statement. -// If the last statement is disrupt, then the sequence is disrupt. +// Parse a list of statements. Give a warning if an unreachable statement +// follows a disruptive statement. - while (next_token.postscript !== true) { - if (next_token.id === ';') { - next_token.warn('unexpected_a'); - semicolon(); - } else { - if (next_token.string === 'use strict') { - if ((!node_js) || funct !== global_funct || array.length > 0) { - next_token.warn('function_strict'); - } - use_strict(); - } - if (disruptor) { - next_token.warn('unreachable_a_b', next_token.string, - disruptor.string); - disruptor = null; - } - the_statement = statement(); - if (the_statement) { - array.push(the_statement); - if (the_statement.disrupt) { - disruptor = the_statement; - array.disrupt = true; - } + var array = []; + (function next(disrupt) { + var a_statement; + switch (next_token.id) { + case '}': + case 'case': + case 'default': + case 'else': + case '(end)': + break; + default: + a_statement = statement(); + array.push(a_statement); + if (disrupt) { + warn('unreachable_a', a_statement); } + return next(a_statement.disrupt); } - } + }(false)); return array; } + function not_top_level(thing) { + +// Some features should not be at the outermost level. - function block(kind) { + if (functionage === global) { + warn('unexpected_at_top_level_a', thing); + } + } -// A block is a sequence of statements wrapped in braces. + function top_level_only(the_thing) { - var array, - curly = next_token, - old_block_var = block_var, - old_in_block = in_block, - old_strict_mode = strict_mode; +// Some features must be at the most outermost level. - in_block = kind !== 'function' && kind !== 'try' && kind !== 'catch'; - block_var = []; - if (curly.id === '{') { - spaces(); - advance('{'); - step_in(); - if (kind === 'function' && !use_strict() && !old_strict_mode && - !option.sloppy && funct.level === 1) { - next_token.warn('missing_use_strict'); - } - array = statements(); - strict_mode = old_strict_mode; - step_out('}', curly); - } else if (in_block) { - curly.stop('expected_a_b', '{', artifact()); - } else { - curly.warn('expected_a_b', '{', artifact()); - array = [statement()]; - array.disrupt = array[0].disrupt; - } - if (kind !== 'catch' && array.length === 0 && !option.debug) { - curly.warn('empty_block'); + if (blockage !== global) { + warn('misplaced_a', the_thing); } - block_var.forEach(function (name) { - scope[name].dead = true; - }); - block_var = old_block_var; - in_block = old_in_block; - return array; } + function block(special) { - function tally_property(name) { - if (option.properties && typeof property[name] !== 'number') { - token.warn('unexpected_property_a', name); +// Parse a block, a sequence of statements wrapped in braces. +// special 'body' The block is a function body. +// 'ignore' No warning on an empty block. +// 'naked' No advance. +// undefined Not special. + + var stmts, the_block; + if (special !== 'naked') { + advance('{'); } - if (property[name]) { - property[name] += 1; + the_block = token; + the_block.arity = 'statement'; + the_block.body = special === 'body'; + +// All top level function bodies should include the 'use strict' pragma unless +// the whole file is strict. + + if (the_block.body && stack.length <= 1 && !global.strict) { + if ( + next_token.id === '(string)' || + next_token.value === 'use strict' + ) { + next_token.statement = true; + functionage.strict = true; + advance('(string)'); + advance(';'); + } else { + warn( + 'expected_a_before_b', + next_token, + (next_token.id === '`') + ? '\'' + : 'use strict', + artifact(next_token) + ); + } + } + stmts = statements(); + the_block.block = stmts; + if (stmts.length === 0) { + if (!option.devel && special !== 'ignore') { + warn('empty_block', the_block); + } + the_block.disrupt = false; } else { - property[name] = 1; + the_block.disrupt = stmts[stmts.length - 1].disrupt; } + advance('}'); + return the_block; } + function mutation_check(the_thing) { -// ECMAScript parser +// The only expressions that may be assigned to are +// e.b +// e[b] +// v - (function () { - var x = symbol('(identifier)'); - x.nud = function () { - var name = this.string, - master = scope[name], - writeable; + if ( + the_thing.id !== '.' && + (the_thing.id !== '[' || the_thing.arity !== 'binary') && + the_thing.arity !== 'variable' + ) { + warn('bad_assignment_a', the_thing); + return false; + } + return true; + } -// If the master is not in scope, then we may have an undeclared variable. -// Check the predefined list. If it was predefined, create the global -// variable. + function left_check(left, right) { - if (!master) { - writeable = predefined[name]; - if (typeof writeable === 'boolean') { - global_scope[name] = master = { - dead: false, - function: global_funct, - kind: 'var', - string: name, - writeable: writeable - }; +// Warn if the left is not one of these: +// e.b +// e[b] +// e() +// identifier + + var id = left.id; + if ( + !left.identifier && + ( + left.arity !== 'binary' || + (id !== '.' && id !== '(' && id !== '[') + ) + ) { + warn('unexpected_a', right); + return false; + } + return true; + } -// But if the variable is not in scope, and is not predefined, and if we are not -// in the global scope, then we have an undefined variable error. +// These functions are used to specify the grammar of our language: - } else { - token.warn('used_before_a'); - } + function symbol(id, bp) { + +// Make a symbol if it does not already exist in the language's syntax. + + var the_symbol = syntax[id]; + if (the_symbol === undefined) { + the_symbol = empty(); + the_symbol.id = id; + the_symbol.lbp = bp || 0; + syntax[id] = the_symbol; + } + return the_symbol; + } + + function assignment(id) { + +// Make an assignment operator. The one true assignment is different because +// its left side, when it is a variable, is not treated as an expression. +// That case is special because that is when a variable gets initialized. The +// other assignment operators can modify, but they cannot initialize. + + var the_symbol = symbol(id, 20); + the_symbol.led = function (left) { + var the_token = token, + right; + the_token.arity = 'assignment'; + right = expression(20 - 1); + if (id === '=' && left.arity === 'variable') { + the_token.names = left; + the_token.expression = right; + } else { + the_token.expression = [left, right]; + } + switch (right.arity) { + case 'assignment': + case 'pre': + case 'post': + warn('unexpected_a', right); + break; + } + if ( + option.es6 && + left.arity === 'unary' && + (left.id === '[' || left.id === '{') + ) { + warn('expected_a_before_b', left, 'const', left.id); } else { - this.master = master; + mutation_check(left); } + return the_token; + }; + return the_symbol; + } -// Annotate uses that cross scope boundaries. + function constant(id, type, value) { - if (master) { - if (master.kind === 'label') { - this.warn('a_label'); - } else { - if (master.dead === true || master.dead === funct) { - this.warn('a_scope'); - } - master.used += 1; - if (master.function !== funct) { - if (master.function === global_funct) { - funct.global.push(name); - } else { - master.function.closure.push(name); - funct.outer.push(name); - } - } +// Make a constant symbol. + + var the_symbol = symbol(id); + the_symbol.nud = (typeof value === 'function') + ? value + : function () { + token.constant = true; + if (value !== undefined) { + token.value = value; } + return token; + }; + the_symbol.type = type; + the_symbol.value = value; + return the_symbol; + } + + function infix(id, bp, f) { + +// Make an infix operator. + + var the_symbol = symbol(id, bp); + the_symbol.led = function (left) { + var the_token = token; + the_token.arity = 'binary'; + if (f !== undefined) { + return f(left); } - return this; + the_token.expression = [left, expression(bp)]; + return the_token; }; - x.identifier = true; - }()); + return the_symbol; + } + function post(id) { -// Build the syntax table by declaring the syntactic elements. +// Make one of the post operators. - type('(array)', 'array'); - type('(function)', 'function'); - type('(number)', 'number', return_this); - type('(object)', 'object'); - type('(string)', 'string', return_this); - type('(boolean)', 'boolean', return_this); - type('(regexp)', 'regexp', return_this); + var the_symbol = symbol(id, 150); + the_symbol.led = function (left) { + token.expression = left; + token.arity = 'post'; + mutation_check(token.expression); + return token; + }; + return the_symbol; + } + + function pre(id) { + +// Make one of the pre operators. + + var the_symbol = symbol(id); + the_symbol.nud = function () { + var the_token = token; + the_token.arity = 'pre'; + the_token.expression = expression(150); + mutation_check(the_token.expression); + return the_token; + }; + return the_symbol; + } + + function prefix(id, f) { + +// Make a prefix operator. + + var the_symbol = symbol(id); + the_symbol.nud = function () { + var the_token = token; + the_token.arity = 'unary'; + if (typeof f === 'function') { + return f(); + } + the_token.expression = expression(150); + return the_token; + }; + return the_symbol; + } - ultimate('(begin)'); - ultimate('(end)'); - ultimate('(error)'); - postscript(symbol('}')); + function stmt(id, f) { + +// Make a statement. + + var the_symbol = symbol(id); + the_symbol.fud = function () { + token.arity = 'statement'; + return f(); + }; + return the_symbol; + } + + function ternary(id1, id2) { + +// Make a ternary operator. + + var the_symbol = symbol(id1, 30); + the_symbol.led = function (left) { + var the_token = token, + second = expression(20); + advance(id2); + token.arity = 'ternary'; + the_token.arity = 'ternary'; + the_token.expression = [left, second, expression(10)]; + return the_token; + }; + return the_symbol; + } + +// Begin defining the language. + + syntax = empty(); + + symbol('}'); symbol(')'); symbol(']'); - postscript(symbol('"')); - postscript(symbol('\'')); + symbol(','); symbol(';'); symbol(':'); - symbol(','); - symbol('#'); - symbol('@'); symbol('*/'); - postscript(reserve('case')); - reserve('catch'); - postscript(reserve('default')); - reserve('else'); - reserve('finally'); - - reservevar('arguments', function (x) { - if (strict_mode && funct === global_funct) { - x.warn('strict'); - } - funct.arguments = true; - }); - reservevar('eval'); - constant('false', 'boolean'); - constant('Infinity', 'number'); - constant('NaN', 'number'); - constant('null', ''); - reservevar('this', function (x) { - if (strict_mode && funct.statement && funct.name.charAt(0) > 'Z') { - x.warn('strict'); - } - }); - constant('true', 'boolean'); - constant('undefined', ''); - - infix('?', 30, function (left, that) { - step_in('?'); - that.first = expected_condition(expected_relation(left)); - that.second = expression(0); - spaces(); - step_out(); - var colon = next_token; - advance(':'); - step_in(':'); - spaces(); - that.third = expression(10); - that.arity = 'ternary'; - if (are_similar(that.second, that.third)) { - colon.warn('weird_ternary'); - } else if (are_similar(that.first, that.second)) { - that.warn('use_or'); - } - step_out(); - return that; - }); - - infix('||', 40, function (left, that) { - function paren_check(that) { - if (that.id === '&&' && !that.paren) { - that.warn('and'); - } - return that; - } - - that.first = paren_check(expected_condition(expected_relation(left))); - that.second = paren_check(expected_relation(expression(40))); - if (are_similar(that.first, that.second)) { - that.warn('weird_condition'); - } - return that; + symbol('await'); + symbol('case'); + symbol('catch'); + symbol('class'); + symbol('default'); + symbol('else'); + symbol('enum'); + symbol('finally'); + symbol('implements'); + symbol('interface'); + symbol('package'); + symbol('private'); + symbol('protected'); + symbol('public'); + symbol('static'); + symbol('super'); + symbol('void'); + symbol('yield'); + + constant('(number)', 'number'); + constant('(regexp)', 'regexp'); + constant('(string)', 'string'); + constant('arguments', 'object', function () { + warn('unexpected_a', token); + return token; }); - - infix('&&', 50, function (left, that) { - that.first = expected_condition(expected_relation(left)); - that.second = expected_relation(expression(50)); - if (are_similar(that.first, that.second)) { - that.warn('weird_condition'); + constant('eval', 'function', function () { + if (!option.eval) { + warn('unexpected_a', token); + } else if (next_token.id !== '(') { + warn('expected_a_before_b', next_token, '(', artifact()); } - return that; + return token; }); - - prefix('void', function (that) { - that.first = expression(0); - that.warn('expected_a_b', 'undefined', 'void'); - return that; + constant('false', 'boolean', false); + constant('ignore', 'undefined', function () { + warn('unexpected_a', token); + return token; }); - - bitwise('|', 70); - bitwise('^', 80); - bitwise('&', 90); - - relation('==', '==='); - relation('==='); - relation('!=', '!=='); - relation('!=='); - relation('<'); - relation('>'); - relation('<='); - relation('>='); - - bitwise('<<', 120); - bitwise('>>', 120); - bitwise('>>>', 120); - - infix('in', 120, function (left, that) { - that.warn('infix_in'); - that.left = left; - that.right = expression(130); - return that; + constant('Infinity', 'number', Infinity); + constant('NaN', 'number', NaN); + constant('null', 'null', null); + constant('this', 'object', function () { + if (!option.this) { + warn('unexpected_a', token); + } + return token; }); - infix('instanceof', 120); - infix('+', 130, function (left, that) { - if (left.id === '(number)') { - if (left.number === 0) { - left.warn('unexpected_a', '0'); - } - } else if (left.id === '(string)') { - if (left.string === '') { - left.warn('expected_a_b', 'String', '\'\''); - } - } - var right = expression(130); - if (right.id === '(number)') { - if (right.number === 0) { - right.warn('unexpected_a', '0'); - } - } else if (right.id === '(string)') { - if (right.string === '') { - right.warn('expected_a_b', 'String', '\'\''); + constant('true', 'boolean', true); + constant('undefined', 'undefined'); + + assignment('='); + assignment('+='); + assignment('-='); + assignment('*='); + assignment('/='); + assignment('%='); + assignment('&='); + assignment('|='); + assignment('^='); + assignment('<<='); + assignment('>>='); + assignment('>>>='); + + infix('||', 40); + infix('&&', 50); + infix('|', 70); + infix('^', 80); + infix('&', 90); + infix('==', 100); + infix('===', 100); + infix('!=', 100); + infix('!==', 100); + infix('<', 110); + infix('>', 110); + infix('<=', 110); + infix('>=', 110); + infix('in', 110); + infix('instanceof', 110); + infix('<<', 120); + infix('>>', 120); + infix('>>>', 120); + infix('+', 130); + infix('-', 130); + infix('*', 140); + infix('/', 140); + infix('%', 140); + infix('(', 160, function (left) { + var the_paren = token, + the_argument; + if (left.id !== 'function') { + left_check(left, the_paren); + } + the_paren.expression = [left]; + if (left.identifier) { + if (left.new) { + if ( + left.id.charAt(0) > 'Z' || + left.id === 'Boolean' || + left.id === 'Number' || + left.id === 'String' || + (left.id === 'Symbol' && option.es6) + ) { + warn('unexpected_a', left, 'new'); + } else if (left.id === 'Function') { + if (!option.eval) { + warn('unexpected_a', left, 'new Function'); + } + } else if (left.id === 'Array') { + warn('expected_a_b', left, '[]', 'new Array'); + } else if (left.id === 'Object') { + warn( + 'expected_a_b', + left, + 'Object.create(null)', + 'new Object' + ); + } + } else { + if ( + left.id.charAt(0) >= 'A' && + left.id.charAt(0) <= 'Z' && + left.id !== 'Boolean' && + left.id !== 'Number' && + left.id !== 'String' && + left.id !== 'Symbol' + ) { + warn( + 'expected_a_before_b', + left, + 'new', + artifact(left) + ); + } + if (functionage.arity === 'statement') { + functionage.name.calls[left.id] = left; + } } } - if (left.id === right.id) { - if (left.id === '(string)' || left.id === '(number)') { - if (left.id === '(string)') { - left.string += right.string; - if (jx.test(left.string)) { - left.warn('url'); + if (next_token.id !== ')') { + (function next() { + var ellipsis; + if (next_token.id === '...') { + if (!option.es6) { + warn('es6'); } - } else { - left.number += right.number; + ellipsis = true; + advance('...'); + } + the_argument = expression(10); + if (ellipsis) { + the_argument.ellipsis = true; + } + the_paren.expression.push(the_argument); + if (next_token.id === ',') { + advance(','); + return next(); } - left.thru = right.thru; - return left; + }()); + } + advance(')', the_paren); + if (the_paren.expression.length === 2) { + the_paren.free = true; + if (the_argument.wrapped === true) { + warn('unexpected_a', the_paren); + } + if (the_argument.id === '(') { + the_argument.wrapped = true; } + } else { + the_paren.free = false; } - that.first = left; - that.second = right; - return that; - }); - prefix('+'); - prefix('+++', function () { - token.warn('confusing_a'); - this.first = expression(150); - this.arity = 'prefix'; - return this; - }); - infix('+++', 130, function (left) { - token.warn('confusing_a'); - this.first = left; - this.second = expression(130); - return this; - }); - infix('-', 130, function (left, that) { - if ((left.id === '(number)' && left.number === 0) || left.id === '(string)') { - left.warn('unexpected_a'); - } - var right = expression(130); - if ((right.id === '(number)' && right.number === 0) || right.id === '(string)') { - right.warn('unexpected_a'); - } - if (left.id === right.id && left.id === '(number)') { - left.number -= right.number; - left.thru = right.thru; - return left; - } - that.first = left; - that.second = right; - return that; - }); - prefix('-'); - prefix('---', function () { - token.warn('confusing_a'); - this.first = expression(150); - this.arity = 'prefix'; - return this; - }); - infix('---', 130, function (left) { - token.warn('confusing_a'); - this.first = left; - this.second = expression(130); - return this; + return the_paren; }); - infix('*', 140, function (left, that) { - if ((left.id === '(number)' && (left.number === 0 || left.number === 1)) || left.id === '(string)') { - left.warn('unexpected_a'); - } - var right = expression(140); - if ((right.id === '(number)' && (right.number === 0 || right.number === 1)) || right.id === '(string)') { - right.warn('unexpected_a'); - } - if (left.id === right.id && left.id === '(number)') { - left.number *= right.number; - left.thru = right.thru; - return left; - } - that.first = left; - that.second = right; - return that; + infix('.', 170, function (left) { + var the_token = token, + name = next_token; + if ( + (left.id !== '(string)' || name.id !== 'indexOf') && + (left.id !== '[' || ( + name.id !== 'concat' && name.id !== 'forEach' + )) && + (left.id !== '+' || name.id !== 'slice') && + (left.id !== '(regexp)' || ( + name.id !== 'exec' && name.id !== 'test' + )) + ) { + left_check(left, the_token); + } + if (!name.identifier) { + stop('expected_identifier_a'); + } + advance(); + survey(name); + +// The property name is not an expression. + + the_token.name = name; + the_token.expression = left; + return the_token; }); - infix('/', 140, function (left, that) { - if ((left.id === '(number)' && left.number === 0) || left.id === '(string)') { - left.warn('unexpected_a'); - } - var right = expression(140); - if ((right.id === '(number)' && (right.number === 0 || right.number === 1)) || right.id === '(string)') { - right.warn('unexpected_a'); - } - if (left.id === right.id && left.id === '(number)') { - left.number /= right.number; - left.thru = right.thru; - return left; - } - that.first = left; - that.second = right; - return that; + infix('[', 170, function (left) { + var the_token = token, + the_subscript = expression(0); + if ( + the_subscript.id === '(string)' && + rx_identifier.test(the_subscript.value) + ) { + warn('subscript_a', the_subscript); + survey(the_subscript); + } else if (the_subscript.id === '`') { + warn('unexpected_a', the_subscript); + } + left_check(left, the_token); + the_token.expression = [left, the_subscript]; + advance(']'); + return the_token; }); - infix('%', 140, function (left, that) { - if ((left.id === '(number)' && (left.number === 0 || left.number === 1)) || left.id === '(string)') { - left.warn('unexpected_a'); - } - var right = expression(140); - if ((right.id === '(number)' && right.number === 0) || right.id === '(string)') { - right.warn('unexpected_a'); - } - if (left.id === right.id && left.id === '(number)') { - left.number %= right.number; - left.thru = right.thru; - return left; - } - that.first = left; - that.second = right; - return that; + infix('=>', 170, function (left) { + return stop('expected_a_before_b', left, '(', artifact(left)); }); - suffix('++'); - prefix('++'); - - suffix('--'); - prefix('--'); - prefix('delete', function (that) { - one_space(); - var p = expression(0); - if (!p || (p.id !== '.' && p.id !== '[')) { - next_token.warn('deleted'); + function do_tick() { + var the_tick = token; + if (!option.es6) { + warn('es6', the_tick); + } + the_tick.value = []; + the_tick.expression = []; + if (next_token.id !== '`') { + (function part() { + advance('(string)'); + the_tick.value.push(token); + if (next_token.id === '${') { + advance('${'); + the_tick.expression.push(expression(0)); + advance('}'); + return part(); + } + }()); } - that.first = p; - return that; + advance('`'); + return the_tick; + } + + infix('`', 160, function (left) { + var the_tick = do_tick(); + left_check(left, the_tick); + the_tick.expression = [left].concat(the_tick.expression); + return the_tick; }); + post('++'); + post('--'); + pre('++'); + pre('--'); - prefix('~', function (that) { - no_space_only(); - if (!option.bitwise) { - that.warn('unexpected_a'); - } - that.first = expression(150); - return that; - }); - function banger(that) { - no_space_only(); - that.first = expected_condition(expression(150)); - if (bang[that.first.id] === that || that.first.assign) { - that.warn('confusing_a'); - } - return that; - } - prefix('!', banger); - prefix('!!', banger); - prefix('typeof'); - prefix('new', function (that) { - one_space(); - var c = expression(160), n, p, v; - that.first = c; - if (c.id !== 'function') { - if (c.identifier) { - switch (c.string) { - case 'Object': - token.warn('use_object'); - break; - case 'Array': - if (next_token.id === '(') { - p = next_token; - p.first = this; - advance('('); - if (next_token.id !== ')') { - n = expression(0); - p.second = [n]; - if (n.id === '(string)' || next_token.id === ',') { - p.warn('use_array'); - } - while (next_token.id === ',') { - advance(','); - p.second.push(expression(0)); - } - } else { - token.warn('use_array'); - } - advance(')', p); - return p; - } - token.warn('use_array'); - break; - case 'Number': - case 'String': - case 'Boolean': - case 'Math': - case 'JSON': - c.warn('not_a_constructor'); - break; - case 'Function': - if (!option.evil) { - next_token.warn('function_eval'); - } - break; - case 'Date': - case 'RegExp': - case 'this': - break; - default: - if (c.id !== 'function') { - v = c.string.charAt(0); - if (!option.newcap && (v < 'A' || v > 'Z')) { - token.warn('constructor_name_a'); - } + prefix('+'); + prefix('-'); + prefix('~'); + prefix('!'); + prefix('!!'); + prefix('[', function () { + var the_token = token; + the_token.expression = []; + if (next_token.id !== ']') { + (function next() { + var element, + ellipsis = false; + if (next_token.id === '...') { + ellipsis = true; + if (!option.es6) { + warn('es6'); } + advance('...'); } - } else { - if (c.id !== '.' && c.id !== '[' && c.id !== '(') { - token.warn('bad_constructor'); + element = expression(10); + if (ellipsis) { + element.ellipsis = true; } - } - } else { - that.warn('weird_new'); - } - if (next_token.id !== '(') { - next_token.warn('missing_a', '()'); + the_token.expression.push(element); + if (next_token.id === ',') { + advance(','); + return next(); + } + }()); } - return that; + advance(']'); + return the_token; + }); + prefix('/=', function () { + stop('expected_a_b', token, '/\\=', '/='); + }); + prefix('=>', function () { + return stop('expected_a_before_b', token, '()', '=>'); + }); + prefix('new', function () { + var the_new = token; + next_token.new = true; + the_new.expression = expression(150); + if (the_new.expression.id !== '(') { + warn('expected_a_before_b', next_token, '()', artifact(next_token)); + } + return the_new; + }); + prefix('typeof'); + prefix('void', function () { + var the_void = token; + warn('unexpected_a', the_void); + the_void.expression = expression(0); + return the_void; }); - infix('(', 160, function (left, that) { - var e, p; - if (indent && indent.mode === 'expression') { - no_space(prev_token, token); - } else { - no_space_only(prev_token, token); - } - if (!left.immed && left.id === 'function') { - next_token.warn('wrap_immediate'); - } - p = []; - if (left.identifier) { - if (left.string.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { - if (left.string !== 'Number' && left.string !== 'String' && - left.string !== 'Boolean' && left.string !== 'Date') { - if (left.string === 'Math') { - left.warn('not_a_function'); - } else if (left.string === 'Object') { - token.warn('use_object'); - } else if (left.string === 'Array' || !option.newcap) { - left.warn('missing_a', 'new'); + function parameter(list, signature) { + var ellipsis = false, + param; + if (next_token.id === '{') { + if (!option.es6) { + warn('es6'); + } + param = next_token; + param.names = []; + advance('{'); + signature.push('{'); + (function subparameter() { + var subparam = next_token; + if (!subparam.identifier) { + return stop('expected_identifier_a'); + } + survey(subparam); + advance(); + signature.push(subparam.id); + if (next_token.id === ':') { + advance(':'); + advance(); + token.label = subparam; + subparam = token; + if (!subparam.identifier) { + return stop('expected_identifier_a'); } } - } else if (left.string === 'JSON') { - left.warn('not_a_function'); + param.names.push(subparam); + if (next_token.id === ',') { + advance(','); + signature.push(", "); + return subparameter(); + } + }()); + list.push(param); + advance('}'); + signature.push('}'); + if (next_token.id === ',') { + advance(','); + signature.push(", "); + return parameter(list, signature); } - } else if (left.id === '.') { - if (left.second.string === 'split' && - left.first.id === '(string)') { - left.second.warn('use_array'); + } else if (next_token.id === '[') { + if (!option.es6) { + warn('es6'); } - } - step_in(); - if (next_token.id !== ')') { - no_space(); - for (;;) { - edge(); - e = expression(10); - if (left.string === 'Boolean' && (e.id === '!' || e.id === '~')) { - e.warn('weird_condition'); + param = next_token; + param.names = []; + advance('['); + signature.push("[]"); + (function subparameter() { + var subparam = next_token; + if (!subparam.identifier) { + return stop('expected_identifier_a'); } - p.push(e); - if (next_token.id !== ',') { - break; + advance(); + param.names.push(subparam); + if (next_token.id === ',') { + advance(','); + return subparameter(); } - comma(); - } - } - no_space(); - step_out(')', that); - if (typeof left === 'object') { - if (left.string === 'parseInt' && p.length === 1) { - left.warn('radix'); - } else if (left.string === 'String' && p.length >= 1 && p[0].id === '(string)') { - left.warn('unexpected_a'); + }()); + list.push(param); + advance(']'); + if (next_token.id === ',') { + advance(','); + signature.push(", "); + return parameter(list, signature); } - if (!option.evil) { - if (left.string === 'eval' || left.string === 'Function' || - left.string === 'execScript') { - left.warn('evil'); - } else if (p[0] && p[0].id === '(string)' && - (left.string === 'setTimeout' || - left.string === 'setInterval')) { - left.warn('implied_evil'); + } else { + if (next_token.id === '...') { + if (!option.es6) { + warn('es6'); } + ellipsis = true; + signature.push("..."); + advance('...'); } - if (!left.identifier && left.id !== '.' && left.id !== '[' && - left.id !== '(' && left.id !== '&&' && left.id !== '||' && - left.id !== '?') { - left.warn('bad_invocation'); + if (!next_token.identifier) { + return stop('expected_identifier_a'); } - if (left.id === '.') { - if (p.length > 0 && - left.first && left.first.first && - are_similar(p[0], left.first.first)) { - if (left.second.string === 'call' || - (left.second.string === 'apply' && (p.length === 1 || - (p[1].arity === 'prefix' && p[1].id === '[')))) { - left.second.warn('unexpected_a'); + param = next_token; + list.push(param); + advance(); + signature.push(param.id); + if (ellipsis) { + param.ellipsis = true; + } else { + if (next_token.id === '=') { + if (!option.es6) { + warn('es6'); } + advance('='); + param.expression = expression(0); } - if (left.second.string === 'toString') { - if (left.first.id === '(string)' || left.first.id === '(number)') { - left.second.warn('unexpected_a'); - } + if (next_token.id === ',') { + advance(','); + signature.push(", "); + return parameter(list, signature); } } } - that.first = left; - that.second = p; - return that; - }, true); - - prefix('(', function (that) { - step_in('expression'); - no_space(); - edge(); - if (next_token.id === 'function') { - next_token.immed = true; - } - var value = expression(0); - value.paren = true; - no_space(); - step_out(')', that); - if (value.id === 'function') { - switch (next_token.id) { - case '(': - next_token.warn('move_invocation'); - break; - case '.': - case '[': - next_token.warn('unexpected_a'); - break; - default: - that.warn('bad_wrap'); - } - } else if (!value.arity) { - if (!option.closure || !that.comments) { - that.warn('unexpected_a'); - } + } + + function parameter_list() { + var list = [], signature = ['(']; + if (next_token.id !== ')' && next_token.id !== '(end)') { + parameter(list, signature); } - return value; - }); + advance(')'); + signature.push(')'); + return [list, signature.join('')]; + } - infix('.', 170, function (left, that) { - no_space(prev_token, token); - no_space(); - var name = identifier(); - if (typeof name === 'string') { - tally_property(name); - } - that.first = left; - that.second = token; - if (left && left.string === 'arguments' && - (name === 'callee' || name === 'caller')) { - left.warn('avoid_a', 'arguments.' + name); - } else if (!option.evil && left && left.string === 'document' && - (name === 'write' || name === 'writeln')) { - left.warn('write_is_wrong'); - } else if (!option.stupid && syx.test(name)) { - token.warn('sync_a'); - } else if (left && left.id === '{') { - that.warn('unexpected_a'); - } - if (!option.evil && (name === 'eval' || name === 'execScript')) { - next_token.warn('evil'); - } - return that; - }, true); - - infix('[', 170, function (left, that) { - var e, s; - no_space_only(prev_token, token); - no_space(); - step_in(); - edge(); - e = expression(0); - switch (e.id) { - case '(number)': - if (e.id === '(number)' && left.id === 'arguments') { - left.warn('use_param'); - } - break; - case '(string)': - if (!option.evil && - (e.string === 'eval' || e.string === 'execScript')) { - e.warn('evil'); - } else if (!option.sub && ix.test(e.string)) { - s = syntax[e.string]; - if (!s || !s.reserved) { - e.warn('subscript'); + function do_function(the_function) { + var name; + if (the_function === undefined) { + the_function = token; + +// A function statement must have a name that will be in the parent's scope. + + if (the_function.arity === 'statement') { + if (!next_token.identifier) { + return stop('expected_identifier_a', next_token); } - } - tally_property(e.string); - break; - } - if (left && (left.id === '{' || (left.id === '[' && left.arity === 'prefix'))) { - that.warn('unexpected_a'); - } - step_out(']', that); - no_space(prev_token, token); - that.first = left; - that.second = e; - return that; - }, true); - - prefix('[', function (that) { - that.first = []; - step_in('array'); - while (next_token.id !== '(end)') { - while (next_token.id === ',') { - next_token.warn('unexpected_a'); - advance(','); - } - if (next_token.id === ']') { - break; - } - indent.wrap = false; - edge(); - that.first.push(expression(10)); - if (next_token.id === ',') { - comma(); - if (next_token.id === ']') { - token.warn('unexpected_a'); - break; + name = next_token; + enroll(name, 'variable', true); + the_function.name = name; + name.init = true; + name.calls = empty(); + advance(); + } else if (name === undefined) { + +// A function expression may have an optional name. + + if (next_token.identifier) { + name = next_token; + the_function.name = name; + advance(); + } else { + the_function.name = anon; } - } else { - break; } + } else { + name = the_function.name; + } + the_function.level = functionage.level + 1; + if (mega_mode) { + warn('unexpected_a', the_function); } - step_out(']', that); - return that; - }, 170); +// Don't make functions in loops. It is inefficient, and it can lead to scoping +// errors. - function property_name() { - var id = optional_identifier(); - if (!id) { - if (next_token.id === '(string)') { - id = next_token.string; - advance(); - } else if (next_token.id === '(number)') { - id = next_token.number.toString(); - advance(); - } + if (functionage.loop > 0) { + warn('function_in_loop', the_function); } - return id; - } +// Give the function properties for storing its names and for observing the +// depth of loops and switches. + the_function.context = empty(); + the_function.loop = 0; + the_function.switch = 0; - assignop('='); - assignop('+=', '+'); - assignop('-=', '-'); - assignop('*=', '*'); - assignop('/=', '/').nud = function () { - next_token.stop('slash_equal'); - }; - assignop('%=', '%'); - assignop('&=', '&'); - assignop('|=', '|'); - assignop('^=', '^'); - assignop('<<=', '<<'); - assignop('>>=', '>>'); - assignop('>>>=', '>>>'); - - function function_parameters() { - var id, parameters = [], paren = next_token; - advance('('); - token.function = funct; - step_in(); - no_space(); - if (next_token.id !== ')') { - for (;;) { - edge(); - id = identifier(); - if (token.reserved) { - token.warn('expected_identifier_a_reserved'); - } - define('parameter', token); - parameters.push(id); - token.init = true; - token.writeable = true; - if (next_token.id !== ',') { - break; - } - comma(); - } +// Push the current function context and establish a new one. + + stack.push(functionage); + functions.push(the_function); + functionage = the_function; + if (the_function.arity !== 'statement' && name) { + enroll(name, 'function', true); + name.dead = false; + name.init = true; + name.used = 1; } - no_space(); - step_out(')', paren); - return parameters; - } - function do_function(func, name) { - var old_funct = funct, - old_option = option, - old_scope = scope; - scope = Object.create(old_scope); - funct = { - closure: [], - global: [], - level: old_funct.level + 1, - line: next_token.line, - loopage: 0, - name: name || '\'' + (anonname || '').replace(nx, sanitize) + '\'', - outer: [], - scope: scope - }; - funct.parameter = function_parameters(); - func.function = funct; - option = Object.create(old_option); - functions.push(funct); - if (name) { - func.name = name; - func.string = name; - define('function', func); - func.init = true; - func.used += 1; - } - func.writeable = false; - one_space(); - func.block = block('function'); - Object.keys(scope).forEach(function (name) { - var master = scope[name]; - if (!master.used && master.kind !== 'exception' && - (master.kind !== 'parameter' || !option.unparam)) { - master.warn('unused_a'); - } else if (!master.init) { - master.warn('uninitialized_a'); - } - }); - funct = old_funct; - option = old_option; - scope = old_scope; - } +// Parse the parameter list. - prefix('{', function (that) { - var get, i, j, name, set, seen = Object.create(null); - that.first = []; - step_in(); - while (next_token.id !== '}') { - indent.wrap = false; - -// JSLint recognizes the ES5 extension for get/set in object literals, -// but requires that they be used in pairs. - - edge(); - if (next_token.string === 'get' && peek().id !== ':') { - get = next_token; - advance('get'); - one_space_only(); - name = next_token; - i = property_name(); - if (!i) { - next_token.stop('missing_property'); - } - get.string = ''; - do_function(get); - if (funct.loopage) { - get.warn('function_loop'); - } - if (get.function.parameter.length) { - get.warn('parameter_a_get_b', get.function.parameter[0], i); - } - comma(); - set = next_token; - spaces(); - edge(); - advance('set'); - set.string = ''; - one_space_only(); - j = property_name(); - if (i !== j) { - token.stop('expected_a_b', i, j || next_token.string); - } - do_function(set); - if (set.block.length === 0) { - token.warn('missing_a', 'throw'); - } - if (set.function.parameter.length === 0) { - set.stop('parameter_set_a', 'value'); - } else if (set.function.parameter[0] !== 'value') { - set.stop('expected_a_b', 'value', - set.function.parameter[0]); - } - name.first = [get, set]; + advance('('); + token.free = false; + token.arity = 'function'; + var pl = parameter_list(); + functionage.parameters = pl[0]; + functionage.signature = pl[1]; + functionage.parameters.forEach(function enroll_parameter(name) { + if (name.identifier) { + enroll(name, 'parameter', false); } else { - name = next_token; - i = property_name(); - if (typeof i !== 'string') { - next_token.stop('missing_property'); - } - advance(':'); - spaces(); - name.first = expression(10); - } - that.first.push(name); - if (seen[i] === true) { - next_token.warn('duplicate_a', i); - } - seen[i] = true; - tally_property(i); - if (next_token.id !== ',') { - break; - } - for (;;) { - comma(); - if (next_token.id !== ',') { - break; - } - next_token.warn('unexpected_a'); - } - if (next_token.id === '}') { - token.warn('unexpected_a'); + name.names.forEach(enroll_parameter); } + }); + +// The function's body is a block. + + the_function.block = block('body'); + if (the_function.arity === 'statement' && next_token.line === token.line) { + return stop('unexpected_a', next_token); + } + if (next_token.id === '.' || next_token.id === '[') { + warn('unexpected_a'); } - step_out('}', that); - return that; - }); - stmt('{', function () { - next_token.warn('statement_block'); - this.arity = 'statement'; - this.block = statements(); - this.disrupt = this.block.disrupt; - advance('}', this); - return this; - }); +// Restore the previous context. - stmt('/*global', directive); - stmt('/*globals', directive); - stmt('/*jslint', directive); - stmt('/*member', directive); - stmt('/*members', directive); - stmt('/*property', directive); - stmt('/*properties', directive); + functionage = stack.pop(); + return the_function; + } + + prefix('function', do_function); - stmt('var', function () { + function fart(pl) { + if (next_token.id === ';') { + stop('wrap_assignment', token); + } + advance('=>'); + var the_arrow = token; + the_arrow.arity = 'binary'; + the_arrow.name = "=>"; + the_arrow.level = functionage.level + 1; + functions.push(the_arrow); + if (functionage.loop > 0) { + warn('function_in_loop', the_arrow); + } -// JavaScript does not have block scope. It only has function scope. So, -// declaring a variable in a block can have unexpected consequences. +// Give the function properties storing its names and for observing the depth +// of loops and switches. -// var.first will contain an array, the array containing name tokens -// and assignment tokens. + the_arrow.context = empty(); + the_arrow.loop = 0; + the_arrow.switch = 0; - var assign, id, name; +// Push the current function context and establish a new one. - if (funct.loopage) { - next_token.warn('var_loop'); - } else if (funct.varstatement && !option.vars) { - next_token.warn('combine_var'); + stack.push(functionage); + functionage = the_arrow; + the_arrow.parameters = pl[0]; + the_arrow.signature = pl[1]; + the_arrow.parameters.forEach(function (name) { + enroll(name, 'parameter', true); + }); + if (!option.es6) { + warn('es6', the_arrow); } - if (funct !== global_funct) { - funct.varstatement = true; + if (next_token.id === '{') { + warn('expected_a_b', the_arrow, "function", "=>"); + the_arrow.block = block('body'); + } else { + the_arrow.expression = expression(0); } - this.arity = 'statement'; - this.first = []; - step_in('var'); - for (;;) { - name = next_token; - id = identifier(true); - define('var', name); - name.dead = funct; - if (next_token.id === '=') { - if (funct === global_funct && !name.writeable) { - name.warn('read_only'); + functionage = stack.pop(); + return the_arrow; + } + + prefix('(', function () { + var the_paren = token, + the_value, + cadet = lookahead().id; + +// We can distinguish between a parameter list for => and a wrapped expression +// with one token of lookahead. + + if ( + next_token.id === ')' || + next_token.id === '...' || + (next_token.identifier && (cadet === ',' || cadet === '=')) + ) { + the_paren.free = false; + return fart(parameter_list()); + } + the_paren.free = true; + the_value = expression(0); + if (the_value.wrapped === true) { + warn('unexpected_a', the_paren); + } + the_value.wrapped = true; + advance(')', the_paren); + if (next_token.id === "=>") { + if (the_value.arity !== 'variable') { + return stop('expected_identifier_a', the_value); + } + the_paren.expression = [the_value]; + return fart([the_paren.expression, "(" + the_value.id + ")"]); + } + return the_value; + }); + prefix('`', do_tick); + prefix('{', function () { + var the_brace = token, + seen = empty(); + the_brace.expression = []; + if (next_token.id !== '}') { + (function member() { + var extra = true, + id, + name = next_token, + value; + advance(); + if ( + (name.id === 'get' || name.id === 'set') && + next_token.identifier + ) { + extra = name.id; + name = next_token; + advance(); } - assign = next_token; - assign.first = name; - spaces(); - advance('='); - spaces(); - if (next_token.id === 'undefined') { - token.warn('unnecessary_initialize', id); + id = survey(name); + if (seen[id] === true) { + warn('duplicate_a', name); + } else if (seen[id] === 'get' && extra !== 'set') { + warn('expected_a_before_b', name, 'set', artifact(name)); + } + seen[id] = (extra === 'get') + ? 'get' + : true; + if (name.identifier) { + switch (next_token.id) { + case '}': + case ',': + if (!option.es6) { + warn('es6'); + } else if (extra !== true) { + advance(':'); + } + value = expression(Infinity, true); + break; + case '(': + if (!option.es6 && typeof extra !== 'string') { + warn('es6'); + } + value = do_function({ + arity: 'unary', + from: name.from, + id: 'function', + line: name.line, + name: name, + thru: name.from + }, name); + break; + default: + advance(':'); + value = expression(0); + } + value.label = name; + if (typeof extra === 'string') { + value.extra = extra; + } + the_brace.expression.push(value); + } else { + advance(':'); + value = expression(0); + value.label = name; + the_brace.expression.push(value); } - if (peek(0).id === '=' && next_token.identifier) { - next_token.stop('var_a_not'); + if (next_token.id === ',') { + advance(','); + return member(); } - assign.second = expression(0); - assign.arity = 'infix'; - name.init = true; - this.first.push(assign); - } else { - this.first.push(name); - } - name.dead = false; - name.writeable = true; - if (next_token.id !== ',') { - break; - } - comma(); - indent.wrap = false; - if (var_mode && next_token.line === token.line && - this.first.length === 1) { - var_mode = null; - indent.open = false; - indent.at -= option.indent; - } - spaces(); - edge(); + }()); } - var_mode = null; - step_out(); - return this; + advance('}'); + return the_brace; }); - stmt('function', function () { - one_space(); - if (in_block) { - token.warn('function_block'); - } - var name = next_token, - id = identifier(true); - define('var', name); - if (!name.writeable) { - name.warn('read_only'); - } - name.init = true; - name.statement = true; - no_space(); - this.arity = 'statement'; - do_function(this, id); - if (next_token.id === '(' && next_token.line === token.line) { - next_token.stop('function_statement'); - } - return this; + stmt(';', function () { + warn('unexpected_a', token); + return token; }); - - prefix('function', function (that) { - var id = optional_identifier(true), name; - if (id) { - name = token; - no_space(); - } else { - id = ''; - one_space(); - } - do_function(that, id); - if (name) { - name.function = that.function; - } - if (funct.loopage) { - that.warn('function_loop'); - } - switch (next_token.id) { - case ';': - case '(': - case ')': - case ',': - case ']': - case '}': - case ':': - case '(end)': - break; - case '.': - if (peek().string !== 'bind' || peek(1).id !== '(') { - next_token.warn('unexpected_a'); - } - break; - default: - next_token.stop('unexpected_a'); - } - that.arity = 'function'; - return that; + stmt('{', function () { + warn('naked_block', token); + return block('naked'); }); - - stmt('if', function () { - var paren = next_token; - one_space(); - advance('('); - step_in('control'); - no_space(); - edge(); - this.arity = 'statement'; - this.first = expected_condition(expected_relation(expression(0))); - no_space(); - step_out(')', paren); - one_space(); - this.block = block('if'); - if (next_token.id === 'else') { - if (this.block.disrupt) { - next_token.warn(this.elif ? 'use_nested_if' : 'unnecessary_else'); - } - one_space(); - advance('else'); - one_space(); - if (next_token.id === 'if') { - next_token.elif = true; - this.else = statement(true); + stmt('break', function () { + var the_break = token, + the_label; + if (functionage.loop < 1 && functionage.switch < 1) { + warn('unexpected_a', the_break); + } + the_break.disrupt = true; + if (next_token.identifier && token.line === next_token.line) { + the_label = functionage.context[next_token.id]; + if ( + the_label === undefined || + the_label.role !== 'label' || + the_label.dead + ) { + warn((the_label !== undefined && the_label.dead) + ? 'out_of_scope_a' + : 'not_label_a'); } else { - this.else = block('else'); - } - if (this.else.disrupt && this.block.disrupt) { - this.disrupt = true; + the_label.used += 1; } + the_break.label = next_token; + advance(); } - return this; + advance(';'); + return the_break; }); - stmt('try', function () { + function do_var() { + var the_statement = token, + is_const = the_statement.id === 'const'; + the_statement.names = []; + +// A program may use var or let, but not both, and let and const require +// option.es6. + + if (is_const) { + if (!option.es6) { + warn('es6', the_statement); + } + } else if (var_mode === undefined) { + var_mode = the_statement.id; + if (!option.es6 && var_mode !== 'var') { + warn('es6', the_statement); + } + } else if (the_statement.id !== var_mode) { + warn( + 'expected_a_b', + the_statement, + var_mode, + the_statement.id + ); + } -// try.first The catch variable -// try.second The catch clause -// try.third The finally clause -// try.block The try block +// We don't expect to see variables created in switch statements. - var exception_variable, paren; - one_space(); - this.arity = 'statement'; - this.block = block('try'); - if (next_token.id === 'catch') { - one_space(); - advance('catch'); - one_space(); - paren = next_token; - advance('('); - step_in('control'); - no_space(); - edge(); - exception_variable = next_token; - this.first = identifier(); - define('exception', exception_variable); - exception_variable.init = true; - no_space(); - step_out(')', paren); - one_space(); - this.second = block('catch'); - if (this.second.length) { - if (this.first === 'ignore') { - exception_variable.warn('unexpected_a'); + if (functionage.switch > 0) { + warn('var_switch', the_statement); + } + if (functionage.loop > 0 && the_statement.id === 'var') { + warn('var_loop', the_statement); + } + (function next() { + if (next_token.id === '{' && the_statement.id !== 'var') { + var the_brace = next_token; + the_brace.names = []; + advance('{'); + (function pair() { + if (!next_token.identifier) { + return stop('expected_identifier_a', next_token); + } + var name = next_token; + survey(name); + advance(); + if (next_token.id === ':') { + advance(':'); + if (!next_token.identifier) { + return stop('expected_identifier_a', next_token); + } + next_token.label = name; + the_brace.names.push(next_token); + enroll(next_token, 'variable', is_const); + advance(); + } else { + the_brace.names.push(name); + enroll(name, 'variable', is_const); + } + if (next_token.id === ',') { + advance(','); + return pair(); + } + }()); + advance('}'); + advance('='); + the_brace.expression = expression(0); + the_statement.names.push(the_brace); + } else if (next_token.id === '[' && the_statement.id !== 'var') { + var the_bracket = next_token; + the_bracket.names = []; + advance('['); + (function element() { + var ellipsis; + if (next_token.id === '...') { + ellipsis = true; + advance('...'); + } + if (!next_token.identifier) { + return stop('expected_identifier_a', next_token); + } + var name = next_token; + advance(); + the_bracket.names.push(name); + enroll(name, 'variable', the_statement.id === 'const'); + if (ellipsis) { + name.ellipsis = true; + } else if (next_token.id === ',') { + advance(','); + return element(); + } + }()); + advance(']'); + advance('='); + the_bracket.expression = expression(0); + the_statement.names.push(the_bracket); + } else if (next_token.identifier) { + var name = next_token; + advance(); + if (name.id === 'ignore') { + warn('unexpected_a', name); } - } else { - if (this.first !== 'ignore') { - exception_variable.warn('expected_a_b', 'ignore', - exception_variable.string); + enroll(name, 'variable', is_const); + if (next_token.id === '=' || is_const) { + advance('='); + name.expression = expression(0); + name.init = true; } + the_statement.names.push(name); + } else { + return stop('expected_identifier_a', next_token); } - exception_variable.dead = true; + if (next_token.id === ',') { + advance(','); + return next(); + } + }()); + the_statement.open = + the_statement.names.length > 1 && + the_statement.line !== the_statement.names[1].line; + semicolon(); + return the_statement; + } + + stmt('const', do_var); + stmt('continue', function () { + var the_continue = token; + if (functionage.loop < 1) { + warn('unexpected_a', the_continue); + } + not_top_level(the_continue); + the_continue.disrupt = true; + warn('unexpected_a', the_continue); + advance(';'); + return the_continue; + }); + stmt('debugger', function () { + var the_debug = token; + if (!option.devel) { + warn('unexpected_a', the_debug); } - if (next_token.id === 'finally') { - one_space(); - advance('finally'); - one_space(); - this.third = block('finally'); - } else if (!this.second) { - next_token.stop('expected_a_b', 'catch', artifact()); + semicolon(); + return the_debug; + }); + stmt('delete', function () { + var the_token = token, + the_value = expression(0); + if ( + (the_value.id !== '.' && the_value.id !== '[') || + the_value.arity !== 'binary' + ) { + stop('expected_a_b', the_value, '.', artifact(the_value)); + } + the_token.expression = the_value; + semicolon(); + return the_token; + }); + stmt('do', function () { + var the_do = token; + not_top_level(the_do); + functionage.loop += 1; + the_do.block = block(); + advance('while'); + the_do.expression = condition(); + semicolon(); + if (the_do.block.disrupt === true) { + warn('weird_loop', the_do); } - return this; + functionage.loop -= 1; + return the_do; }); - - labeled_stmt('while', function () { - one_space(); - var paren = next_token; - funct.loopage += 1; + stmt('export', function () { + var the_export = token; + if (!option.es6) { + warn('es6', the_export); + } + if (typeof module_mode === 'object') { + warn('unexpected_directive_a', module_mode, module_mode.directive); + } + advance('default'); + if (export_mode) { + warn('duplicate_a', token); + } + module_mode = true; + export_mode = true; + the_export.expression = expression(0); + semicolon(); + return the_export; + }); + stmt('for', function () { + var first, + the_for = token; + if (!option.for) { + warn('unexpected_a', the_for); + } + not_top_level(the_for); + functionage.loop += 1; advance('('); - step_in('control'); - no_space(); - edge(); - this.arity = 'statement'; - this.first = expected_relation(expression(0)); - if (this.first.id !== 'true') { - expected_condition(this.first, 'unexpected_a'); - } - no_space(); - step_out(')', paren); - one_space(); - this.block = block('while'); - if (this.block.disrupt) { - prev_token.warn('strange_loop'); - } - funct.loopage -= 1; - return this; + token.free = true; + if (next_token.id === ';') { + return stop('expected_a_b', the_for, 'while (', 'for (;'); + } + if ( + next_token.id === 'var' || + next_token.id === 'let' || + next_token.id === 'const' + ) { + return stop('unexpected_a'); + } + first = expression(0); + if (first.id === 'in') { + if (first.expression[0].arity !== 'variable') { + warn('bad_assignment_a', first.expression[0]); + } + the_for.name = first.expression[0]; + the_for.expression = first.expression[1]; + warn('expected_a_b', the_for, 'Object.keys', 'for in'); + } else { + the_for.initial = first; + advance(';'); + the_for.expression = expression(0); + advance(';'); + the_for.inc = expression(0); + if (the_for.inc.id === '++') { + warn('expected_a_b', the_for.inc, '+= 1', '++'); + } + } + advance(')'); + the_for.block = block(); + if (the_for.block.disrupt === true) { + warn('weird_loop', the_for); + } + functionage.loop -= 1; + return the_for; }); - - reserve('with'); - - labeled_stmt('switch', function () { - -// switch.first the switch expression -// switch.second the array of cases. A case is 'case' or 'default' token: -// case.first the array of case expressions -// case.second the array of statements -// If all of the arrays of statements are disrupt, then the switch is disrupt. - - var cases = [], - old_in_block = in_block, - particular, - that = token, - the_case = next_token; - - function find_duplicate_case(value) { - if (are_similar(particular, value)) { - value.warn('duplicate_a'); + stmt('function', do_function); + stmt('if', function () { + var the_else, + the_if = token; + the_if.expression = condition(); + the_if.block = block(); + if (next_token.id === 'else') { + advance('else'); + the_else = token; + the_if.else = (next_token.id === 'if') + ? statement() + : block(); + if (the_if.block.disrupt === true) { + if (the_if.else.disrupt === true) { + the_if.disrupt = true; + } else { + warn('unexpected_a', the_else); + } } } - - one_space(); + return the_if; + }); + stmt('import', function () { + var the_import = token; + if (!option.es6) { + warn('es6', the_import); + } else if (typeof module_mode === 'object') { + warn('unexpected_directive_a', module_mode, module_mode.directive); + } + module_mode = true; + if (!next_token.identifier) { + return stop('expected_identifier_a'); + } + var name = next_token; + advance(); + if (name.id === 'ignore') { + warn('unexpected_a', name); + } + enroll(name, 'variable', true); + advance('from'); + advance('(string)'); + the_import.import = token; + the_import.name = name; + if (!rx_identifier.test(token.value)) { + warn('bad_module_name_a', token); + } + imports.push(token.value); + semicolon(); + return the_import; + }); + stmt('let', do_var); + stmt('return', function () { + var the_return = token; + not_top_level(the_return); + the_return.disrupt = true; + if (next_token.id !== ';' && the_return.line === next_token.line) { + the_return.expression = expression(10); + } + advance(';'); + return the_return; + }); + stmt('switch', function () { + var dups = [], + last, + stmts, + the_cases = [], + the_disrupt = true, + the_switch = token; + not_top_level(the_switch); + functionage.switch += 1; advance('('); - no_space(); - step_in(); - this.arity = 'statement'; - this.first = expected_condition(expected_relation(expression(0))); - no_space(); - step_out(')', the_case); - one_space(); + token.free = true; + the_switch.expression = expression(0); + the_switch.block = the_cases; + advance(')'); advance('{'); - step_in(); - in_block = true; - this.second = []; - if (that.from !== next_token.from && !option.white) { - next_token.warn('expected_a_at_b_c', next_token.string, that.from, next_token.from); - } - while (next_token.id === 'case') { - the_case = next_token; - the_case.first = []; - the_case.arity = 'case'; - for (;;) { - spaces(); - edge('case'); + (function major() { + var the_case = next_token; + the_case.arity = 'statement'; + the_case.expression = []; + (function minor() { advance('case'); - one_space(); - particular = expression(0); - cases.forEach(find_duplicate_case); - cases.push(particular); - the_case.first.push(particular); - if (particular.id === 'NaN') { - particular.warn('unexpected_a'); + token.switch = true; + var exp = expression(0); + if (dups.some(function (thing) { + return are_similar(thing, exp); + })) { + warn('unexpected_a', exp); } - no_space_only(); + dups.push(exp); + the_case.expression.push(exp); advance(':'); - if (next_token.id !== 'case') { - break; + if (next_token.id === 'case') { + return minor(); } + }()); + stmts = statements(); + if (stmts.length < 1) { + warn('expected_statements_a'); + return; } - spaces(); - the_case.second = statements(); - if (the_case.second && the_case.second.length > 0) { - if (!the_case.second[the_case.second.length - 1].disrupt) { - next_token.warn('missing_a_after_b', 'break', 'case'); + the_case.block = stmts; + the_cases.push(the_case); + last = stmts[stmts.length - 1]; + if (last.disrupt) { + if (last.id === 'break' && last.label === undefined) { + the_disrupt = false; } } else { - next_token.warn('empty_case'); - } - this.second.push(the_case); - } - if (this.second.length === 0) { - next_token.warn('missing_a', 'case'); - } + warn( + 'expected_a_before_b', + next_token, + 'break;', + artifact(next_token) + ); + } + if (next_token.id === 'case') { + return major(); + } + }()); + dups = undefined; if (next_token.id === 'default') { - spaces(); - the_case = next_token; - the_case.arity = 'case'; - edge('case'); advance('default'); - no_space_only(); + token.switch = true; advance(':'); - spaces(); - the_case.second = statements(); - if (the_case.second && the_case.second.length > 0) { - this.disrupt = the_case.second[the_case.second.length - 1].disrupt; + the_switch.else = statements(); + if (the_switch.else.length < 1) { + warn('expected_statements_a'); + the_disrupt = false; } else { - the_case.warn('empty_case'); + the_disrupt = + the_disrupt && + the_switch.else[the_switch.else.length - 1].disrupt; } - this.second.push(the_case); - } - if (this.break) { - this.disrupt = false; - } - spaces(); - step_out('}', this); - in_block = old_in_block; - return this; - }); - - stmt('debugger', function () { - if (!option.debug) { - this.warn('unexpected_a'); + } else { + the_disrupt = false; } - this.arity = 'statement'; - return this; + advance('}', the_switch); + functionage.switch -= 1; + the_switch.disrupt = the_disrupt; + return the_switch; }); - - labeled_stmt('do', function () { - funct.loopage += 1; - one_space(); - this.arity = 'statement'; - this.block = block('do'); - if (this.block.disrupt) { - prev_token.warn('strange_loop'); - } - one_space(); - advance('while'); - var paren = next_token; - one_space(); - advance('('); - step_in(); - no_space(); - edge(); - this.first = expected_condition(expected_relation(expression(0)), 'unexpected_a'); - no_space(); - step_out(')', paren); - funct.loopage -= 1; - return this; + stmt('throw', function () { + var the_throw = token; + the_throw.disrupt = true; + the_throw.expression = expression(10); + semicolon(); + return the_throw; }); - - labeled_stmt('for', function () { - - var blok, filter, master, ok = false, paren = next_token, value; - this.arity = 'statement'; - funct.loopage += 1; - advance('('); - if (next_token.id === ';') { - no_space(); - advance(';'); - no_space(); - advance(';'); - no_space(); - advance(')'); - blok = block('for'); - } else { - step_in('control'); - spaces(this, paren); - no_space(); - if (next_token.id === 'var') { - next_token.stop('move_var'); + stmt('try', function () { + var clause = false, + the_catch, + the_disrupt, + the_try = token; + the_try.block = block(); + the_disrupt = the_try.block.disrupt; + if (next_token.id === 'catch') { + var ignored = 'ignore'; + clause = true; + the_catch = next_token; + the_try.catch = the_catch; + advance('catch'); + advance('('); + if (!next_token.identifier) { + return stop('expected_identifier_a', next_token); } - edge(); - if (peek(0).id === 'in') { - this.forin = true; - value = expression(1000); - master = value.master; - if (!master) { - value.stop('bad_in_a'); - } - if (master.kind !== 'var' || master.function !== funct || - !master.writeable || master.dead) { - value.warn('bad_in_a'); - } - master.init = true; - master.used -= 1; - this.first = value; - advance('in'); - this.second = expression(20); - step_out(')', paren); - blok = block('for'); - if (!option.forin) { - if (blok.length === 1 && typeof blok[0] === 'object') { - if (blok[0].id === 'if' && !blok[0].else) { - filter = blok[0].first; - while (filter.id === '&&') { - filter = filter.first; - } - switch (filter.id) { - case '===': - case '!==': - ok = filter.first.id === '[' - ? are_similar(filter.first.first, this.second) && - are_similar(filter.first.second, this.first) - : filter.first.id === 'typeof' && - filter.first.first.id === '[' && - are_similar(filter.first.first.first, this.second) && - are_similar(filter.first.first.second, this.first); - break; - case '(': - ok = filter.first.id === '.' && (( - are_similar(filter.first.first, this.second) && - filter.first.second.string === 'hasOwnProperty' && - are_similar(filter.second[0], this.first) - ) || ( - filter.first.first.id === '.' && - filter.first.first.first.first && - filter.first.first.first.first.string === 'Object' && - filter.first.first.first.id === '.' && - filter.first.first.first.second.string === 'prototype' && - filter.first.first.second.string === 'hasOwnProperty' && - filter.first.second.string === 'call' && - are_similar(filter.second[0], this.second) && - are_similar(filter.second[1], this.first) - )); - break; - } - } else if (blok[0].id === 'switch') { - ok = blok[0].id === 'switch' && - blok[0].first.id === 'typeof' && - blok[0].first.first.id === '[' && - are_similar(blok[0].first.first.first, this.second) && - are_similar(blok[0].first.first.second, this.first); - } - } - if (!ok) { - this.warn('for_if'); - } - } - } else { - edge(); - this.first = []; - for (;;) { - this.first.push(expression(0, 'for')); - if (next_token.id !== ',') { - break; - } - comma(); - } - semicolon(); - edge(); - this.second = expected_relation(expression(0)); - if (this.second.id !== 'true') { - expected_condition(this.second, 'unexpected_a'); - } - semicolon(token); - if (next_token.id === ';') { - next_token.stop('expected_a_b', ')', ';'); - } - this.third = []; - edge(); - for (;;) { - this.third.push(expression(0, 'for')); - if (next_token.id !== ',') { - break; - } - comma(); - } - no_space(); - step_out(')', paren); - one_space(); - blok = block('for'); + if (next_token.id !== 'ignore') { + ignored = undefined; + the_catch.name = next_token; + enroll(next_token, 'exception', true); + } + advance(); + advance(')'); + the_catch.block = block(ignored); + if (the_catch.block.disrupt !== true) { + the_disrupt = false; } } - if (blok.disrupt) { - prev_token.warn('strange_loop'); + if (next_token.id === 'finally') { + clause = true; + advance('finally'); + the_try.else = block(); + the_disrupt = the_try.else.disrupt; } - this.block = blok; - funct.loopage -= 1; - return this; + the_try.disrupt = the_disrupt; + if (!clause) { + warn('expected_a_before_b', next_token, 'catch', artifact(next_token)); + } + return the_try; + }); + stmt('var', do_var); + stmt('while', function () { + var the_while = token; + not_top_level(the_while); + functionage.loop += 1; + the_while.expression = condition(); + the_while.block = block(); + if (the_while.block.disrupt === true) { + warn('weird_loop', the_while); + } + functionage.loop -= 1; + return the_while; + }); + stmt('with', function () { + stop('unexpected_a', token); }); - function optional_label(that) { - var label = next_token.string, - master; - that.arity = 'statement'; - if (!funct.breakage || (!option.continue && that.id === 'continue')) { - that.warn('unexpected_a'); - } else if (next_token.identifier && token.line === next_token.line) { - one_space_only(); - master = scope[label]; - if (!master || master.kind !== 'label') { - next_token.warn('not_a_label'); - } else if (master.dead || master.function !== funct) { - next_token.warn('not_a_scope'); - } else { - master.used += 1; - if (that.id === 'break') { - master.statement.break = true; - } - if (funct.breakage[funct.breakage.length - 1] === master.statement) { - next_token.warn('unexpected_a'); - } - } - that.first = next_token; - advance(); - } else { - if (that.id === 'break') { - funct.breakage[funct.breakage.length - 1].break = true; - } - } - return that; + ternary('?', ':'); - } +// Ambulation of the parse tree. - disrupt_stmt('break', function () { - return optional_label(this); - }); + function action(when) { - disrupt_stmt('continue', function () { - return optional_label(this); - }); +// Produce a function that will register task functions that will be called as +// the tree is traversed. - disrupt_stmt('return', function () { - if (funct === global_funct) { - this.warn('unexpected_a'); - } - this.arity = 'statement'; - if (next_token.id !== ';' && next_token.line === token.line) { - if (option.closure) { - spaces(); - } else { - one_space_only(); + return function (arity, id, task) { + var a_set = when[arity], + i_set; + +// The id parameter is optional. If excluded, the task will be applied to all +// ids. + + if (typeof id !== 'string') { + task = id; + id = '(all)'; } - if (next_token.id === '/' || next_token.id === '(regexp)') { - next_token.warn('wrap_regexp'); + +// If this arity has no registrations yet, then create a set object to hold +// them. + + if (a_set === undefined) { + a_set = empty(); + when[arity] = a_set; } - this.first = expression(0); - if (this.first.assign) { - this.first.warn('unexpected_a'); + +// If this id has no registrations yet, then create a set array to hold them. + + i_set = a_set[id]; + if (i_set === undefined) { + i_set = []; + a_set[id] = i_set; } - } - return this; - }); - disrupt_stmt('throw', function () { - this.arity = 'statement'; - one_space_only(); - this.first = expression(20); - return this; - }); +// Register the task with the arity and the id. + i_set.push(task); + }; + } -// Superfluous reserved words + function amble(when) { - reserve('class'); - reserve('const'); - reserve('enum'); - reserve('export'); - reserve('extends'); - reserve('import'); - reserve('super'); +// Produce a function that will act on the tasks registered by an action +// function while walking the tree. -// Harmony reserved words + return function (the_token) { - reserve('implements'); - reserve('interface'); - reserve('let'); - reserve('package'); - reserve('private'); - reserve('protected'); - reserve('public'); - reserve('static'); - reserve('yield'); +// Given a task set that was built by an action function, run all of the +// relevant tasks on the token. + var a_set = when[the_token.arity], + i_set; -// Parse JSON +// If there are tasks associated with the token's arity... - function json_value() { + if (a_set !== undefined) { - function json_object() { - var brace = next_token, object = Object.create(null); - advance('{'); - if (next_token.id !== '}') { - while (next_token.id !== '(end)') { - while (next_token.id === ',') { - next_token.warn('unexpected_a'); - advance(','); - } - if (next_token.id !== '(string)') { - next_token.warn('expected_string_a'); - } - if (object[next_token.string] === true) { - next_token.warn('duplicate_a'); - } else if (next_token.string === '__proto__') { - next_token.warn('dangling_a'); - } else { - object[next_token.string] = true; - } - advance(); - advance(':'); - json_value(); - if (next_token.id !== ',') { - break; - } - advance(','); - if (next_token.id === '}') { - token.warn('unexpected_a'); - break; - } +// If there are tasks associated with the token's id... + + i_set = a_set[the_token.id]; + if (i_set !== undefined) { + i_set.forEach(function (task) { + return task(the_token); + }); + } + +// If there are tasks for all ids. + + i_set = a_set['(all)']; + if (i_set !== undefined) { + i_set.forEach(function (task) { + return task(the_token); + }); } } - advance('}', brace); + }; + } + + var posts = empty(), + pres = empty(), + preaction = action(pres), + postaction = action(posts), + preamble = amble(pres), + postamble = amble(posts); + + function walk_expression(thing) { + if (thing) { + if (Array.isArray(thing)) { + thing.forEach(walk_expression); + } else { + preamble(thing); + walk_expression(thing.expression); + if (thing.id === 'function') { + walk_statement(thing.block); + } + switch (thing.arity) { + case 'post': + case 'pre': + warn('unexpected_a', thing); + break; + case 'statement': + case 'assignment': + warn('unexpected_statement_a', thing); + break; + } + postamble(thing); + } } + } - function json_array() { - var bracket = next_token; - advance('['); - if (next_token.id !== ']') { - while (next_token.id !== '(end)') { - while (next_token.id === ',') { - next_token.warn('unexpected_a'); - advance(','); + function walk_statement(thing) { + if (thing) { + if (Array.isArray(thing)) { + thing.forEach(walk_statement); + } else { + preamble(thing); + walk_expression(thing.expression); + switch (thing.arity) { + case 'statement': + case 'assignment': + break; + case 'binary': + if (thing.id !== '(') { + warn('unexpected_expression_a', thing); } - json_value(); - if (next_token.id !== ',') { - break; + break; + default: + warn('unexpected_expression_a', thing); + } + walk_statement(thing.block); + walk_statement(thing.else); + postamble(thing); + } + } + } + + function lookup(thing) { + if (thing.arity === 'variable') { + +// Look up the variable in the current context. + + var the_variable = functionage.context[thing.id]; + +// If it isn't local, search all the other contexts. If there are name +// collisions, take the most recent. + + if (the_variable === undefined) { + stack.forEach(function (outer) { + var a_variable = outer.context[thing.id]; + if ( + a_variable !== undefined && + a_variable.role !== 'label' + ) { + the_variable = a_variable; } - advance(','); - if (next_token.id === ']') { - token.warn('unexpected_a'); - break; + }); + +// If it isn't in any of those either, perhaps it is a predefined global. +// If so, add it to the global context. + + if (the_variable === undefined) { + if (declared_globals[thing.id] === undefined) { + warn('undeclared_a', thing); + return; } + the_variable = { + dead: false, + function: global, + id: thing.id, + init: true, + role: 'variable', + used: 0, + writable: false + }; + global.context[thing.id] = the_variable; } + the_variable.closure = true; + functionage.context[thing.id] = the_variable; + } else if (the_variable.role === 'label') { + warn('label_a', thing); } - advance(']', bracket); + if (the_variable.dead) { + warn('out_of_scope_a', thing); + } + return the_variable; } + } - switch (next_token.id) { - case '{': - json_object(); - break; - case '[': - json_array(); - break; - case 'true': - case 'false': - case 'null': - case '(number)': - case '(string)': - advance(); + function subactivate(name) { + name.init = true; + name.dead = false; + blockage.live.push(name); + } + + function preaction_function(thing) { + if (thing.arity === 'statement' && blockage.body !== true) { + warn('unexpected_a', thing); + } + stack.push(functionage); + block_stack.push(blockage); + functionage = thing; + blockage = thing; + thing.live = []; + if (typeof thing.name === 'object') { + thing.name.dead = false; + thing.name.init = true; + } + switch (thing.extra) { + case 'get': + if (thing.parameters.length !== 0) { + warn('bad_get', thing); + } break; - case '-': - advance('-'); - no_space_only(); - advance('(number)'); + case 'set': + if (thing.parameters.length !== 1) { + warn('bad_set', thing); + } break; - default: - next_token.stop('unexpected_a'); } + thing.parameters.forEach(function (name) { + walk_expression(name.expression); + if (name.id === '{' || name.id === '[') { + name.names.forEach(subactivate); + } else { + name.dead = false; + name.init = true; + } + }); } + function bitwise_check(thing) { + if (!option.bitwise && bitwiseop[thing.id] === true) { + warn('unexpected_a', thing); + } + if ( + thing.id !== '(' && + thing.id !== '&&' && + thing.id !== '||' && + thing.id !== '=' && + Array.isArray(thing.expression) && + thing.expression.length === 2 && ( + relationop[thing.expression[0].id] === true || + relationop[thing.expression[1].id] === true + ) + ) { + warn('unexpected_a', thing); + } + } -// The actual JSLINT function itself. - - itself = function JSLint(the_source, the_option) { - - var i, predef, tree; - itself.errors = []; - itself.tree = ''; - itself.properties = ''; - begin = prev_token = token = next_token = - Object.create(syntax['(begin)']); - tokens = []; - predefined = Object.create(null); - add_to_predefined(standard); - property = Object.create(null); - if (the_option) { - option = Object.create(the_option); - predef = option.predef; - if (predef) { - if (Array.isArray(predef)) { - for (i = 0; i < predef.length; i += 1) { - predefined[predef[i]] = true; - } - } else if (typeof predef === 'object') { - add_to_predefined(predef); - } - } - } else { - option = Object.create(null); - } - option.indent = +option.indent || 4; - option.maxerr = +option.maxerr || 50; - global_scope = scope = Object.create(null); - global_funct = funct = { - scope: scope, - loopage: 0, - level: 0 - }; - functions = [funct]; - block_var = []; - - comments = []; - comments_off = false; - in_block = false; - indent = null; - json_mode = false; - lookahead = []; - node_js = false; - prereg = true; - strict_mode = false; - var_mode = null; - warnings = 0; - lex.init(the_source); - - assume(); + function pop_block() { + blockage.live.forEach(function (name) { + name.dead = true; + }); + delete blockage.live; + blockage = block_stack.pop(); + } - try { - advance(); - if (next_token.id === '(number)') { - next_token.stop('unexpected_a'); + function activate(name) { + if (name.expression !== undefined) { + walk_expression(name.expression); + if (name.id === '{' || name.id === '[') { + name.names.forEach(subactivate); } else { - switch (next_token.id) { - case '{': - case '[': - comments_off = true; - json_mode = true; - json_value(); - break; - default: + name.init = true; + } + } + name.dead = false; + blockage.live.push(name); + } -// If the first token is a semicolon, ignore it. This is sometimes used when -// files are intended to be appended to files that may be sloppy. A sloppy -// file may be depending on semicolon insertion on its last line. + function action_var(thing) { + thing.names.forEach(activate); + } - step_in(1); - if (next_token.id === ';' && !node_js) { - next_token.edge = true; - advance(';'); + preaction('assignment', bitwise_check); + preaction('binary', bitwise_check); + preaction('binary', function (thing) { + if (relationop[thing.id] === true) { + var left = thing.expression[0], + right = thing.expression[1]; + if (left.id === 'NaN' || right.id === 'NaN') { + warn('isNaN', thing); + } else if (left.id === 'typeof') { + if (right.id !== '(string)') { + if (right.id !== 'typeof') { + warn('expected_string_a', right); } - tree = statements(); - begin.first = tree; - itself.tree = begin; - if (tree.disrupt) { - prev_token.warn('weird_program'); + } else { + var value = right.value; + if (value === 'symbol') { + if (!option.es6) { + warn('es6', right, value); + } + } else if (value === 'null' || value === 'undefined') { + warn('unexpected_typeof_a', right, value); + } else if ( + value !== 'boolean' && + value !== 'function' && + value !== 'number' && + value !== 'object' && + value !== 'string' + ) { + warn('expected_type_string_a', right, value); } } } - indent = null; - advance('(end)'); - itself.property = property; - } catch (e) { - if (e) { // ~~ - itself.errors.push({ - reason : e.message, - line : e.line || next_token.line, - character : e.character || next_token.from - }, null); + } + }); + preaction('binary', '==', function (thing) { + warn('expected_a_b', thing, '===', '=='); + }); + preaction('binary', '!=', function (thing) { + warn('expected_a_b', thing, '!==', '!='); + }); + preaction('binary', '=>', preaction_function); + preaction('binary', '||', function (thing) { + thing.expression.forEach(function (thang) { + if (thang.id === '&&' && !thang.wrapped) { + warn('and', thang); + } + }); + }); + preaction('binary', '(', function (thing) { + var left = thing.expression[0]; + if ( + left.identifier && + functionage.context[left.id] === undefined && + typeof functionage.name === 'object' + ) { + var parent = functionage.name.function; + if (parent) { + var left_variable = parent.context[left.id]; + if ( + left_variable !== undefined && + left_variable.dead && + left_variable.function === parent && + left_variable.calls !== undefined && + left_variable.calls[functionage.name.id] !== undefined + ) { + left_variable.dead = false; + } } } - return itself.errors.length === 0; - }; + }); + preaction('binary', 'in', function (thing) { + warn('infix_in', thing); + }); + preaction('statement', '{', function (thing) { + block_stack.push(blockage); + blockage = thing; + thing.live = []; + }); + preaction('statement', 'for', function (thing) { + if (thing.name !== undefined) { + var the_variable = lookup(thing.name); + if (the_variable !== undefined) { + the_variable.init = true; + if (!the_variable.writable) { + warn('bad_assignment_a', thing.name); + } + } + } + walk_statement(thing.initial); + }); + preaction('statement', 'function', preaction_function); + preaction('unary', '~', bitwise_check); + preaction('unary', 'function', preaction_function); + preaction('variable', function (thing) { + var the_variable = lookup(thing); + if (the_variable !== undefined) { + thing.variable = the_variable; + the_variable.used += 1; + } + }); - function unique(array) { - array = array.sort(); - var i, length = 0, previous, value; - for (i = 0; i < array.length; i += 1) { - value = array[i]; - if (value !== previous) { - array[length] = value; - previous = value; - length += 1; + function init_variable(name) { + var the_variable = lookup(name); + if (the_variable !== undefined) { + if (the_variable.writable) { + the_variable.init = true; + return; } } - array.length = length; - return array; + warn('bad_assignment_a', name); } -// Data summary. - - itself.data = function () { - var data = {functions: []}, - function_data, - i, - the_function, - the_scope; - data.errors = itself.errors; - data.json = json_mode; - data.global = unique(Object.keys(global_scope)); - - function selects(name) { - var kind = the_scope[name].kind; - switch (kind) { - case 'var': - case 'exception': - case 'label': - function_data[kind].push(name); - break; + postaction('assignment', function (thing) { + +// Assignment using = sets the init property of a variable. No other assignment +// operator can do this. A = token keeps that variable (or array of variables +// in case of destructuring) in its name property. + + if (thing.id === '=') { + if (thing.names !== undefined) { + if (Array.isArray(thing.names)) { + thing.names.forEach(init_variable); + } else { + init_variable(thing.names); + } + } + } else { + var lvalue = thing.expression[0]; + if (lvalue.arity === 'variable') { + if (!lvalue.variable || lvalue.variable.writable !== true) { + warn('bad_assignment_a', lvalue); + } } } + }); - for (i = 1; i < functions.length; i += 1) { - the_function = functions[i]; - function_data = { - name: the_function.name, - line: the_function.line, - level: the_function.level, - parameter: the_function.parameter, - var: [], - exception: [], - closure: unique(the_function.closure), - outer: unique(the_function.outer), - global: unique(the_function.global), - label: [] - }; - the_scope = the_function.scope; - Object.keys(the_scope).forEach(selects); - function_data.var.sort(); - function_data.exception.sort(); - function_data.label.sort(); - data.functions.push(function_data); - } - data.tokens = tokens; - return data; - }; + function postaction_function(thing) { + delete functionage.loop; + delete functionage.switch; + functionage = stack.pop(); + if (thing.wrapped) { + warn('unexpected_parens', thing); + } + return pop_block(); + } - itself.error_report = function (data) { - var evidence, i, output = [], warning; - if (data.errors.length) { - if (data.json) { - output.push('JSON: bad.
'); + postaction('binary', function (thing) { + var right; + if (relationop[thing.id]) { + if ( + is_weird(thing.expression[0]) || + is_weird(thing.expression[1]) || + are_similar(thing.expression[0], thing.expression[1]) || + ( + thing.expression[0].constant === true && + thing.expression[1].constant === true + ) + ) { + warn('weird_relation_a', thing); + } + } + switch (thing.id) { + case '+': + case '-': + right = thing.expression[1]; + if ( + right.id === thing.id && + right.arity === 'unary' && + !right.wrapped + ) { + warn('wrap_unary', right); } - for (i = 0; i < data.errors.length; i += 1) { - warning = data.errors[i]; - if (warning) { - evidence = warning.evidence || ''; - output.push(''); - if (isFinite(warning.line)) { - output.push('
line ' + - String(warning.line) + - ' character ' + String(warning.character) + - '
'); - } - output.push(warning.reason.entityify() + '
'); - if (evidence) { - output.push('
' + evidence.entityify() + '
'); + break; + case '=>': + case '(': + break; + case '.': + if (thing.expression.id === 'RegExp') { + warn('weird_expression_a', thing); + } + break; + default: + if ( + thing.expression[0].constant === true && + thing.expression[1].constant === true + ) { + thing.constant = true; + } + } + }); + postaction('binary', '&&', function (thing) { + if ( + is_weird(thing.expression[0]) || + are_similar(thing.expression[0], thing.expression[1]) || + thing.expression[0].constant === true || + thing.expression[1].constant === true + ) { + warn('weird_condition_a', thing); + } + }); + postaction('binary', '||', function (thing) { + if ( + is_weird(thing.expression[0]) || + are_similar(thing.expression[0], thing.expression[1]) || + thing.expression[0].constant === true + ) { + warn('weird_condition_a', thing); + } + }); + postaction('binary', '=>', postaction_function); + postaction('binary', '(', function (thing) { + if (!thing.wrapped && thing.expression[0].id === 'function') { + warn('wrap_immediate', thing); + } + }); + postaction('binary', '[', function (thing) { + if (thing.expression[0].id === 'RegExp') { + warn('weird_expression_a', thing); + } + if (is_weird(thing.expression[1])) { + warn('weird_expression_a', thing.expression[1]); + } + }); + postaction('statement', '{', pop_block); + postaction('statement', 'const', action_var); + postaction('statement', 'export', top_level_only); + postaction('statement', 'for', function (thing) { + walk_statement(thing.inc); + }); + postaction('statement', 'function', postaction_function); + postaction('statement', 'import', function (the_thing) { + var name = the_thing.name; + name.init = true; + name.dead = false; + blockage.live.push(name); + return top_level_only(the_thing); + }); + postaction('statement', 'let', action_var); + postaction('statement', 'try', function (thing) { + if (thing.catch !== undefined) { + var the_name = thing.catch.name; + if (the_name !== undefined) { + var the_variable = functionage.context[the_name.id]; + the_variable.dead = false; + the_variable.init = true; + } + walk_statement(thing.catch.block); + } + }); + postaction('statement', 'var', action_var); + postaction('ternary', function (thing) { + if ( + is_weird(thing.expression[0]) || + thing.expression[0].constant === true || + are_similar(thing.expression[1], thing.expression[2]) + ) { + warn('unexpected_a', thing); + } else if (are_similar(thing.expression[0], thing.expression[1])) { + warn('expected_a_b', thing, '||', '?'); + } else if (are_similar(thing.expression[0], thing.expression[2])) { + warn('expected_a_b', thing, '&&', '?'); + } else if ( + thing.expression[1].id === 'true' && + thing.expression[2].id === 'false' + ) { + warn('expected_a_b', thing, '!!', '?'); + } else if ( + thing.expression[1].id === 'false' && + thing.expression[2].id === 'true' + ) { + warn('expected_a_b', thing, '!', '?'); + } else if (thing.expression[0].wrapped !== true && ( + thing.expression[0].id === '||' || + thing.expression[0].id === '&&' + )) { + warn('wrap_condition', thing.expression[0]); + } + }); + postaction('unary', function (thing) { + switch (thing.id) { + case '[': + case '{': + case 'function': + case 'new': + break; + case '`': + if (thing.expression.every(function (thing) { + return thing.constant; + })) { + thing.constant = true; + } + break; + default: + if (thing.expression.constant === true) { + thing.constant = true; + } + } + }); + postaction('unary', 'function', postaction_function); + + function delve(the_function) { + Object.keys(the_function.context).forEach(function (id) { + if (id !== 'ignore') { + var name = the_function.context[id]; + if (name.function === the_function) { + if (name.used === 0) { + warn('unused_a', name); + } else if (!name.init) { + warn('uninitialized_a', name); } } } - } - return output.join(''); - }; + }); + } + function uninitialized_and_unused() { - itself.report = function (data) { - var dl, i, j, names, output = [], the_function; +// Delve into the functions looking for variables that were not initialized +// or used. If the file imports or exports, then its global object is also +// delved. - function detail(h, array) { - var comma_needed = false; - if (array.length) { - output.push("
" + h + "
"); - array.forEach(function (item) { - output.push((comma_needed ? ', ' : '') + item); - comma_needed = true; - }); - output.push("
"); - } + if (module_mode === true || option.node) { + delve(global); + } + functions.forEach(delve); + } + +// Go through the token list, looking at usage of whitespace. + + function whitage() { + var closer = '(end)', + free = false, + left = global, + margin = 0, + nr_comments_skipped = 0, + open = true, + qmark = '', + result, + right; + + function expected_at(at) { + warn( + 'expected_a_at_b_c', + right, + artifact(right), + fudge + at, + artifact_column(right) + ); } - output.push('
'); - if (data.global.length) { - detail('global', data.global); - dl = true; - } else if (data.json) { - if (!data.errors.length) { - output.push("
JSON: good.
"); + function at_margin(fit) { + var at = margin + fit; + if (right.from !== at) { + return expected_at(at); } - } else { - output.push("
No new global variables introduced.
"); } - if (dl) { - output.push("
"); - } else { - output[0] = ''; + + function no_space_only() { + if (left.line !== right.line || left.thru !== right.from) { + warn( + 'unexpected_space_a_b', + right, + artifact(left), + artifact(right) + ); + } } - if (data.functions) { - for (i = 0; i < data.functions.length; i += 1) { - the_function = data.functions[i]; - names = []; - if (the_function.params) { - for (j = 0; j < the_function.params.length; j += 1) { - names[j] = the_function.params[j].string; + function no_space() { + if (left.line === right.line) { + if (left.thru !== right.from && nr_comments_skipped === 0) { + warn( + 'unexpected_space_a_b', + right, + artifact(left), + artifact(right) + ); + } + } else { + if (open) { + var at = (free) + ? margin + : margin + 8; + if (right.from < at) { + expected_at(at); + } + } else { + if (right.from !== margin + 8) { + expected_at(margin + 8); } } - output.push('
line ' + String(the_function.line) + - '
' + the_function.name.entityify()); - detail('parameter', the_function.parameter); - detail('variable', the_function.var); - detail('exception', the_function.exception); - detail('closure', the_function.closure); - detail('outer', the_function.outer); - detail('global', the_function.global); - detail('label', the_function.label); - output.push('
'); } } - return output.join(''); - }; - itself.properties_report = function (property) { - if (!property) { - return ''; - } - var i, - key, - keys = Object.keys(property).sort(), - mem = ' ', - name, - not_first = false, - output = ['/*properties']; - for (i = 0; i < keys.length; i += 1) { - key = keys[i]; - if (property[key] > 0) { - if (not_first) { - mem += ','; + function one_space_only() { + if (left.line !== right.line || left.thru + 1 !== right.from) { + warn( + 'expected_space_a_b', + right, + artifact(left), + artifact(right) + ); + } + } + + function one_space() { + if (left.line === right.line) { + if (left.thru + 1 !== right.from && nr_comments_skipped === 0) { + warn( + 'expected_space_a_b', + right, + artifact(left), + artifact(right) + ); } - name = ix.test(key) - ? key - : '\'' + key.replace(nx, sanitize) + '\''; - if (mem.length + name.length >= 80) { - output.push(mem); - mem = ' '; + } else { + if (free) { + if (right.from < margin) { + expected_at(margin); + } } else { - mem += ' '; + if (right.from !== margin + 8) { + expected_at(margin + 8); + } } - mem += name; - not_first = true; } } - output.push(mem, '*/\n'); - return output.join('\n'); - }; - itself.color = function (data) { - var from, - i = 1, - level, - line, - result = [], - thru, - data_token = data.tokens[0]; - while (data_token && data_token.id !== '(end)') { - from = data_token.from; - line = data_token.line; - thru = data_token.thru; - level = data_token.function.level; - do { - thru = data_token.thru; - data_token = data.tokens[i]; - i += 1; - } while (data_token && data_token.line === line && - data_token.from - thru < 5 && - level === data_token.function.level); - result.push({ - line: line, - level: level, - from: from, - thru: thru - }); + function unqmark() { + +// Undo the effects of dangling nested ternary operators. + + var level = qmark.length; + if (level > 0) { + margin -= level * 4; + } + qmark = ''; } - return result; - }; - itself.jslint = itself; + stack = []; + tokens.forEach(function (the_token) { + right = the_token; + if (right.id === '(comment)' || right.id === '(end)') { + nr_comments_skipped += 1; + } else { + +// If left is an opener and right is not the closer, then push the previous +// state. If the token following the opener is on the next line, then this is +// an open form. If the tokens are on different lines, then it is a closed for. +// Open form is more readable, with each item (statement, argument, parameter, +// etc) starting on its own line. Closed form is more compact. Statement blocks +// are always in open form. + + var new_closer = opener[left.id]; + if (typeof new_closer === 'string') { + if (new_closer !== right.id) { + stack.push({ + closer: closer, + free: free, + margin: margin, + open: open, + qmark: qmark + }); + qmark = ''; + closer = new_closer; + if (left.line !== right.line) { + free = closer === ')' && left.free; + open = true; + margin += 4; + if (right.role === 'label') { + if (right.from !== 0) { + expected_at(0); + } + } else if (right.switch) { + unqmark(); + at_margin(-4); + } else { + at_margin(0); + } + } else { + if (right.statement || right.role === 'label') { + warn( + 'expected_line_break_a_b', + right, + artifact(left), + artifact(right) + ); + } + free = false; + open = false; + no_space_only(); + } + } else { + +// If left and right are opener and closer, then the placement of right depends +// on the openness. Illegal pairs (like {]) have already been detected. + + if (left.line === right.line) { + no_space(); + } else { + at_margin(0); + } + } + } else { + +// If right is a closer, then pop the previous state, - itself.edition = '2014-07-08'; + if (right.id === closer) { + var previous = stack.pop(); + margin = previous.margin; + if (open && right.id !== ';') { + at_margin(0); + } else { + no_space_only(); + } + closer = previous.closer; + free = previous.free; + open = previous.open; + qmark = previous.qmark; + } else { + +// Left is not an opener, and right is not a closer. The nature of left and +// right will determine the space between them. + +// If left is , or ; or right is a statement then if open, right must go at the +// margin, or if closed, a space before. + + + if (right.switch) { + unqmark(); + at_margin(-4); + } else if (right.role === 'label') { + if (right.from !== 0) { + expected_at(0); + } + } else if (left.id === ',') { + unqmark(); + if (!open || ( + (free || closer === ']') && + left.line === right.line + )) { + one_space(); + } else { + at_margin(0); + } + +// If right is a ternary operator, line it up on the margin. Use qmark to +// deal with nested ternary operators. + + } else if (right.arity === 'ternary') { + if (right.id === '?') { + margin += 4; + qmark += '?'; + } else { + result = qmark.match(rx_colons); + qmark = result[1] + ':'; + margin -= 4 * result[2].length; + } + at_margin(0); + } else if (right.arity === 'binary' && right.id === '(' && free) { + no_space(); + } else if ( + left.id === '.' || + left.id === '...' || + right.id === ',' || + right.id === ';' || + right.id === ':' || + (right.arity === 'binary' && ( + right.id === '(' || + right.id === '[' + )) || + (right.arity === 'function' && left.id !== 'function') + ) { + no_space_only(); + } else if (right.id === '.') { + if (left.line === right.line) { + no_space(); + } else { + if (!rx_dot.test(qmark)) { + qmark += '.'; + margin += 4; + } + at_margin(0); + } + } else if (left.id === ';') { + unqmark(); + if (open) { + at_margin(0); + } else { + one_space(); + } + } else if ( + left.arity === 'ternary' || + left.id === 'case' || + left.id === 'catch' || + left.id === 'else' || + left.id === 'finally' || + left.id === 'while' || + right.id === 'catch' || + right.id === 'else' || + right.id === 'finally' || + (right.id === 'while' && !right.statement) || + (left.id === ')' && right.id === '{') + ) { + one_space_only(); + } else if (right.statement === true) { + if (open) { + at_margin(0); + } else { + one_space(); + } + } else if ( + left.id === 'var' || + left.id === 'const' || + left.id === 'let' + ) { + stack.push({ + closer: closer, + free: free, + margin: margin, + open: open, + qmark: qmark + }); + closer = ';'; + free = false; + open = left.open; + qmark = ''; + if (open) { + margin = margin + 4; + at_margin(0); + } else { + one_space_only(); + } + } else if ( + +// There is a space between left and right. + + spaceop[left.id] === true || + spaceop[right.id] === true || + ( + left.arity === 'binary' && + (left.id === '+' || left.id === '-') + ) || + ( + right.arity === 'binary' && + (right.id === '+' || right.id === '-') + ) || + left.id === 'function' || + left.id === ':' || + ( + ( + left.identifier || + left.id === '(string)' || + left.id === '(number)' + ) && + ( + right.identifier || + right.id === '(string)' || + right.id === '(number)' + ) + ) || + (left.arity === 'statement' && right.id !== ';') + ) { + one_space(); + } else if (left.arity === 'unary') { + no_space_only(); + } + } + } + nr_comments_skipped = 0; + delete left.calls; + delete left.dead; + delete left.free; + delete left.init; + delete left.open; + delete left.used; + left = right; + } + }); + } + +// The jslint function itself. + + return function (source, option_object, global_array) { + try { + warnings = []; + option = option_object || empty(); + anon = "anonymous"; + block_stack = []; + declared_globals = empty(); + directive_mode = true; + early_stop = true; + export_mode = false; + fudge = (option.fudge) + ? 1 + : 0; + functions = []; + global = { + id: '(global)', + body: true, + context: empty(), + from: 0, + level: 0, + line: 0, + live: [], + loop: 0, + switch: 0, + thru: 0 + }; + blockage = global; + functionage = global; + imports = []; + json_mode = false; + mega_mode = false; + module_mode = false; + next_token = global; + property = empty(); + stack = []; + tenure = undefined; + token = global; + token_nr = 0; + var_mode = undefined; + populate(declared_globals, standard, false); + if (global_array !== undefined) { + populate(declared_globals, global_array, false); + } + Object.keys(option).forEach(function (name) { + if (option[name] === true) { + var allowed = allowed_option[name]; + if (Array.isArray(allowed)) { + populate(declared_globals, allowed, false); + } + } + }); + tokenize(source); + advance(); + if (tokens[0].id === '{' || tokens[0].id === '[') { + json_mode = true; + tree = json_value(); + advance('(end)'); + } else { + +// Because browsers encourage combining of script files, the first token might +// be a semicolon to defend against a missing semicolon in the preceding file. + + if (option.browser) { + if (next_token.id === ';') { + advance(';'); + } + } else { + +// If we are not in a browser, then the file form of strict pragma may be used. + + if ( + next_token.id === '(string)' && + next_token.value === 'use strict' + ) { + advance('(string)'); + advance(';'); + global.strict = true; + } + } + tree = statements(); + advance('(end)'); + functionage = global; + walk_statement(tree); + uninitialized_and_unused(); + if (!option.white) { + whitage(); + } + } + early_stop = false; + } catch (e) { + if (e.name !== 'JSLintError') { + warnings.push(e); + } + } + return { + edition: "2015-10-29", + functions: functions, + global: global, + id: "(JSLint)", + imports: imports, + json: json_mode, + lines: lines, + module: module_mode === true, + ok: warnings.length === 0 && !early_stop, + option: option, + property: property, + stop: early_stop, + tokens: tokens, + tree: tree, + warnings: warnings.sort(function (a, b) { + return a.line - b.line || a.column - b.column; + }) + }; + }; +}()); - return itself; -}()); \ No newline at end of file +/*node module.exports = jslint;*/ diff --git a/testsuite/test16.html b/testsuite/test16.html index d784ca8..26cfdd8 100644 --- a/testsuite/test16.html +++ b/testsuite/test16.html @@ -45,49 +45,27 @@

Test 16

Check Hyphenator with JSLint!

\ No newline at end of file From dec7869636bedbaf169fdfdcb3afca0cb50bbb88 Mon Sep 17 00:00:00 2001 From: mnater Date: Wed, 25 Nov 2015 22:37:41 +0100 Subject: [PATCH 24/86] Add fail msg to test16 --- testsuite/test16.html | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/testsuite/test16.html b/testsuite/test16.html index 26cfdd8..001dff8 100644 --- a/testsuite/test16.html +++ b/testsuite/test16.html @@ -58,11 +58,20 @@

Test 16

document.writeln("Hyphenator.js has JSLint " + jsl.edition + " check passed." ); } } else { - var errorCount = jsl.warnings.length; - document.writeln("JSLint " + jsl.edition + " error(s):\n"); - for (i = 0; i < errorCount; i++ ) { - document.writeln("\n" + jsl.warnings[i].message + "\n"); - document.writeln(" Problem at line " + jsl.warnings[i].line + " column " + jsl.warnings[i].column + ": " + jsl.warnings[i].code); + if (window != parent) { + var msg = { + desc: "Make JSLint " + jsl.edition + " happy ;-)", + index: 16, + result: 'failed' + }; + parent.postMessage(JSON.stringify(msg), window.location.href); + } else { + var errorCount = jsl.warnings.length; + document.writeln("JSLint " + jsl.edition + " error(s):\n"); + for (i = 0; i < errorCount; i++ ) { + document.writeln("\n" + jsl.warnings[i].message + "\n"); + document.writeln(" Problem at line " + jsl.warnings[i].line + " column " + jsl.warnings[i].column + ": " + jsl.warnings[i].code); + } } } From 3f7e0b2760cef3b7ee34a2628d05b583e05247e2 Mon Sep 17 00:00:00 2001 From: mnater Date: Wed, 25 Nov 2015 22:45:12 +0100 Subject: [PATCH 25/86] Remove trailing white space (JSLint) --- Hyphenator.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index d62937b..64bf450 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -1,7 +1,7 @@ /** @license Hyphenator 5.2.0(devel) - client side hyphenation for webbrowsers * Copyright (C) 2015 Mathias Nater, Zürich (mathiasnater at gmail dot com) * https://github.com/mnater/Hyphenator - * + * * Released under the MIT license * http://mnater.github.io/Hyphenator/LICENSE.txt */ @@ -183,7 +183,7 @@ var Hyphenator = (function (window) { * @member {boolean} Hyphenator~persistentConfig * @access private * @desc - * if persistentConfig is set to true (defaults to false), config options and the state of the + * if persistentConfig is set to true (defaults to false), config options and the state of the * toggleBox are stored in DOM-storage (according to the storage-setting). So they haven't to be * set for each page. * @default false @@ -999,7 +999,7 @@ var Hyphenator = (function (window) { * @member {Object} Hyphenator~CSSEdit~sheet * @desc * A StyleSheet, where Hyphenator can write to. - * If no StyleSheet can be found, lets create one. + * If no StyleSheet can be found, lets create one. * @access private */ sheet = (function () { @@ -1050,7 +1050,7 @@ var Hyphenator = (function (window) { * @desc * Searches the StyleSheets for a given selector and returns an object containing the rule. * If nothing can be found, false is returned. - * @param {string} sel + * @param {string} sel * @return {Hyphenator~CSSEdit~rule|false} * @access private */ @@ -1719,7 +1719,7 @@ var Hyphenator = (function (window) { * Use ValueStore.finalize() when the last value of a pattern is added. It will set the length and return the starting index of the pattern. * To prevent doubles we could temporarly store the values in a object {value: startIndex} and only add new values, * but this object deoptimizes very fast (new hidden map for each entry); here we gain speed and pay memory - * + * * 3. Create and zero initialize a (typed) array to store the trie. The trie uses two slots for each entry/node: * i: a link to another position in the array or -1 if the pattern ends here or more rows have to be added. * i + 1: a link to a value in the ValueStore or 0 if there's no value for the path to this node. @@ -1735,8 +1735,8 @@ var Hyphenator = (function (window) { * to the trie (adding more "rows" if necessary, i.e. if the last link pointed to -1). * So the first "row" holds all starting characters, where the subsequent rows hold the characters that follow the * character that link to this row. Therefor the array is dense at the beginning and very sparse at the end. - * - * + * + * * @access private * @param {Object} language object */ @@ -1905,7 +1905,7 @@ var Hyphenator = (function (window) { * Checks if the requested file is available in the network. * Adds a <script>-Tag to the DOM to load an externeal .js-file containing patterns and settings for the given language. * If the given language is not in the {@link Hyphenator~supportedLangs}-Object it returns. - * One may ask why we are not using AJAX to load the patterns. The XMLHttpRequest-Object + * One may ask why we are not using AJAX to load the patterns. The XMLHttpRequest-Object * has a same-origin-policy. This makes the Bookmarklet impossible. * @param {string} lang The language to load the patterns for * @access private @@ -3085,7 +3085,7 @@ var Hyphenator = (function (window) { /** * @method Hyphenator.addExceptions * @desc - * Adds the exceptions from the string to the appropriate language in the + * Adds the exceptions from the string to the appropriate language in the * {@link Hyphenator~languages}-object * @param {string} lang The language * @param {string} words A comma separated string of hyphenated words WITH spaces. From 35b1fb8023208e9a7ee31a2cd744230d3d017cfd Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 26 Nov 2015 16:39:29 +0100 Subject: [PATCH 26/86] JSLint for Hyphenator_Loader --- Hyphenator_Loader.js | 14 +++++---- testsuite/test104.html | 71 +++++++++++++++++------------------------- 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/Hyphenator_Loader.js b/Hyphenator_Loader.js index d7a5527..728e576 100644 --- a/Hyphenator_Loader.js +++ b/Hyphenator_Loader.js @@ -1,7 +1,7 @@ /** @license Hyphenator_Loader 5.0.1(devel) - client side hyphenation for webbrowsers * Copyright (C) 2015 Mathias Nater, Zürich (mathiasnater at gmail dot com) * https://github.com/mnater/Hyphenator - * + * * Released under the MIT license * http://mnater.github.io/Hyphenator/LICENSE.txt */ @@ -16,8 +16,8 @@ */ /* The following comment is for JSLint: */ -/*jslint browser: true */ -/*global Hyphenator: false */ +/*jslint browser: true*/ +/*global window Hyphenator*/ var Hyphenator_Loader = (function (window) { 'use strict'; @@ -57,19 +57,21 @@ var Hyphenator_Loader = (function (window) { script = createElem('script'); script.src = path; script.type = 'text/javascript'; - script.onload = script.onreadystatechange = function () { - if (!done && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) { + script.onreadystatechange = function () { + if (!done && (!script.readyState || script.readyState === "loaded" || script.readyState === "complete")) { done = true; Hyphenator.config(config); Hyphenator.run(); // Handle memory leak in IE - script.onload = script.onreadystatechange = null; + script.onreadystatechange = null; + script.onload = null; if (head && script.parentNode) { head.removeChild(script); } } }; + script.onload = script.onreadystatechange; head.appendChild(script); }, diff --git a/testsuite/test104.html b/testsuite/test104.html index 5e0d1f8..4cf2a42 100644 --- a/testsuite/test104.html +++ b/testsuite/test104.html @@ -45,48 +45,35 @@

Test 104

Check Hyphenator_Loader.js with JSLint!

\ No newline at end of file From fc522b5fa92df96ced9a4cb883716c9c1da8a696 Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 26 Nov 2015 16:39:48 +0100 Subject: [PATCH 27/86] Refactoring for JSLint - avoid `this` - replace for ... in with the forEachKey-function - some smaller changes --- Hyphenator.js | 1387 +++++++++++++++++++++++++------------------------ 1 file changed, 706 insertions(+), 681 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index 64bf450..fbf8675 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -12,7 +12,8 @@ */ /* The following comment is for JSLint: */ -/*jslint browser: true */ +/*jslint browser: true for: true*/ +/*global Hyphenator window*/ /** * @desc Provides all functionality to do hyphenation, except the patterns that are loaded externally @@ -153,7 +154,9 @@ var Hyphenator = (function (window) { i += 1; t = s[i]; } - return !!r ? r : '//mnater.github.io/Hyphenator/'; + return !!r + ? r + : '//mnater.github.io/Hyphenator/'; }()), /** @@ -311,6 +314,22 @@ var Hyphenator = (function (window) { return el; }, + forEachKey = function (o, f) { + var a, k; + if (Object.hasOwnProperty("keys")) { + a = Object.keys(o); + a.forEach(function (v) { + f(v); + }); + } else { + for (k in o) { + if (o.hasOwnProperty(k)) { + f(k); + } + } + } + }, + /** * @member {boolean} Hyphenator~css3 * @desc @@ -321,73 +340,54 @@ var Hyphenator = (function (window) { */ css3 = false, - /** - * @typedef {Object} Hyphenator~css3_hsupport - * @property {boolean} support - if css3-hyphenation is supported - * @property {string} property - the css property name to access hyphen-settings (e.g. -webkit-hyphens) - * @property {Object.} supportedBrowserLangs - an object caching tested languages - * @property {function} checkLangSupport - a method that checks if the browser supports a requested language - */ - - /** - * @member {Hyphenator~css3_h9n} Hyphenator~css3_h9n - * @desc - * A generated object containing information for CSS3-hyphenation support - * This is set by {@link Hyphenator~css3_gethsupport} - * @default undefined - * @access private - * @see {@link Hyphenator~css3_gethsupport} - * @example - * //Check if browser supports a language - * css3_h9n.checkLangSupport(<lang>) - */ - css3_h9n, - /** * @method Hyphenator~css3_gethsupport * @desc - * This function sets {@link Hyphenator~css3_h9n} for the current UA + * This function returns a {@link Hyphenator~css3_hsupport} object for the current UA * @type function * @access private * @see Hyphenator~css3_h9n */ css3_gethsupport = function () { - var s, + var support = false, + supportedBrowserLangs = {}, + property = '', + checkLangSupport, createLangSupportChecker = function (prefix) { var testStrings = [ - //latin: 0 - 'aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz', - //cyrillic: 1 - 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя', - //arabic: 2 - 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', - //armenian: 3 - 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆ', - //bengali: 4 - 'ঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ়ঽািীুূৃৄেৈোৌ্ৎৗড়ঢ়য়ৠৡৢৣ', - //devangari: 5 - 'ँंःअआइईउऊऋऌएऐओऔकखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसहऽािीुूृॄेैोौ्॒॑ॠॡॢॣ', - //greek: 6 - 'αβγδεζηθικλμνξοπρσςτυφχψω', - //gujarati: 7 - 'બહઅઆઇઈઉઊઋૠએઐઓઔાિીુૂૃૄૢૣેૈોૌકખગઘઙચછજઝઞટઠડઢણતથદધનપફસભમયરલળવશષ', - //kannada: 8 - 'ಂಃಅಆಇಈಉಊಋಌಎಏಐಒಓಔಕಖಗಘಙಚಛಜಝಞಟಠಡಢಣತಥದಧನಪಫಬಭಮಯರಱಲಳವಶಷಸಹಽಾಿೀುೂೃೄೆೇೈೊೋೌ್ೕೖೞೠೡ', - //lao: 9 - 'ກຂຄງຈຊຍດຕຖທນບປຜຝພຟມຢຣລວສຫອຮະັາິີຶືຸູົຼເແໂໃໄ່້໊໋ໜໝ', - //malayalam: 10 - 'ംഃഅആഇഈഉഊഋഌഎഏഐഒഓഔകഖഗഘങചഛജഝഞടഠഡഢണതഥദധനപഫബഭമയരറലളഴവശഷസഹാിീുൂൃെേൈൊോൌ്ൗൠൡൺൻർൽൾൿ', - //oriya: 11 - 'ଁଂଃଅଆଇଈଉଊଋଌଏଐଓଔକଖଗଘଙଚଛଜଝଞଟଠଡଢଣତଥଦଧନପଫବଭମଯରଲଳଵଶଷସହାିୀୁୂୃେୈୋୌ୍ୗୠୡ', - //persian: 12 - 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', - //punjabi: 13 - 'ਁਂਃਅਆਇਈਉਊਏਐਓਔਕਖਗਘਙਚਛਜਝਞਟਠਡਢਣਤਥਦਧਨਪਫਬਭਮਯਰਲਲ਼ਵਸ਼ਸਹਾਿੀੁੂੇੈੋੌ੍ੰੱ', - //tamil: 14 - 'ஃஅஆஇஈஉஊஎஏஐஒஓஔகஙசஜஞடணதநனபமயரறலளழவஷஸஹாிீுூெேைொோௌ்ௗ', - //telugu: 15 - 'ఁంఃఅఆఇఈఉఊఋఌఎఏఐఒఓఔకఖగఘఙచఛజఝఞటఠడఢణతథదధనపఫబభమయరఱలళవశషసహాిీుూృౄెేైొోౌ్ౕౖౠౡ' - ], + //latin: 0 + 'aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz', + //cyrillic: 1 + 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя', + //arabic: 2 + 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', + //armenian: 3 + 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆ', + //bengali: 4 + 'ঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ়ঽািীুূৃৄেৈোৌ্ৎৗড়ঢ়য়ৠৡৢৣ', + //devangari: 5 + 'ँंःअआइईउऊऋऌएऐओऔकखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसहऽािीुूृॄेैोौ्॒॑ॠॡॢॣ', + //greek: 6 + 'αβγδεζηθικλμνξοπρσςτυφχψω', + //gujarati: 7 + 'બહઅઆઇઈઉઊઋૠએઐઓઔાિીુૂૃૄૢૣેૈોૌકખગઘઙચછજઝઞટઠડઢણતથદધનપફસભમયરલળવશષ', + //kannada: 8 + 'ಂಃಅಆಇಈಉಊಋಌಎಏಐಒಓಔಕಖಗಘಙಚಛಜಝಞಟಠಡಢಣತಥದಧನಪಫಬಭಮಯರಱಲಳವಶಷಸಹಽಾಿೀುೂೃೄೆೇೈೊೋೌ್ೕೖೞೠೡ', + //lao: 9 + 'ກຂຄງຈຊຍດຕຖທນບປຜຝພຟມຢຣລວສຫອຮະັາິີຶືຸູົຼເແໂໃໄ່້໊໋ໜໝ', + //malayalam: 10 + 'ംഃഅആഇഈഉഊഋഌഎഏഐഒഓഔകഖഗഘങചഛജഝഞടഠഡഢണതഥദധനപഫബഭമയരറലളഴവശഷസഹാിീുൂൃെേൈൊോൌ്ൗൠൡൺൻർൽൾൿ', + //oriya: 11 + 'ଁଂଃଅଆଇଈଉଊଋଌଏଐଓଔକଖଗଘଙଚଛଜଝଞଟଠଡଢଣତଥଦଧନପଫବଭମଯରଲଳଵଶଷସହାିୀୁୂୃେୈୋୌ୍ୗୠୡ', + //persian: 12 + 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', + //punjabi: 13 + 'ਁਂਃਅਆਇਈਉਊਏਐਓਔਕਖਗਘਙਚਛਜਝਞਟਠਡਢਣਤਥਦਧਨਪਫਬਭਮਯਰਲਲ਼ਵਸ਼ਸਹਾਿੀੁੂੇੈੋੌ੍ੰੱ', + //tamil: 14 + 'ஃஅஆஇஈஉஊஎஏஐஒஓஔகஙசஜஞடணதநனபமயரறலளழவஷஸஹாிீுூெேைொோௌ்ௗ', + //telugu: 15 + 'ఁంఃఅఆఇఈఉఊఋఌఎఏఐఒఓఔకఖగఘఙచఛజఝఞటఠడఢణతథదధనపఫబభమయరఱలళవశషసహాిీుూృౄెేైొోౌ్ౕౖౠౡ' + ], f = function (lang) { var shadow, computedHeight, @@ -395,8 +395,8 @@ var Hyphenator = (function (window) { r = false; //check if lang has already been tested - if (this.supportedBrowserLangs.hasOwnProperty(lang)) { - r = this.supportedBrowserLangs[lang]; + if (supportedBrowserLangs.hasOwnProperty(lang)) { + r = supportedBrowserLangs[lang]; } else if (supportedLangs.hasOwnProperty(lang)) { //create and append shadow-test-element bdy = window.document.getElementsByTagName('body')[0]; @@ -419,8 +419,8 @@ var Hyphenator = (function (window) { computedHeight = shadow.offsetHeight; //remove shadow element bdy.removeChild(shadow); - r = (computedHeight > 12) ? true : false; - this.supportedBrowserLangs[lang] = r; + r = !!(computedHeight > 12); + supportedBrowserLangs[lang] = r; } else { r = false; } @@ -428,41 +428,60 @@ var Hyphenator = (function (window) { }; return f; }, - r = { - support: false, - supportedBrowserLangs: {}, - property: '', - checkLangSupport: {} - }; + s; if (window.getComputedStyle) { s = window.getComputedStyle(window.document.getElementsByTagName('body')[0], null); - } else { - //ancient Browsers don't support CSS3 anyway - css3_h9n = r; - return; - } + if (s.hyphens !== undefined) { + support = true; + property = 'hyphens'; + checkLangSupport = createLangSupportChecker('hyphens'); + } else if (s['-webkit-hyphens'] !== undefined) { + support = true; + property = '-webkit-hyphens'; + checkLangSupport = createLangSupportChecker('-webkit-hyphens'); + } else if (s.MozHyphens !== undefined) { + support = true; + property = '-moz-hyphens'; + checkLangSupport = createLangSupportChecker('MozHyphens'); + } else if (s['-ms-hyphens'] !== undefined) { + support = true; + property = '-ms-hyphens'; + checkLangSupport = createLangSupportChecker('-ms-hyphens'); + } + } //else we just return the initial values because ancient browsers don't support css3 anyway + - if (s.hyphens !== undefined) { - r.support = true; - r.property = 'hyphens'; - r.checkLangSupport = createLangSupportChecker('hyphens'); - } else if (s['-webkit-hyphens'] !== undefined) { - r.support = true; - r.property = '-webkit-hyphens'; - r.checkLangSupport = createLangSupportChecker('-webkit-hyphens'); - } else if (s.MozHyphens !== undefined) { - r.support = true; - r.property = '-moz-hyphens'; - r.checkLangSupport = createLangSupportChecker('MozHyphens'); - } else if (s['-ms-hyphens'] !== undefined) { - r.support = true; - r.property = '-ms-hyphens'; - r.checkLangSupport = createLangSupportChecker('-ms-hyphens'); - } - css3_h9n = r; + return { + support: support, + property: property, + supportedBrowserLangs: supportedBrowserLangs, + checkLangSupport: checkLangSupport + }; }, + /** + * @typedef {Object} Hyphenator~css3_hsupport + * @property {boolean} support - if css3-hyphenation is supported + * @property {string} property - the css property name to access hyphen-settings (e.g. -webkit-hyphens) + * @property {Object.} supportedBrowserLangs - an object caching tested languages + * @property {function} checkLangSupport - a method that checks if the browser supports a requested language + */ + + /** + * @member {Hyphenator~css3_h9n} Hyphenator~css3_h9n + * @desc + * A generated object containing information for CSS3-hyphenation support + * This is set by {@link Hyphenator~css3_gethsupport} + * @default undefined + * @access private + * @see {@link Hyphenator~css3_gethsupport} + * @example + * //Check if browser supports a language + * css3_h9n.checkLangSupport(<lang>) + */ + css3_h9n, + /** * @member {string} Hyphenator~hyphenateClass * @desc @@ -635,126 +654,95 @@ var Hyphenator = (function (window) { * @desc represents a DOM Element with additional information * @access private */ - var Element = function (element) { - /** - * @member {Object} Hyphenator~elements~ElementCollection~Element~element - * @desc A DOM Element - * @access protected - */ - this.element = element; - /** - * @member {boolean} Hyphenator~elements~ElementCollection~Element~hyphenated - * @desc Marks if the element has been hyphenated - * @access protected - */ - this.hyphenated = false; - /** - * @member {boolean} Hyphenator~elements~ElementCollection~Element~treated - * @desc Marks if information of the element has been collected but not hyphenated (e.g. dohyphenation is off) - * @access protected - */ - this.treated = false; - }, + var makeElement = function (element) { + return { + /** + * @member {Object} Hyphenator~elements~ElementCollection~Element~element + * @desc A DOM Element + * @access protected + */ + element: element, + /** + * @member {boolean} Hyphenator~elements~ElementCollection~Element~hyphenated + * @desc Marks if the element has been hyphenated + * @access protected + */ + hyphenated: false, + /** + * @member {boolean} Hyphenator~elements~ElementCollection~Element~treated + * @desc Marks if information of the element has been collected but not hyphenated (e.g. dohyphenation is off) + * @access protected + */ + treated: false + }; + }, /** * @constructor Hyphenator~elements~ElementCollection * @desc A collection of Elements to be hyphenated * @access protected */ - ElementCollection = function () { - /** - * @member {number} Hyphenator~elements~ElementCollection~count - * @desc The Number of collected Elements - * @access protected - */ - this.count = 0; - /** - * @member {number} Hyphenator~elements~ElementCollection~hyCount - * @desc The Number of hyphenated Elements - * @access protected - */ - this.hyCount = 0; - /** - * @member {Object.>} Hyphenator~elements~ElementCollection~list - * @desc The collection of elements, where the key is a language code and the value is an array of elements - * @access protected - */ - this.list = {}; - }; - /** - * @member {Object} Hyphenator~elements~ElementCollection.prototype - * @augments Hyphenator~elements~ElementCollection - * @access protected - */ - ElementCollection.prototype = { - /** - * @method Hyphenator~elements~ElementCollection.prototype~add - * @augments Hyphenator~elements~ElementCollection - * @access protected - * @desc adds a DOM element to the collection - * @param {Object} el - The DOM element - * @param {string} lang - The language of the element - */ - add: function (el, lang) { - var elo = new Element(el); - if (!this.list.hasOwnProperty(lang)) { - this.list[lang] = []; - } - this.list[lang].push(elo); - this.count += 1; - return elo; - }, - - /** - * @method Hyphenator~elements~ElementCollection.prototype~remove - * @augments Hyphenator~elements~ElementCollection - * @access protected - * @desc removes a DOM element from the collection - * @param {Object} el - The DOM element - */ - remove: function (el) { - var lang, i, e, l; - for (lang in this.list) { - if (this.list.hasOwnProperty(lang)) { - for (i = 0; i < this.list[lang].length; i += 1) { - if (this.list[lang][i].element === el) { - e = i; - l = lang; - break; - } + makeElementCollection = function () { + /** + * @member {number} Hyphenator~elements~ElementCollection~counters + * @desc Array of [number of collected elements, number of hyphenated elements] + * @access protected + */ + var counters = [0, 0], + /** + * @member {Object.>} Hyphenator~elements~ElementCollection~list + * @desc The collection of elements, where the key is a language code and the value is an array of elements + * @access protected + */ + list = {}, + /** + * @method Hyphenator~elements~ElementCollection.prototype~add + * @augments Hyphenator~elements~ElementCollection + * @access protected + * @desc adds a DOM element to the collection + * @param {Object} el - The DOM element + * @param {string} lang - The language of the element + */ + add = function (el, lang) { + var elo = makeElement(el); + if (!list.hasOwnProperty(lang)) { + list[lang] = []; } - } - } - this.list[l].splice(e, 1); - this.count -= 1; - this.hyCount -= 1; - }, - /** - * @callback Hyphenator~elements~ElementCollection.prototype~each~callback fn - The callback that is executed for each element - * @param {string} [k] The key (i.e. language) of the collection - * @param {Hyphenator~elements~ElementCollection~Element} element - */ + list[lang].push(elo); + counters[0] += 1; + return elo; + }, + /** + * @callback Hyphenator~elements~ElementCollection.prototype~each~callback fn - The callback that is executed for each element + * @param {string} [k] The key (i.e. language) of the collection + * @param {Hyphenator~elements~ElementCollection~Element} element + */ + + /** + * @method Hyphenator~elements~ElementCollection.prototype~each + * @augments Hyphenator~elements~ElementCollection + * @access protected + * @desc takes each element of the collection as an argument of fn + * @param {Hyphenator~elements~ElementCollection.prototype~each~callback} fn - A function that takes an element as an argument + */ + each = function (fn) { + forEachKey(list, function (k) { + if (fn.length === 2) { + fn(k, list[k]); + } else { + fn(list[k]); + } + }); + }; - /** - * @method Hyphenator~elements~ElementCollection.prototype~each - * @augments Hyphenator~elements~ElementCollection - * @access protected - * @desc takes each element of the collection as an argument of fn - * @param {Hyphenator~elements~ElementCollection.prototype~each~callback} fn - A function that takes an element as an argument - */ - each: function (fn) { - var k; - for (k in this.list) { - if (this.list.hasOwnProperty(k)) { - if (fn.length === 2) { - fn(k, this.list[k]); - } else { - fn(this.list[k]); - } - } - } - } - }; - return new ElementCollection(); + return { + counters: counters, + list: list, + add: add, + each: each + }; + + }; + return makeElementCollection(); }()), @@ -992,7 +980,7 @@ var Hyphenator = (function (window) { * can be changed in one place instead for each element. * @access private */ - CSSEdit = function (w) { + makeCSSEdit = function (w) { w = w || window; var doc = w.document, /** @@ -1291,76 +1279,83 @@ var Hyphenator = (function (window) { */ runWhenLoaded = function (w, f) { var toplevel, - add = window.document.addEventListener ? 'addEventListener' : 'attachEvent', - rem = window.document.addEventListener ? 'removeEventListener' : 'detachEvent', - pre = window.document.addEventListener ? '' : 'on', + add = window.document.addEventListener + ? 'addEventListener' + : 'attachEvent', + rem = window.document.addEventListener + ? 'removeEventListener' + : 'detachEvent', + pre = window.document.addEventListener + ? '' + : 'on'; + + function init(context) { + if (hyphRunFor[context.location.href]) { + onWarning(new Error("Warning: multiple execution of Hyphenator.run() – This may slow down the script!")); + } + contextWindow = context || window; + f(); + hyphRunFor[contextWindow.location.href] = true; + } - init = function (context) { - if (hyphRunFor[context.location.href]) { - onWarning(new Error("Warning: multiple execution of Hyphenator.run() – This may slow down the script!")); - } - contextWindow = context || window; - f(); - hyphRunFor[contextWindow.location.href] = true; - }, + function doScrollCheck() { + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + w.document.documentElement.doScroll("left"); + } catch (ignore) { + window.setTimeout(doScrollCheck, 1); + return; + } + //maybe modern IE fired DOMContentLoaded + if (!hyphRunFor[w.location.href]) { + documentLoaded = true; + init(w); + } + } - doScrollCheck = function () { - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - w.document.documentElement.doScroll("left"); - } catch (error) { - window.setTimeout(doScrollCheck, 1); - return; - } - //maybe modern IE fired DOMContentLoaded - if (!hyphRunFor[w.location.href]) { - documentLoaded = true; - init(w); - } - }, + function doOnEvent(e) { + var i, fl, haveAccess; + if (!!e && e.type === 'readystatechange' && w.document.readyState !== 'interactive' && w.document.readyState !== 'complete') { + return; + } - doOnEvent = function (e) { - var i, fl, haveAccess; - if (!!e && e.type === 'readystatechange' && w.document.readyState !== 'interactive' && w.document.readyState !== 'complete') { - return; - } + //DOM is ready/interactive, but frames may not be loaded yet! + //cleanup events + w.document[rem](pre + 'DOMContentLoaded', doOnEvent, false); + w.document[rem](pre + 'readystatechange', doOnEvent, false); - //DOM is ready/interactive, but frames may not be loaded yet! + //check frames + fl = w.frames.length; + if (fl === 0 || !doFrames) { + //there are no frames! //cleanup events - w.document[rem](pre + 'DOMContentLoaded', doOnEvent, false); - w.document[rem](pre + 'readystatechange', doOnEvent, false); - - //check frames - fl = w.frames.length; - if (fl === 0 || !doFrames) { - //there are no frames! + w[rem](pre + 'load', doOnEvent, false); + documentLoaded = true; + init(w); + } else if (doFrames && fl > 0) { + //we have frames, so wait for onload and then initiate runWhenLoaded recursevly for each frame: + if (!!e && e.type === 'load') { //cleanup events w[rem](pre + 'load', doOnEvent, false); - documentLoaded = true; - init(w); - } else if (doFrames && fl > 0) { - //we have frames, so wait for onload and then initiate runWhenLoaded recursevly for each frame: - if (!!e && e.type === 'load') { - //cleanup events - w[rem](pre + 'load', doOnEvent, false); - for (i = 0; i < fl; i += 1) { + for (i = 0; i < fl; i += 1) { + haveAccess = undefined; + //try catch isn't enough for webkit + try { + //opera throws only on document.toString-access + haveAccess = w.frames[i].document.toString(); + } catch (ignore) { haveAccess = undefined; - //try catch isn't enough for webkit - try { - //opera throws only on document.toString-access - haveAccess = w.frames[i].document.toString(); - } catch (err) { - haveAccess = undefined; - } - if (!!haveAccess) { - runWhenLoaded(w.frames[i], f); - } } - init(w); + if (!!haveAccess) { + runWhenLoaded(w.frames[i], f); + } } + init(w); } - }; + } + } + if (documentLoaded || w.document.readyState === 'complete') { //Hyphenator has run already (documentLoaded is true) or //it has been loaded after onLoad @@ -1393,11 +1388,15 @@ var Hyphenator = (function (window) { */ getLang = function (el, fallback) { try { - return !!el.getAttribute('lang') ? el.getAttribute('lang').toLowerCase() : - !!el.getAttribute('xml:lang') ? el.getAttribute('xml:lang').toLowerCase() : - el.tagName.toLowerCase() !== 'html' ? getLang(el.parentNode, fallback) : - fallback ? mainLanguage : - null; + return !!el.getAttribute('lang') + ? el.getAttribute('lang').toLowerCase() + : !!el.getAttribute('xml:lang') + ? el.getAttribute('xml:lang').toLowerCase() + : el.tagName.toLowerCase() !== 'html' + ? getLang(el.parentNode, fallback) + : fallback + ? mainLanguage + : null; } catch (ignore) {} }, @@ -1434,12 +1433,10 @@ var Hyphenator = (function (window) { ml = window.showModalDialog(basePath + 'modalLangDialog.html', supportedLangs, "dialogWidth: " + dW + "px; dialogHeight: " + dH + "px; dialogtop: " + dY + "; dialogleft: " + dX + "; center: on; resizable: off; scroll: off;"); } else { languageHint = (function () { - var k, r = ''; - for (k in supportedLangs) { - if (supportedLangs.hasOwnProperty(k)) { - r += k + ', '; - } - } + var r = ''; + forEachKey(supportedLangs, function (k) { + r += k + ', '; + }); r = r.substring(0, r.length - 2); return r; }()); @@ -1495,7 +1492,10 @@ var Hyphenator = (function (window) { * @access private */ gatherDocumentInfos = function () { - var elToProcess, urlhyphenEls, tmp, i = 0, + var elToProcess, + urlhyphenEls, + tmp, + i = 0, /** * @method Hyphenator~gatherDocumentInfos * @desc @@ -1507,10 +1507,12 @@ var Hyphenator = (function (window) { * @param {boolean} isChild true, if the parent of el has been processed */ process = function (el, pLang, isChild) { - isChild = isChild || false; - var n, j = 0, hyphenate = true, eLang, + var n, + j = 0, + hyphenate = true, + eLang, useCSS3 = function () { - css3hyphenateClassHandle = new CSSEdit(contextWindow); + css3hyphenateClassHandle = makeCSSEdit(contextWindow); css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, css3_h9n.property + ': auto;'); css3hyphenateClassHandle.setRule('.' + dontHyphenateClass, css3_h9n.property + ': manual;'); if ((eLang !== pLang) && css3_h9n.property.indexOf('webkit') !== -1) { @@ -1542,8 +1544,8 @@ var Hyphenator = (function (window) { elements.add(el, eLang); } }; - - if (el.lang && typeof (el.lang) === 'string') { + isChild = isChild || false; + if (el.lang && typeof el.lang === 'string') { eLang = el.lang.toLowerCase(); //copy attribute-lang to internal eLang } else if (!!pLang && pLang !== '') { eLang = pLang.toLowerCase(); @@ -1599,14 +1601,14 @@ var Hyphenator = (function (window) { }; if (css3) { - css3_gethsupport(); + css3_h9n = css3_gethsupport(); } if (isBookmarklet) { elToProcess = contextWindow.document.getElementsByTagName('body')[0]; process(elToProcess, mainLanguage, false); } else { if (!css3 && intermediateState === 'hidden') { - CSSEditors.push(new CSSEdit(contextWindow)); + CSSEditors.push(makeCSSEdit(contextWindow)); CSSEditors[CSSEditors.length - 1].setRule('.' + hyphenateClass, 'visibility: hidden;'); CSSEditors[CSSEditors.length - 1].setRule('.' + hideClass, 'visibility: hidden;'); CSSEditors[CSSEditors.length - 1].setRule('.' + unhideClass, 'visibility: visible;'); @@ -1628,7 +1630,7 @@ var Hyphenator = (function (window) { tmp = urlhyphenEls[i]; } } - if (elements.count === 0) { + if (elements.counters[0] === 0) { //nothing to hyphenate or all hyphenated by css3 for (i = 0; i < CSSEditors.length; i += 1) { CSSEditors[i].clearChanges(); @@ -1650,14 +1652,19 @@ var Hyphenator = (function (window) { * @access private * @param {Object} language object */ - CharMap = function () { - this.int2code = []; - this.code2int = {}; - this.add = function (newValue) { - if (!this.code2int[newValue]) { - this.int2code.push(newValue); - this.code2int[newValue] = this.int2code.length - 1; - } + makeCharMap = function () { + var int2code = [], + code2int = {}, + add = function (newValue) { + if (!code2int[newValue]) { + int2code.push(newValue); + code2int[newValue] = int2code.length - 1; + } + }; + return { + int2code: int2code, + code2int: code2int, + add: add }; }, @@ -1666,37 +1673,41 @@ var Hyphenator = (function (window) { * @desc Storage-Object for storing hyphenation points (aka values) * @access private */ - ValueStore = function (len) { - var startIndex = 1, - actualIndex = 2, - lastValueIndex = 2; - this.keys = (function () { - var i, r; - if (Object.prototype.hasOwnProperty.call(window, "Uint8Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) - return new window.Uint8Array(len); - } - r = []; - r.length = len; - for (i = r.length - 1; i >= 0; i -= 1) { - r[i] = 0; - } - return r; - }()); - this.add = function (p) { - this.keys[actualIndex] = p; - lastValueIndex = actualIndex; - actualIndex += 1; - }; - this.add0 = function () { - //just do a step, since array is initialized with zeroes - actualIndex += 1; - }; - this.finalize = function () { - var start = startIndex; - this.keys[start] = lastValueIndex - start; - startIndex = lastValueIndex + 1; - actualIndex = lastValueIndex + 2; - return start; + makeValueStore = function (len) { + var indexes = [1, 2, 2], + keys = (function () { + var i, r; + if (Object.prototype.hasOwnProperty.call(window, "Uint8Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) + return new window.Uint8Array(len); + } + r = []; + r.length = len; + for (i = r.length - 1; i >= 0; i -= 1) { + r[i] = 0; + } + return r; + }()), + add = function (p) { + keys[indexes[1]] = p; + indexes[2] = indexes[1]; + indexes[1] += 1; + }, + add0 = function () { + //just do a step, since array is initialized with zeroes + indexes[1] += 1; + }, + finalize = function () { + var start = indexes[0]; + keys[start] = indexes[2] - start; + indexes[0] = indexes[2] + 1; + indexes[1] = indexes[2] + 2; + return start; + }; + return { + keys: keys, + add: add, + add0: add0, + finalize: finalize }; }, @@ -1825,13 +1836,14 @@ var Hyphenator = (function (window) { console.log(s); };*/ - lo.charMap = new CharMap(); + lo.charMap = makeCharMap(); for (i = 0; i < lo.patternChars.length; i += 1) { lo.charMap.add(lo.patternChars.charCodeAt(i)); } charMapc2i = lo.charMap.code2int; - lo.valueStore = valueStore = new ValueStore(lo.valueStoreLength); + valueStore = makeValueStore(lo.valueStoreLength); + lo.valueStore = valueStore; if (Object.prototype.hasOwnProperty.call(window, "Int32Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) lo.indexedTrie = new window.Int32Array(lo.patternArrayLength * 2); @@ -1845,11 +1857,9 @@ var Hyphenator = (function (window) { indexedTrie = lo.indexedTrie; trieRowLength = lo.charMap.int2code.length * 2; - for (i in lo.patterns) { - if (lo.patterns.hasOwnProperty(i)) { - extract(parseInt(i, 10), lo.patterns[i]); - } - } + forEachKey(lo.patterns, function (i) { + extract(parseInt(i, 10), lo.patterns[i]); + }); //prettyPrintIndexedTrie(lo.charMap.int2code.length * 2); }, @@ -1887,14 +1897,15 @@ var Hyphenator = (function (window) { convertExceptionsToObject = function (exc) { var w = exc.split(', '), r = {}, - i, - l, + i = 0, + l = w.length, key; - for (i = 0, l = w.length; i < l; i += 1) { + while (i < l) { key = w[i].replace(/-/g, ''); if (!r.hasOwnProperty(key)) { r[key] = w[i]; } + i += 1; } return r; }, @@ -1924,16 +1935,16 @@ var Hyphenator = (function (window) { try { // Mozilla, Opera, Safari and Internet Explorer (ab v7) xhr = new window.XMLHttpRequest(); - } catch (e) { + } catch (ignore) { try { //IE>=6 - xhr = new window.ActiveXObject("Microsoft.XMLHTTP"); - } catch (e2) { + xhr = new window.ActiveXObject("Microsoft.XMLHTTP"); + } catch (ignore) { try { //IE>=5 - xhr = new window.ActiveXObject("Msxml2.XMLHTTP"); - } catch (e3) { - xhr = null; + xhr = new window.ActiveXObject("Msxml2.XMLHTTP"); + } catch (ignore) { + xhr = null; } } } @@ -1960,19 +1971,21 @@ var Hyphenator = (function (window) { script.src = location; script.type = 'text/javascript'; script.charset = 'utf8'; - script.onload = script.onreadystatechange = function () { - if (!done && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) { + script.onreadystatechange = function () { + if (!done && (!script.readyState || script.readyState === "loaded" || script.readyState === "complete")) { done = true; cb(); // Handle memory leak in IE - script.onload = script.onreadystatechange = null; + script.onreadystatechange = null; + script.onload = null; if (head && script.parentNode) { head.removeChild(script); } } }; + script.onload = script.onreadystatechange; head.appendChild(script); } }, @@ -2043,75 +2056,64 @@ var Hyphenator = (function (window) { * @access private */ prepare = function (callback) { - var lang, tmp1, tmp2, + var tmp1, languagesLoaded = function () { - var l; - for (l in docLanguages) { - if (docLanguages.hasOwnProperty(l)) { - if (Hyphenator.languages.hasOwnProperty(l)) { - delete docLanguages[l]; - if (!!storage) { - storage.setItem(l, window.JSON.stringify(Hyphenator.languages[l])); - } - prepareLanguagesObj(l); - callback(l); + forEachKey(docLanguages, function (l) { + if (Hyphenator.languages.hasOwnProperty(l)) { + delete docLanguages[l]; + if (!!storage) { + storage.setItem(l, window.JSON.stringify(Hyphenator.languages[l])); } + prepareLanguagesObj(l); + callback(l); } - } + }); }; if (!enableRemoteLoading) { - for (lang in Hyphenator.languages) { - if (Hyphenator.languages.hasOwnProperty(lang)) { - prepareLanguagesObj(lang); - } - } + forEachKey(Hyphenator.languages, function (lang) { + prepareLanguagesObj(lang); + }); callback('*'); return; } // get all languages that are used and preload the patterns - for (lang in docLanguages) { - if (docLanguages.hasOwnProperty(lang)) { - if (!!storage && storage.test(lang)) { - Hyphenator.languages[lang] = window.JSON.parse(storage.getItem(lang)); - prepareLanguagesObj(lang); - if (exceptions.hasOwnProperty('global')) { - tmp1 = convertExceptionsToObject(exceptions.global); - for (tmp2 in tmp1) { - if (tmp1.hasOwnProperty(tmp2)) { - Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; - } - } - } - //Replace exceptions since they may have been changed: - if (exceptions.hasOwnProperty(lang)) { - tmp1 = convertExceptionsToObject(exceptions[lang]); - for (tmp2 in tmp1) { - if (tmp1.hasOwnProperty(tmp2)) { - Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; - } - } - delete exceptions[lang]; - } - //Replace genRegExp since it may have been changed: - if (String.prototype.normalize) { - tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + Hyphenator.languages[lang].specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; - } else { - tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; - } - Hyphenator.languages[lang].genRegExp = new RegExp('(' + tmp1 + ')|(' + url + ')|(' + mail + ')', 'gi'); - if (enableCache) { - if (!Hyphenator.languages[lang].cache) { - Hyphenator.languages[lang].cache = {}; - } - } - delete docLanguages[lang]; - callback(lang); + forEachKey(docLanguages, function (lang) { + if (!!storage && storage.test(lang)) { + Hyphenator.languages[lang] = window.JSON.parse(storage.getItem(lang)); + prepareLanguagesObj(lang); + if (exceptions.hasOwnProperty('global')) { + tmp1 = convertExceptionsToObject(exceptions.global); + forEachKey(tmp1, function (tmp2) { + Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; + }); + } + //Replace exceptions since they may have been changed: + if (exceptions.hasOwnProperty(lang)) { + tmp1 = convertExceptionsToObject(exceptions[lang]); + forEachKey(tmp1, function (tmp2) { + Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; + }); + delete exceptions[lang]; + } + //Replace genRegExp since it may have been changed: + if (String.prototype.normalize) { + tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + Hyphenator.languages[lang].specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; } else { - loadPatterns(lang, languagesLoaded); + tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + } + Hyphenator.languages[lang].genRegExp = new RegExp('(' + tmp1 + ')|(' + url + ')|(' + mail + ')', 'gi'); + if (enableCache) { + if (!Hyphenator.languages[lang].cache) { + Hyphenator.languages[lang].cache = {}; + } } + delete docLanguages[lang]; + callback(lang); + } else { + loadPatterns(lang, languagesLoaded); } - } + }); //call languagesLoaded in case language has been loaded manually //and remoteLoading is on (onload won't fire) languagesLoaded(); @@ -2125,8 +2127,11 @@ var Hyphenator = (function (window) { * @access private */ toggleBox = function () { - var bdy, myTextNode, - text = (Hyphenator.doHyphenation ? 'Hy-phen-a-tion' : 'Hyphenation'), + var bdy, + myTextNode, + text = (Hyphenator.doHyphenation + ? 'Hy-phen-a-tion' + : 'Hyphenation'), myBox = contextWindow.document.getElementById('HyphenatorToggleBox'); if (!!myBox) { myBox.firstChild.data = text; @@ -2167,12 +2172,10 @@ var Hyphenator = (function (window) { * @access private */ doCharSubst = function (loCharSubst, w) { - var subst, r = w; - for (subst in loCharSubst) { - if (loCharSubst.hasOwnProperty(subst)) { - r = r.replace(new RegExp(subst, 'g'), loCharSubst[subst]); - } - } + var r = w; + forEachKey(loCharSubst, function (subst) { + r = r.replace(new RegExp(subst, 'g'), loCharSubst[subst]); + }); return r; }, @@ -2394,91 +2397,101 @@ var Hyphenator = (function (window) { }, copy = (function () { - var Copy = function () { - - this.oncopyHandler = function (e) { - e = e || window.event; - var shadow, selection, range, rangeShadow, restore, - target = e.target || e.srcElement, - currDoc = target.ownerDocument, - bdy = currDoc.getElementsByTagName('body')[0], - targetWindow = currDoc.defaultView || currDoc.parentWindow; - if (target.tagName && dontHyphenate[target.tagName.toLowerCase()]) { - //Safari needs this - return; - } - //create a hidden shadow element - shadow = currDoc.createElement('div'); - //Moving the element out of the screen doesn't work for IE9 (https://connect.microsoft.com/IE/feedback/details/663981/) - //shadow.style.overflow = 'hidden'; - //shadow.style.position = 'absolute'; - //shadow.style.top = '-5000px'; - //shadow.style.height = '1px'; - //doing this instead: - shadow.style.color = window.getComputedStyle ? targetWindow.getComputedStyle(bdy, null).backgroundColor : '#FFFFFF'; - shadow.style.fontSize = '0px'; - bdy.appendChild(shadow); - if (!!window.getSelection) { - //FF3, Webkit, IE9 - e.stopPropagation(); - selection = targetWindow.getSelection(); - range = selection.getRangeAt(0); - shadow.appendChild(range.cloneContents()); - removeHyphenationFromElement(shadow); - selection.selectAllChildren(shadow); - restore = function () { - shadow.parentNode.removeChild(shadow); - selection.removeAllRanges(); //IE9 needs that - selection.addRange(range); - }; - } else { - // IE<9 - e.cancelBubble = true; - selection = targetWindow.document.selection; - range = selection.createRange(); - shadow.innerHTML = range.htmlText; - removeHyphenationFromElement(shadow); - rangeShadow = bdy.createTextRange(); - rangeShadow.moveToElementText(shadow); - rangeShadow.select(); - restore = function () { - shadow.parentNode.removeChild(shadow); - if (range.text !== "") { - range.select(); - } - }; - } - zeroTimeOut(restore); - }; - - this.removeOnCopy = function (el) { - var body = el.ownerDocument.getElementsByTagName('body')[0]; - if (!body) { - return; - } - el = el || body; - if (window.removeEventListener) { - el.removeEventListener("copy", this.oncopyHandler, true); - } else { - el.detachEvent("oncopy", this.oncopyHandler); - } - }; - - this.registerOnCopy = function (el) { - var body = el.ownerDocument.getElementsByTagName('body')[0]; - if (!body) { - return; - } - el = el || body; - if (window.addEventListener) { - el.addEventListener("copy", this.oncopyHandler, true); - } else { - el.attachEvent("oncopy", this.oncopyHandler); - } + var makeCopy = function () { + var oncopyHandler = function (e) { + e = e || window.event; + var shadow, + selection, + range, + rangeShadow, + restore, + target = e.target || e.srcElement, + currDoc = target.ownerDocument, + bdy = currDoc.getElementsByTagName('body')[0], + targetWindow = currDoc.defaultView || currDoc.parentWindow; + if (target.tagName && dontHyphenate[target.tagName.toLowerCase()]) { + //Safari needs this + return; + } + //create a hidden shadow element + shadow = currDoc.createElement('div'); + //Moving the element out of the screen doesn't work for IE9 (https://connect.microsoft.com/IE/feedback/details/663981/) + //shadow.style.overflow = 'hidden'; + //shadow.style.position = 'absolute'; + //shadow.style.top = '-5000px'; + //shadow.style.height = '1px'; + //doing this instead: + shadow.style.color = window.getComputedStyle + ? targetWindow.getComputedStyle(bdy, null).backgroundColor + : '#FFFFFF'; + shadow.style.fontSize = '0px'; + bdy.appendChild(shadow); + if (!!window.getSelection) { + //FF3, Webkit, IE9 + e.stopPropagation(); + selection = targetWindow.getSelection(); + range = selection.getRangeAt(0); + shadow.appendChild(range.cloneContents()); + removeHyphenationFromElement(shadow); + selection.selectAllChildren(shadow); + restore = function () { + shadow.parentNode.removeChild(shadow); + selection.removeAllRanges(); //IE9 needs that + selection.addRange(range); + }; + } else { + // IE<9 + e.cancelBubble = true; + selection = targetWindow.document.selection; + range = selection.createRange(); + shadow.innerHTML = range.htmlText; + removeHyphenationFromElement(shadow); + rangeShadow = bdy.createTextRange(); + rangeShadow.moveToElementText(shadow); + rangeShadow.select(); + restore = function () { + shadow.parentNode.removeChild(shadow); + if (range.text !== "") { + range.select(); + } + }; + } + zeroTimeOut(restore); + }, + removeOnCopy = function (el) { + var body = el.ownerDocument.getElementsByTagName('body')[0]; + if (!body) { + return; + } + el = el || body; + if (window.removeEventListener) { + el.removeEventListener("copy", oncopyHandler, true); + } else { + el.detachEvent("oncopy", oncopyHandler); + } + }, + registerOnCopy = function (el) { + var body = el.ownerDocument.getElementsByTagName('body')[0]; + if (!body) { + return; + } + el = el || body; + if (window.addEventListener) { + el.addEventListener("copy", oncopyHandler, true); + } else { + el.attachEvent("oncopy", oncopyHandler); + } + }; + return { + oncopyHandler: oncopyHandler, + removeOnCopy: removeOnCopy, + registerOnCopy: registerOnCopy }; }; - return (safeCopy ? new Copy() : false); + return (safeCopy + ? makeCopy() + : false); }()), @@ -2489,7 +2502,7 @@ var Hyphenator = (function (window) { * @access private */ checkIfAllDone = function () { - var allDone = true, i, doclist = {}, doc; + var allDone = true, i, doclist = {}; elements.each(function (ellist) { var j, l = ellist.length; for (j = 0; j < l; j += 1) { @@ -2516,11 +2529,9 @@ var Hyphenator = (function (window) { for (i = 0; i < CSSEditors.length; i += 1) { CSSEditors[i].clearChanges(); } - for (doc in doclist) { - if (doclist.hasOwnProperty(doc) && doc === contextWindow.location.href) { - onHyphenationDone(doc); - } - } + forEachKey(doclist, function (doc) { + onHyphenationDone(doc); + }); if (!!storage && storage.deferred.length > 0) { for (i = 0; i < storage.deferred.length; i += 1) { storage.deferred[i].call(); @@ -2566,7 +2577,7 @@ var Hyphenator = (function (window) { } if (orphanControl === 3) { //replace spaces by non breaking spaces - r = r.replace(/[ ]+/g, String.fromCharCode(160)); + r = r.replace(/[\ ]+/g, String.fromCharCode(160)); } return r; }, @@ -2605,11 +2616,11 @@ var Hyphenator = (function (window) { n = el.childNodes[i]; while (!!n) { if (n.nodeType === 3 //type 3 = #text - && /\S/.test(n.data) //not just white space + && (/\S/).test(n.data) //not just white space && n.data.length >= min) { //longer then min n.data = n.data.replace(lo.genRegExp, hyphenate); if (orphanControl !== 1) { - n.data = n.data.replace(/[\S]+ [\S]+[\s]*$/, controlOrphans); + n.data = n.data.replace(/[\S]+\ [\S]+[\s]*$/, controlOrphans); } } i += 1; @@ -2626,8 +2637,8 @@ var Hyphenator = (function (window) { el.className = el.className.replace(hideClassRegExp, ' ' + unhideClass); } elo.hyphenated = true; - elements.hyCount += 1; - if (elements.count <= elements.hyCount) { + elements.counters[1] += 1; + if (elements.counters[0] <= elements.counters[1]) { checkIfAllDone(); } }, @@ -2697,7 +2708,32 @@ var Hyphenator = (function (window) { * @access private */ createStorage = function () { - var s; + var s, + makeStorage = function (s) { + var store = s, + prefix = 'Hyphenator_' + Hyphenator.version + '_', + deferred = [], + test = function (name) { + var val = store.getItem(prefix + name); + return !!val; + }, + getItem = function (name) { + return store.getItem(prefix + name); + }, + setItem = function (name, value) { + try { + store.setItem(prefix + name, value); + } catch (e) { + onError(e); + } + }; + return { + deferred: deferred, + test: test, + getItem: getItem, + setItem: setItem + }; + }; try { if (storageType !== 'none' && window.JSON !== undefined && @@ -2720,30 +2756,12 @@ var Hyphenator = (function (window) { s.setItem('storageTest', '1'); s.removeItem('storageTest'); } - } catch (e) { + } catch (ignore) { //FF throws an error if DOM.storage.enabled is set to false s = undefined; } if (s) { - storage = { - prefix: 'Hyphenator_' + Hyphenator.version + '_', - store: s, - deferred: [], - test: function (name) { - var val = this.store.getItem(this.prefix + name); - return (!!val) ? true : false; - }, - getItem: function (name) { - return this.store.getItem(this.prefix + name); - }, - setItem: function (name, value) { - try { - this.store.setItem(this.prefix + name, value); - } catch (e) { - onError(e); - } - } - }; + storage = makeStorage(s); } else { storage = undefined; } @@ -2865,17 +2883,17 @@ var Hyphenator = (function (window) { */ config: function (obj) { var assert = function (name, type) { - var r, t; - t = typeof obj[name]; - if (t === type) { - r = true; - } else { - onError(new Error('Config onError: ' + name + ' must be of type ' + type)); - r = false; - } - return r; - }, - key; + var r, + t; + t = typeof obj[name]; + if (t === type) { + r = true; + } else { + onError(new Error('Config onError: ' + name + ' must be of type ' + type)); + r = false; + } + return r; + }; if (obj.hasOwnProperty('storagetype')) { if (assert('storagetype', 'string')) { @@ -2889,156 +2907,154 @@ var Hyphenator = (function (window) { restoreConfiguration(); } - for (key in obj) { - if (obj.hasOwnProperty(key)) { - switch (key) { - case 'STORED': - break; - case 'classname': - if (assert('classname', 'string')) { - hyphenateClass = obj[key]; - } - break; - case 'urlclassname': - if (assert('urlclassname', 'string')) { - urlHyphenateClass = obj[key]; - } - break; - case 'donthyphenateclassname': - if (assert('donthyphenateclassname', 'string')) { - dontHyphenateClass = obj[key]; - } - break; - case 'minwordlength': - if (assert('minwordlength', 'number')) { - min = obj[key]; - } - break; - case 'hyphenchar': - if (assert('hyphenchar', 'string')) { - if (obj.hyphenchar === '­') { - obj.hyphenchar = String.fromCharCode(173); - } - hyphen = obj[key]; - } - break; - case 'urlhyphenchar': - if (obj.hasOwnProperty('urlhyphenchar')) { - if (assert('urlhyphenchar', 'string')) { - urlhyphen = obj[key]; - } - } - break; - case 'togglebox': - if (assert('togglebox', 'function')) { - toggleBox = obj[key]; - } - break; - case 'displaytogglebox': - if (assert('displaytogglebox', 'boolean')) { - displayToggleBox = obj[key]; - } - break; - case 'remoteloading': - if (assert('remoteloading', 'boolean')) { - enableRemoteLoading = obj[key]; - } - break; - case 'enablecache': - if (assert('enablecache', 'boolean')) { - enableCache = obj[key]; - } - break; - case 'enablereducedpatternset': - if (assert('enablereducedpatternset', 'boolean')) { - enableReducedPatternSet = obj[key]; - } - break; - case 'onhyphenationdonecallback': - if (assert('onhyphenationdonecallback', 'function')) { - onHyphenationDone = obj[key]; - } - break; - case 'onerrorhandler': - if (assert('onerrorhandler', 'function')) { - onError = obj[key]; - } - break; - case 'onwarninghandler': - if (assert('onwarninghandler', 'function')) { - onWarning = obj[key]; - } - break; - case 'intermediatestate': - if (assert('intermediatestate', 'string')) { - intermediateState = obj[key]; - } - break; - case 'selectorfunction': - if (assert('selectorfunction', 'function')) { - selectorFunction = obj[key]; - } - break; - case 'safecopy': - if (assert('safecopy', 'boolean')) { - safeCopy = obj[key]; - } - break; - case 'doframes': - if (assert('doframes', 'boolean')) { - doFrames = obj[key]; - } - break; - case 'storagetype': - if (assert('storagetype', 'string')) { - storageType = obj[key]; - } - break; - case 'orphancontrol': - if (assert('orphancontrol', 'number')) { - orphanControl = obj[key]; - } - break; - case 'dohyphenation': - if (assert('dohyphenation', 'boolean')) { - Hyphenator.doHyphenation = obj[key]; - } - break; - case 'persistentconfig': - if (assert('persistentconfig', 'boolean')) { - persistentConfig = obj[key]; - } - break; - case 'defaultlanguage': - if (assert('defaultlanguage', 'string')) { - defaultLanguage = obj[key]; - } - break; - case 'useCSS3hyphenation': - if (assert('useCSS3hyphenation', 'boolean')) { - css3 = obj[key]; - } - break; - case 'unhide': - if (assert('unhide', 'string')) { - unhide = obj[key]; - } - break; - case 'onbeforewordhyphenation': - if (assert('onbeforewordhyphenation', 'function')) { - onBeforeWordHyphenation = obj[key]; + forEachKey(obj, function (key) { + switch (key) { + case 'STORED': + break; + case 'classname': + if (assert('classname', 'string')) { + hyphenateClass = obj[key]; + } + break; + case 'urlclassname': + if (assert('urlclassname', 'string')) { + urlHyphenateClass = obj[key]; + } + break; + case 'donthyphenateclassname': + if (assert('donthyphenateclassname', 'string')) { + dontHyphenateClass = obj[key]; + } + break; + case 'minwordlength': + if (assert('minwordlength', 'number')) { + min = obj[key]; + } + break; + case 'hyphenchar': + if (assert('hyphenchar', 'string')) { + if (obj.hyphenchar === '­') { + obj.hyphenchar = String.fromCharCode(173); } - break; - case 'onafterwordhyphenation': - if (assert('onafterwordhyphenation', 'function')) { - onAfterWordHyphenation = obj[key]; + hyphen = obj[key]; + } + break; + case 'urlhyphenchar': + if (obj.hasOwnProperty('urlhyphenchar')) { + if (assert('urlhyphenchar', 'string')) { + urlhyphen = obj[key]; } - break; - default: - onError(new Error('Hyphenator.config: property ' + key + ' not known.')); } + break; + case 'togglebox': + if (assert('togglebox', 'function')) { + toggleBox = obj[key]; + } + break; + case 'displaytogglebox': + if (assert('displaytogglebox', 'boolean')) { + displayToggleBox = obj[key]; + } + break; + case 'remoteloading': + if (assert('remoteloading', 'boolean')) { + enableRemoteLoading = obj[key]; + } + break; + case 'enablecache': + if (assert('enablecache', 'boolean')) { + enableCache = obj[key]; + } + break; + case 'enablereducedpatternset': + if (assert('enablereducedpatternset', 'boolean')) { + enableReducedPatternSet = obj[key]; + } + break; + case 'onhyphenationdonecallback': + if (assert('onhyphenationdonecallback', 'function')) { + onHyphenationDone = obj[key]; + } + break; + case 'onerrorhandler': + if (assert('onerrorhandler', 'function')) { + onError = obj[key]; + } + break; + case 'onwarninghandler': + if (assert('onwarninghandler', 'function')) { + onWarning = obj[key]; + } + break; + case 'intermediatestate': + if (assert('intermediatestate', 'string')) { + intermediateState = obj[key]; + } + break; + case 'selectorfunction': + if (assert('selectorfunction', 'function')) { + selectorFunction = obj[key]; + } + break; + case 'safecopy': + if (assert('safecopy', 'boolean')) { + safeCopy = obj[key]; + } + break; + case 'doframes': + if (assert('doframes', 'boolean')) { + doFrames = obj[key]; + } + break; + case 'storagetype': + if (assert('storagetype', 'string')) { + storageType = obj[key]; + } + break; + case 'orphancontrol': + if (assert('orphancontrol', 'number')) { + orphanControl = obj[key]; + } + break; + case 'dohyphenation': + if (assert('dohyphenation', 'boolean')) { + Hyphenator.doHyphenation = obj[key]; + } + break; + case 'persistentconfig': + if (assert('persistentconfig', 'boolean')) { + persistentConfig = obj[key]; + } + break; + case 'defaultlanguage': + if (assert('defaultlanguage', 'string')) { + defaultLanguage = obj[key]; + } + break; + case 'useCSS3hyphenation': + if (assert('useCSS3hyphenation', 'boolean')) { + css3 = obj[key]; + } + break; + case 'unhide': + if (assert('unhide', 'string')) { + unhide = obj[key]; + } + break; + case 'onbeforewordhyphenation': + if (assert('onbeforewordhyphenation', 'function')) { + onBeforeWordHyphenation = obj[key]; + } + break; + case 'onafterwordhyphenation': + if (assert('onafterwordhyphenation', 'function')) { + onAfterWordHyphenation = obj[key]; + } + break; + default: + onError(new Error('Hyphenator.config: property ' + key + ' not known.')); } - } + }); if (storage && persistentConfig) { storeConfiguration(); } @@ -3144,7 +3160,7 @@ var Hyphenator = (function (window) { n = target.childNodes[i]; while (!!n) { if (n.nodeType === 3 //type 3 = #text - && /\S/.test(n.data) //not just white space + && (/\S/).test(n.data) //not just white space && n.data.length >= min) { //longer then min n.data = n.data.replace(lo.genRegExp, hyphenate); } else if (n.nodeType === 1) { @@ -3196,8 +3212,16 @@ var Hyphenator = (function (window) { */ getConfigFromURI: function () { /*jslint evil: true*/ - var loc = null, re = {}, jsArray = contextWindow.document.getElementsByTagName('script'), i, j, l, s, gp, option; - for (i = 0, l = jsArray.length; i < l; i += 1) { + var loc = null, + re = {}, + jsArray = contextWindow.document.getElementsByTagName('script'), + i = 0, + j, + l = jsArray.length, + s, + gp, + option; + while (i < l) { if (!!jsArray[i].getAttribute('src')) { loc = jsArray[i].getAttribute('src'); } @@ -3227,6 +3251,7 @@ var Hyphenator = (function (window) { } break; } + i += 1; } return re; }, From 4e20728696da4a1eb2daa03526d01319b28d28d6 Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 26 Nov 2015 23:24:05 +0100 Subject: [PATCH 28/86] Prevent deopt --- Hyphenator.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index fbf8675..b12e15e 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -1674,7 +1674,19 @@ var Hyphenator = (function (window) { * @access private */ makeValueStore = function (len) { - var indexes = [1, 2, 2], + //var indexes = [1, 2, 2], + var indexes = (function () { + var arr; + if (Object.prototype.hasOwnProperty.call(window, "Uint32Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) + arr = new window.Uint32Array(3); + arr[0] = 1; + arr[1] = 2; + arr[2] = 2; + } else { + arr = [1, 2, 2]; + } + return arr; + }()), keys = (function () { var i, r; if (Object.prototype.hasOwnProperty.call(window, "Uint8Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) @@ -2248,7 +2260,6 @@ var Hyphenator = (function (window) { indexedTrie = lo.indexedTrie, valueStore = lo.valueStore.keys, wwAsMappedCharCode = wwAsMappedCharCodeStore; - word = onBeforeWordHyphenation(word, lang); if (word === '') { hw = ''; @@ -2283,11 +2294,9 @@ var Hyphenator = (function (window) { for (pstart = 0; pstart < wwlen; pstart += 1) { wwhp[pstart] = 0; charCode = ww.charCodeAt(pstart); - if (charMap[charCode] !== undefined) { - wwAsMappedCharCode[pstart] = charMap[charCode]; - } else { - wwAsMappedCharCode[pstart] = -1; - } + wwAsMappedCharCode[pstart] = charMap.hasOwnProperty(charCode) + ? charMap[charCode] + : -1; } //get hyphenation points for all substrings for (pstart = 0; pstart < wwlen; pstart += 1) { From adf2585197d46f593d66128a4313ec763757509d Mon Sep 17 00:00:00 2001 From: mnater Date: Sun, 29 Nov 2015 23:06:51 +0100 Subject: [PATCH 29/86] Refactor Use function declaration instead of function expression --- Hyphenator.js | 5432 +++++++++++++++++++++++++------------------------ 1 file changed, 2756 insertions(+), 2676 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index b12e15e..7067118 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -12,7 +12,7 @@ */ /* The following comment is for JSLint: */ -/*jslint browser: true for: true*/ +/*jslint browser: true for: false*/ /*global Hyphenator window*/ /** @@ -27,2811 +27,2891 @@ * Hyphenator.run(); * </script> */ -var Hyphenator = (function (window) { +var Hyphenator; +Hyphenator = (function (window) { 'use strict'; - /** - * @member Hyphenator~contextWindow - * @access private - * @desc - * contextWindow stores the window for the actual document to be hyphenated. - * If there are frames this will change. - * So use contextWindow instead of window! - */ - var contextWindow = window, - - - /** - * @member {Object.} Hyphenator~supportedLangs - * @desc - * A generated key-value object that stores supported languages and meta data. - * The key is the {@link http://tools.ietf.org/rfc/bcp/bcp47.txt bcp47} code of the language and the value - * is an object of type {@link Hyphenator~supportedLangs~supportedLanguage} - * @namespace Hyphenator~supportedLangs - * @access private - * //Check if language lang is supported: - * if (supportedLangs.hasOwnProperty(lang)) - */ - supportedLangs = (function () { - /** - * @typedef {Object} Hyphenator~supportedLangs~supportedLanguage - * @property {string} file - The name of the pattern file - * @property {number} script - The script type of the language (e.g. 'latin' for english), this type is abbreviated by an id - * @property {string} prompt - The sentence prompted to the user, if Hyphenator.js doesn't find a language hint - */ - - /** - * @lends Hyphenator~supportedLangs - */ - var r = {}, - /** - * @method Hyphenator~supportedLangs~o - * @desc - * Sets a value of Hyphenator~supportedLangs - * @access protected - * @param {string} code The {@link http://tools.ietf.org/rfc/bcp/bcp47.txt bcp47} code of the language - * @param {string} file The name of the pattern file - * @param {Number} script A shortcut for a specific script: latin:0, cyrillic: 1, arabic: 2, armenian:3, bengali: 4, devangari: 5, greek: 6 - * gujarati: 7, kannada: 8, lao: 9, malayalam: 10, oriya: 11, persian: 12, punjabi: 13, tamil: 14, telugu: 15 - * @param {string} prompt The sentence prompted to the user, if Hyphenator.js doesn't find a language hint - */ - o = function (code, file, script, prompt) { - r[code] = {'file': file, 'script': script, 'prompt': prompt}; - }; - - o('be', 'be.js', 1, 'Мова гэтага сайта не можа быць вызначаны аўтаматычна. Калі ласка пакажыце мову:'); - o('ca', 'ca.js', 0, ''); - o('cs', 'cs.js', 0, 'Jazyk této internetové stránky nebyl automaticky rozpoznán. Určete prosím její jazyk:'); - o('da', 'da.js', 0, 'Denne websides sprog kunne ikke bestemmes. Angiv venligst sprog:'); - o('bn', 'bn.js', 4, ''); - o('de', 'de.js', 0, 'Die Sprache dieser Webseite konnte nicht automatisch bestimmt werden. Bitte Sprache angeben:'); - o('el', 'el-monoton.js', 6, ''); - o('el-monoton', 'el-monoton.js', 6, ''); - o('el-polyton', 'el-polyton.js', 6, ''); - o('en', 'en-us.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); - o('en-gb', 'en-gb.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); - o('en-us', 'en-us.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); - o('eo', 'eo.js', 0, 'La lingvo de ĉi tiu retpaĝo ne rekoneblas aŭtomate. Bonvolu indiki ĝian ĉeflingvon:'); - o('es', 'es.js', 0, 'El idioma del sitio no pudo determinarse autom%E1ticamente. Por favor, indique el idioma principal:'); - o('et', 'et.js', 0, 'Veebilehe keele tuvastamine ebaõnnestus, palun valige kasutatud keel:'); - o('fi', 'fi.js', 0, 'Sivun kielt%E4 ei tunnistettu automaattisesti. M%E4%E4rit%E4 sivun p%E4%E4kieli:'); - o('fr', 'fr.js', 0, 'La langue de ce site n%u2019a pas pu %EAtre d%E9termin%E9e automatiquement. Veuillez indiquer une langue, s.v.p.%A0:'); - o('grc', 'grc.js', 6, ''); - o('gu', 'gu.js', 7, ''); - o('hi', 'hi.js', 5, ''); - o('hu', 'hu.js', 0, 'A weboldal nyelvét nem sikerült automatikusan megállapítani. Kérem adja meg a nyelvet:'); - o('hy', 'hy.js', 3, 'Չհաջողվեց հայտնաբերել այս կայքի լեզուն։ Խնդրում ենք նշեք հիմնական լեզուն՝'); - o('it', 'it.js', 0, 'Lingua del sito sconosciuta. Indicare una lingua, per favore:'); - o('kn', 'kn.js', 8, 'ಜಾಲ ತಾಣದ ಭಾಷೆಯನ್ನು ನಿರ್ಧರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ದಯವಿಟ್ಟು ಮುಖ್ಯ ಭಾಷೆಯನ್ನು ಸೂಚಿಸಿ:'); - o('la', 'la.js', 0, ''); - o('lt', 'lt.js', 0, 'Nepavyko automatiškai nustatyti šios svetainės kalbos. Prašome įvesti kalbą:'); - o('lv', 'lv.js', 0, 'Šīs lapas valodu nevarēja noteikt automātiski. Lūdzu norādiet pamata valodu:'); - o('ml', 'ml.js', 10, 'ഈ വെ%u0D2C%u0D4D%u200Cസൈറ്റിന്റെ ഭാഷ കണ്ടുപിടിയ്ക്കാ%u0D28%u0D4D%u200D കഴിഞ്ഞില്ല. ഭാഷ ഏതാണെന്നു തിരഞ്ഞെടുക്കുക:'); - o('nb', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); - o('no', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); - o('nb-no', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); - o('nl', 'nl.js', 0, 'De taal van deze website kan niet automatisch worden bepaald. Geef de hoofdtaal op:'); - o('or', 'or.js', 11, ''); - o('pa', 'pa.js', 13, ''); - o('pl', 'pl.js', 0, 'Języka tej strony nie można ustalić automatycznie. Proszę wskazać język:'); - o('pt', 'pt.js', 0, 'A língua deste site não pôde ser determinada automaticamente. Por favor indique a língua principal:'); - o('ru', 'ru.js', 1, 'Язык этого сайта не может быть определен автоматически. Пожалуйста укажите язык:'); - o('sk', 'sk.js', 0, ''); - o('sl', 'sl.js', 0, 'Jezika te spletne strani ni bilo mogoče samodejno določiti. Prosim navedite jezik:'); - o('sr-cyrl', 'sr-cyrl.js', 1, 'Језик овог сајта није детектован аутоматски. Молим вас наведите језик:'); - o('sr-latn', 'sr-latn.js', 0, 'Jezika te spletne strani ni bilo mogoče samodejno določiti. Prosim navedite jezik:'); - o('sv', 'sv.js', 0, 'Spr%E5ket p%E5 den h%E4r webbplatsen kunde inte avg%F6ras automatiskt. V%E4nligen ange:'); - o('ta', 'ta.js', 14, ''); - o('te', 'te.js', 15, ''); - o('tr', 'tr.js', 0, 'Bu web sitesinin dili otomatik olarak tespit edilememiştir. Lütfen dökümanın dilini seçiniz%A0:'); - o('uk', 'uk.js', 1, 'Мова цього веб-сайту не може бути визначена автоматично. Будь ласка, вкажіть головну мову:'); - o('ro', 'ro.js', 0, 'Limba acestui sit nu a putut fi determinată automat. Alege limba principală:'); - - return r; - }()), - - - /** - * @member {string} Hyphenator~basePath - * @desc - * A string storing the basepath from where Hyphenator.js was loaded. - * This is used to load the pattern files. - * The basepath is determined dynamically by searching all script-tags for Hyphenator.js - * If the path cannot be determined {@link http://mnater.github.io/Hyphenator/} is used as fallback. - * @access private - * @see {@link Hyphenator~loadPatterns} - */ - basePath = (function () { - var s = contextWindow.document.getElementsByTagName('script'), i = 0, p, src, t = s[i], r = ''; - while (!!t) { - if (!!t.src) { - src = t.src; - p = src.indexOf('Hyphenator.js'); - if (p !== -1) { - r = src.substring(0, p); - } - } - i += 1; - t = s[i]; - } - return !!r - ? r - : '//mnater.github.io/Hyphenator/'; - }()), - - /** - * @member {boolean} Hyphenator~isLocal - * @access private - * @desc - * isLocal is true, if Hyphenator is loaded from the same domain, as the webpage, but false, if - * it's loaded from an external source (i.e. directly from github) - */ - isLocal = (function () { - var re = false; - if (window.location.href.indexOf(basePath) !== -1) { - re = true; - } - return re; - }()), - - /** - * @member {boolean} Hyphenator~documentLoaded - * @access private - * @desc - * documentLoaded is true, when the DOM has been loaded. This is set by {@link Hyphenator~runWhenLoaded} - */ - documentLoaded = false, - - /** - * @member {boolean} Hyphenator~persistentConfig - * @access private - * @desc - * if persistentConfig is set to true (defaults to false), config options and the state of the - * toggleBox are stored in DOM-storage (according to the storage-setting). So they haven't to be - * set for each page. - * @default false - * @see {@link Hyphenator.config} - */ - persistentConfig = false, - - /** - * @member {boolean} Hyphenator~doFrames - * @access private - * @desc - * switch to control if frames/iframes should be hyphenated, too. - * defaults to false (frames are a bag of hurt!) - * @default false - * @see {@link Hyphenator.config} - */ - doFrames = false, - - /** - * @member {Object.} Hyphenator~dontHyphenate - * @desc - * A key-value object containing all html-tags whose content should not be hyphenated - * @access private - */ - dontHyphenate = {'video': true, 'audio': true, 'script': true, 'code': true, 'pre': true, 'img': true, 'br': true, 'samp': true, 'kbd': true, 'var': true, 'abbr': true, 'acronym': true, 'sub': true, 'sup': true, 'button': true, 'option': true, 'label': true, 'textarea': true, 'input': true, 'math': true, 'svg': true, 'style': true}, - - /** - * @member {boolean} Hyphenator~enableCache - * @desc - * A variable to set if caching is enabled or not - * @default true - * @access private - * @see {@link Hyphenator.config} - */ - enableCache = true, - - /** - * @member {string} Hyphenator~storageType - * @desc - * A variable to define what html5-DOM-Storage-Method is used ('none', 'local' or 'session') - * @default 'local' - * @access private - * @see {@link Hyphenator.config} - */ - storageType = 'local', - - /** - * @member {Object|undefined} Hyphenator~storage - * @desc - * An alias to the storage defined in storageType. This is set by {@link Hyphenator~createStorage}. - * Set by {@link Hyphenator.run} - * @default null - * @access private - * @see {@link Hyphenator~createStorage} - */ - storage, - - /** - * @member {boolean} Hyphenator~enableReducedPatternSet - * @desc - * A variable to set if storing the used patterns is set - * @default false - * @access private - * @see {@link Hyphenator.config} - * @see {@link Hyphenator.getRedPatternSet} - */ - enableReducedPatternSet = false, - - /** - * @member {boolean} Hyphenator~enableRemoteLoading - * @desc - * A variable to set if pattern files should be loaded remotely or not - * @default true - * @access private - * @see {@link Hyphenator.config} - */ - enableRemoteLoading = true, - - /** - * @member {boolean} Hyphenator~displayToggleBox - * @desc - * A variable to set if the togglebox should be displayed or not - * @default false - * @access private - * @see {@link Hyphenator.config} - */ - displayToggleBox = false, - - /** - * @method Hyphenator~onError - * @desc - * A function that can be called upon an error. - * @see {@link Hyphenator.config} - * @access private - */ - onError = function (e) { - window.alert("Hyphenator.js says:\n\nAn Error occurred:\n" + e.message); - }, - - /** - * @method Hyphenator~onWarning - * @desc - * A function that can be called upon a warning. - * @see {@link Hyphenator.config} - * @access private - */ - onWarning = function (e) { - window.console.log(e.message); - }, - - /** - * @method Hyphenator~createElem - * @desc - * A function alias to document.createElementNS or document.createElement - * @access private - */ - createElem = function (tagname, context) { - context = context || contextWindow; - var el; - if (window.document.createElementNS) { - el = context.document.createElementNS('http://www.w3.org/1999/xhtml', tagname); - } else if (window.document.createElement) { - el = context.document.createElement(tagname); - } - return el; - }, - - forEachKey = function (o, f) { - var a, k; - if (Object.hasOwnProperty("keys")) { - a = Object.keys(o); - a.forEach(function (v) { - f(v); - }); - } else { - for (k in o) { - if (o.hasOwnProperty(k)) { - f(k); - } - } - } - }, - - /** - * @member {boolean} Hyphenator~css3 - * @desc - * A variable to set if css3 hyphenation should be used - * @default false - * @access private - * @see {@link Hyphenator.config} - */ - css3 = false, - - /** - * @method Hyphenator~css3_gethsupport - * @desc - * This function returns a {@link Hyphenator~css3_hsupport} object for the current UA - * @type function - * @access private - * @see Hyphenator~css3_h9n - */ - css3_gethsupport = function () { - var support = false, - supportedBrowserLangs = {}, - property = '', - checkLangSupport, - createLangSupportChecker = function (prefix) { - var testStrings = [ - //latin: 0 - 'aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz', - //cyrillic: 1 - 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя', - //arabic: 2 - 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', - //armenian: 3 - 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆ', - //bengali: 4 - 'ঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ়ঽািীুূৃৄেৈোৌ্ৎৗড়ঢ়য়ৠৡৢৣ', - //devangari: 5 - 'ँंःअआइईउऊऋऌएऐओऔकखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसहऽािीुूृॄेैोौ्॒॑ॠॡॢॣ', - //greek: 6 - 'αβγδεζηθικλμνξοπρσςτυφχψω', - //gujarati: 7 - 'બહઅઆઇઈઉઊઋૠએઐઓઔાિીુૂૃૄૢૣેૈોૌકખગઘઙચછજઝઞટઠડઢણતથદધનપફસભમયરલળવશષ', - //kannada: 8 - 'ಂಃಅಆಇಈಉಊಋಌಎಏಐಒಓಔಕಖಗಘಙಚಛಜಝಞಟಠಡಢಣತಥದಧನಪಫಬಭಮಯರಱಲಳವಶಷಸಹಽಾಿೀುೂೃೄೆೇೈೊೋೌ್ೕೖೞೠೡ', - //lao: 9 - 'ກຂຄງຈຊຍດຕຖທນບປຜຝພຟມຢຣລວສຫອຮະັາິີຶືຸູົຼເແໂໃໄ່້໊໋ໜໝ', - //malayalam: 10 - 'ംഃഅആഇഈഉഊഋഌഎഏഐഒഓഔകഖഗഘങചഛജഝഞടഠഡഢണതഥദധനപഫബഭമയരറലളഴവശഷസഹാിീുൂൃെേൈൊോൌ്ൗൠൡൺൻർൽൾൿ', - //oriya: 11 - 'ଁଂଃଅଆଇଈଉଊଋଌଏଐଓଔକଖଗଘଙଚଛଜଝଞଟଠଡଢଣତଥଦଧନପଫବଭମଯରଲଳଵଶଷସହାିୀୁୂୃେୈୋୌ୍ୗୠୡ', - //persian: 12 - 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', - //punjabi: 13 - 'ਁਂਃਅਆਇਈਉਊਏਐਓਔਕਖਗਘਙਚਛਜਝਞਟਠਡਢਣਤਥਦਧਨਪਫਬਭਮਯਰਲਲ਼ਵਸ਼ਸਹਾਿੀੁੂੇੈੋੌ੍ੰੱ', - //tamil: 14 - 'ஃஅஆஇஈஉஊஎஏஐஒஓஔகஙசஜஞடணதநனபமயரறலளழவஷஸஹாிீுூெேைொோௌ்ௗ', - //telugu: 15 - 'ఁంఃఅఆఇఈఉఊఋఌఎఏఐఒఓఔకఖగఘఙచఛజఝఞటఠడఢణతథదధనపఫబభమయరఱలళవశషసహాిీుూృౄెేైొోౌ్ౕౖౠౡ' - ], - f = function (lang) { - var shadow, - computedHeight, - bdy, - r = false; - - //check if lang has already been tested - if (supportedBrowserLangs.hasOwnProperty(lang)) { - r = supportedBrowserLangs[lang]; - } else if (supportedLangs.hasOwnProperty(lang)) { - //create and append shadow-test-element - bdy = window.document.getElementsByTagName('body')[0]; - shadow = createElem('div', window); - shadow.id = 'Hyphenator_LanguageChecker'; - shadow.style.width = '5em'; - shadow.style.padding = '0'; - shadow.style.border = 'none'; - shadow.style[prefix] = 'auto'; - shadow.style.hyphens = 'auto'; - shadow.style.fontSize = '12px'; - shadow.style.lineHeight = '12px'; - shadow.style.wordWrap = 'normal'; - shadow.style.visibility = 'hidden'; - shadow.lang = lang; - shadow.style['-webkit-locale'] = "'" + lang + "'"; - shadow.innerHTML = testStrings[supportedLangs[lang].script]; - bdy.appendChild(shadow); - //measure its height - computedHeight = shadow.offsetHeight; - //remove shadow element - bdy.removeChild(shadow); - r = !!(computedHeight > 12); - supportedBrowserLangs[lang] = r; - } else { - r = false; - } - return r; - }; - return f; - }, - s; - - if (window.getComputedStyle) { - s = window.getComputedStyle(window.document.getElementsByTagName('body')[0], null); - if (s.hyphens !== undefined) { - support = true; - property = 'hyphens'; - checkLangSupport = createLangSupportChecker('hyphens'); - } else if (s['-webkit-hyphens'] !== undefined) { - support = true; - property = '-webkit-hyphens'; - checkLangSupport = createLangSupportChecker('-webkit-hyphens'); - } else if (s.MozHyphens !== undefined) { - support = true; - property = '-moz-hyphens'; - checkLangSupport = createLangSupportChecker('MozHyphens'); - } else if (s['-ms-hyphens'] !== undefined) { - support = true; - property = '-ms-hyphens'; - checkLangSupport = createLangSupportChecker('-ms-hyphens'); - } - } //else we just return the initial values because ancient browsers don't support css3 anyway - - - return { - support: support, - property: property, - supportedBrowserLangs: supportedBrowserLangs, - checkLangSupport: checkLangSupport - }; - }, - - /** - * @typedef {Object} Hyphenator~css3_hsupport - * @property {boolean} support - if css3-hyphenation is supported - * @property {string} property - the css property name to access hyphen-settings (e.g. -webkit-hyphens) - * @property {Object.} supportedBrowserLangs - an object caching tested languages - * @property {function} checkLangSupport - a method that checks if the browser supports a requested language - */ - - /** - * @member {Hyphenator~css3_h9n} Hyphenator~css3_h9n - * @desc - * A generated object containing information for CSS3-hyphenation support - * This is set by {@link Hyphenator~css3_gethsupport} - * @default undefined - * @access private - * @see {@link Hyphenator~css3_gethsupport} - * @example - * //Check if browser supports a language - * css3_h9n.checkLangSupport(<lang>) - */ - css3_h9n, - - /** - * @member {string} Hyphenator~hyphenateClass - * @desc - * A string containing the css-class-name for the hyphenate class - * @default 'hyphenate' - * @access private - * @example - * <p class = "hyphenate">Text</p> - * @see {@link Hyphenator.config} - */ - hyphenateClass = 'hyphenate', - - /** - * @member {string} Hyphenator~urlHyphenateClass - * @desc - * A string containing the css-class-name for the urlhyphenate class - * @default 'urlhyphenate' - * @access private - * @example - * <p class = "urlhyphenate">Text</p> - * @see {@link Hyphenator.config} - */ - urlHyphenateClass = 'urlhyphenate', - - /** - * @member {string} Hyphenator~classPrefix - * @desc - * A string containing a unique className prefix to be used - * whenever Hyphenator sets a CSS-class - * @access private - */ - classPrefix = 'Hyphenator' + Math.round(Math.random() * 1000), - - /** - * @member {string} Hyphenator~hideClass - * @desc - * The name of the class that hides elements - * @access private - */ - hideClass = classPrefix + 'hide', - - /** - * @member {RegExp} Hyphenator~hideClassRegExp - * @desc - * RegExp to remove hideClass from a list of classes - * @access private - */ - hideClassRegExp = new RegExp("\\s?\\b" + hideClass + "\\b", "g"), - - /** - * @member {string} Hyphenator~hideClass - * @desc - * The name of the class that unhides elements - * @access private - */ - unhideClass = classPrefix + 'unhide', - - /** - * @member {RegExp} Hyphenator~hideClassRegExp - * @desc - * RegExp to remove unhideClass from a list of classes - * @access private - */ - unhideClassRegExp = new RegExp("\\s?\\b" + unhideClass + "\\b", "g"), - - /** - * @member {string} Hyphenator~css3hyphenateClass - * @desc - * The name of the class that hyphenates elements with css3 - * @access private - */ - css3hyphenateClass = classPrefix + 'css3hyphenate', - - /** - * @member {CSSEdit} Hyphenator~css3hyphenateClass - * @desc - * The var where CSSEdit class is stored - * @access private - */ - css3hyphenateClassHandle, - - /** - * @member {string} Hyphenator~dontHyphenateClass - * @desc - * A string containing the css-class-name for elements that should not be hyphenated - * @default 'donthyphenate' - * @access private - * @example - * <p class = "donthyphenate">Text</p> - * @see {@link Hyphenator.config} - */ - dontHyphenateClass = 'donthyphenate', - - /** - * @member {number} Hyphenator~min - * @desc - * A number wich indicates the minimal length of words to hyphenate. - * @default 6 - * @access private - * @see {@link Hyphenator.config} - */ - min = 6, - - /** - * @member {number} Hyphenator~orphanControl - * @desc - * Control how the last words of a line are handled: - * level 1 (default): last word is hyphenated - * level 2: last word is not hyphenated - * level 3: last word is not hyphenated and last space is non breaking - * @default 1 - * @access private - */ - orphanControl = 1, - - /** - * @member {boolean} Hyphenator~isBookmarklet - * @desc - * True if Hyphanetor runs as bookmarklet. - * @access private - */ - isBookmarklet = (function () { - var loc = null, - re = false, - scripts = contextWindow.document.getElementsByTagName('script'), - i = 0, - l = scripts.length; - while (!re && i < l) { - loc = scripts[i].getAttribute('src'); - if (!!loc && loc.indexOf('Hyphenator.js?bm=true') !== -1) { - re = true; - } - i += 1; - } - return re; - }()), - - /** - * @member {string|null} Hyphenator~mainLanguage - * @desc - * The general language of the document. In contrast to {@link Hyphenator~defaultLanguage}, - * mainLanguage is defined by the client (i.e. by the html or by a prompt). - * @access private - * @see {@link Hyphenator~autoSetMainLanguage} - */ - mainLanguage = null, - - /** - * @member {string|null} Hyphenator~defaultLanguage - * @desc - * The language defined by the developper. This language setting is defined by a config option. - * It is overwritten by any html-lang-attribute and only taken in count, when no such attribute can - * be found (i.e. just before the prompt). - * @access private - * @see {@link Hyphenator.config} - * @see {@link Hyphenator~autoSetMainLanguage} - */ - defaultLanguage = '', - - /** - * @member {ElementCollection} Hyphenator~elements - * @desc - * A class representing all elements (of type Element) that have to be hyphenated. This var is filled by - * {@link Hyphenator~gatherDocumentInfos} - * @access private - */ - elements = (function () { - /** - * @constructor Hyphenator~elements~ElementCollection~Element - * @desc represents a DOM Element with additional information - * @access private - */ - var makeElement = function (element) { - return { - /** - * @member {Object} Hyphenator~elements~ElementCollection~Element~element - * @desc A DOM Element - * @access protected - */ - element: element, - /** - * @member {boolean} Hyphenator~elements~ElementCollection~Element~hyphenated - * @desc Marks if the element has been hyphenated - * @access protected - */ - hyphenated: false, - /** - * @member {boolean} Hyphenator~elements~ElementCollection~Element~treated - * @desc Marks if information of the element has been collected but not hyphenated (e.g. dohyphenation is off) - * @access protected - */ - treated: false - }; - }, - /** - * @constructor Hyphenator~elements~ElementCollection - * @desc A collection of Elements to be hyphenated - * @access protected - */ - makeElementCollection = function () { - /** - * @member {number} Hyphenator~elements~ElementCollection~counters - * @desc Array of [number of collected elements, number of hyphenated elements] - * @access protected - */ - var counters = [0, 0], - /** - * @member {Object.>} Hyphenator~elements~ElementCollection~list - * @desc The collection of elements, where the key is a language code and the value is an array of elements - * @access protected - */ - list = {}, - /** - * @method Hyphenator~elements~ElementCollection.prototype~add - * @augments Hyphenator~elements~ElementCollection - * @access protected - * @desc adds a DOM element to the collection - * @param {Object} el - The DOM element - * @param {string} lang - The language of the element - */ - add = function (el, lang) { - var elo = makeElement(el); - if (!list.hasOwnProperty(lang)) { - list[lang] = []; - } - list[lang].push(elo); - counters[0] += 1; - return elo; - }, - /** - * @callback Hyphenator~elements~ElementCollection.prototype~each~callback fn - The callback that is executed for each element - * @param {string} [k] The key (i.e. language) of the collection - * @param {Hyphenator~elements~ElementCollection~Element} element - */ - - /** - * @method Hyphenator~elements~ElementCollection.prototype~each - * @augments Hyphenator~elements~ElementCollection - * @access protected - * @desc takes each element of the collection as an argument of fn - * @param {Hyphenator~elements~ElementCollection.prototype~each~callback} fn - A function that takes an element as an argument - */ - each = function (fn) { - forEachKey(list, function (k) { - if (fn.length === 2) { - fn(k, list[k]); - } else { - fn(list[k]); - } - }); - }; - - return { - counters: counters, - list: list, - add: add, - each: each - }; - - }; - return makeElementCollection(); - }()), - - - /** - * @member {Object.} Hyphenator~exceptions - * @desc - * An object containing exceptions as comma separated strings for each language. - * When the language-objects are loaded, their exceptions are processed, copied here and then deleted. - * Exceptions can also be set by the user. - * @see {@link Hyphenator~prepareLanguagesObj} - * @access private - */ - exceptions = {}, - - /** - * @member {Object.} Hyphenator~docLanguages - * @desc - * An object holding all languages used in the document. This is filled by - * {@link Hyphenator~gatherDocumentInfos} - * @access private - */ - docLanguages = {}, - - /** - * @member {string} Hyphenator~url - * @desc - * A string containing a insane RegularExpression to match URL's - * @access private - */ - url = '(?:\\w*:\/\/)?(?:(?:\\w*:)?(?:\\w*)@)?(?:(?:(?:[\\d]{1,3}\\.){3}(?:[\\d]{1,3}))|(?:(?:www\\.|[a-zA-Z]\\.)?[a-zA-Z0-9\\-\\.]+\\.(?:[a-z]{2,4})))(?::\\d*)?(?:\/[\\w#!:\\.?\\+=&%@!\\-]*)*', - // protocoll usr pwd ip or host tld port path - - /** - * @member {string} Hyphenator~mail - * @desc - * A string containing a RegularExpression to match mail-adresses - * @access private - */ - mail = '[\\w-\\.]+@[\\w\\.]+', - - /** - * @member {string} Hyphenator~zeroWidthSpace - * @desc - * A string that holds a char. - * Depending on the browser, this is the zero with space or an empty string. - * zeroWidthSpace is used to break URLs - * @access private - */ - zeroWidthSpace = (function () { - var zws, ua = window.navigator.userAgent.toLowerCase(); - zws = String.fromCharCode(8203); //Unicode zero width space - if (ua.indexOf('msie 6') !== -1) { - zws = ''; //IE6 doesn't support zws - } - if (ua.indexOf('opera') !== -1 && ua.indexOf('version/10.00') !== -1) { - zws = ''; //opera 10 on XP doesn't support zws - } - return zws; - }()), - - /** - * @method Hyphenator~onBeforeWordHyphenation - * @desc - * This method is called just before a word is hyphenated. - * It is called with two parameters: the word and its language. - * The method must return a string (aka the word). - * @see {@link Hyphenator.config} - * @access private - * @param {string} word - * @param {string} lang - * @return {string} The word that goes into hyphenation - */ - onBeforeWordHyphenation = function (word) { - return word; - }, - - /** - * @method Hyphenator~onAfterWordHyphenation - * @desc - * This method is called for each word after it is hyphenated. - * Takes the word as a first parameter and its language as a second parameter. - * Returns a string that will replace the word that has been hyphenated. - * @see {@link Hyphenator.config} - * @access private - * @param {string} word - * @param {string} lang - * @return {string} The word that goes into hyphenation - */ - onAfterWordHyphenation = function (word) { - return word; - }, - - /** - * @method Hyphenator~onHyphenationDone - * @desc - * A method to be called, when the last element has been hyphenated. - * If there are frames the method is called for each frame. - * Therefore the location.href of the contextWindow calling this method is given as a parameter - * @see {@link Hyphenator.config} - * @param {string} context - * @access private - */ - onHyphenationDone = function (context) { - return context; - }, - - /** - * @name Hyphenator~selectorFunction - * @desc - * A function set by the user that has to return a HTMLNodeList or array of Elements to be hyphenated. - * By default this is set to false so we can check if a selectorFunction is set… - * @see {@link Hyphenator.config} - * @see {@link Hyphenator~mySelectorFunction} - * @default false - * @type {function|boolean} - * @access private - */ - selectorFunction = false, - - /** - * @name Hyphenator~flattenNodeList - * @desc - * Takes a nodeList and returns an array with all elements that are not contained by another element in the nodeList - * By using this function the elements returned by selectElements can be 'flattened'. - * @see {@link Hyphenator~selectElements} - * @param {nodeList} nl - * @return {Array} Array of 'parent'-elements - * @access private - */ - flattenNodeList = function (nl) { - var parentElements = [], - i = 0, - j = 0, - isParent = true; - - parentElements.push(nl[0]); //add the first item, since this is always an parent - - for (i = 1; i < nl.length; i += 1) { //cycle through nodeList - for (j = 0; j < parentElements.length; j += 1) { //cycle through parentElements - if (parentElements[j].contains(nl[i])) { - isParent = false; - break; - } - } - if (isParent) { - parentElements.push(nl[i]); - } - isParent = true; - } - - return parentElements; - }, - - /** - * @method Hyphenator~mySelectorFunction - * @desc - * A function that returns a HTMLNodeList or array of Elements to be hyphenated. - * By default it uses the classname ('hyphenate') to select the elements. - * @access private - */ - mySelectorFunction = function (hyphenateClass) { - var tmp, el = [], i, l; - if (window.document.getElementsByClassName) { - el = contextWindow.document.getElementsByClassName(hyphenateClass); - } else if (window.document.querySelectorAll) { - el = contextWindow.document.querySelectorAll('.' + hyphenateClass); - } else { - tmp = contextWindow.document.getElementsByTagName('*'); - l = tmp.length; - for (i = 0; i < l; i += 1) { - if (tmp[i].className.indexOf(hyphenateClass) !== -1 && tmp[i].className.indexOf(dontHyphenateClass) === -1) { - el.push(tmp[i]); - } - } - } - return el; - }, - - /** - * @method Hyphenator~selectElements - * @desc - * A function that uses either selectorFunction set by the user - * or the default mySelectorFunction. - * @access private - */ - selectElements = function () { - var elems; - if (selectorFunction) { - elems = selectorFunction(); - } else { - elems = mySelectorFunction(hyphenateClass); - } - if (elems.length !== 0) { - elems = flattenNodeList(elems); - } - return elems; - }, - - /** - * @member {string} Hyphenator~intermediateState - * @desc - * The visibility of elements while they are hyphenated: - * 'visible': unhyphenated text is visible and then redrawn when hyphenated. - * 'hidden': unhyphenated text is made invisible as soon as possible and made visible after hyphenation. - * @default 'hidden' - * @see {@link Hyphenator.config} - * @access private - */ - intermediateState = 'hidden', - - /** - * @member {string} Hyphenator~unhide - * @desc - * How hidden elements unhide: either simultaneous (default: 'wait') or progressively. - * 'wait' makes Hyphenator.js to wait until all elements are hyphenated (one redraw) - * With 'progressive' Hyphenator.js unhides elements as soon as they are hyphenated. - * @see {@link Hyphenator.config} - * @access private - */ - unhide = 'wait', - - /** - * @member {Array.} Hyphenator~CSSEditors - * @desc A container array that holds CSSEdit classes - * For each window object one CSSEdit class is inserted - * @access private - */ - CSSEditors = [], - - /** - * @constructor Hyphenator~CSSEdit - * @desc - * This class handles access and editing of StyleSheets. - * Thanks to this styles (e.g. hiding and unhiding elements upon hyphenation) - * can be changed in one place instead for each element. - * @access private - */ - makeCSSEdit = function (w) { - w = w || window; - var doc = w.document, - /** - * @member {Object} Hyphenator~CSSEdit~sheet - * @desc - * A StyleSheet, where Hyphenator can write to. - * If no StyleSheet can be found, lets create one. - * @access private - */ - sheet = (function () { - var i, - l = doc.styleSheets.length, - s, - element, - r = false; - for (i = 0; i < l; i += 1) { - s = doc.styleSheets[i]; - try { - if (!!s.cssRules) { - r = s; - break; - } - } catch (ignore) {} - } - if (r === false) { - element = doc.createElement('style'); - element.type = 'text/css'; - doc.getElementsByTagName('head')[0].appendChild(element); - r = doc.styleSheets[doc.styleSheets.length - 1]; - } - return r; - }()), - - /** - * @typedef {Object} Hyphenator~CSSEdit~changes - * @property {Object} sheet - The StyleSheet where the change was made - * @property {number} index - The index of the changed rule - */ - - /** - * @member {Array.} Hyphenator~CSSEdit~changes - * @desc - * Sets a CSS rule for a specified selector - * @access private - */ - changes = [], - - /** - * @typedef Hyphenator~CSSEdit~rule - * @property {number} index - The index of the rule - * @property {Object} rule - The style rule - */ - /** - * @method Hyphenator~CSSEdit~findRule - * @desc - * Searches the StyleSheets for a given selector and returns an object containing the rule. - * If nothing can be found, false is returned. - * @param {string} sel - * @return {Hyphenator~CSSEdit~rule|false} - * @access private - */ - findRule = function (sel) { - var s, rule, sheets = w.document.styleSheets, rules, i, j, r = false; - for (i = 0; i < sheets.length; i += 1) { - s = sheets[i]; - try { //FF has issues here with external CSS (s.o.p) - if (!!s.cssRules) { - rules = s.cssRules; - } else if (!!s.rules) { - // IE < 9 - rules = s.rules; - } - } catch (ignore) {} - if (!!rules && !!rules.length) { - for (j = 0; j < rules.length; j += 1) { - rule = rules[j]; - if (rule.selectorText === sel) { - r = { - index: j, - rule: rule - }; - } - } - } - } - return r; - }, - /** - * @method Hyphenator~CSSEdit~addRule - * @desc - * Adds a rule to the {@link Hyphenator~CSSEdit~sheet} - * @param {string} sel - The selector to be added - * @param {string} rulesStr - The rules for the specified selector - * @return {number} index of the new rule - * @access private - */ - addRule = function (sel, rulesStr) { - var i, r; - if (!!sheet.insertRule) { - if (!!sheet.cssRules) { - i = sheet.cssRules.length; - } else { - i = 0; - } - r = sheet.insertRule(sel + '{' + rulesStr + '}', i); - } else if (!!sheet.addRule) { - // IE < 9 - if (!!sheet.rules) { - i = sheet.rules.length; - } else { - i = 0; - } - sheet.addRule(sel, rulesStr, i); - r = i; - } - return r; - }, - /** - * @method Hyphenator~CSSEdit~removeRule - * @desc - * Removes a rule with the specified index from the specified sheet - * @param {Object} sheet - The style sheet - * @param {number} index - the index of the rule - * @access private - */ - removeRule = function (sheet, index) { - if (sheet.deleteRule) { - sheet.deleteRule(index); - } else { - // IE < 9 - sheet.removeRule(index); - } - }; + /** + * @member Hyphenator~contextWindow + * @access private + * @desc + * contextWindow stores the window for the actual document to be hyphenated. + * If there are frames this will change. + * So use contextWindow instead of window! + */ + var contextWindow = window; - return { - /** - * @method Hyphenator~CSSEdit.setRule - * @desc - * Sets a CSS rule for a specified selector - * @access public - * @param {string} sel - Selector - * @param {string} rulesString - CSS-Rules - */ - setRule: function (sel, rulesString) { - var i, existingRule, cssText; - existingRule = findRule(sel); - if (!!existingRule) { - if (!!existingRule.rule.cssText) { - cssText = existingRule.rule.cssText; - } else { - // IE < 9 - cssText = existingRule.rule.style.cssText.toLowerCase(); - } - if (cssText !== sel + ' { ' + rulesString + ' }') { - //cssText of the found rule is not uniquely selector + rulesString, - if (cssText.indexOf(rulesString) !== -1) { - //maybe there are other rules or IE < 9 - //clear existing def - existingRule.rule.style.visibility = ''; - } - //add rule and register for later removal - i = addRule(sel, rulesString); - changes.push({sheet: sheet, index: i}); - } - } else { - i = addRule(sel, rulesString); - changes.push({sheet: sheet, index: i}); - } - }, - /** - * @method Hyphenator~CSSEdit.clearChanges - * @desc - * Removes all changes Hyphenator has made from the StyleSheets - * @access public - */ - clearChanges: function () { - var change = changes.pop(); - while (!!change) { - removeRule(change.sheet, change.index); - change = changes.pop(); - } - } - }; - }, - - /** - * @member {string} Hyphenator~hyphen - * @desc - * A string containing the character for in-word-hyphenation - * @default the soft hyphen - * @access private - * @see {@link Hyphenator.config} - */ - hyphen = String.fromCharCode(173), - - /** - * @member {string} Hyphenator~urlhyphen - * @desc - * A string containing the character for url/mail-hyphenation - * @default the zero width space - * @access private - * @see {@link Hyphenator.config} - * @see {@link Hyphenator~zeroWidthSpace} - */ - urlhyphen = zeroWidthSpace, - - /** - * @method Hyphenator~hyphenateURL - * @desc - * Puts {@link Hyphenator~urlhyphen} (default: zero width space) after each no-alphanumeric char that my be in a URL. - * @param {string} url to hyphenate - * @returns string the hyphenated URL - * @access public - */ - hyphenateURL = function (url) { - var tmp = url.replace(/([:\/\.\?#&\-_,;!@]+)/gi, '$&' + urlhyphen), - parts = tmp.split(urlhyphen), - i; - for (i = 0; i < parts.length; i += 1) { - if (parts[i].length > (2 * min)) { - parts[i] = parts[i].replace(/(\w{3})(\w)/gi, "$1" + urlhyphen + "$2"); - } - } - if (parts[parts.length - 1] === "") { - parts.pop(); - } - return parts.join(urlhyphen); - }, + /** + * @member {Object.} Hyphenator~supportedLangs + * @desc + * A generated key-value object that stores supported languages and meta data. + * The key is the {@link http://tools.ietf.org/rfc/bcp/bcp47.txt bcp47} code of the language and the value + * is an object of type {@link Hyphenator~supportedLangs~supportedLanguage} + * @namespace Hyphenator~supportedLangs + * @access private + * //Check if language lang is supported: + * if (supportedLangs.hasOwnProperty(lang)) + */ + var supportedLangs = (function () { /** - * @member {boolean} Hyphenator~safeCopy - * @desc - * Defines wether work-around for copy issues is active or not - * @default true - * @access private - * @see {@link Hyphenator.config} - * @see {@link Hyphenator~registerOnCopy} + * @typedef {Object} Hyphenator~supportedLangs~supportedLanguage + * @property {string} file - The name of the pattern file + * @property {number} script - The script type of the language (e.g. 'latin' for english), this type is abbreviated by an id + * @property {string} prompt - The sentence prompted to the user, if Hyphenator.js doesn't find a language hint */ - safeCopy = true, /** - * @method Hyphenator~zeroTimeOut - * @desc - * defer execution of a function on the call stack - * Analog to window.setTimeout(fn, 0) but without a clamped delay if postMessage is supported - * @access private - * @see {@link http://dbaron.org/log/20100309-faster-timeouts} + * @lends Hyphenator~supportedLangs */ - zeroTimeOut = (function () { - if (window.postMessage && window.addEventListener) { - return (function () { - var timeouts = [], - msg = "Hyphenator_zeroTimeOut_message", - setZeroTimeOut = function (fn) { - timeouts.push(fn); - window.postMessage(msg, "*"); - }, - handleMessage = function (event) { - if (event.source === window && event.data === msg) { - event.stopPropagation(); - if (timeouts.length > 0) { - //var efn = timeouts.shift(); - //efn(); - timeouts.shift()(); - } - } - }; - window.addEventListener("message", handleMessage, true); - return setZeroTimeOut; - }()); - } - return function (fn) { - window.setTimeout(fn, 0); + var r = {}, + /** + * @method Hyphenator~supportedLangs~o + * @desc + * Sets a value of Hyphenator~supportedLangs + * @access protected + * @param {string} code The {@link http://tools.ietf.org/rfc/bcp/bcp47.txt bcp47} code of the language + * @param {string} file The name of the pattern file + * @param {Number} script A shortcut for a specific script: latin:0, cyrillic: 1, arabic: 2, armenian:3, bengali: 4, devangari: 5, greek: 6 + * gujarati: 7, kannada: 8, lao: 9, malayalam: 10, oriya: 11, persian: 12, punjabi: 13, tamil: 14, telugu: 15 + * @param {string} prompt The sentence prompted to the user, if Hyphenator.js doesn't find a language hint + */ + o = function (code, file, script, prompt) { + r[code] = {'file': file, 'script': script, 'prompt': prompt}; }; - }()), - - /** - * @member {Object} Hyphenator~hyphRunFor - * @desc - * stores location.href for documents where run() has been executed - * to warn when Hyphenator.run() executed multiple times - * @access private - * @see {@link Hyphenator~runWhenLoaded} - */ - hyphRunFor = {}, - - /** - * @method Hyphenator~runWhenLoaded - * @desc - * A crossbrowser solution for the DOMContentLoaded-Event based on - * jQuery - * I added some functionality: e.g. support for frames and iframes… - * @param {Object} w the window-object - * @param {function()} f the function to call when the document is ready - * @access private - */ - runWhenLoaded = function (w, f) { - var toplevel, - add = window.document.addEventListener - ? 'addEventListener' - : 'attachEvent', - rem = window.document.addEventListener - ? 'removeEventListener' - : 'detachEvent', - pre = window.document.addEventListener - ? '' - : 'on'; - - function init(context) { - if (hyphRunFor[context.location.href]) { - onWarning(new Error("Warning: multiple execution of Hyphenator.run() – This may slow down the script!")); - } - contextWindow = context || window; - f(); - hyphRunFor[contextWindow.location.href] = true; - } - function doScrollCheck() { - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - w.document.documentElement.doScroll("left"); - } catch (ignore) { - window.setTimeout(doScrollCheck, 1); - return; - } - //maybe modern IE fired DOMContentLoaded - if (!hyphRunFor[w.location.href]) { - documentLoaded = true; - init(w); + o('be', 'be.js', 1, 'Мова гэтага сайта не можа быць вызначаны аўтаматычна. Калі ласка пакажыце мову:'); + o('ca', 'ca.js', 0, ''); + o('cs', 'cs.js', 0, 'Jazyk této internetové stránky nebyl automaticky rozpoznán. Určete prosím její jazyk:'); + o('da', 'da.js', 0, 'Denne websides sprog kunne ikke bestemmes. Angiv venligst sprog:'); + o('bn', 'bn.js', 4, ''); + o('de', 'de.js', 0, 'Die Sprache dieser Webseite konnte nicht automatisch bestimmt werden. Bitte Sprache angeben:'); + o('el', 'el-monoton.js', 6, ''); + o('el-monoton', 'el-monoton.js', 6, ''); + o('el-polyton', 'el-polyton.js', 6, ''); + o('en', 'en-us.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); + o('en-gb', 'en-gb.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); + o('en-us', 'en-us.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); + o('eo', 'eo.js', 0, 'La lingvo de ĉi tiu retpaĝo ne rekoneblas aŭtomate. Bonvolu indiki ĝian ĉeflingvon:'); + o('es', 'es.js', 0, 'El idioma del sitio no pudo determinarse autom%E1ticamente. Por favor, indique el idioma principal:'); + o('et', 'et.js', 0, 'Veebilehe keele tuvastamine ebaõnnestus, palun valige kasutatud keel:'); + o('fi', 'fi.js', 0, 'Sivun kielt%E4 ei tunnistettu automaattisesti. M%E4%E4rit%E4 sivun p%E4%E4kieli:'); + o('fr', 'fr.js', 0, 'La langue de ce site n%u2019a pas pu %EAtre d%E9termin%E9e automatiquement. Veuillez indiquer une langue, s.v.p.%A0:'); + o('grc', 'grc.js', 6, ''); + o('gu', 'gu.js', 7, ''); + o('hi', 'hi.js', 5, ''); + o('hu', 'hu.js', 0, 'A weboldal nyelvét nem sikerült automatikusan megállapítani. Kérem adja meg a nyelvet:'); + o('hy', 'hy.js', 3, 'Չհաջողվեց հայտնաբերել այս կայքի լեզուն։ Խնդրում ենք նշեք հիմնական լեզուն՝'); + o('it', 'it.js', 0, 'Lingua del sito sconosciuta. Indicare una lingua, per favore:'); + o('kn', 'kn.js', 8, 'ಜಾಲ ತಾಣದ ಭಾಷೆಯನ್ನು ನಿರ್ಧರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ದಯವಿಟ್ಟು ಮುಖ್ಯ ಭಾಷೆಯನ್ನು ಸೂಚಿಸಿ:'); + o('la', 'la.js', 0, ''); + o('lt', 'lt.js', 0, 'Nepavyko automatiškai nustatyti šios svetainės kalbos. Prašome įvesti kalbą:'); + o('lv', 'lv.js', 0, 'Šīs lapas valodu nevarēja noteikt automātiski. Lūdzu norādiet pamata valodu:'); + o('ml', 'ml.js', 10, 'ഈ വെ%u0D2C%u0D4D%u200Cസൈറ്റിന്റെ ഭാഷ കണ്ടുപിടിയ്ക്കാ%u0D28%u0D4D%u200D കഴിഞ്ഞില്ല. ഭാഷ ഏതാണെന്നു തിരഞ്ഞെടുക്കുക:'); + o('nb', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); + o('no', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); + o('nb-no', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); + o('nl', 'nl.js', 0, 'De taal van deze website kan niet automatisch worden bepaald. Geef de hoofdtaal op:'); + o('or', 'or.js', 11, ''); + o('pa', 'pa.js', 13, ''); + o('pl', 'pl.js', 0, 'Języka tej strony nie można ustalić automatycznie. Proszę wskazać język:'); + o('pt', 'pt.js', 0, 'A língua deste site não pôde ser determinada automaticamente. Por favor indique a língua principal:'); + o('ru', 'ru.js', 1, 'Язык этого сайта не может быть определен автоматически. Пожалуйста укажите язык:'); + o('sk', 'sk.js', 0, ''); + o('sl', 'sl.js', 0, 'Jezika te spletne strani ni bilo mogoče samodejno določiti. Prosim navedite jezik:'); + o('sr-cyrl', 'sr-cyrl.js', 1, 'Језик овог сајта није детектован аутоматски. Молим вас наведите језик:'); + o('sr-latn', 'sr-latn.js', 0, 'Jezika te spletne strani ni bilo mogoče samodejno določiti. Prosim navedite jezik:'); + o('sv', 'sv.js', 0, 'Spr%E5ket p%E5 den h%E4r webbplatsen kunde inte avg%F6ras automatiskt. V%E4nligen ange:'); + o('ta', 'ta.js', 14, ''); + o('te', 'te.js', 15, ''); + o('tr', 'tr.js', 0, 'Bu web sitesinin dili otomatik olarak tespit edilememiştir. Lütfen dökümanın dilini seçiniz%A0:'); + o('uk', 'uk.js', 1, 'Мова цього веб-сайту не може бути визначена автоматично. Будь ласка, вкажіть головну мову:'); + o('ro', 'ro.js', 0, 'Limba acestui sit nu a putut fi determinată automat. Alege limba principală:'); + + return r; + }()); + + + /** + * @member {string} Hyphenator~basePath + * @desc + * A string storing the basepath from where Hyphenator.js was loaded. + * This is used to load the pattern files. + * The basepath is determined dynamically by searching all script-tags for Hyphenator.js + * If the path cannot be determined {@link http://mnater.github.io/Hyphenator/} is used as fallback. + * @access private + * @see {@link Hyphenator~loadPatterns} + */ + var basePath = (function () { + var s = contextWindow.document.getElementsByTagName('script'), i = 0, p, src, t = s[i], r = ''; + while (!!t) { + if (!!t.src) { + src = t.src; + p = src.indexOf('Hyphenator.js'); + if (p !== -1) { + r = src.substring(0, p); } } + i += 1; + t = s[i]; + } + return !!r + ? r + : '//mnater.github.io/Hyphenator/'; + }()); + + /** + * @member {boolean} Hyphenator~isLocal + * @access private + * @desc + * isLocal is true, if Hyphenator is loaded from the same domain, as the webpage, but false, if + * it's loaded from an external source (i.e. directly from github) + */ + var isLocal = (function () { + var re = false; + if (window.location.href.indexOf(basePath) !== -1) { + re = true; + } + return re; + }()); + + /** + * @member {boolean} Hyphenator~documentLoaded + * @access private + * @desc + * documentLoaded is true, when the DOM has been loaded. This is set by {@link Hyphenator~runWhenLoaded} + */ + var documentLoaded = false; + + /** + * @member {boolean} Hyphenator~persistentConfig + * @access private + * @desc + * if persistentConfig is set to true (defaults to false), config options and the state of the + * toggleBox are stored in DOM-storage (according to the storage-setting). So they haven't to be + * set for each page. + * @default false + * @see {@link Hyphenator.config} + */ + var persistentConfig = false; + + /** + * @member {boolean} Hyphenator~doFrames + * @access private + * @desc + * switch to control if frames/iframes should be hyphenated, too. + * defaults to false (frames are a bag of hurt!) + * @default false + * @see {@link Hyphenator.config} + */ + var doFrames = false; + + /** + * @member {Object.} Hyphenator~dontHyphenate + * @desc + * A key-value object containing all html-tags whose content should not be hyphenated + * @access private + */ + var dontHyphenate = {'video': true, 'audio': true, 'script': true, 'code': true, 'pre': true, 'img': true, 'br': true, 'samp': true, 'kbd': true, 'var': true, 'abbr': true, 'acronym': true, 'sub': true, 'sup': true, 'button': true, 'option': true, 'label': true, 'textarea': true, 'input': true, 'math': true, 'svg': true, 'style': true}; + + /** + * @member {boolean} Hyphenator~enableCache + * @desc + * A variable to set if caching is enabled or not + * @default true + * @access private + * @see {@link Hyphenator.config} + */ + var enableCache = true; + + /** + * @member {string} Hyphenator~storageType + * @desc + * A variable to define what html5-DOM-Storage-Method is used ('none', 'local' or 'session') + * @default 'local' + * @access private + * @see {@link Hyphenator.config} + */ + var storageType = 'local'; + + /** + * @member {Object|undefined} Hyphenator~storage + * @desc + * An alias to the storage defined in storageType. This is set by {@link Hyphenator~createStorage}. + * Set by {@link Hyphenator.run} + * @default null + * @access private + * @see {@link Hyphenator~createStorage} + */ + var storage; + + /** + * @member {boolean} Hyphenator~enableReducedPatternSet + * @desc + * A variable to set if storing the used patterns is set + * @default false + * @access private + * @see {@link Hyphenator.config} + * @see {@link Hyphenator.getRedPatternSet} + */ + var enableReducedPatternSet = false; + + /** + * @member {boolean} Hyphenator~enableRemoteLoading + * @desc + * A variable to set if pattern files should be loaded remotely or not + * @default true + * @access private + * @see {@link Hyphenator.config} + */ + var enableRemoteLoading = true; + + /** + * @member {boolean} Hyphenator~displayToggleBox + * @desc + * A variable to set if the togglebox should be displayed or not + * @default false + * @access private + * @see {@link Hyphenator.config} + */ + var displayToggleBox = false; + + /** + * @method Hyphenator~onError + * @desc + * A function that can be called upon an error. + * @see {@link Hyphenator.config} + * @access private + */ + var onError = function (e) { + window.alert("Hyphenator.js says:\n\nAn Error occurred:\n" + e.message); + }; - function doOnEvent(e) { - var i, fl, haveAccess; - if (!!e && e.type === 'readystatechange' && w.document.readyState !== 'interactive' && w.document.readyState !== 'complete') { - return; - } - - //DOM is ready/interactive, but frames may not be loaded yet! - //cleanup events - w.document[rem](pre + 'DOMContentLoaded', doOnEvent, false); - w.document[rem](pre + 'readystatechange', doOnEvent, false); - - //check frames - fl = w.frames.length; - if (fl === 0 || !doFrames) { - //there are no frames! - //cleanup events - w[rem](pre + 'load', doOnEvent, false); - documentLoaded = true; - init(w); - } else if (doFrames && fl > 0) { - //we have frames, so wait for onload and then initiate runWhenLoaded recursevly for each frame: - if (!!e && e.type === 'load') { - //cleanup events - w[rem](pre + 'load', doOnEvent, false); - for (i = 0; i < fl; i += 1) { - haveAccess = undefined; - //try catch isn't enough for webkit - try { - //opera throws only on document.toString-access - haveAccess = w.frames[i].document.toString(); - } catch (ignore) { - haveAccess = undefined; - } - if (!!haveAccess) { - runWhenLoaded(w.frames[i], f); - } - } - init(w); - } - } - } + /** + * @method Hyphenator~onWarning + * @desc + * A function that can be called upon a warning. + * @see {@link Hyphenator.config} + * @access private + */ + var onWarning = function (e) { + window.console.log(e.message); + }; - if (documentLoaded || w.document.readyState === 'complete') { - //Hyphenator has run already (documentLoaded is true) or - //it has been loaded after onLoad - documentLoaded = true; - doOnEvent({type: 'load'}); - } else { - //register events - w.document[add](pre + 'DOMContentLoaded', doOnEvent, false); - w.document[add](pre + 'readystatechange', doOnEvent, false); - w[add](pre + 'load', doOnEvent, false); - toplevel = false; - try { - toplevel = !window.frameElement; - } catch (ignore) {} - if (toplevel && w.document.documentElement.doScroll) { - doScrollCheck(); //calls init() + /** + * @method Hyphenator~createElem + * @desc + * A function alias to document.createElementNS or document.createElement + * @access private + */ + function createElem(tagname, context) { + context = context || contextWindow; + var el; + if (window.document.createElementNS) { + el = context.document.createElementNS('http://www.w3.org/1999/xhtml', tagname); + } else if (window.document.createElement) { + el = context.document.createElement(tagname); + } + return el; + } + /** + * @method Hyphenator~forEachKey + * @desc + * Calls the function f on every property of o + * @access private + */ + function forEachKey(o, f) { + var a, k; + if (Object.hasOwnProperty("keys")) { + a = Object.keys(o); + a.forEach(function (v) { + f(v); + }); + } else { + for (k in o) { + if (o.hasOwnProperty(k)) { + f(k); } } - }, - - /** - * @method Hyphenator~getLang - * @desc - * Gets the language of an element. If no language is set, it may use the {@link Hyphenator~mainLanguage}. - * @param {Object} el The first parameter is an DOM-Element-Object - * @param {boolean} fallback The second parameter is a boolean to tell if the function should return the {@link Hyphenator~mainLanguage} - * if there's no language found for the element. - * @return {string} The language of the element - * @access private - */ - getLang = function (el, fallback) { - try { - return !!el.getAttribute('lang') - ? el.getAttribute('lang').toLowerCase() - : !!el.getAttribute('xml:lang') - ? el.getAttribute('xml:lang').toLowerCase() - : el.tagName.toLowerCase() !== 'html' - ? getLang(el.parentNode, fallback) - : fallback - ? mainLanguage - : null; - } catch (ignore) {} - }, - - /** - * @method Hyphenator~autoSetMainLanguage - * @desc - * Retrieves the language of the document from the DOM and sets the lang attribute of the html-tag. - * The function looks in the following places: - *
    - *
  • lang-attribute in the html-tag
  • - *
  • <meta http-equiv = "content-language" content = "xy" />
  • - *
  • <meta name = "DC.Language" content = "xy" />
  • - *
  • <meta name = "language" content = "xy" />
  • - * - * If nothing can be found a prompt using {@link Hyphenator~languageHint} and a prompt-string is displayed. - * If the retrieved language is in the object {@link Hyphenator~supportedLangs} it is copied to {@link Hyphenator~mainLanguage} - * @access private - */ - autoSetMainLanguage = function (w) { - w = w || contextWindow; - var el = w.document.getElementsByTagName('html')[0], - m = w.document.getElementsByTagName('meta'), - i, - getLangFromUser = function () { - var ml, - text = '', - dH = 300, - dW = 450, - dX = Math.floor((w.outerWidth - dW) / 2) + window.screenX, - dY = Math.floor((w.outerHeight - dH) / 2) + window.screenY, - ul = '', - languageHint; - if (!!window.showModalDialog && (w.location.href.indexOf(basePath) !== -1)) { - ml = window.showModalDialog(basePath + 'modalLangDialog.html', supportedLangs, "dialogWidth: " + dW + "px; dialogHeight: " + dH + "px; dialogtop: " + dY + "; dialogleft: " + dX + "; center: on; resizable: off; scroll: off;"); - } else { - languageHint = (function () { - var r = ''; - forEachKey(supportedLangs, function (k) { - r += k + ', '; - }); - r = r.substring(0, r.length - 2); - return r; - }()); - ul = window.navigator.language || window.navigator.userLanguage; - ul = ul.substring(0, 2); - if (!!supportedLangs[ul] && supportedLangs[ul].prompt !== '') { - text = supportedLangs[ul].prompt; + } + } + + /** + * @member {boolean} Hyphenator~css3 + * @desc + * A variable to set if css3 hyphenation should be used + * @default false + * @access private + * @see {@link Hyphenator.config} + */ + var css3 = false; + + /** + * @method Hyphenator~css3_gethsupport + * @desc + * This function returns a {@link Hyphenator~css3_hsupport} object for the current UA + * @type function + * @access private + * @see Hyphenator~css3_h9n + */ + function css3_gethsupport() { + var support = false, + supportedBrowserLangs = {}, + property = '', + checkLangSupport, + createLangSupportChecker = function (prefix) { + var testStrings = [ + //latin: 0 + 'aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz', + //cyrillic: 1 + 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя', + //arabic: 2 + 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', + //armenian: 3 + 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆ', + //bengali: 4 + 'ঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ়ঽািীুূৃৄেৈোৌ্ৎৗড়ঢ়য়ৠৡৢৣ', + //devangari: 5 + 'ँंःअआइईउऊऋऌएऐओऔकखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसहऽािीुूृॄेैोौ्॒॑ॠॡॢॣ', + //greek: 6 + 'αβγδεζηθικλμνξοπρσςτυφχψω', + //gujarati: 7 + 'બહઅઆઇઈઉઊઋૠએઐઓઔાિીુૂૃૄૢૣેૈોૌકખગઘઙચછજઝઞટઠડઢણતથદધનપફસભમયરલળવશષ', + //kannada: 8 + 'ಂಃಅಆಇಈಉಊಋಌಎಏಐಒಓಔಕಖಗಘಙಚಛಜಝಞಟಠಡಢಣತಥದಧನಪಫಬಭಮಯರಱಲಳವಶಷಸಹಽಾಿೀುೂೃೄೆೇೈೊೋೌ್ೕೖೞೠೡ', + //lao: 9 + 'ກຂຄງຈຊຍດຕຖທນບປຜຝພຟມຢຣລວສຫອຮະັາິີຶືຸູົຼເແໂໃໄ່້໊໋ໜໝ', + //malayalam: 10 + 'ംഃഅആഇഈഉഊഋഌഎഏഐഒഓഔകഖഗഘങചഛജഝഞടഠഡഢണതഥദധനപഫബഭമയരറലളഴവശഷസഹാിീുൂൃെേൈൊോൌ്ൗൠൡൺൻർൽൾൿ', + //oriya: 11 + 'ଁଂଃଅଆଇଈଉଊଋଌଏଐଓଔକଖଗଘଙଚଛଜଝଞଟଠଡଢଣତଥଦଧନପଫବଭମଯରଲଳଵଶଷସହାିୀୁୂୃେୈୋୌ୍ୗୠୡ', + //persian: 12 + 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', + //punjabi: 13 + 'ਁਂਃਅਆਇਈਉਊਏਐਓਔਕਖਗਘਙਚਛਜਝਞਟਠਡਢਣਤਥਦਧਨਪਫਬਭਮਯਰਲਲ਼ਵਸ਼ਸਹਾਿੀੁੂੇੈੋੌ੍ੰੱ', + //tamil: 14 + 'ஃஅஆஇஈஉஊஎஏஐஒஓஔகஙசஜஞடணதநனபமயரறலளழவஷஸஹாிீுூெேைொோௌ்ௗ', + //telugu: 15 + 'ఁంఃఅఆఇఈఉఊఋఌఎఏఐఒఓఔకఖగఘఙచఛజఝఞటఠడఢణతథదధనపఫబభమయరఱలళవశషసహాిీుూృౄెేైొోౌ్ౕౖౠౡ' + ], + f = function (lang) { + var shadow, + computedHeight, + bdy, + r = false; + + //check if lang has already been tested + if (supportedBrowserLangs.hasOwnProperty(lang)) { + r = supportedBrowserLangs[lang]; + } else if (supportedLangs.hasOwnProperty(lang)) { + //create and append shadow-test-element + bdy = window.document.getElementsByTagName('body')[0]; + shadow = createElem('div', window); + shadow.id = 'Hyphenator_LanguageChecker'; + shadow.style.width = '5em'; + shadow.style.padding = '0'; + shadow.style.border = 'none'; + shadow.style[prefix] = 'auto'; + shadow.style.hyphens = 'auto'; + shadow.style.fontSize = '12px'; + shadow.style.lineHeight = '12px'; + shadow.style.wordWrap = 'normal'; + shadow.style.visibility = 'hidden'; + shadow.lang = lang; + shadow.style['-webkit-locale'] = "'" + lang + "'"; + shadow.innerHTML = testStrings[supportedLangs[lang].script]; + bdy.appendChild(shadow); + //measure its height + computedHeight = shadow.offsetHeight; + //remove shadow element + bdy.removeChild(shadow); + r = !!(computedHeight > 12); + supportedBrowserLangs[lang] = r; } else { - text = supportedLangs.en.prompt; + r = false; } - text += ' (ISO 639-1)\n\n' + languageHint; - ml = window.prompt(window.unescape(text), ul).toLowerCase(); - } - return ml; - }; - mainLanguage = getLang(el, false); - if (!mainLanguage) { - for (i = 0; i < m.length; i += 1) { - // - if (!!m[i].getAttribute('http-equiv') && (m[i].getAttribute('http-equiv').toLowerCase() === 'content-language')) { - mainLanguage = m[i].getAttribute('content').toLowerCase(); - } - // - if (!!m[i].getAttribute('name') && (m[i].getAttribute('name').toLowerCase() === 'dc.language')) { - mainLanguage = m[i].getAttribute('content').toLowerCase(); - } - // - if (!!m[i].getAttribute('name') && (m[i].getAttribute('name').toLowerCase() === 'language')) { - mainLanguage = m[i].getAttribute('content').toLowerCase(); - } - } - } - //get lang for frame from enclosing document - if (!mainLanguage && doFrames && (!!contextWindow.frameElement)) { - autoSetMainLanguage(window.parent); - } - //fallback to defaultLang if set - if (!mainLanguage && defaultLanguage !== '') { - mainLanguage = defaultLanguage; - } - //ask user for lang - if (!mainLanguage) { - mainLanguage = getLangFromUser(); + return r; + }; + return f; + }, + s; + + if (window.getComputedStyle) { + s = window.getComputedStyle(window.document.getElementsByTagName('body')[0], null); + if (s.hyphens !== undefined) { + support = true; + property = 'hyphens'; + checkLangSupport = createLangSupportChecker('hyphens'); + } else if (s['-webkit-hyphens'] !== undefined) { + support = true; + property = '-webkit-hyphens'; + checkLangSupport = createLangSupportChecker('-webkit-hyphens'); + } else if (s.MozHyphens !== undefined) { + support = true; + property = '-moz-hyphens'; + checkLangSupport = createLangSupportChecker('MozHyphens'); + } else if (s['-ms-hyphens'] !== undefined) { + support = true; + property = '-ms-hyphens'; + checkLangSupport = createLangSupportChecker('-ms-hyphens'); + } + } //else we just return the initial values because ancient browsers don't support css3 anyway + + + return { + support: support, + property: property, + supportedBrowserLangs: supportedBrowserLangs, + checkLangSupport: checkLangSupport + }; + } + + /** + * @typedef {Object} Hyphenator~css3_hsupport + * @property {boolean} support - if css3-hyphenation is supported + * @property {string} property - the css property name to access hyphen-settings (e.g. -webkit-hyphens) + * @property {Object.} supportedBrowserLangs - an object caching tested languages + * @property {function} checkLangSupport - a method that checks if the browser supports a requested language + */ + + /** + * @member {Hyphenator~css3_h9n} Hyphenator~css3_h9n + * @desc + * A generated object containing information for CSS3-hyphenation support + * This is set by {@link Hyphenator~css3_gethsupport} + * @default undefined + * @access private + * @see {@link Hyphenator~css3_gethsupport} + * @example + * //Check if browser supports a language + * css3_h9n.checkLangSupport(<lang>) + */ + var css3_h9n; + + /** + * @member {string} Hyphenator~hyphenateClass + * @desc + * A string containing the css-class-name for the hyphenate class + * @default 'hyphenate' + * @access private + * @example + * <p class = "hyphenate">Text</p> + * @see {@link Hyphenator.config} + */ + var hyphenateClass = 'hyphenate'; + + /** + * @member {string} Hyphenator~urlHyphenateClass + * @desc + * A string containing the css-class-name for the urlhyphenate class + * @default 'urlhyphenate' + * @access private + * @example + * <p class = "urlhyphenate">Text</p> + * @see {@link Hyphenator.config} + */ + var urlHyphenateClass = 'urlhyphenate'; + + /** + * @member {string} Hyphenator~classPrefix + * @desc + * A string containing a unique className prefix to be used + * whenever Hyphenator sets a CSS-class + * @access private + */ + var classPrefix = 'Hyphenator' + Math.round(Math.random() * 1000); + + /** + * @member {string} Hyphenator~hideClass + * @desc + * The name of the class that hides elements + * @access private + */ + var hideClass = classPrefix + 'hide'; + + /** + * @member {RegExp} Hyphenator~hideClassRegExp + * @desc + * RegExp to remove hideClass from a list of classes + * @access private + */ + var hideClassRegExp = new RegExp("\\s?\\b" + hideClass + "\\b", "g"); + + /** + * @member {string} Hyphenator~hideClass + * @desc + * The name of the class that unhides elements + * @access private + */ + var unhideClass = classPrefix + 'unhide'; + + /** + * @member {RegExp} Hyphenator~hideClassRegExp + * @desc + * RegExp to remove unhideClass from a list of classes + * @access private + */ + var unhideClassRegExp = new RegExp("\\s?\\b" + unhideClass + "\\b", "g"); + + /** + * @member {string} Hyphenator~css3hyphenateClass + * @desc + * The name of the class that hyphenates elements with css3 + * @access private + */ + var css3hyphenateClass = classPrefix + 'css3hyphenate'; + + /** + * @member {CSSEdit} Hyphenator~css3hyphenateClass + * @desc + * The var where CSSEdit class is stored + * @access private + */ + var css3hyphenateClassHandle; + + /** + * @member {string} Hyphenator~dontHyphenateClass + * @desc + * A string containing the css-class-name for elements that should not be hyphenated + * @default 'donthyphenate' + * @access private + * @example + * <p class = "donthyphenate">Text</p> + * @see {@link Hyphenator.config} + */ + var dontHyphenateClass = 'donthyphenate'; + + /** + * @member {number} Hyphenator~min + * @desc + * A number wich indicates the minimal length of words to hyphenate. + * @default 6 + * @access private + * @see {@link Hyphenator.config} + */ + var min = 6; + + /** + * @member {number} Hyphenator~orphanControl + * @desc + * Control how the last words of a line are handled: + * level 1 (default): last word is hyphenated + * level 2: last word is not hyphenated + * level 3: last word is not hyphenated and last space is non breaking + * @default 1 + * @access private + */ + var orphanControl = 1; + + /** + * @member {boolean} Hyphenator~isBookmarklet + * @desc + * True if Hyphanetor runs as bookmarklet. + * @access private + */ + var isBookmarklet = (function () { + var loc = null, + re = false, + scripts = contextWindow.document.getElementsByTagName('script'), + i = 0, + l = scripts.length; + while (!re && i < l) { + loc = scripts[i].getAttribute('src'); + if (!!loc && loc.indexOf('Hyphenator.js?bm=true') !== -1) { + re = true; } - el.lang = mainLanguage; - }, - - /** - * @method Hyphenator~gatherDocumentInfos - * @desc - * This method runs through the DOM and executes the process()-function on: - * - every node returned by the {@link Hyphenator~selectorFunction}. - * @access private - */ - gatherDocumentInfos = function () { - var elToProcess, - urlhyphenEls, - tmp, - i = 0, - /** - * @method Hyphenator~gatherDocumentInfos - * @desc - * This method copies the element to the elements-variable, sets its visibility - * to intermediateState, retrieves its language and recursivly descends the DOM-tree until - * the child-Nodes aren't of type 1 - * @param {Object} el a DOM element - * @param {string} plang the language of the parent element - * @param {boolean} isChild true, if the parent of el has been processed - */ - process = function (el, pLang, isChild) { - var n, - j = 0, - hyphenate = true, - eLang, - useCSS3 = function () { - css3hyphenateClassHandle = makeCSSEdit(contextWindow); - css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, css3_h9n.property + ': auto;'); - css3hyphenateClassHandle.setRule('.' + dontHyphenateClass, css3_h9n.property + ': manual;'); - if ((eLang !== pLang) && css3_h9n.property.indexOf('webkit') !== -1) { - css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, '-webkit-locale : ' + eLang + ';'); - } - el.className = el.className + ' ' + css3hyphenateClass; - }, - useHyphenator = function () { - //quick fix for test111.html - //better: weight elements - if (isBookmarklet && eLang !== mainLanguage) { - return; - } - if (supportedLangs.hasOwnProperty(eLang)) { - docLanguages[eLang] = true; - } else { - if (supportedLangs.hasOwnProperty(eLang.split('-')[0])) { //try subtag - eLang = eLang.split('-')[0]; - docLanguages[eLang] = true; - } else if (!isBookmarklet) { - hyphenate = false; - onError(new Error('Language "' + eLang + '" is not yet supported.')); - } - } - if (hyphenate) { - if (intermediateState === 'hidden') { - el.className = el.className + ' ' + hideClass; - } - elements.add(el, eLang); - } - }; - isChild = isChild || false; - if (el.lang && typeof el.lang === 'string') { - eLang = el.lang.toLowerCase(); //copy attribute-lang to internal eLang - } else if (!!pLang && pLang !== '') { - eLang = pLang.toLowerCase(); - } else { - eLang = getLang(el, true); - } - - if (!isChild) { - if (css3 && css3_h9n.support && !!css3_h9n.checkLangSupport(eLang)) { - useCSS3(); - } else { - useHyphenator(); + i += 1; + } + return re; + }()); + + /** + * @member {string|null} Hyphenator~mainLanguage + * @desc + * The general language of the document. In contrast to {@link Hyphenator~defaultLanguage}, + * mainLanguage is defined by the client (i.e. by the html or by a prompt). + * @access private + * @see {@link Hyphenator~autoSetMainLanguage} + */ + var mainLanguage = null; + + /** + * @member {string|null} Hyphenator~defaultLanguage + * @desc + * The language defined by the developper. This language setting is defined by a config option. + * It is overwritten by any html-lang-attribute and only taken in count, when no such attribute can + * be found (i.e. just before the prompt). + * @access private + * @see {@link Hyphenator.config} + * @see {@link Hyphenator~autoSetMainLanguage} + */ + var defaultLanguage = ''; + + /** + * @member {ElementCollection} Hyphenator~elements + * @desc + * A class representing all elements (of type Element) that have to be hyphenated. This var is filled by + * {@link Hyphenator~gatherDocumentInfos} + * @access private + */ + var elements = (function () { + /** + * @constructor Hyphenator~elements~ElementCollection~Element + * @desc represents a DOM Element with additional information + * @access private + */ + var makeElement = function (element) { + return { + /** + * @member {Object} Hyphenator~elements~ElementCollection~Element~element + * @desc A DOM Element + * @access protected + */ + element: element, + /** + * @member {boolean} Hyphenator~elements~ElementCollection~Element~hyphenated + * @desc Marks if the element has been hyphenated + * @access protected + */ + hyphenated: false, + /** + * @member {boolean} Hyphenator~elements~ElementCollection~Element~treated + * @desc Marks if information of the element has been collected but not hyphenated (e.g. dohyphenation is off) + * @access protected + */ + treated: false + }; + }, + /** + * @constructor Hyphenator~elements~ElementCollection + * @desc A collection of Elements to be hyphenated + * @access protected + */ + makeElementCollection = function () { + /** + * @member {number} Hyphenator~elements~ElementCollection~counters + * @desc Array of [number of collected elements, number of hyphenated elements] + * @access protected + */ + var counters = [0, 0], + /** + * @member {Object.>} Hyphenator~elements~ElementCollection~list + * @desc The collection of elements, where the key is a language code and the value is an array of elements + * @access protected + */ + list = {}, + /** + * @method Hyphenator~elements~ElementCollection.prototype~add + * @augments Hyphenator~elements~ElementCollection + * @access protected + * @desc adds a DOM element to the collection + * @param {Object} el - The DOM element + * @param {string} lang - The language of the element + */ + add = function (el, lang) { + var elo = makeElement(el); + if (!list.hasOwnProperty(lang)) { + list[lang] = []; } - } else { - if (eLang !== pLang) { - if (css3 && css3_h9n.support && !!css3_h9n.checkLangSupport(eLang)) { - useCSS3(); + list[lang].push(elo); + counters[0] += 1; + return elo; + }, + /** + * @callback Hyphenator~elements~ElementCollection.prototype~each~callback fn - The callback that is executed for each element + * @param {string} [k] The key (i.e. language) of the collection + * @param {Hyphenator~elements~ElementCollection~Element} element + */ + + /** + * @method Hyphenator~elements~ElementCollection.prototype~each + * @augments Hyphenator~elements~ElementCollection + * @access protected + * @desc takes each element of the collection as an argument of fn + * @param {Hyphenator~elements~ElementCollection.prototype~each~callback} fn - A function that takes an element as an argument + */ + each = function (fn) { + forEachKey(list, function (k) { + if (fn.length === 2) { + fn(k, list[k]); } else { - useHyphenator(); + fn(list[k]); } - } else { - if (!css3 || !css3_h9n.support || !css3_h9n.checkLangSupport(eLang)) { - useHyphenator(); - } // else do nothing - } - } - n = el.childNodes[j]; - while (!!n) { - if (n.nodeType === 1 && !dontHyphenate[n.nodeName.toLowerCase()] && - n.className.indexOf(dontHyphenateClass) === -1 && - n.className.indexOf(urlHyphenateClass) === -1 && !elToProcess[n]) { - process(n, eLang, true); - } - j += 1; - n = el.childNodes[j]; - } - }, - processUrlStyled = function (el) { - var n, j = 0; + }); + }; - n = el.childNodes[j]; - while (!!n) { - if (n.nodeType === 1 && !dontHyphenate[n.nodeName.toLowerCase()] && - n.className.indexOf(dontHyphenateClass) === -1 && - n.className.indexOf(hyphenateClass) === -1 && !urlhyphenEls[n]) { - processUrlStyled(n); - } else if (n.nodeType === 3) { - n.data = hyphenateURL(n.data); - } - j += 1; - n = el.childNodes[j]; - } + return { + counters: counters, + list: list, + add: add, + each: each }; - if (css3) { - css3_h9n = css3_gethsupport(); - } - if (isBookmarklet) { - elToProcess = contextWindow.document.getElementsByTagName('body')[0]; - process(elToProcess, mainLanguage, false); - } else { - if (!css3 && intermediateState === 'hidden') { - CSSEditors.push(makeCSSEdit(contextWindow)); - CSSEditors[CSSEditors.length - 1].setRule('.' + hyphenateClass, 'visibility: hidden;'); - CSSEditors[CSSEditors.length - 1].setRule('.' + hideClass, 'visibility: hidden;'); - CSSEditors[CSSEditors.length - 1].setRule('.' + unhideClass, 'visibility: visible;'); - } - elToProcess = selectElements(); - tmp = elToProcess[i]; - while (!!tmp) { - process(tmp, '', false); - i += 1; - tmp = elToProcess[i]; - } + }; + return makeElementCollection(); + }()); + + + /** + * @member {Object.} Hyphenator~exceptions + * @desc + * An object containing exceptions as comma separated strings for each language. + * When the language-objects are loaded, their exceptions are processed, copied here and then deleted. + * Exceptions can also be set by the user. + * @see {@link Hyphenator~prepareLanguagesObj} + * @access private + */ + var exceptions = {}; + + /** + * @member {Object.} Hyphenator~docLanguages + * @desc + * An object holding all languages used in the document. This is filled by + * {@link Hyphenator~gatherDocumentInfos} + * @access private + */ + var docLanguages = {}; + + /** + * @member {string} Hyphenator~url + * @desc + * A string containing a insane RegularExpression to match URL's + * @access private + */ + var url = '(?:\\w*:\/\/)?(?:(?:\\w*:)?(?:\\w*)@)?(?:(?:(?:[\\d]{1,3}\\.){3}(?:[\\d]{1,3}))|(?:(?:www\\.|[a-zA-Z]\\.)?[a-zA-Z0-9\\-\\.]+\\.(?:[a-z]{2,4})))(?::\\d*)?(?:\/[\\w#!:\\.?\\+=&%@!\\-]*)*'; + // protocoll usr pwd ip or host tld port path + + /** + * @member {string} Hyphenator~mail + * @desc + * A string containing a RegularExpression to match mail-adresses + * @access private + */ + var mail = '[\\w-\\.]+@[\\w\\.]+'; + + /** + * @member {string} Hyphenator~zeroWidthSpace + * @desc + * A string that holds a char. + * Depending on the browser, this is the zero with space or an empty string. + * zeroWidthSpace is used to break URLs + * @access private + */ + var zeroWidthSpace = (function () { + var zws, ua = window.navigator.userAgent.toLowerCase(); + zws = String.fromCharCode(8203); //Unicode zero width space + if (ua.indexOf('msie 6') !== -1) { + zws = ''; //IE6 doesn't support zws + } + if (ua.indexOf('opera') !== -1 && ua.indexOf('version/10.00') !== -1) { + zws = ''; //opera 10 on XP doesn't support zws + } + return zws; + }()); + + /** + * @method Hyphenator~onBeforeWordHyphenation + * @desc + * This method is called just before a word is hyphenated. + * It is called with two parameters: the word and its language. + * The method must return a string (aka the word). + * @see {@link Hyphenator.config} + * @access private + * @param {string} word + * @param {string} lang + * @return {string} The word that goes into hyphenation + */ + var onBeforeWordHyphenation = function (word) { + return word; + }; - urlhyphenEls = mySelectorFunction(urlHyphenateClass); - i = 0; - tmp = urlhyphenEls[i]; - while (!!tmp) { - processUrlStyled(tmp); - i += 1; - tmp = urlhyphenEls[i]; + /** + * @method Hyphenator~onAfterWordHyphenation + * @desc + * This method is called for each word after it is hyphenated. + * Takes the word as a first parameter and its language as a second parameter. + * Returns a string that will replace the word that has been hyphenated. + * @see {@link Hyphenator.config} + * @access private + * @param {string} word + * @param {string} lang + * @return {string} The word that goes into hyphenation + */ + var onAfterWordHyphenation = function (word) { + return word; + }; + + /** + * @method Hyphenator~onHyphenationDone + * @desc + * A method to be called, when the last element has been hyphenated. + * If there are frames the method is called for each frame. + * Therefore the location.href of the contextWindow calling this method is given as a parameter + * @see {@link Hyphenator.config} + * @param {string} context + * @access private + */ + var onHyphenationDone = function (context) { + return context; + }; + + /** + * @name Hyphenator~selectorFunction + * @desc + * A function set by the user that has to return a HTMLNodeList or array of Elements to be hyphenated. + * By default this is set to false so we can check if a selectorFunction is set… + * @see {@link Hyphenator.config} + * @see {@link Hyphenator~mySelectorFunction} + * @default false + * @type {function|boolean} + * @access private + */ + var selectorFunction = false; + + /** + * @name Hyphenator~flattenNodeList + * @desc + * Takes a nodeList and returns an array with all elements that are not contained by another element in the nodeList + * By using this function the elements returned by selectElements can be 'flattened'. + * @see {@link Hyphenator~selectElements} + * @param {nodeList} nl + * @return {Array} Array of 'parent'-elements + * @access private + */ + function flattenNodeList(nl) { + var parentElements = [], + i = 1, + j = 0, + isParent = true; + + parentElements.push(nl[0]); //add the first item, since this is always an parent + + while (i < nl.length) { //cycle through nodeList + while (j < parentElements.length) { //cycle through parentElements + if (parentElements[j].contains(nl[i])) { + isParent = false; + break; } + j += 1; + } + if (isParent) { + parentElements.push(nl[i]); } - if (elements.counters[0] === 0) { - //nothing to hyphenate or all hyphenated by css3 - for (i = 0; i < CSSEditors.length; i += 1) { - CSSEditors[i].clearChanges(); + isParent = true; + i += 1; + } + + return parentElements; + } + + /** + * @method Hyphenator~mySelectorFunction + * @desc + * A function that returns a HTMLNodeList or array of Elements to be hyphenated. + * By default it uses the classname ('hyphenate') to select the elements. + * @access private + */ + function mySelectorFunction(hyphenateClass) { + var tmp, + el = [], + i = 0; + if (window.document.getElementsByClassName) { + el = contextWindow.document.getElementsByClassName(hyphenateClass); + } else if (window.document.querySelectorAll) { + el = contextWindow.document.querySelectorAll('.' + hyphenateClass); + } else { + tmp = contextWindow.document.getElementsByTagName('*'); + while (i < tmp.length) { + if (tmp[i].className.indexOf(hyphenateClass) !== -1 && tmp[i].className.indexOf(dontHyphenateClass) === -1) { + el.push(tmp[i]); } - onHyphenationDone(contextWindow.location.href); + i += 1; } - }, + } + return el; + } + + /** + * @method Hyphenator~selectElements + * @desc + * A function that uses either selectorFunction set by the user + * or the default mySelectorFunction. + * @access private + */ + function selectElements() { + var elems; + if (selectorFunction) { + elems = selectorFunction(); + } else { + elems = mySelectorFunction(hyphenateClass); + } + if (elems.length !== 0) { + elems = flattenNodeList(elems); + } + return elems; + } + + /** + * @member {string} Hyphenator~intermediateState + * @desc + * The visibility of elements while they are hyphenated: + * 'visible': unhyphenated text is visible and then redrawn when hyphenated. + * 'hidden': unhyphenated text is made invisible as soon as possible and made visible after hyphenation. + * @default 'hidden' + * @see {@link Hyphenator.config} + * @access private + */ + var intermediateState = 'hidden'; + + /** + * @member {string} Hyphenator~unhide + * @desc + * How hidden elements unhide: either simultaneous (default: 'wait') or progressively. + * 'wait' makes Hyphenator.js to wait until all elements are hyphenated (one redraw) + * With 'progressive' Hyphenator.js unhides elements as soon as they are hyphenated. + * @see {@link Hyphenator.config} + * @access private + */ + var unhide = 'wait'; + + /** + * @member {Array.} Hyphenator~CSSEditors + * @desc A container array that holds CSSEdit classes + * For each window object one CSSEdit class is inserted + * @access private + */ + var CSSEditors = []; + + /** + * @constructor Hyphenator~CSSEdit + * @desc + * This class handles access and editing of StyleSheets. + * Thanks to this styles (e.g. hiding and unhiding elements upon hyphenation) + * can be changed in one place instead for each element. + * @access private + */ + function makeCSSEdit(w) { + w = w || window; + var doc = w.document, + /** + * @member {Object} Hyphenator~CSSEdit~sheet + * @desc + * A StyleSheet, where Hyphenator can write to. + * If no StyleSheet can be found, lets create one. + * @access private + */ + sheet = (function () { + var i = 0, + l = doc.styleSheets.length, + s, + element, + r = false; + while (i < l) { + s = doc.styleSheets[i]; + try { + if (!!s.cssRules) { + r = s; + break; + } + } catch (ignore) {} + i += 1; + } + if (r === false) { + element = doc.createElement('style'); + element.type = 'text/css'; + doc.getElementsByTagName('head')[0].appendChild(element); + r = doc.styleSheets[doc.styleSheets.length - 1]; + } + return r; + }()), - /** - * @method Hyphenator~createCharMap - * @desc - * reads the charCodes from lo.characters and stores them in a bidi map: - * charMap.int2code = [0: 97, //a - * 1: 98, //b - * 2: 99] //c etc. - * charMap.code2int = {"97": 0, //a - * "98": 1, //b - * "99": 2} //c etc. - * @access private - * @param {Object} language object - */ - makeCharMap = function () { - var int2code = [], - code2int = {}, - add = function (newValue) { - if (!code2int[newValue]) { - int2code.push(newValue); - code2int[newValue] = int2code.length - 1; - } - }; - return { - int2code: int2code, - code2int: code2int, - add: add - }; - }, + /** + * @typedef {Object} Hyphenator~CSSEdit~changes + * @property {Object} sheet - The StyleSheet where the change was made + * @property {number} index - The index of the changed rule + */ - /** - * @constructor Hyphenator~ValueStore - * @desc Storage-Object for storing hyphenation points (aka values) - * @access private - */ - makeValueStore = function (len) { - //var indexes = [1, 2, 2], - var indexes = (function () { - var arr; - if (Object.prototype.hasOwnProperty.call(window, "Uint32Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) - arr = new window.Uint32Array(3); - arr[0] = 1; - arr[1] = 2; - arr[2] = 2; - } else { - arr = [1, 2, 2]; + /** + * @member {Array.} Hyphenator~CSSEdit~changes + * @desc + * Sets a CSS rule for a specified selector + * @access private + */ + changes = [], + + /** + * @typedef Hyphenator~CSSEdit~rule + * @property {number} index - The index of the rule + * @property {Object} rule - The style rule + */ + /** + * @method Hyphenator~CSSEdit~findRule + * @desc + * Searches the StyleSheets for a given selector and returns an object containing the rule. + * If nothing can be found, false is returned. + * @param {string} sel + * @return {Hyphenator~CSSEdit~rule|false} + * @access private + */ + findRule = function (sel) { + var s, + rule, + sheets = w.document.styleSheets, + rules, + i = 0, + j = 0, + r = false; + while (i < sheets.length) { + s = sheets[i]; + try { //FF has issues here with external CSS (s.o.p) + if (!!s.cssRules) { + rules = s.cssRules; + } else if (!!s.rules) { + // IE < 9 + rules = s.rules; + } + } catch (ignore) {} + if (!!rules && !!rules.length) { + while (j < rules.length) { + rule = rules[j]; + if (rule.selectorText === sel) { + r = { + index: j, + rule: rule + }; + } + j += 1; + } } - return arr; - }()), - keys = (function () { - var i, r; - if (Object.prototype.hasOwnProperty.call(window, "Uint8Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) - return new window.Uint8Array(len); + i += 1; + } + return r; + }, + /** + * @method Hyphenator~CSSEdit~addRule + * @desc + * Adds a rule to the {@link Hyphenator~CSSEdit~sheet} + * @param {string} sel - The selector to be added + * @param {string} rulesStr - The rules for the specified selector + * @return {number} index of the new rule + * @access private + */ + addRule = function (sel, rulesStr) { + var i, r; + if (!!sheet.insertRule) { + if (!!sheet.cssRules) { + i = sheet.cssRules.length; + } else { + i = 0; } - r = []; - r.length = len; - for (i = r.length - 1; i >= 0; i -= 1) { - r[i] = 0; + r = sheet.insertRule(sel + '{' + rulesStr + '}', i); + } else if (!!sheet.addRule) { + // IE < 9 + if (!!sheet.rules) { + i = sheet.rules.length; + } else { + i = 0; } - return r; - }()), - add = function (p) { - keys[indexes[1]] = p; - indexes[2] = indexes[1]; - indexes[1] += 1; - }, - add0 = function () { - //just do a step, since array is initialized with zeroes - indexes[1] += 1; - }, - finalize = function () { - var start = indexes[0]; - keys[start] = indexes[2] - start; - indexes[0] = indexes[2] + 1; - indexes[1] = indexes[2] + 2; - return start; - }; - return { - keys: keys, - add: add, - add0: add0, - finalize: finalize + sheet.addRule(sel, rulesStr, i); + r = i; + } + return r; + }, + /** + * @method Hyphenator~CSSEdit~removeRule + * @desc + * Removes a rule with the specified index from the specified sheet + * @param {Object} sheet - The style sheet + * @param {number} index - the index of the rule + * @access private + */ + removeRule = function (sheet, index) { + if (sheet.deleteRule) { + sheet.deleteRule(index); + } else { + // IE < 9 + sheet.removeRule(index); + } }; - }, - /** - * @method Hyphenator~convertPatternsToArray - * @desc - * converts the patterns to a (typed, if possible) array as described by Liang: - * - * 1. Create the CharMap: an alphabet of used character codes mapped to an int (e.g. a: "97" -> 0) - * This map is bidirectional: - * charMap.code2int is an object with charCodes as keys and corresponging ints as values - * charMao.int2code is an array of charCodes at int indizes - * the length of charMao.int2code is equal the length of the alphabet - * - * 2. Create a ValueStore: (typed) array that holds "values", i.e. the digits extracted from the patterns - * The first value starts at index 1 (since the trie is initialized with zeroes, starting at 0 would create errors) - * Each value starts with its length at index i, actual values are stored in i + n where n < length - * Trailing 0 are not stored. So pattern values like e.g. "010200" will become […,4,0,1,0,2,…] - * The ValueStore-Object manages handling of indizes automatically. Use ValueStore.add(p) to add a running value. - * Use ValueStore.finalize() when the last value of a pattern is added. It will set the length and return the starting index of the pattern. - * To prevent doubles we could temporarly store the values in a object {value: startIndex} and only add new values, - * but this object deoptimizes very fast (new hidden map for each entry); here we gain speed and pay memory - * - * 3. Create and zero initialize a (typed) array to store the trie. The trie uses two slots for each entry/node: - * i: a link to another position in the array or -1 if the pattern ends here or more rows have to be added. - * i + 1: a link to a value in the ValueStore or 0 if there's no value for the path to this node. - * Although the array is one-dimensional it can be described as an array of "rows", - * where each "row" is an array of length trieRowLength (see below). - * The first entry of this "row" represents the first character of the alphabet, the second a possible link to value store, - * the third represents the second character of the alphabet and so on… - * - * 4. Initialize trieRowLength (length of the alphabet * 2) - * - * 5. Now we apply extract to each pattern collection (patterns of the same length are collected and concatenated to one string) - * extract goes through these pattern collections char by char and adds them either to the ValueStore (if they are digits) or - * to the trie (adding more "rows" if necessary, i.e. if the last link pointed to -1). - * So the first "row" holds all starting characters, where the subsequent rows hold the characters that follow the - * character that link to this row. Therefor the array is dense at the beginning and very sparse at the end. - * - * - * @access private - * @param {Object} language object - */ - convertPatternsToArray = function (lo) { - var trieNextEmptyRow = 0, - i, - charMapc2i, - valueStore, - indexedTrie, - trieRowLength, - - extract = function (patternSizeInt, patterns) { - var charPos = 0, - charCode = 0, - mappedCharCode = 0, - rowStart = 0, - nextRowStart = 0, - prevWasDigit = false; - for (charPos = 0; charPos < patterns.length; charPos += 1) { - charCode = patterns.charCodeAt(charPos); - if ((charPos + 1) % patternSizeInt !== 0) { - //more to come… - if (charCode <= 57 && charCode >= 49) { - //charCode is a digit - valueStore.add(charCode - 48); - prevWasDigit = true; - } else { - //charCode is alphabetical - if (!prevWasDigit) { - valueStore.add0(); - } - prevWasDigit = false; - if (nextRowStart === -1) { - nextRowStart = trieNextEmptyRow + trieRowLength; - trieNextEmptyRow = nextRowStart; - indexedTrie[rowStart + mappedCharCode * 2] = nextRowStart; - } - mappedCharCode = charMapc2i[charCode]; - rowStart = nextRowStart; - nextRowStart = indexedTrie[rowStart + mappedCharCode * 2]; - if (nextRowStart === 0) { - indexedTrie[rowStart + mappedCharCode * 2] = -1; - nextRowStart = -1; - } - } - } else { - //last part of pattern - if (charCode <= 57 && charCode >= 49) { - //the last charCode is a digit - valueStore.add(charCode - 48); - indexedTrie[rowStart + mappedCharCode * 2 + 1] = valueStore.finalize(); - } else { - //the last charCode is alphabetical - if (!prevWasDigit) { - valueStore.add0(); - } - valueStore.add0(); - if (nextRowStart === -1) { - nextRowStart = trieNextEmptyRow + trieRowLength; - trieNextEmptyRow = nextRowStart; - indexedTrie[rowStart + mappedCharCode * 2] = nextRowStart; - } - mappedCharCode = charMapc2i[charCode]; - rowStart = nextRowStart; - if (indexedTrie[rowStart + mappedCharCode * 2] === 0) { - indexedTrie[rowStart + mappedCharCode * 2] = -1; - } - indexedTrie[rowStart + mappedCharCode * 2 + 1] = valueStore.finalize(); - } - rowStart = 0; - nextRowStart = 0; - prevWasDigit = false; + return { + /** + * @method Hyphenator~CSSEdit.setRule + * @desc + * Sets a CSS rule for a specified selector + * @access public + * @param {string} sel - Selector + * @param {string} rulesString - CSS-Rules + */ + setRule: function (sel, rulesString) { + var i, existingRule, cssText; + existingRule = findRule(sel); + if (!!existingRule) { + if (!!existingRule.rule.cssText) { + cssText = existingRule.rule.cssText; + } else { + // IE < 9 + cssText = existingRule.rule.style.cssText.toLowerCase(); + } + if (cssText !== sel + ' { ' + rulesString + ' }') { + //cssText of the found rule is not uniquely selector + rulesString, + if (cssText.indexOf(rulesString) !== -1) { + //maybe there are other rules or IE < 9 + //clear existing def + existingRule.rule.style.visibility = ''; } + //add rule and register for later removal + i = addRule(sel, rulesString); + changes.push({sheet: sheet, index: i}); } - };/*, - prettyPrintIndexedTrie = function (rowLength) { - var s = "0: ", - idx; - for (idx = 0; idx < indexedTrie.length; idx += 1) { - s += indexedTrie[idx]; - s += ","; - if ((idx + 1) % rowLength === 0) { - s += "\n" + (idx + 1) + ": "; + } else { + i = addRule(sel, rulesString); + changes.push({sheet: sheet, index: i}); + } + }, + /** + * @method Hyphenator~CSSEdit.clearChanges + * @desc + * Removes all changes Hyphenator has made from the StyleSheets + * @access public + */ + clearChanges: function () { + var change = changes.pop(); + while (!!change) { + removeRule(change.sheet, change.index); + change = changes.pop(); + } + } + }; + } + + /** + * @member {string} Hyphenator~hyphen + * @desc + * A string containing the character for in-word-hyphenation + * @default the soft hyphen + * @access private + * @see {@link Hyphenator.config} + */ + var hyphen = String.fromCharCode(173); + + /** + * @member {string} Hyphenator~urlhyphen + * @desc + * A string containing the character for url/mail-hyphenation + * @default the zero width space + * @access private + * @see {@link Hyphenator.config} + * @see {@link Hyphenator~zeroWidthSpace} + */ + var urlhyphen = zeroWidthSpace; + + /** + * @method Hyphenator~hyphenateURL + * @desc + * Puts {@link Hyphenator~urlhyphen} (default: zero width space) after each no-alphanumeric char that my be in a URL. + * @param {string} url to hyphenate + * @returns string the hyphenated URL + * @access public + */ + function hyphenateURL(url) { + var tmp = url.replace(/([:\/\.\?#&\-_,;!@]+)/gi, '$&' + urlhyphen), + parts = tmp.split(urlhyphen), + i = 0; + while (i < parts.length) { + if (parts[i].length > (2 * min)) { + parts[i] = parts[i].replace(/(\w{3})(\w)/gi, "$1" + urlhyphen + "$2"); + } + i += 1; + } + if (parts[parts.length - 1] === "") { + parts.pop(); + } + return parts.join(urlhyphen); + } + + /** + * @member {boolean} Hyphenator~safeCopy + * @desc + * Defines wether work-around for copy issues is active or not + * @default true + * @access private + * @see {@link Hyphenator.config} + * @see {@link Hyphenator~registerOnCopy} + */ + var safeCopy = true; + + /** + * @method Hyphenator~zeroTimeOut + * @desc + * defer execution of a function on the call stack + * Analog to window.setTimeout(fn, 0) but without a clamped delay if postMessage is supported + * @access private + * @see {@link http://dbaron.org/log/20100309-faster-timeouts} + */ + var zeroTimeOut = (function () { + if (window.postMessage && window.addEventListener) { + return (function () { + var timeouts = [], + msg = "Hyphenator_zeroTimeOut_message", + setZeroTimeOut = function (fn) { + timeouts.push(fn); + window.postMessage(msg, "*"); + }, + handleMessage = function (event) { + if (event.source === window && event.data === msg) { + event.stopPropagation(); + if (timeouts.length > 0) { + //var efn = timeouts.shift(); + //efn(); + timeouts.shift()(); + } } - } - console.log(s); - };*/ + }; + window.addEventListener("message", handleMessage, true); + return setZeroTimeOut; + }()); + } + return function (fn) { + window.setTimeout(fn, 0); + }; + }()); - lo.charMap = makeCharMap(); - for (i = 0; i < lo.patternChars.length; i += 1) { - lo.charMap.add(lo.patternChars.charCodeAt(i)); - } - charMapc2i = lo.charMap.code2int; + /** + * @member {Object} Hyphenator~hyphRunFor + * @desc + * stores location.href for documents where run() has been executed + * to warn when Hyphenator.run() executed multiple times + * @access private + * @see {@link Hyphenator~runWhenLoaded} + */ + var hyphRunFor = {}; - valueStore = makeValueStore(lo.valueStoreLength); - lo.valueStore = valueStore; - if (Object.prototype.hasOwnProperty.call(window, "Int32Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) - lo.indexedTrie = new window.Int32Array(lo.patternArrayLength * 2); - } else { - lo.indexedTrie = []; - lo.indexedTrie.length = lo.patternArrayLength * 2; - for (i = lo.indexedTrie.length - 1; i >= 0; i -= 1) { - lo.indexedTrie[i] = 0; - } - } - indexedTrie = lo.indexedTrie; - trieRowLength = lo.charMap.int2code.length * 2; - forEachKey(lo.patterns, function (i) { - extract(parseInt(i, 10), lo.patterns[i]); - }); - //prettyPrintIndexedTrie(lo.charMap.int2code.length * 2); - }, - /** - * @method Hyphenator~recreatePattern - * @desc - * Recreates the pattern for the reducedPatternSet - * @param {string} pattern The pattern (chars) - * @param {string} nodePoints The nodePoints (integers) - * @access private - * @return {string} The pattern (chars and numbers) - */ - recreatePattern = function (pattern, nodePoints) { - var r = [], c = pattern.split(''), i; - for (i = 0; i <= c.length; i += 1) { - if (nodePoints[i] && nodePoints[i] !== 0) { - r.push(nodePoints[i]); - } - if (c[i]) { - r.push(c[i]); - } + + + + + + + + + + + + + + + + + /** + * @method Hyphenator~runWhenLoaded + * @desc + * A crossbrowser solution for the DOMContentLoaded-Event based on + * jQuery + * I added some functionality: e.g. support for frames and iframes… + * @param {Object} w the window-object + * @param {function()} f the function to call when the document is ready + * @access private + */ + function runWhenLoaded(w, f) { + var toplevel, + add = window.document.addEventListener + ? 'addEventListener' + : 'attachEvent', + rem = window.document.addEventListener + ? 'removeEventListener' + : 'detachEvent', + pre = window.document.addEventListener + ? '' + : 'on'; + + function init(context) { + if (hyphRunFor[context.location.href]) { + onWarning(new Error("Warning: multiple execution of Hyphenator.run() – This may slow down the script!")); } - return r.join(''); - }, + contextWindow = context || window; + f(); + hyphRunFor[contextWindow.location.href] = true; + } - /** - * @method Hyphenator~convertExceptionsToObject - * @desc - * Converts a list of comma seprated exceptions to an object: - * 'Fortran,Hy-phen-a-tion' -> {'Fortran':'Fortran','Hyphenation':'Hy-phen-a-tion'} - * @access private - * @param {string} exc a comma separated string of exceptions (without spaces) - * @return {Object.} - */ - convertExceptionsToObject = function (exc) { - var w = exc.split(', '), - r = {}, - i = 0, - l = w.length, - key; - while (i < l) { - key = w[i].replace(/-/g, ''); - if (!r.hasOwnProperty(key)) { - r[key] = w[i]; - } - i += 1; + function doScrollCheck() { + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + w.document.documentElement.doScroll("left"); + } catch (ignore) { + window.setTimeout(doScrollCheck, 1); + return; } - return r; - }, + //maybe modern IE fired DOMContentLoaded + if (!hyphRunFor[w.location.href]) { + documentLoaded = true; + init(w); + } + } - /** - * @method Hyphenator~loadPatterns - * @desc - * Checks if the requested file is available in the network. - * Adds a <script>-Tag to the DOM to load an externeal .js-file containing patterns and settings for the given language. - * If the given language is not in the {@link Hyphenator~supportedLangs}-Object it returns. - * One may ask why we are not using AJAX to load the patterns. The XMLHttpRequest-Object - * has a same-origin-policy. This makes the Bookmarklet impossible. - * @param {string} lang The language to load the patterns for - * @access private - * @see {@link Hyphenator~basePath} - */ - loadPatterns = function (lang, cb) { - var location, xhr, head, script, done = false; - if (supportedLangs.hasOwnProperty(lang) && !Hyphenator.languages[lang]) { - location = basePath + 'patterns/' + supportedLangs[lang].file; - } else { + function doOnEvent(e) { + var i = 0, + fl, + haveAccess; + if (!!e && e.type === 'readystatechange' && w.document.readyState !== 'interactive' && w.document.readyState !== 'complete') { return; } - if (isLocal && !isBookmarklet) { - //check if 'location' is available: - xhr = null; - try { - // Mozilla, Opera, Safari and Internet Explorer (ab v7) - xhr = new window.XMLHttpRequest(); - } catch (ignore) { - try { - //IE>=6 - xhr = new window.ActiveXObject("Microsoft.XMLHTTP"); - } catch (ignore) { + + //DOM is ready/interactive, but frames may not be loaded yet! + //cleanup events + w.document[rem](pre + 'DOMContentLoaded', doOnEvent, false); + w.document[rem](pre + 'readystatechange', doOnEvent, false); + + //check frames + fl = w.frames.length; + if (fl === 0 || !doFrames) { + //there are no frames! + //cleanup events + w[rem](pre + 'load', doOnEvent, false); + documentLoaded = true; + init(w); + } else if (doFrames && fl > 0) { + //we have frames, so wait for onload and then initiate runWhenLoaded recursevly for each frame: + if (!!e && e.type === 'load') { + //cleanup events + w[rem](pre + 'load', doOnEvent, false); + while (i < fl) { + haveAccess = undefined; + //try catch isn't enough for webkit try { - //IE>=5 - xhr = new window.ActiveXObject("Msxml2.XMLHTTP"); + //opera throws only on document.toString-access + haveAccess = w.frames[i].document.toString(); } catch (ignore) { - xhr = null; - } - } - } - - if (xhr) { - xhr.open('HEAD', location, true); - xhr.setRequestHeader('Cache-Control', 'no-cache'); - xhr.onreadystatechange = function () { - if (xhr.readyState === 2) { - if (xhr.status >= 400) { - onError(new Error('Could not load\n' + location)); - delete docLanguages[lang]; - return; - } - xhr.abort(); + haveAccess = undefined; } - }; - xhr.send(null); - } - } - if (createElem) { - head = window.document.getElementsByTagName('head').item(0); - script = createElem('script', window); - script.src = location; - script.type = 'text/javascript'; - script.charset = 'utf8'; - script.onreadystatechange = function () { - if (!done && (!script.readyState || script.readyState === "loaded" || script.readyState === "complete")) { - done = true; - - cb(); - - // Handle memory leak in IE - script.onreadystatechange = null; - script.onload = null; - if (head && script.parentNode) { - head.removeChild(script); + if (!!haveAccess) { + runWhenLoaded(w.frames[i], f); } + i += 1; } - }; - script.onload = script.onreadystatechange; - head.appendChild(script); + init(w); + } } - }, - - /** - * @method Hyphenator~prepareLanguagesObj - * @desc - * Adds some feature to the language object: - * - cache - * - exceptions - * Converts the patterns to a trie using {@link Hyphenator~convertPatterns} - * @access private - * @param {string} lang The language of the language object - */ - prepareLanguagesObj = function (lang) { - var lo = Hyphenator.languages[lang], wrd; + } - if (!lo.prepared) { - if (enableCache) { - lo.cache = {}; - //Export - //lo['cache'] = lo.cache; - } - if (enableReducedPatternSet) { - lo.redPatSet = {}; - } - //add exceptions from the pattern file to the local 'exceptions'-obj - if (lo.hasOwnProperty('exceptions')) { - Hyphenator.addExceptions(lang, lo.exceptions); - delete lo.exceptions; - } - //copy global exceptions to the language specific exceptions - if (exceptions.hasOwnProperty('global')) { - if (exceptions.hasOwnProperty(lang)) { - exceptions[lang] += ', ' + exceptions.global; + if (documentLoaded || w.document.readyState === 'complete') { + //Hyphenator has run already (documentLoaded is true) or + //it has been loaded after onLoad + documentLoaded = true; + doOnEvent({type: 'load'}); + } else { + //register events + w.document[add](pre + 'DOMContentLoaded', doOnEvent, false); + w.document[add](pre + 'readystatechange', doOnEvent, false); + w[add](pre + 'load', doOnEvent, false); + toplevel = false; + try { + toplevel = !window.frameElement; + } catch (ignore) {} + if (toplevel && w.document.documentElement.doScroll) { + doScrollCheck(); //calls init() + } + } + } + + /** + * @method Hyphenator~getLang + * @desc + * Gets the language of an element. If no language is set, it may use the {@link Hyphenator~mainLanguage}. + * @param {Object} el The first parameter is an DOM-Element-Object + * @param {boolean} fallback The second parameter is a boolean to tell if the function should return the {@link Hyphenator~mainLanguage} + * if there's no language found for the element. + * @return {string} The language of the element + * @access private + */ + function getLang(el, fallback) { + try { + return !!el.getAttribute('lang') + ? el.getAttribute('lang').toLowerCase() + : !!el.getAttribute('xml:lang') + ? el.getAttribute('xml:lang').toLowerCase() + : el.tagName.toLowerCase() !== 'html' + ? getLang(el.parentNode, fallback) + : fallback + ? mainLanguage + : null; + } catch (ignore) {} + } + + /** + * @method Hyphenator~autoSetMainLanguage + * @desc + * Retrieves the language of the document from the DOM and sets the lang attribute of the html-tag. + * The function looks in the following places: + *
      + *
    • lang-attribute in the html-tag
    • + *
    • <meta http-equiv = "content-language" content = "xy" />
    • + *
    • <meta name = "DC.Language" content = "xy" />
    • + *
    • <meta name = "language" content = "xy" />
    • + * + * If nothing can be found a prompt using {@link Hyphenator~languageHint} and a prompt-string is displayed. + * If the retrieved language is in the object {@link Hyphenator~supportedLangs} it is copied to {@link Hyphenator~mainLanguage} + * @access private + */ + function autoSetMainLanguage(w) { + w = w || contextWindow; + var el = w.document.getElementsByTagName('html')[0], + m = w.document.getElementsByTagName('meta'), + i = 0, + getLangFromUser = function () { + var ml, + text = '', + dH = 300, + dW = 450, + dX = Math.floor((w.outerWidth - dW) / 2) + window.screenX, + dY = Math.floor((w.outerHeight - dH) / 2) + window.screenY, + ul = '', + languageHint; + if (!!window.showModalDialog && (w.location.href.indexOf(basePath) !== -1)) { + ml = window.showModalDialog(basePath + 'modalLangDialog.html', supportedLangs, "dialogWidth: " + dW + "px; dialogHeight: " + dH + "px; dialogtop: " + dY + "; dialogleft: " + dX + "; center: on; resizable: off; scroll: off;"); + } else { + languageHint = (function () { + var r = ''; + forEachKey(supportedLangs, function (k) { + r += k + ', '; + }); + r = r.substring(0, r.length - 2); + return r; + }()); + ul = window.navigator.language || window.navigator.userLanguage; + ul = ul.substring(0, 2); + if (!!supportedLangs[ul] && supportedLangs[ul].prompt !== '') { + text = supportedLangs[ul].prompt; } else { - exceptions[lang] = exceptions.global; + text = supportedLangs.en.prompt; } + text += ' (ISO 639-1)\n\n' + languageHint; + ml = window.prompt(window.unescape(text), ul).toLowerCase(); } - //move exceptions from the the local 'exceptions'-obj to the 'language'-object - if (exceptions.hasOwnProperty(lang)) { - lo.exceptions = convertExceptionsToObject(exceptions[lang]); - delete exceptions[lang]; - } else { - lo.exceptions = {}; + return ml; + }; + mainLanguage = getLang(el, false); + if (!mainLanguage) { + while (i < m.length) { + // + if (!!m[i].getAttribute('http-equiv') && (m[i].getAttribute('http-equiv').toLowerCase() === 'content-language')) { + mainLanguage = m[i].getAttribute('content').toLowerCase(); } - convertPatternsToArray(lo); - if (String.prototype.normalize) { - wrd = '[\\w' + lo.specialChars + lo.specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; - } else { - wrd = '[\\w' + lo.specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + // + if (!!m[i].getAttribute('name') && (m[i].getAttribute('name').toLowerCase() === 'dc.language')) { + mainLanguage = m[i].getAttribute('content').toLowerCase(); } - lo.genRegExp = new RegExp('(' + wrd + ')|(' + url + ')|(' + mail + ')', 'gi'); - lo.prepared = true; + // + if (!!m[i].getAttribute('name') && (m[i].getAttribute('name').toLowerCase() === 'language')) { + mainLanguage = m[i].getAttribute('content').toLowerCase(); + } + i += 1; } - }, - - /**** - * @method Hyphenator~prepare + } + //get lang for frame from enclosing document + if (!mainLanguage && doFrames && (!!contextWindow.frameElement)) { + autoSetMainLanguage(window.parent); + } + //fallback to defaultLang if set + if (!mainLanguage && defaultLanguage !== '') { + mainLanguage = defaultLanguage; + } + //ask user for lang + if (!mainLanguage) { + mainLanguage = getLangFromUser(); + } + el.lang = mainLanguage; + } + + /** + * @method Hyphenator~gatherDocumentInfos + * @desc + * This method runs through the DOM and executes the process()-function on: + * - every node returned by the {@link Hyphenator~selectorFunction}. + * @access private + */ + function gatherDocumentInfos() { + var elToProcess, + urlhyphenEls, + tmp, + i = 0; + /** + * @method Hyphenator~gatherDocumentInfos * @desc - * This funtion prepares the Hyphenator~Object: If RemoteLoading is turned off, it assumes - * that the patternfiles are loaded, all conversions are made and the callback is called. - * If storage is active the object is retrieved there. - * If RemoteLoading is on (default), it loads the pattern files and repeatedly checks Hyphenator.languages. - * If a patternfile is loaded the patterns are stored in storage (if enabled), - * converted to their object style and the lang-object extended. - * Finally the callback is called. - * @access private + * This method copies the element to the elements-variable, sets its visibility + * to intermediateState, retrieves its language and recursivly descends the DOM-tree until + * the child-Nodes aren't of type 1 + * @param {Object} el a DOM element + * @param {string} plang the language of the parent element + * @param {boolean} isChild true, if the parent of el has been processed */ - prepare = function (callback) { - var tmp1, - languagesLoaded = function () { - forEachKey(docLanguages, function (l) { - if (Hyphenator.languages.hasOwnProperty(l)) { - delete docLanguages[l]; - if (!!storage) { - storage.setItem(l, window.JSON.stringify(Hyphenator.languages[l])); - } - prepareLanguagesObj(l); - callback(l); - } - }); - }; - - if (!enableRemoteLoading) { - forEachKey(Hyphenator.languages, function (lang) { - prepareLanguagesObj(lang); - }); - callback('*'); - return; - } - // get all languages that are used and preload the patterns - forEachKey(docLanguages, function (lang) { - if (!!storage && storage.test(lang)) { - Hyphenator.languages[lang] = window.JSON.parse(storage.getItem(lang)); - prepareLanguagesObj(lang); - if (exceptions.hasOwnProperty('global')) { - tmp1 = convertExceptionsToObject(exceptions.global); - forEachKey(tmp1, function (tmp2) { - Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; - }); - } - //Replace exceptions since they may have been changed: - if (exceptions.hasOwnProperty(lang)) { - tmp1 = convertExceptionsToObject(exceptions[lang]); - forEachKey(tmp1, function (tmp2) { - Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; - }); - delete exceptions[lang]; + function process(el, pLang, isChild) { + var n, + j = 0, + hyphenate = true, + eLang, + useCSS3 = function () { + css3hyphenateClassHandle = makeCSSEdit(contextWindow); + css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, css3_h9n.property + ': auto;'); + css3hyphenateClassHandle.setRule('.' + dontHyphenateClass, css3_h9n.property + ': manual;'); + if ((eLang !== pLang) && css3_h9n.property.indexOf('webkit') !== -1) { + css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, '-webkit-locale : ' + eLang + ';'); } - //Replace genRegExp since it may have been changed: - if (String.prototype.normalize) { - tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + Hyphenator.languages[lang].specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + el.className = el.className + ' ' + css3hyphenateClass; + }, + useHyphenator = function () { + //quick fix for test111.html + //better: weight elements + if (isBookmarklet && eLang !== mainLanguage) { + return; + } + if (supportedLangs.hasOwnProperty(eLang)) { + docLanguages[eLang] = true; } else { - tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + if (supportedLangs.hasOwnProperty(eLang.split('-')[0])) { //try subtag + eLang = eLang.split('-')[0]; + docLanguages[eLang] = true; + } else if (!isBookmarklet) { + hyphenate = false; + onError(new Error('Language "' + eLang + '" is not yet supported.')); + } } - Hyphenator.languages[lang].genRegExp = new RegExp('(' + tmp1 + ')|(' + url + ')|(' + mail + ')', 'gi'); - if (enableCache) { - if (!Hyphenator.languages[lang].cache) { - Hyphenator.languages[lang].cache = {}; + if (hyphenate) { + if (intermediateState === 'hidden') { + el.className = el.className + ' ' + hideClass; } + elements.add(el, eLang); } - delete docLanguages[lang]; - callback(lang); + }; + isChild = isChild || false; + if (el.lang && typeof el.lang === 'string') { + eLang = el.lang.toLowerCase(); //copy attribute-lang to internal eLang + } else if (!!pLang && pLang !== '') { + eLang = pLang.toLowerCase(); + } else { + eLang = getLang(el, true); + } + + if (!isChild) { + if (css3 && css3_h9n.support && !!css3_h9n.checkLangSupport(eLang)) { + useCSS3(); } else { - loadPatterns(lang, languagesLoaded); + useHyphenator(); } - }); - //call languagesLoaded in case language has been loaded manually - //and remoteLoading is on (onload won't fire) - languagesLoaded(); - }, - - /** - * @method Hyphenator~toggleBox - * @desc - * Creates the toggleBox: a small button to turn off/on hyphenation on a page. - * @see {@link Hyphenator.config} - * @access private - */ - toggleBox = function () { - var bdy, - myTextNode, - text = (Hyphenator.doHyphenation - ? 'Hy-phen-a-tion' - : 'Hyphenation'), - myBox = contextWindow.document.getElementById('HyphenatorToggleBox'); - if (!!myBox) { - myBox.firstChild.data = text; } else { - bdy = contextWindow.document.getElementsByTagName('body')[0]; - myBox = createElem('div', contextWindow); - myBox.setAttribute('id', 'HyphenatorToggleBox'); - myBox.setAttribute('class', dontHyphenateClass); - myTextNode = contextWindow.document.createTextNode(text); - myBox.appendChild(myTextNode); - myBox.onclick = Hyphenator.toggleHyphenation; - myBox.style.position = 'absolute'; - myBox.style.top = '0px'; - myBox.style.right = '0px'; - myBox.style.zIndex = '1000'; - myBox.style.margin = '0'; - myBox.style.backgroundColor = '#AAAAAA'; - myBox.style.color = '#FFFFFF'; - myBox.style.font = '6pt Arial'; - myBox.style.letterSpacing = '0.2em'; - myBox.style.padding = '3px'; - myBox.style.cursor = 'pointer'; - myBox.style.WebkitBorderBottomLeftRadius = '4px'; - myBox.style.MozBorderRadiusBottomleft = '4px'; - myBox.style.borderBottomLeftRadius = '4px'; - bdy.appendChild(myBox); + if (eLang !== pLang) { + if (css3 && css3_h9n.support && !!css3_h9n.checkLangSupport(eLang)) { + useCSS3(); + } else { + useHyphenator(); + } + } else { + if (!css3 || !css3_h9n.support || !css3_h9n.checkLangSupport(eLang)) { + useHyphenator(); + } // else do nothing + } } - }, - - /** - * @method Hyphenator~doCharSubst - * @desc - * Replace chars in a word - * - * @param {Object} loCharSubst Map of substitutions ({'ä': 'a', 'ü': 'u', …}) - * @param {string} w the word - * @returns string The word with substituted characers - * @access private - */ - doCharSubst = function (loCharSubst, w) { - var r = w; - forEachKey(loCharSubst, function (subst) { - r = r.replace(new RegExp(subst, 'g'), loCharSubst[subst]); - }); - return r; - }, + n = el.childNodes[j]; + while (!!n) { + if (n.nodeType === 1 && !dontHyphenate[n.nodeName.toLowerCase()] && + n.className.indexOf(dontHyphenateClass) === -1 && + n.className.indexOf(urlHyphenateClass) === -1 && !elToProcess[n]) { + process(n, eLang, true); + } + j += 1; + n = el.childNodes[j]; + } + } + function processUrlStyled(el) { + var n, j = 0; - /** - * @member {Array} Hyphenator~wwAsMappedCharCodeStore - * @desc - * Array (typed if supported) container for charCodes - * @access private - * @see {@link Hyphenator~hyphenateWord} - */ - wwAsMappedCharCodeStore = (function () { - if (Object.prototype.hasOwnProperty.call(window, "Int32Array")) { - return new window.Int32Array(64); + n = el.childNodes[j]; + while (!!n) { + if (n.nodeType === 1 && !dontHyphenate[n.nodeName.toLowerCase()] && + n.className.indexOf(dontHyphenateClass) === -1 && + n.className.indexOf(hyphenateClass) === -1 && !urlhyphenEls[n]) { + processUrlStyled(n); + } else if (n.nodeType === 3) { + n.data = hyphenateURL(n.data); + } + j += 1; + n = el.childNodes[j]; } - return []; - }()), + } - /** - * @member {Array} Hyphenator~wwhpStore - * @desc - * Array (typed if supported) container for hyphenation points - * @access private - * @see {@link Hyphenator~hyphenateWord} - */ - wwhpStore = (function () { - var r; - if (Object.prototype.hasOwnProperty.call(window, "Uint8Array")) { - r = new window.Uint8Array(64); - } else { - r = []; + if (css3) { + css3_h9n = css3_gethsupport(); + } + if (isBookmarklet) { + elToProcess = contextWindow.document.getElementsByTagName('body')[0]; + process(elToProcess, mainLanguage, false); + } else { + if (!css3 && intermediateState === 'hidden') { + CSSEditors.push(makeCSSEdit(contextWindow)); + CSSEditors[CSSEditors.length - 1].setRule('.' + hyphenateClass, 'visibility: hidden;'); + CSSEditors[CSSEditors.length - 1].setRule('.' + hideClass, 'visibility: hidden;'); + CSSEditors[CSSEditors.length - 1].setRule('.' + unhideClass, 'visibility: visible;'); + } + elToProcess = selectElements(); + tmp = elToProcess[i]; + while (!!tmp) { + process(tmp, '', false); + i += 1; + tmp = elToProcess[i]; } - return r; - }()), - /** - * @method Hyphenator~hyphenateWord - * @desc - * This function is the heart of Hyphenator.js. It returns a hyphenated word. - * - * If there's already a {@link Hyphenator~hypen} in the word, the word is returned as it is. - * If the word is in the exceptions list or in the cache, it is retrieved from it. - * If there's a '-' hyphenate the parts. - * The hyphenated word is returned and (if acivated) cached. - * Both special Events onBeforeWordHyphenation and onAfterWordHyphenation are called for the word. - * @param {Object} lo A language object (containing the patterns) - * @param {string} lang The language of the word - * @param {string} word The word - * @returns string The hyphenated word - * @access private - */ - hyphenateWord = function (lo, lang, word) { - var parts, - i, - pattern = "", - ww, - wwlen, - wwhp = wwhpStore, - pstart, - plen, - hp, - wordLength = word.length, - hw = '', - charMap = lo.charMap.code2int, - charCode, - mappedCharCode, - row = 0, - link = 0, - value = 0, - values, - indexedTrie = lo.indexedTrie, - valueStore = lo.valueStore.keys, - wwAsMappedCharCode = wwAsMappedCharCodeStore; - word = onBeforeWordHyphenation(word, lang); - if (word === '') { - hw = ''; - } else if (enableCache && lo.cache && lo.cache.hasOwnProperty(word)) { //the word is in the cache - hw = lo.cache[word]; - } else if (word.indexOf(hyphen) !== -1) { - //word already contains shy; -> leave at it is! - hw = word; - } else if (lo.exceptions.hasOwnProperty(word)) { //the word is in the exceptions list - hw = lo.exceptions[word].replace(/-/g, hyphen); - } else if (word.indexOf('-') !== -1) { - //word contains '-' -> hyphenate the parts separated with '-' - parts = word.split('-'); - for (i = 0; i < parts.length; i += 1) { - parts[i] = hyphenateWord(lo, lang, parts[i]); - } - hw = parts.join('-'); - } else { - ww = word.toLowerCase(); - if (String.prototype.normalize) { - ww = ww.normalize("NFC"); + urlhyphenEls = mySelectorFunction(urlHyphenateClass); + i = 0; + tmp = urlhyphenEls[i]; + while (!!tmp) { + processUrlStyled(tmp); + i += 1; + tmp = urlhyphenEls[i]; + } + } + if (elements.counters[0] === 0) { + //nothing to hyphenate or all hyphenated by css3 + i = 0; + while (i < CSSEditors.length) { + CSSEditors[i].clearChanges(); + i += 1; + } + onHyphenationDone(contextWindow.location.href); + } + } + + /** + * @method Hyphenator~createCharMap + * @desc + * reads the charCodes from lo.characters and stores them in a bidi map: + * charMap.int2code = [0: 97, //a + * 1: 98, //b + * 2: 99] //c etc. + * charMap.code2int = {"97": 0, //a + * "98": 1, //b + * "99": 2} //c etc. + * @access private + * @param {Object} language object + */ + function makeCharMap() { + var int2code = [], + code2int = {}, + add = function (newValue) { + if (!code2int[newValue]) { + int2code.push(newValue); + code2int[newValue] = int2code.length - 1; } - if (lo.hasOwnProperty("charSubstitution")) { - ww = doCharSubst(lo.charSubstitution, ww); + }; + return { + int2code: int2code, + code2int: code2int, + add: add + }; + } + + /** + * @constructor Hyphenator~ValueStore + * @desc Storage-Object for storing hyphenation points (aka values) + * @access private + */ + function makeValueStore(len) { + //var indexes = [1, 2, 2], + var indexes = (function () { + var arr; + if (Object.prototype.hasOwnProperty.call(window, "Uint32Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) + arr = new window.Uint32Array(3); + arr[0] = 1; + arr[1] = 2; + arr[2] = 2; + } else { + arr = [1, 2, 2]; } - if (word.indexOf("'") !== -1) { - ww = ww.replace(/'/g, "’"); //replace APOSTROPHE with RIGHT SINGLE QUOTATION MARK (since the latter is used in the patterns) + return arr; + }()), + keys = (function () { + var i, r; + if (Object.prototype.hasOwnProperty.call(window, "Uint8Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) + return new window.Uint8Array(len); } - ww = '_' + ww + '_'; - wwlen = ww.length; - //prepare wwhp and wwAsMappedCharCode - for (pstart = 0; pstart < wwlen; pstart += 1) { - wwhp[pstart] = 0; - charCode = ww.charCodeAt(pstart); - wwAsMappedCharCode[pstart] = charMap.hasOwnProperty(charCode) - ? charMap[charCode] - : -1; + r = []; + r.length = len; + i = r.length - 1; + while (i >= 0) { + r[i] = 0; + i -= 1; } - //get hyphenation points for all substrings - for (pstart = 0; pstart < wwlen; pstart += 1) { - row = 0; - pattern = ''; - for (plen = pstart; plen < wwlen; plen += 1) { - mappedCharCode = wwAsMappedCharCode[plen]; - if (mappedCharCode === -1) { - break; - } - if (enableReducedPatternSet) { - pattern += ww.charAt(plen); - } - link = indexedTrie[row + mappedCharCode * 2]; - value = indexedTrie[row + mappedCharCode * 2 + 1]; - if (value > 0) { - hp = valueStore[value]; - while (hp) { - hp -= 1; - if (valueStore[value + 1 + hp] > wwhp[pstart + hp]) { - wwhp[pstart + hp] = valueStore[value + 1 + hp]; - } + return r; + }()), + add = function (p) { + keys[indexes[1]] = p; + indexes[2] = indexes[1]; + indexes[1] += 1; + }, + add0 = function () { + //just do a step, since array is initialized with zeroes + indexes[1] += 1; + }, + finalize = function () { + var start = indexes[0]; + keys[start] = indexes[2] - start; + indexes[0] = indexes[2] + 1; + indexes[1] = indexes[2] + 2; + return start; + }; + return { + keys: keys, + add: add, + add0: add0, + finalize: finalize + }; + } + + /** + * @method Hyphenator~convertPatternsToArray + * @desc + * converts the patterns to a (typed, if possible) array as described by Liang: + * + * 1. Create the CharMap: an alphabet of used character codes mapped to an int (e.g. a: "97" -> 0) + * This map is bidirectional: + * charMap.code2int is an object with charCodes as keys and corresponging ints as values + * charMao.int2code is an array of charCodes at int indizes + * the length of charMao.int2code is equal the length of the alphabet + * + * 2. Create a ValueStore: (typed) array that holds "values", i.e. the digits extracted from the patterns + * The first value starts at index 1 (since the trie is initialized with zeroes, starting at 0 would create errors) + * Each value starts with its length at index i, actual values are stored in i + n where n < length + * Trailing 0 are not stored. So pattern values like e.g. "010200" will become […,4,0,1,0,2,…] + * The ValueStore-Object manages handling of indizes automatically. Use ValueStore.add(p) to add a running value. + * Use ValueStore.finalize() when the last value of a pattern is added. It will set the length and return the starting index of the pattern. + * To prevent doubles we could temporarly store the values in a object {value: startIndex} and only add new values, + * but this object deoptimizes very fast (new hidden map for each entry); here we gain speed and pay memory + * + * 3. Create and zero initialize a (typed) array to store the trie. The trie uses two slots for each entry/node: + * i: a link to another position in the array or -1 if the pattern ends here or more rows have to be added. + * i + 1: a link to a value in the ValueStore or 0 if there's no value for the path to this node. + * Although the array is one-dimensional it can be described as an array of "rows", + * where each "row" is an array of length trieRowLength (see below). + * The first entry of this "row" represents the first character of the alphabet, the second a possible link to value store, + * the third represents the second character of the alphabet and so on… + * + * 4. Initialize trieRowLength (length of the alphabet * 2) + * + * 5. Now we apply extract to each pattern collection (patterns of the same length are collected and concatenated to one string) + * extract goes through these pattern collections char by char and adds them either to the ValueStore (if they are digits) or + * to the trie (adding more "rows" if necessary, i.e. if the last link pointed to -1). + * So the first "row" holds all starting characters, where the subsequent rows hold the characters that follow the + * character that link to this row. Therefor the array is dense at the beginning and very sparse at the end. + * + * + * @access private + * @param {Object} language object + */ + function convertPatternsToArray(lo) { + var trieNextEmptyRow = 0, + i, + charMapc2i, + valueStore, + indexedTrie, + trieRowLength, + + extract = function (patternSizeInt, patterns) { + var charPos = 0, + charCode = 0, + mappedCharCode = 0, + rowStart = 0, + nextRowStart = 0, + prevWasDigit = false; + while (charPos < patterns.length) { + charCode = patterns.charCodeAt(charPos); + if ((charPos + 1) % patternSizeInt !== 0) { + //more to come… + if (charCode <= 57 && charCode >= 49) { + //charCode is a digit + valueStore.add(charCode - 48); + prevWasDigit = true; + } else { + //charCode is alphabetical + if (!prevWasDigit) { + valueStore.add0(); + } + prevWasDigit = false; + if (nextRowStart === -1) { + nextRowStart = trieNextEmptyRow + trieRowLength; + trieNextEmptyRow = nextRowStart; + indexedTrie[rowStart + mappedCharCode * 2] = nextRowStart; } - if (enableReducedPatternSet) { - if (!lo.redPatSet) { - lo.redPatSet = {}; - } - if (valueStore.subarray) { - values = valueStore.subarray(value + 1, value + 1 + valueStore[value]); - } else { - values = valueStore.slice(value + 1, value + 1 + valueStore[value]); - } - lo.redPatSet[pattern] = recreatePattern(pattern, values); + mappedCharCode = charMapc2i[charCode]; + rowStart = nextRowStart; + nextRowStart = indexedTrie[rowStart + mappedCharCode * 2]; + if (nextRowStart === 0) { + indexedTrie[rowStart + mappedCharCode * 2] = -1; + nextRowStart = -1; } } - if (link > 0) { - row = link; + } else { + //last part of pattern + if (charCode <= 57 && charCode >= 49) { + //the last charCode is a digit + valueStore.add(charCode - 48); + indexedTrie[rowStart + mappedCharCode * 2 + 1] = valueStore.finalize(); } else { - break; + //the last charCode is alphabetical + if (!prevWasDigit) { + valueStore.add0(); + } + valueStore.add0(); + if (nextRowStart === -1) { + nextRowStart = trieNextEmptyRow + trieRowLength; + trieNextEmptyRow = nextRowStart; + indexedTrie[rowStart + mappedCharCode * 2] = nextRowStart; + } + mappedCharCode = charMapc2i[charCode]; + rowStart = nextRowStart; + if (indexedTrie[rowStart + mappedCharCode * 2] === 0) { + indexedTrie[rowStart + mappedCharCode * 2] = -1; + } + indexedTrie[rowStart + mappedCharCode * 2 + 1] = valueStore.finalize(); } + rowStart = 0; + nextRowStart = 0; + prevWasDigit = false; } + charPos += 1; } - //create hyphenated word - for (hp = 0; hp < wordLength; hp += 1) { - if (hp >= lo.leftmin && hp <= (wordLength - lo.rightmin) && (wwhp[hp + 1] % 2) !== 0) { - hw += hyphen + word.charAt(hp); - } else { - hw += word.charAt(hp); + };/*, + prettyPrintIndexedTrie = function (rowLength) { + var s = "0: ", + idx; + for (idx = 0; idx < indexedTrie.length; idx += 1) { + s += indexedTrie[idx]; + s += ","; + if ((idx + 1) % rowLength === 0) { + s += "\n" + (idx + 1) + ": "; } } - } - hw = onAfterWordHyphenation(hw, lang); - if (enableCache) { //put the word in the cache - lo.cache[word] = hw; - } - return hw; - }, + console.log(s); + };*/ + + lo.charMap = makeCharMap(); + i = 0; + while (i < lo.patternChars.length) { + lo.charMap.add(lo.patternChars.charCodeAt(i)); + i += 1; + } + charMapc2i = lo.charMap.code2int; - /** - * @method Hyphenator~removeHyphenationFromElement - * @desc - * Removes all hyphens from the element. If there are other elements, the function is - * called recursively. - * Removing hyphens is usefull if you like to copy text. Some browsers are buggy when the copy hyphenated texts. - * @param {Object} el The element where to remove hyphenation. - * @access public - */ - removeHyphenationFromElement = function (el) { - var h, u, i = 0, n; - switch (hyphen) { - case '|': - h = '\\|'; - break; - case '+': - h = '\\+'; - break; - case '*': - h = '\\*'; - break; - default: - h = hyphen; - } - switch (urlhyphen) { - case '|': - u = '\\|'; - break; - case '+': - u = '\\+'; - break; - case '*': - u = '\\*'; - break; - default: - u = urlhyphen; + valueStore = makeValueStore(lo.valueStoreLength); + lo.valueStore = valueStore; + + if (Object.prototype.hasOwnProperty.call(window, "Int32Array")) { //IE<9 doesn't have window.hasOwnProperty (host object) + lo.indexedTrie = new window.Int32Array(lo.patternArrayLength * 2); + } else { + lo.indexedTrie = []; + lo.indexedTrie.length = lo.patternArrayLength * 2; + i = lo.indexedTrie.length - 1; + while (i >= 0) { + lo.indexedTrie[i] = 0; + i -= 1; } - n = el.childNodes[i]; - while (!!n) { - if (n.nodeType === 3) { - n.data = n.data.replace(new RegExp(h, 'g'), ''); - n.data = n.data.replace(new RegExp(u, 'g'), ''); - } else if (n.nodeType === 1) { - removeHyphenationFromElement(n); + } + indexedTrie = lo.indexedTrie; + trieRowLength = lo.charMap.int2code.length * 2; + + forEachKey(lo.patterns, function (i) { + extract(parseInt(i, 10), lo.patterns[i]); + }); + //prettyPrintIndexedTrie(lo.charMap.int2code.length * 2); + } + + /** + * @method Hyphenator~recreatePattern + * @desc + * Recreates the pattern for the reducedPatternSet + * @param {string} pattern The pattern (chars) + * @param {string} nodePoints The nodePoints (integers) + * @access private + * @return {string} The pattern (chars and numbers) + */ + function recreatePattern(pattern, nodePoints) { + var r = [], + c = pattern.split(''), + i = 0; + while (i <= c.length) { + if (nodePoints[i] && nodePoints[i] !== 0) { + r.push(nodePoints[i]); + } + if (c[i]) { + r.push(c[i]); + } + i += 1; + } + return r.join(''); + } + + /** + * @method Hyphenator~convertExceptionsToObject + * @desc + * Converts a list of comma seprated exceptions to an object: + * 'Fortran,Hy-phen-a-tion' -> {'Fortran':'Fortran','Hyphenation':'Hy-phen-a-tion'} + * @access private + * @param {string} exc a comma separated string of exceptions (without spaces) + * @return {Object.} + */ + function convertExceptionsToObject(exc) { + var w = exc.split(', '), + r = {}, + i = 0, + l = w.length, + key; + while (i < l) { + key = w[i].replace(/-/g, ''); + if (!r.hasOwnProperty(key)) { + r[key] = w[i]; + } + i += 1; + } + return r; + } + + /** + * @method Hyphenator~loadPatterns + * @desc + * Checks if the requested file is available in the network. + * Adds a <script>-Tag to the DOM to load an externeal .js-file containing patterns and settings for the given language. + * If the given language is not in the {@link Hyphenator~supportedLangs}-Object it returns. + * One may ask why we are not using AJAX to load the patterns. The XMLHttpRequest-Object + * has a same-origin-policy. This makes the Bookmarklet impossible. + * @param {string} lang The language to load the patterns for + * @access private + * @see {@link Hyphenator~basePath} + */ + function loadPatterns(lang, cb) { + var location, xhr, head, script, done = false; + if (supportedLangs.hasOwnProperty(lang) && !Hyphenator.languages[lang]) { + location = basePath + 'patterns/' + supportedLangs[lang].file; + } else { + return; + } + if (isLocal && !isBookmarklet) { + //check if 'location' is available: + xhr = null; + try { + // Mozilla, Opera, Safari and Internet Explorer (ab v7) + xhr = new window.XMLHttpRequest(); + } catch (ignore) { + try { + //IE>=6 + xhr = new window.ActiveXObject("Microsoft.XMLHTTP"); + } catch (ignore) { + try { + //IE>=5 + xhr = new window.ActiveXObject("Msxml2.XMLHTTP"); + } catch (ignore) { + xhr = null; + } } - i += 1; - n = el.childNodes[i]; } - }, - copy = (function () { - var makeCopy = function () { - var oncopyHandler = function (e) { - e = e || window.event; - var shadow, - selection, - range, - rangeShadow, - restore, - target = e.target || e.srcElement, - currDoc = target.ownerDocument, - bdy = currDoc.getElementsByTagName('body')[0], - targetWindow = currDoc.defaultView || currDoc.parentWindow; - if (target.tagName && dontHyphenate[target.tagName.toLowerCase()]) { - //Safari needs this - return; - } - //create a hidden shadow element - shadow = currDoc.createElement('div'); - //Moving the element out of the screen doesn't work for IE9 (https://connect.microsoft.com/IE/feedback/details/663981/) - //shadow.style.overflow = 'hidden'; - //shadow.style.position = 'absolute'; - //shadow.style.top = '-5000px'; - //shadow.style.height = '1px'; - //doing this instead: - shadow.style.color = window.getComputedStyle - ? targetWindow.getComputedStyle(bdy, null).backgroundColor - : '#FFFFFF'; - shadow.style.fontSize = '0px'; - bdy.appendChild(shadow); - if (!!window.getSelection) { - //FF3, Webkit, IE9 - e.stopPropagation(); - selection = targetWindow.getSelection(); - range = selection.getRangeAt(0); - shadow.appendChild(range.cloneContents()); - removeHyphenationFromElement(shadow); - selection.selectAllChildren(shadow); - restore = function () { - shadow.parentNode.removeChild(shadow); - selection.removeAllRanges(); //IE9 needs that - selection.addRange(range); - }; - } else { - // IE<9 - e.cancelBubble = true; - selection = targetWindow.document.selection; - range = selection.createRange(); - shadow.innerHTML = range.htmlText; - removeHyphenationFromElement(shadow); - rangeShadow = bdy.createTextRange(); - rangeShadow.moveToElementText(shadow); - rangeShadow.select(); - restore = function () { - shadow.parentNode.removeChild(shadow); - if (range.text !== "") { - range.select(); - } - }; - } - zeroTimeOut(restore); - }, - removeOnCopy = function (el) { - var body = el.ownerDocument.getElementsByTagName('body')[0]; - if (!body) { - return; - } - el = el || body; - if (window.removeEventListener) { - el.removeEventListener("copy", oncopyHandler, true); - } else { - el.detachEvent("oncopy", oncopyHandler); - } - }, - registerOnCopy = function (el) { - var body = el.ownerDocument.getElementsByTagName('body')[0]; - if (!body) { + if (xhr) { + xhr.open('HEAD', location, true); + xhr.setRequestHeader('Cache-Control', 'no-cache'); + xhr.onreadystatechange = function () { + if (xhr.readyState === 2) { + if (xhr.status >= 400) { + onError(new Error('Could not load\n' + location)); + delete docLanguages[lang]; return; } - el = el || body; - if (window.addEventListener) { - el.addEventListener("copy", oncopyHandler, true); - } else { - el.attachEvent("oncopy", oncopyHandler); - } - }; - return { - oncopyHandler: oncopyHandler, - removeOnCopy: removeOnCopy, - registerOnCopy: registerOnCopy + xhr.abort(); + } }; + xhr.send(null); + } + } + if (createElem) { + head = window.document.getElementsByTagName('head').item(0); + script = createElem('script', window); + script.src = location; + script.type = 'text/javascript'; + script.charset = 'utf8'; + script.onreadystatechange = function () { + if (!done && (!script.readyState || script.readyState === "loaded" || script.readyState === "complete")) { + done = true; + + cb(); + + // Handle memory leak in IE + script.onreadystatechange = null; + script.onload = null; + if (head && script.parentNode) { + head.removeChild(script); + } + } }; - - return (safeCopy - ? makeCopy() - : false); - }()), - - - /** - * @method Hyphenator~checkIfAllDone - * @desc - * Checks if all elements in {@link Hyphenator~elements} are hyphenated, unhides them and fires onHyphenationDone() - * @access private - */ - checkIfAllDone = function () { - var allDone = true, i, doclist = {}; - elements.each(function (ellist) { - var j, l = ellist.length; - for (j = 0; j < l; j += 1) { - allDone = allDone && ellist[j].hyphenated; - if (!doclist.hasOwnProperty(ellist[j].element.baseURI)) { - doclist[ellist[j].element.ownerDocument.location.href] = true; - } - doclist[ellist[j].element.ownerDocument.location.href] = doclist[ellist[j].element.ownerDocument.location.href] && ellist[j].hyphenated; + script.onload = script.onreadystatechange; + head.appendChild(script); + } + } + + /** + * @method Hyphenator~prepareLanguagesObj + * @desc + * Adds some feature to the language object: + * - cache + * - exceptions + * Converts the patterns to a trie using {@link Hyphenator~convertPatterns} + * @access private + * @param {string} lang The language of the language object + */ + function prepareLanguagesObj(lang) { + var lo = Hyphenator.languages[lang], wrd; + + if (!lo.prepared) { + if (enableCache) { + lo.cache = {}; + //Export + //lo['cache'] = lo.cache; + } + if (enableReducedPatternSet) { + lo.redPatSet = {}; + } + //add exceptions from the pattern file to the local 'exceptions'-obj + if (lo.hasOwnProperty('exceptions')) { + Hyphenator.addExceptions(lang, lo.exceptions); + delete lo.exceptions; + } + //copy global exceptions to the language specific exceptions + if (exceptions.hasOwnProperty('global')) { + if (exceptions.hasOwnProperty(lang)) { + exceptions[lang] += ', ' + exceptions.global; + } else { + exceptions[lang] = exceptions.global; + } + } + //move exceptions from the the local 'exceptions'-obj to the 'language'-object + if (exceptions.hasOwnProperty(lang)) { + lo.exceptions = convertExceptionsToObject(exceptions[lang]); + delete exceptions[lang]; + } else { + lo.exceptions = {}; + } + convertPatternsToArray(lo); + if (String.prototype.normalize) { + wrd = '[\\w' + lo.specialChars + lo.specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + } else { + wrd = '[\\w' + lo.specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + } + lo.genRegExp = new RegExp('(' + wrd + ')|(' + url + ')|(' + mail + ')', 'gi'); + lo.prepared = true; + } + } + + /**** + * @method Hyphenator~prepare + * @desc + * This funtion prepares the Hyphenator~Object: If RemoteLoading is turned off, it assumes + * that the patternfiles are loaded, all conversions are made and the callback is called. + * If storage is active the object is retrieved there. + * If RemoteLoading is on (default), it loads the pattern files and repeatedly checks Hyphenator.languages. + * If a patternfile is loaded the patterns are stored in storage (if enabled), + * converted to their object style and the lang-object extended. + * Finally the callback is called. + * @access private + */ + function prepare(callback) { + var tmp1; + + function languagesLoaded() { + forEachKey(docLanguages, function (l) { + if (Hyphenator.languages.hasOwnProperty(l)) { + delete docLanguages[l]; + if (!!storage) { + storage.setItem(l, window.JSON.stringify(Hyphenator.languages[l])); + } + prepareLanguagesObj(l); + callback(l); } }); - if (allDone) { - if (intermediateState === 'hidden' && unhide === 'progressive') { - elements.each(function (ellist) { - var j, l = ellist.length, el; - for (j = 0; j < l; j += 1) { - el = ellist[j].element; - el.className = el.className.replace(unhideClassRegExp, ''); - if (el.className === '') { - el.removeAttribute('class'); - } - } + } + + if (!enableRemoteLoading) { + forEachKey(Hyphenator.languages, function (lang) { + prepareLanguagesObj(lang); + }); + callback('*'); + return; + } + // get all languages that are used and preload the patterns + forEachKey(docLanguages, function (lang) { + if (!!storage && storage.test(lang)) { + Hyphenator.languages[lang] = window.JSON.parse(storage.getItem(lang)); + prepareLanguagesObj(lang); + if (exceptions.hasOwnProperty('global')) { + tmp1 = convertExceptionsToObject(exceptions.global); + forEachKey(tmp1, function (tmp2) { + Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; }); } - for (i = 0; i < CSSEditors.length; i += 1) { - CSSEditors[i].clearChanges(); + //Replace exceptions since they may have been changed: + if (exceptions.hasOwnProperty(lang)) { + tmp1 = convertExceptionsToObject(exceptions[lang]); + forEachKey(tmp1, function (tmp2) { + Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; + }); + delete exceptions[lang]; } - forEachKey(doclist, function (doc) { - onHyphenationDone(doc); - }); - if (!!storage && storage.deferred.length > 0) { - for (i = 0; i < storage.deferred.length; i += 1) { - storage.deferred[i].call(); + //Replace genRegExp since it may have been changed: + if (String.prototype.normalize) { + tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + Hyphenator.languages[lang].specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + } else { + tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + } + Hyphenator.languages[lang].genRegExp = new RegExp('(' + tmp1 + ')|(' + url + ')|(' + mail + ')', 'gi'); + if (enableCache) { + if (!Hyphenator.languages[lang].cache) { + Hyphenator.languages[lang].cache = {}; } - storage.deferred = []; } - } - }, - - /** - * @method Hyphenator~controlOrphans - * @desc - * removes orphans depending on the 'orphanControl'-setting: - * orphanControl === 1: do nothing - * orphanControl === 2: prevent last word to be hyphenated - * orphanControl === 3: prevent one word on a last line (inserts a nobreaking space) - * @param {string} part - The sring where orphans have to be removed - * @access private - */ - controlOrphans = function (part) { - var h, r; - switch (hyphen) { - case '|': - h = '\\|'; - break; - case '+': - h = '\\+'; - break; - case '*': - h = '\\*'; - break; - default: - h = hyphen; - } - //strip off blank space at the end (omitted closing tags) - part = part.replace(/[\s]*$/, ''); - if (orphanControl >= 2) { - //remove hyphen points from last word - r = part.split(' '); - r[1] = r[1].replace(new RegExp(h, 'g'), ''); - r[1] = r[1].replace(new RegExp(zeroWidthSpace, 'g'), ''); - r = r.join(' '); - } - if (orphanControl === 3) { - //replace spaces by non breaking spaces - r = r.replace(/[\ ]+/g, String.fromCharCode(160)); - } - return r; - }, + delete docLanguages[lang]; + callback(lang); + } else { + loadPatterns(lang, languagesLoaded); + } + }); + //call languagesLoaded in case language has been loaded manually + //and remoteLoading is on (onload won't fire) + languagesLoaded(); + } + + /** + * @method Hyphenator~toggleBox + * @desc + * Creates the toggleBox: a small button to turn off/on hyphenation on a page. + * @see {@link Hyphenator.config} + * @access private + */ + var toggleBox = function () { + var bdy, + myTextNode, + text = (Hyphenator.doHyphenation + ? 'Hy-phen-a-tion' + : 'Hyphenation'), + myBox = contextWindow.document.getElementById('HyphenatorToggleBox'); + if (!!myBox) { + myBox.firstChild.data = text; + } else { + bdy = contextWindow.document.getElementsByTagName('body')[0]; + myBox = createElem('div', contextWindow); + myBox.setAttribute('id', 'HyphenatorToggleBox'); + myBox.setAttribute('class', dontHyphenateClass); + myTextNode = contextWindow.document.createTextNode(text); + myBox.appendChild(myTextNode); + myBox.onclick = Hyphenator.toggleHyphenation; + myBox.style.position = 'absolute'; + myBox.style.top = '0px'; + myBox.style.right = '0px'; + myBox.style.zIndex = '1000'; + myBox.style.margin = '0'; + myBox.style.backgroundColor = '#AAAAAA'; + myBox.style.color = '#FFFFFF'; + myBox.style.font = '6pt Arial'; + myBox.style.letterSpacing = '0.2em'; + myBox.style.padding = '3px'; + myBox.style.cursor = 'pointer'; + myBox.style.WebkitBorderBottomLeftRadius = '4px'; + myBox.style.MozBorderRadiusBottomleft = '4px'; + myBox.style.borderBottomLeftRadius = '4px'; + bdy.appendChild(myBox); + } + }; - /** - * @method Hyphenator~hyphenateElement - * @desc - * Takes the content of the given element and - if there's text - replaces the words - * by hyphenated words. If there's another element, the function is called recursively. - * When all words are hyphenated, the visibility of the element is set to 'visible'. - * @param {string} lang - The language-code of the element - * @param {Element} elo - The element to hyphenate {@link Hyphenator~elements~ElementCollection~Element} - * @access private - */ - hyphenateElement = function (lang, elo) { - var el = elo.element, - hyphenate, - n, - i, - lo; - if (Hyphenator.languages.hasOwnProperty(lang) && Hyphenator.doHyphenation) { - lo = Hyphenator.languages[lang]; - hyphenate = function (match, word, url, mail) { - var r; - if (!!url || !!mail) { - r = hyphenateURL(match); + /** + * @method Hyphenator~doCharSubst + * @desc + * Replace chars in a word + * + * @param {Object} loCharSubst Map of substitutions ({'ä': 'a', 'ü': 'u', …}) + * @param {string} w the word + * @returns string The word with substituted characers + * @access private + */ + function doCharSubst(loCharSubst, w) { + var r = w; + forEachKey(loCharSubst, function (subst) { + r = r.replace(new RegExp(subst, 'g'), loCharSubst[subst]); + }); + return r; + } + + /** + * @member {Array} Hyphenator~wwAsMappedCharCodeStore + * @desc + * Array (typed if supported) container for charCodes + * @access private + * @see {@link Hyphenator~hyphenateWord} + */ + var wwAsMappedCharCodeStore = (function () { + if (Object.prototype.hasOwnProperty.call(window, "Int32Array")) { + return new window.Int32Array(64); + } + return []; + }()); + + /** + * @member {Array} Hyphenator~wwhpStore + * @desc + * Array (typed if supported) container for hyphenation points + * @access private + * @see {@link Hyphenator~hyphenateWord} + */ + var wwhpStore = (function () { + var r; + if (Object.prototype.hasOwnProperty.call(window, "Uint8Array")) { + r = new window.Uint8Array(64); + } else { + r = []; + } + return r; + }()); + + /** + * @method Hyphenator~hyphenateWord + * @desc + * This function is the heart of Hyphenator.js. It returns a hyphenated word. + * + * If there's already a {@link Hyphenator~hypen} in the word, the word is returned as it is. + * If the word is in the exceptions list or in the cache, it is retrieved from it. + * If there's a '-' hyphenate the parts. + * The hyphenated word is returned and (if acivated) cached. + * Both special Events onBeforeWordHyphenation and onAfterWordHyphenation are called for the word. + * @param {Object} lo A language object (containing the patterns) + * @param {string} lang The language of the word + * @param {string} word The word + * @returns string The hyphenated word + * @access private + */ + function hyphenateWord(lo, lang, word) { + var parts, + i = 0, + pattern = "", + ww, + wwlen, + wwhp = wwhpStore, + pstart = 0, + plen, + hp, + wordLength = word.length, + hw = '', + charMap = lo.charMap.code2int, + charCode, + mappedCharCode, + row = 0, + link = 0, + value = 0, + values, + indexedTrie = lo.indexedTrie, + valueStore = lo.valueStore.keys, + wwAsMappedCharCode = wwAsMappedCharCodeStore; + word = onBeforeWordHyphenation(word, lang); + if (word === '') { + hw = ''; + } else if (enableCache && lo.cache && lo.cache.hasOwnProperty(word)) { //the word is in the cache + hw = lo.cache[word]; + } else if (word.indexOf(hyphen) !== -1) { + //word already contains shy; -> leave at it is! + hw = word; + } else if (lo.exceptions.hasOwnProperty(word)) { //the word is in the exceptions list + hw = lo.exceptions[word].replace(/-/g, hyphen); + } else if (word.indexOf('-') !== -1) { + //word contains '-' -> hyphenate the parts separated with '-' + parts = word.split('-'); + while (i < parts.length) { + parts[i] = hyphenateWord(lo, lang, parts[i]); + i += 1; + } + hw = parts.join('-'); + } else { + ww = word.toLowerCase(); + if (String.prototype.normalize) { + ww = ww.normalize("NFC"); + } + if (lo.hasOwnProperty("charSubstitution")) { + ww = doCharSubst(lo.charSubstitution, ww); + } + if (word.indexOf("'") !== -1) { + ww = ww.replace(/'/g, "’"); //replace APOSTROPHE with RIGHT SINGLE QUOTATION MARK (since the latter is used in the patterns) + } + ww = '_' + ww + '_'; + wwlen = ww.length; + //prepare wwhp and wwAsMappedCharCode + while (pstart < wwlen) { + wwhp[pstart] = 0; + charCode = ww.charCodeAt(pstart); + wwAsMappedCharCode[pstart] = charMap.hasOwnProperty(charCode) + ? charMap[charCode] + : -1; + pstart += 1; + } + //get hyphenation points for all substrings + pstart = 0; + while (pstart < wwlen) { + row = 0; + pattern = ''; + plen = pstart; + while (plen < wwlen) { + mappedCharCode = wwAsMappedCharCode[plen]; + if (mappedCharCode === -1) { + break; + } + if (enableReducedPatternSet) { + pattern += ww.charAt(plen); + } + link = indexedTrie[row + mappedCharCode * 2]; + value = indexedTrie[row + mappedCharCode * 2 + 1]; + if (value > 0) { + hp = valueStore[value]; + while (hp) { + hp -= 1; + if (valueStore[value + 1 + hp] > wwhp[pstart + hp]) { + wwhp[pstart + hp] = valueStore[value + 1 + hp]; + } + } + if (enableReducedPatternSet) { + if (!lo.redPatSet) { + lo.redPatSet = {}; + } + if (valueStore.subarray) { + values = valueStore.subarray(value + 1, value + 1 + valueStore[value]); + } else { + values = valueStore.slice(value + 1, value + 1 + valueStore[value]); + } + lo.redPatSet[pattern] = recreatePattern(pattern, values); + } + } + if (link > 0) { + row = link; } else { - r = hyphenateWord(lo, lang, word); + break; + } + plen += 1; + } + pstart += 1; + } + //create hyphenated word + hp = 0; + while (hp < wordLength) { + if (hp >= lo.leftmin && hp <= (wordLength - lo.rightmin) && (wwhp[hp + 1] % 2) !== 0) { + hw += hyphen + word.charAt(hp); + } else { + hw += word.charAt(hp); + } + hp += 1; + } + } + hw = onAfterWordHyphenation(hw, lang); + if (enableCache) { //put the word in the cache + lo.cache[word] = hw; + } + return hw; + } + + /** + * @method Hyphenator~removeHyphenationFromElement + * @desc + * Removes all hyphens from the element. If there are other elements, the function is + * called recursively. + * Removing hyphens is usefull if you like to copy text. Some browsers are buggy when the copy hyphenated texts. + * @param {Object} el The element where to remove hyphenation. + * @access public + */ + function removeHyphenationFromElement(el) { + var h, u, i = 0, n; + switch (hyphen) { + case '|': + h = '\\|'; + break; + case '+': + h = '\\+'; + break; + case '*': + h = '\\*'; + break; + default: + h = hyphen; + } + switch (urlhyphen) { + case '|': + u = '\\|'; + break; + case '+': + u = '\\+'; + break; + case '*': + u = '\\*'; + break; + default: + u = urlhyphen; + } + n = el.childNodes[i]; + while (!!n) { + if (n.nodeType === 3) { + n.data = n.data.replace(new RegExp(h, 'g'), ''); + n.data = n.data.replace(new RegExp(u, 'g'), ''); + } else if (n.nodeType === 1) { + removeHyphenationFromElement(n); + } + i += 1; + n = el.childNodes[i]; + } + } + + var copy = (function () { + var makeCopy = function () { + var oncopyHandler = function (e) { + e = e || window.event; + var shadow, + selection, + range, + rangeShadow, + restore, + target = e.target || e.srcElement, + currDoc = target.ownerDocument, + bdy = currDoc.getElementsByTagName('body')[0], + targetWindow = currDoc.defaultView || currDoc.parentWindow; + if (target.tagName && dontHyphenate[target.tagName.toLowerCase()]) { + //Safari needs this + return; + } + //create a hidden shadow element + shadow = currDoc.createElement('div'); + //Moving the element out of the screen doesn't work for IE9 (https://connect.microsoft.com/IE/feedback/details/663981/) + //shadow.style.overflow = 'hidden'; + //shadow.style.position = 'absolute'; + //shadow.style.top = '-5000px'; + //shadow.style.height = '1px'; + //doing this instead: + shadow.style.color = window.getComputedStyle + ? targetWindow.getComputedStyle(bdy, null).backgroundColor + : '#FFFFFF'; + shadow.style.fontSize = '0px'; + bdy.appendChild(shadow); + if (!!window.getSelection) { + //FF3, Webkit, IE9 + e.stopPropagation(); + selection = targetWindow.getSelection(); + range = selection.getRangeAt(0); + shadow.appendChild(range.cloneContents()); + removeHyphenationFromElement(shadow); + selection.selectAllChildren(shadow); + restore = function () { + shadow.parentNode.removeChild(shadow); + selection.removeAllRanges(); //IE9 needs that + selection.addRange(range); + }; + } else { + // IE<9 + e.cancelBubble = true; + selection = targetWindow.document.selection; + range = selection.createRange(); + shadow.innerHTML = range.htmlText; + removeHyphenationFromElement(shadow); + rangeShadow = bdy.createTextRange(); + rangeShadow.moveToElementText(shadow); + rangeShadow.select(); + restore = function () { + shadow.parentNode.removeChild(shadow); + if (range.text !== "") { + range.select(); + } + }; + } + zeroTimeOut(restore); + }, + removeOnCopy = function (el) { + var body = el.ownerDocument.getElementsByTagName('body')[0]; + if (!body) { + return; + } + el = el || body; + if (window.removeEventListener) { + el.removeEventListener("copy", oncopyHandler, true); + } else { + el.detachEvent("oncopy", oncopyHandler); + } + }, + registerOnCopy = function (el) { + var body = el.ownerDocument.getElementsByTagName('body')[0]; + if (!body) { + return; + } + el = el || body; + if (window.addEventListener) { + el.addEventListener("copy", oncopyHandler, true); + } else { + el.attachEvent("oncopy", oncopyHandler); } - return r; }; - if (safeCopy && (el.tagName.toLowerCase() !== 'body')) { - copy.registerOnCopy(el); + return { + oncopyHandler: oncopyHandler, + removeOnCopy: removeOnCopy, + registerOnCopy: registerOnCopy + }; + }; + + return (safeCopy + ? makeCopy() + : false); + }()); + + + /** + * @method Hyphenator~checkIfAllDone + * @desc + * Checks if all elements in {@link Hyphenator~elements} are hyphenated, unhides them and fires onHyphenationDone() + * @access private + */ + function checkIfAllDone() { + var allDone = true, + i = 0, + doclist = {}; + elements.each(function (ellist) { + var j = 0, + l = ellist.length; + while (j < l) { + allDone = allDone && ellist[j].hyphenated; + if (!doclist.hasOwnProperty(ellist[j].element.baseURI)) { + doclist[ellist[j].element.ownerDocument.location.href] = true; } - i = 0; - n = el.childNodes[i]; - while (!!n) { - if (n.nodeType === 3 //type 3 = #text - && (/\S/).test(n.data) //not just white space - && n.data.length >= min) { //longer then min - n.data = n.data.replace(lo.genRegExp, hyphenate); - if (orphanControl !== 1) { - n.data = n.data.replace(/[\S]+\ [\S]+[\s]*$/, controlOrphans); + doclist[ellist[j].element.ownerDocument.location.href] = doclist[ellist[j].element.ownerDocument.location.href] && ellist[j].hyphenated; + j += 1; + } + }); + if (allDone) { + if (intermediateState === 'hidden' && unhide === 'progressive') { + elements.each(function (ellist) { + var j = 0, + l = ellist.length, + el; + while (j < l) { + el = ellist[j].element; + el.className = el.className.replace(unhideClassRegExp, ''); + if (el.className === '') { + el.removeAttribute('class'); } + j += 1; } + }); + } + while (i < CSSEditors.length) { + CSSEditors[i].clearChanges(); + i += 1; + } + forEachKey(doclist, function (doc) { + onHyphenationDone(doc); + }); + if (!!storage && storage.deferred.length > 0) { + i = 0; + while (i < storage.deferred.length) { + storage.deferred[i].call(); i += 1; - n = el.childNodes[i]; } + storage.deferred = []; } - if (intermediateState === 'hidden' && unhide === 'wait') { - el.className = el.className.replace(hideClassRegExp, ''); - if (el.className === '') { - el.removeAttribute('class'); + } + } + + /** + * @method Hyphenator~controlOrphans + * @desc + * removes orphans depending on the 'orphanControl'-setting: + * orphanControl === 1: do nothing + * orphanControl === 2: prevent last word to be hyphenated + * orphanControl === 3: prevent one word on a last line (inserts a nobreaking space) + * @param {string} part - The sring where orphans have to be removed + * @access private + */ + function controlOrphans(part) { + var h, r; + switch (hyphen) { + case '|': + h = '\\|'; + break; + case '+': + h = '\\+'; + break; + case '*': + h = '\\*'; + break; + default: + h = hyphen; + } + //strip off blank space at the end (omitted closing tags) + part = part.replace(/[\s]*$/, ''); + if (orphanControl >= 2) { + //remove hyphen points from last word + r = part.split(' '); + r[1] = r[1].replace(new RegExp(h, 'g'), ''); + r[1] = r[1].replace(new RegExp(zeroWidthSpace, 'g'), ''); + r = r.join(' '); + } + if (orphanControl === 3) { + //replace spaces by non breaking spaces + r = r.replace(/[\ ]+/g, String.fromCharCode(160)); + } + return r; + } + + /** + * @method Hyphenator~hyphenateElement + * @desc + * Takes the content of the given element and - if there's text - replaces the words + * by hyphenated words. If there's another element, the function is called recursively. + * When all words are hyphenated, the visibility of the element is set to 'visible'. + * @param {string} lang - The language-code of the element + * @param {Element} elo - The element to hyphenate {@link Hyphenator~elements~ElementCollection~Element} + * @access private + */ + function hyphenateElement(lang, elo) { + var el = elo.element, + hyphenate, + n, + i, + lo; + if (Hyphenator.languages.hasOwnProperty(lang) && Hyphenator.doHyphenation) { + lo = Hyphenator.languages[lang]; + hyphenate = function (match, word, url, mail) { + var r; + if (!!url || !!mail) { + r = hyphenateURL(match); + } else { + r = hyphenateWord(lo, lang, word); } + return r; + }; + if (safeCopy && (el.tagName.toLowerCase() !== 'body')) { + copy.registerOnCopy(el); } - if (intermediateState === 'hidden' && unhide === 'progressive') { - el.className = el.className.replace(hideClassRegExp, ' ' + unhideClass); - } - elo.hyphenated = true; - elements.counters[1] += 1; - if (elements.counters[0] <= elements.counters[1]) { - checkIfAllDone(); - } - }, - - /** - * @method Hyphenator~hyphenateLanguageElements - * @desc - * Calls hyphenateElement() for all elements of the specified language. - * If the language is '*' then all elements are hyphenated. - * This is done with a setTimout - * to prevent a "long running Script"-alert when hyphenating large pages. - * Therefore a tricky bind()-function was necessary. - * @param {string} lang The language of the elements to hyphenate - * @access private - */ - - hyphenateLanguageElements = function (lang) { - /*function bind(fun, arg1, arg2) { - return function () { - return fun(arg1, arg2); - }; - }*/ - var i, l; - if (lang === '*') { - elements.each(function (lang, ellist) { - var j, le = ellist.length; - for (j = 0; j < le; j += 1) { - //zeroTimeOut(bind(hyphenateElement, lang, ellist[j])); - hyphenateElement(lang, ellist[j]); - } - }); - } else { - if (elements.list.hasOwnProperty(lang)) { - l = elements.list[lang].length; - for (i = 0; i < l; i += 1) { - //zeroTimeOut(bind(hyphenateElement, lang, elements.list[lang][i])); - hyphenateElement(lang, elements.list[lang][i]); + i = 0; + n = el.childNodes[i]; + while (!!n) { + if (n.nodeType === 3 //type 3 = #text + && (/\S/).test(n.data) //not just white space + && n.data.length >= min) { //longer then min + n.data = n.data.replace(lo.genRegExp, hyphenate); + if (orphanControl !== 1) { + n.data = n.data.replace(/[\S]+\ [\S]+[\s]*$/, controlOrphans); } } + i += 1; + n = el.childNodes[i]; } - }, - - /** - * @method Hyphenator~removeHyphenationFromDocument - * @desc - * Does what it says and unregisters the onCopyEvent from the elements - * @access private - */ - removeHyphenationFromDocument = function () { - elements.each(function (ellist) { - var i, l = ellist.length; - for (i = 0; i < l; i += 1) { - removeHyphenationFromElement(ellist[i].element); - if (safeCopy) { - copy.removeOnCopy(ellist[i].element); - } - ellist[i].hyphenated = false; + } + if (intermediateState === 'hidden' && unhide === 'wait') { + el.className = el.className.replace(hideClassRegExp, ''); + if (el.className === '') { + el.removeAttribute('class'); + } + } + if (intermediateState === 'hidden' && unhide === 'progressive') { + el.className = el.className.replace(hideClassRegExp, ' ' + unhideClass); + } + elo.hyphenated = true; + elements.counters[1] += 1; + if (elements.counters[0] <= elements.counters[1]) { + checkIfAllDone(); + } + } + + /** + * @method Hyphenator~hyphenateLanguageElements + * @desc + * Calls hyphenateElement() for all elements of the specified language. + * If the language is '*' then all elements are hyphenated. + * This is done with a setTimout + * to prevent a "long running Script"-alert when hyphenating large pages. + * Therefore a tricky bind()-function was necessary. + * @param {string} lang The language of the elements to hyphenate + * @access private + */ + + function hyphenateLanguageElements(lang) { + /*function bind(fun, arg1, arg2) { + return function () { + return fun(arg1, arg2); + }; + }*/ + var i = 0, + l; + if (lang === '*') { + elements.each(function (lang, ellist) { + var j = 0, + le = ellist.length; + while (j < le) { + //zeroTimeOut(bind(hyphenateElement, lang, ellist[j])); + hyphenateElement(lang, ellist[j]); + j += 1; } }); - }, - - /** - * @method Hyphenator~createStorage - * @desc - * inits the private var {@link Hyphenator~storage) depending of the setting in {@link Hyphenator~storageType} - * and the supported features of the system. - * @access private - */ - createStorage = function () { - var s, - makeStorage = function (s) { - var store = s, - prefix = 'Hyphenator_' + Hyphenator.version + '_', - deferred = [], - test = function (name) { - var val = store.getItem(prefix + name); - return !!val; - }, - getItem = function (name) { - return store.getItem(prefix + name); - }, - setItem = function (name, value) { - try { - store.setItem(prefix + name, value); - } catch (e) { - onError(e); - } - }; - return { - deferred: deferred, - test: test, - getItem: getItem, - setItem: setItem - }; - }; - try { - if (storageType !== 'none' && - window.JSON !== undefined && - window.localStorage !== undefined && - window.sessionStorage !== undefined && - window.JSON.stringify !== undefined && - window.JSON.parse !== undefined) { - switch (storageType) { - case 'session': - s = window.sessionStorage; - break; - case 'local': - s = window.localStorage; - break; - default: - s = undefined; - break; - } - //check for private mode - s.setItem('storageTest', '1'); - s.removeItem('storageTest'); + } else { + if (elements.list.hasOwnProperty(lang)) { + l = elements.list[lang].length; + while (i < l) { + //zeroTimeOut(bind(hyphenateElement, lang, elements.list[lang][i])); + hyphenateElement(lang, elements.list[lang][i]); + i += 1; } - } catch (ignore) { - //FF throws an error if DOM.storage.enabled is set to false - s = undefined; - } - if (s) { - storage = makeStorage(s); - } else { - storage = undefined; } - }, - - /** - * @method Hyphenator~storeConfiguration - * @desc - * Stores the current config-options in DOM-Storage - * @access private - */ - storeConfiguration = function () { - if (!storage) { - return; + } + } + + /** + * @method Hyphenator~removeHyphenationFromDocument + * @desc + * Does what it says and unregisters the onCopyEvent from the elements + * @access private + */ + function removeHyphenationFromDocument() { + elements.each(function (ellist) { + var i = 0, + l = ellist.length; + while (i < l) { + removeHyphenationFromElement(ellist[i].element); + if (safeCopy) { + copy.removeOnCopy(ellist[i].element); + } + ellist[i].hyphenated = false; + i += 1; } - var settings = { - 'STORED': true, - 'classname': hyphenateClass, - 'urlclassname': urlHyphenateClass, - 'donthyphenateclassname': dontHyphenateClass, - 'minwordlength': min, - 'hyphenchar': hyphen, - 'urlhyphenchar': urlhyphen, - 'togglebox': toggleBox, - 'displaytogglebox': displayToggleBox, - 'remoteloading': enableRemoteLoading, - 'enablecache': enableCache, - 'enablereducedpatternset': enableReducedPatternSet, - 'onhyphenationdonecallback': onHyphenationDone, - 'onerrorhandler': onError, - 'onwarninghandler': onWarning, - 'intermediatestate': intermediateState, - 'selectorfunction': selectorFunction || mySelectorFunction, - 'safecopy': safeCopy, - 'doframes': doFrames, - 'storagetype': storageType, - 'orphancontrol': orphanControl, - 'dohyphenation': Hyphenator.doHyphenation, - 'persistentconfig': persistentConfig, - 'defaultlanguage': defaultLanguage, - 'useCSS3hyphenation': css3, - 'unhide': unhide, - 'onbeforewordhyphenation': onBeforeWordHyphenation, - 'onafterwordhyphenation': onAfterWordHyphenation + }); + } + + /** + * @method Hyphenator~createStorage + * @desc + * inits the private var {@link Hyphenator~storage) depending of the setting in {@link Hyphenator~storageType} + * and the supported features of the system. + * @access private + */ + function createStorage() { + var s; + function makeStorage(s) { + var store = s, + prefix = 'Hyphenator_' + Hyphenator.version + '_', + deferred = [], + test = function (name) { + var val = store.getItem(prefix + name); + return !!val; + }, + getItem = function (name) { + return store.getItem(prefix + name); + }, + setItem = function (name, value) { + try { + store.setItem(prefix + name, value); + } catch (e) { + onError(e); + } + }; + return { + deferred: deferred, + test: test, + getItem: getItem, + setItem: setItem }; - storage.setItem('config', window.JSON.stringify(settings)); - }, - - /** - * @method Hyphenator~restoreConfiguration - * @desc - * Retrieves config-options from DOM-Storage and does configuration accordingly - * @access private - */ - restoreConfiguration = function () { - var settings; - if (storage.test('config')) { - settings = window.JSON.parse(storage.getItem('config')); - Hyphenator.config(settings); + } + try { + if (storageType !== 'none' && + window.JSON !== undefined && + window.localStorage !== undefined && + window.sessionStorage !== undefined && + window.JSON.stringify !== undefined && + window.JSON.parse !== undefined) { + switch (storageType) { + case 'session': + s = window.sessionStorage; + break; + case 'local': + s = window.localStorage; + break; + default: + s = undefined; + break; + } + //check for private mode + s.setItem('storageTest', '1'); + s.removeItem('storageTest'); } + } catch (ignore) { + //FF throws an error if DOM.storage.enabled is set to false + s = undefined; + } + if (s) { + storage = makeStorage(s); + } else { + storage = undefined; + } + } + + /** + * @method Hyphenator~storeConfiguration + * @desc + * Stores the current config-options in DOM-Storage + * @access private + */ + function storeConfiguration() { + if (!storage) { + return; + } + var settings = { + 'STORED': true, + 'classname': hyphenateClass, + 'urlclassname': urlHyphenateClass, + 'donthyphenateclassname': dontHyphenateClass, + 'minwordlength': min, + 'hyphenchar': hyphen, + 'urlhyphenchar': urlhyphen, + 'togglebox': toggleBox, + 'displaytogglebox': displayToggleBox, + 'remoteloading': enableRemoteLoading, + 'enablecache': enableCache, + 'enablereducedpatternset': enableReducedPatternSet, + 'onhyphenationdonecallback': onHyphenationDone, + 'onerrorhandler': onError, + 'onwarninghandler': onWarning, + 'intermediatestate': intermediateState, + 'selectorfunction': selectorFunction || mySelectorFunction, + 'safecopy': safeCopy, + 'doframes': doFrames, + 'storagetype': storageType, + 'orphancontrol': orphanControl, + 'dohyphenation': Hyphenator.doHyphenation, + 'persistentconfig': persistentConfig, + 'defaultlanguage': defaultLanguage, + 'useCSS3hyphenation': css3, + 'unhide': unhide, + 'onbeforewordhyphenation': onBeforeWordHyphenation, + 'onafterwordhyphenation': onAfterWordHyphenation }; + storage.setItem('config', window.JSON.stringify(settings)); + } + + /** + * @method Hyphenator~restoreConfiguration + * @desc + * Retrieves config-options from DOM-Storage and does configuration accordingly + * @access private + */ + function restoreConfiguration() { + var settings; + if (storage.test('config')) { + settings = window.JSON.parse(storage.getItem('config')); + Hyphenator.config(settings); + } + } return { @@ -3220,12 +3300,11 @@ var Hyphenator = (function (window) { * @access public */ getConfigFromURI: function () { - /*jslint evil: true*/ var loc = null, re = {}, jsArray = contextWindow.document.getElementsByTagName('script'), i = 0, - j, + j = 0, l = jsArray.length, s, gp, @@ -3237,7 +3316,7 @@ var Hyphenator = (function (window) { if (loc && (loc.indexOf('Hyphenator.js?') !== -1)) { s = loc.indexOf('Hyphenator.js?'); gp = loc.substring(s + 14).split('&'); - for (j = 0; j < gp.length; j += 1) { + while (j < gp.length) { option = gp[j].split('='); if (option[0] !== 'bm') { if (option[1] === 'true') { @@ -3257,6 +3336,7 @@ var Hyphenator = (function (window) { } re[option[0]] = option[1]; } + j += 1; } break; } From 85fedadb299b57c0c53e723b76980d054ce26952 Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 10 Dec 2015 23:47:37 +0100 Subject: [PATCH 30/86] Refactor --- Hyphenator.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index 7067118..3e556d9 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -12,7 +12,7 @@ */ /* The following comment is for JSLint: */ -/*jslint browser: true for: false*/ +/*jslint browser: true*/ /*global Hyphenator window*/ /** @@ -321,10 +321,9 @@ Hyphenator = (function (window) { * @access private */ function forEachKey(o, f) { - var a, k; + var k; if (Object.hasOwnProperty("keys")) { - a = Object.keys(o); - a.forEach(function (v) { + Object.keys(o).forEach(function (v) { f(v); }); } else { From 9a5ba677047e315f9f12546cc34764f29b710b4c Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 10 Dec 2015 23:49:34 +0100 Subject: [PATCH 31/86] Fix doctype --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 9339aba..569825b 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ - + From d765869ca75f99014c91f5b050600e488ca99f4c Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 10 Dec 2015 23:53:01 +0100 Subject: [PATCH 32/86] Fix version number --- Hyphenator_Loader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Hyphenator_Loader.js b/Hyphenator_Loader.js index 728e576..55268b8 100644 --- a/Hyphenator_Loader.js +++ b/Hyphenator_Loader.js @@ -1,4 +1,4 @@ -/** @license Hyphenator_Loader 5.0.1(devel) - client side hyphenation for webbrowsers +/** @license Hyphenator_Loader 5.2.0(devel) - client side hyphenation for webbrowsers * Copyright (C) 2015 Mathias Nater, Zürich (mathiasnater at gmail dot com) * https://github.com/mnater/Hyphenator * @@ -11,7 +11,7 @@ * @description Checks if there's CSS-hyphenation available for the given languages and * loads and runs Hyphenator if there's no CSS-hyphenation * @author Mathias Nater, mathias@mnn.ch - * @version 5.0.1(devel) + * @version 5.2.0(devel) * @namespace Holds all methods and properties */ From 3e9c928ad7179e3d79da29663eb052fceb996556 Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 10 Dec 2015 23:56:30 +0100 Subject: [PATCH 33/86] Use current Loader --- index.html | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/index.html b/index.html index 569825b..ef432e3 100644 --- a/index.html +++ b/index.html @@ -40,16 +40,16 @@ } From 0f490a6fce92e2facc9e2adaf0fef5e6245d8fb1 Mon Sep 17 00:00:00 2001 From: Kevin Scannell Date: Thu, 10 Dec 2015 17:33:05 -0600 Subject: [PATCH 34/86] Add Irish hyphenation patterns --- Hyphenator.js | 1 + patterns/ga.js | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 patterns/ga.js diff --git a/Hyphenator.js b/Hyphenator.js index 3e556d9..2370409 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -97,6 +97,7 @@ Hyphenator = (function (window) { o('et', 'et.js', 0, 'Veebilehe keele tuvastamine ebaõnnestus, palun valige kasutatud keel:'); o('fi', 'fi.js', 0, 'Sivun kielt%E4 ei tunnistettu automaattisesti. M%E4%E4rit%E4 sivun p%E4%E4kieli:'); o('fr', 'fr.js', 0, 'La langue de ce site n%u2019a pas pu %EAtre d%E9termin%E9e automatiquement. Veuillez indiquer une langue, s.v.p.%A0:'); + o('ga', 'ga.js', 0, 'Níorbh fhéidir teanga an tsuímh a fháil go huathoibríoch. Cuir isteach príomhtheanga an tsuímh:'); o('grc', 'grc.js', 6, ''); o('gu', 'gu.js', 7, ''); o('hi', 'hi.js', 5, ''); diff --git a/patterns/ga.js b/patterns/ga.js new file mode 100644 index 0000000..25a9f21 --- /dev/null +++ b/patterns/ga.js @@ -0,0 +1,20 @@ +// For questions about the Irish hyphenation patterns +// ask Kevin Scannell (kscanne at gmail dot com) +Hyphenator.languages['ga'] = { + leftmin : 2, + rightmin : 2, + specialChars : "óúíáé", + patterns : { + 3 : "2ce2ge2nga1haf1ap1b1cb1fb1tc1pc1ác2hc2od1bd1cd1gd1md1nd1sd2he1ce1de1fe1ge1ten1er1f1nf2tg1ag1bg1dg1ág1íg2hh1bh1ch1dh1gh1phn2ht1i1hic1if1ip1ir1iv1l1fl1ml1nl1rl1tl1vm1cm1dm1em1gm1lm1rm1tm1ám1ím1ón1an1bn1cn1fn1in1ln1mn1pn1rn1top1oí1p1cp1fp1np1sp1tr1fr1ls1as1bs1ds1fs1gs1ls1ps1rs1át1bt1ct1gt1mt1ít2hts2ud1uf1up1v1av1áád1ál1án1áp1ár1é1bé1cé1fé1gé1ré1sé1tí1fí1hín1ód1óg1ól1ón1ór1ú1fú1áúb1úd1úl1úp1úr1", + 4 : "1bho1bhu1chu1dhá1fh21gio1gum1lál1méa1p2h1sh21tei2alr2asl2c1f2c1t2clo2cn22cí_2d1f2eá_2g1f2g1t2img2m1f2mh_2nag2nap2nio2nn_2ocf2oct2roí2t1f2t1l2ír12óp13acm3ché3cip3cír3cón3cúr3dho3dhu3dor3dó_3gho3gru3lúb3nom3pís3tá_3tól3tóp4adc4amb4amt4bhs4ch_4cht4clu4dib4din4eid4eil4eip4eám4fri4fás4gh_4gri4gú_4ilc4ios4its4iúd4lóv4lúd4móf4ná_4oc_4pe_4rap4rih4róc4róm4rúd4th_4ths4ísh4óda4ódó4óia4úid5cos5dip5mul5tír6amp6anb6aod6bh_6cóp6dh_6ghd6iút6mál6ois6olt6onr6pu_6píl6sc_6sif6st_6ti_6urn6us_6áip6íop6ógt6óiv6úlr6únl_ar2_aí4_bh4_ca4_ch4_ci6_cí6_da6_dh2_ei6_fa6_gh2_ha4_há6_hí2_hó6_id2_il3_ir4_is4_it6_la4_li6_lú2_mh2_nd6_ng4_od6_ra4_rá6_sc6_si4_sm4_st4_ta6_th2_ti6_íl3_ío6_óp6_úd2_úm5a1bra1dóa1moa3foa3goa3lía5bia5bua5roa5vóa6lla6ltab1aab1lab1áab1úab3dabh1ac1aac1lac1nac1óac5éac5úad1rad1úad3iad3uadh1ae1áae3aaf6úag1lag3eag3iag3éag3úagh1ah6aal1aal1áal1óal3ial3úal5oamh1an1áan1óan1úan3ean3uan3éang1ann5ar1aar1ear1par1áar1óar3iar3uas1oas1uas1óas1úas3ias3éas3íasc1at1aat1uat1úath1até3aí2cb1aíb1eáb1idb1líb1lób1ríb1s2b1álb1ínb1ítb1ógb3dhb3ghb3níb4hab4heb5dab5déb5pobc4ábh1óbin4bl6iblá4bn6ibp6ibp6ábré6bth6bun1bur2bár4bí3cbúm3c1acc1adc1aíc1eác1m2c1ímc2rec2átc3dhc3ghc4eic4únc6húc6óccas1ch1fchá6ci5vcla4cna6co4mcod3cof5crí6cs3ócs3úcth4cul3cus3cá6icéi6cíl5cít6cór5cú6icúl5d1acd1add1aid1and1aíd1eod1igd1imd1itd1lad1léd1rád1ríd1t2d1áld1ímd1ítd1ófd2ísd3lód3ved6emd6ádda6bdae5dar1deá4dh2bdh5fdic4dm6idmh2dn4ido3tdob4dr4úds4ads6rdta6dur1dár5dí2odív3e3bhe3lue3láe3mhe5seeg6íei4cei4sel1ael3óeor1eá1teá5geó5df2ísf3chf3ghf4epf4hef4luf4oif4orf5téf6huf6úlfa4bfea6fg4afha6fl6ifn4ifo1dfo3bft3ift5áfí4ofús4g1c2g1eog1eág1idg1igg1img1isg1itg1iúg1líg1m2g1róg1s2g1ógg2abg2aeg2nág3irg3ucg3álg3ódg4ecg4ólg5wag6esg6logb6agc6úgca4gcí6gd6agh1fght4gip4gl6úgmh2gth4gó1ch1aíh1idh1igh1líh1mhh1neh1nih1níh1nóh1s2h1ófh2bah2tóh2óth3vóh4dth4gíh4mth4nrh4ogh4omh4onh4árh6céh6esh6píha4chc4ahd2ahd4óhdh4hg6nhgh2hi4mhi6bhl6úhla6hma6hn5thr6úhsc2ht6iháí6hó6si1toi5éai6fei6scib1eib1iib1lib1rib1íibh1ich1id1eid1lid1rid1éig1eig1lig1rig1éigh1il1eil1iil1éil1íil3aim5aimh1in1éin1íin3ein3iin3oin3áing1io6tiod1iof1ip3íir3íis1eis1iis1éis1íis3oit1iit1rith1l1arl1d2l1idl1irl1s2l1ísl1únl2l1l2mal2mel3bál3cll3gél3hal3pél3pól4ecl4efl4eil4eml4fcl4fgl4msl4tml5hel6lól6tblb3nlc1alc3íldú3lg1elg3ilg3llg3rlig3lis1llt4lm6álm6ílmh2ln4aln4ilod5lp1alp1elp3álré5lt2elt2ilár5ló1slúg4lús3m1acm1adm1aim1amm1asm1aím1b2m1icm1igm1ilm1imm1itm1iúm1oim1pem1pim1pom1prm1púm1s2m1uam2ónm3abm3aem3agm3iam3pím3úlm3úsm4blm4pfm4átm4ósm5nam6bdm6esm6ptmb4ómch2mh1fmh1lmh1nmhd6mor2msc4mth6mur5muí6már5mí3bmó5mmór5mút5n1d2n1s2n1uin1áln1árn1ógn1óln1ónn1órn1úln1únn1úsn2can2cán2n1n3iln3ran3trn3ven3írn4edn4egn4emn4men4tmn5dén5hán5inn5lín5rin5sén5áín6bín6cbn6mcn6min6mín6tsnaf5nal3nan2nb6anc3eneo6ng2ángt4ni3fnis1nm4ónmh4nol6nr6únst4ná6inéa6nú5ínút6o1lio1loo1roo3hóo3léo3líob1aob1lob1rob1áob1óob3úobh1oc1loc3áoc5úod1áod3úod5eoen6of5óog1log1rog1óog1úog3eog3oog3uogh1oif3ol1aol1bol1áol1óom1pom3úom5óomh1on1oon1áon1óon1úon3eon3éon5aor1éor1óor1úor3eor3ior5aor5uor5áos1óos1úos3uot1rot1áot1óot1úot3aot3uot5ioth1oí2coíl4p1álp3imp4eip6léph4iph6aph6lpla4pn6apot3ps4apth4pun4pás5pí6tpós3pót3r1brr1chr1grr1s2r1úlr2gir2gír2mer2mír2r1r2ter2tír3búr3gúr3har3nor3wir4ber4cmr4dtr4gdr4gsr4lgr4mlr4mor4msr4nfr4olr4sfr4tcr4tor4udr6dnr6dsr6tsraf3rb3lrc1arc1erc1lrc3nrc3src5úrd1ard1órd3lrd3urd3érd3úrin2rir4rm3úrn1órn2irn3úro4crof5roi4rp1rrr5drrc4rrt4rt1art1rrt1árt1órt3urí2crír2ró6frób4rói6rót1s1ias1ics1ids1igs1ims1iús1m2s1n2s1trs1tés1ófs1ógs1úns3fes3fis3nós4úfs6údsb6asbh6sc1nsis3sla4sm6ismh4sod3sr6úst6usv4asíl3sú5csús5t1eot1igt1sít1óft2art3dht3sit3sut3sút3vit4het4rut5net5nít5sat6hat6hét6áttbh6teá6th1fth1ltis3tm4atm6etm6itof5tr6útíg5ub1aub5áubh1uc1auc3ruc3suc5luc5úug3lui4mui6suid1ul1aul3ául3óum1aumh1ump1un1óun3oun3áun3úun5aun5eung1ur3iur3pur3áur3óur3úur5uut3eut3óut5auth1uz3auí1guí1muí3buí3duí3óv3eov3lav4adv6ícvar5vir5x3acx5aix5aíá1faá3fáá3góá5boá5háá5úláb1láb1ááb3aáb3óáb3úábh1ác1aác3lác3rác3úáf1ráf3lág3rág5uái6máid1álc6ámh1ánt4ás1óás3aás3uás3íás3úás5eásc3át1áát1óát3aát3ráth1é3dhé3héé3láé3líé5leé5mhé5úlé6goé6iné6rbéal1éch4éid1í1chí1dhí1luí1láí1lóí1mhí1ocí1thí1trí3tií3úlí5baí5loí5ráí6nní6úiíb1líb1ríb3oíc1eíc1iíd1eíd1iíg3eígh4íl3aíl3éíof1íp3eíp3ríp3éíp5iís1eís1íís3iít4eít5éó1bhó3áló3úló5yóób3aób5róc1aóc1úóc3ióc3róc5óóf3róf5áóg3aóir3óng2órg4ós3óós5uós5úóst1ót1áót3óú1ghú1mhú5anú5úiú5úlú6dóú6fóúb4húc1aúc1lúc1rúc1óúd5rúd5úúg1rúl5úúlc4últ4ún1óún3oún3áún5aúr4úúr5óúrt4ús2áús3óús3úúsc1út1rút3aúth1", + 5 : "1chro1scrí1scóp1tós42c1ín2che_2d1óg2g1n22m1n22n2ót2oc1a2oc1r2sc1í2t1n22t1ál2íor12ó1nn3beab3béit3búid3c4ho3chót3cint3cion3cirt3d2ro3d4at3d4lú3d4ru3d4uc3d4ul3d4óc3d6hé3dict3dróc3dróm3dáid3dónn3f4ób3g2ao3g4ár3gine3giní3glif3grád3leáf3m4íl3miúd3món_3nóia3s4ón3scia3t4at3t4ás3t4íp3teab3thon3thur3tiún3tróp3tóip3tús33v4at3v4ei3vol43éa3p4ad3l4aisp4aivi4amál4as3e4ascr4aíní4bacá4bhe_4bhíg4bhío4bhít4c1óf4dann4deor4drog4easm4easú4eáib4fean4iail4ilia4isic4iúid4lacá4maim4mh5r4néas4oc1ó4oc3u4ochb4pall4peir4raob4raol4riat4roid4róit4steo4téig4uire4ur1a4árn24éann4ís3é4ú1nn5b4ei5c6ác5caod5ceá_5chár5chó_5chóc5céas5d6lá5doir5dóiv5eáis5lóp_5n6ób5p6ór5péin5seai5siút5tanb5tata5tíop5tíor6al5e6alám6andu6anná6b1ir6bis36cead6d5ós6deam6eagm6eamá6eanú6eash6eimh6feol6gaig6gáis6iomá6isis6nnac6oc3n6ochn6oinn6oir_6p6us6pias6píol6rasn6seag6seo_6siúd6sti_6thab6theá6toid6uaid6uig36uirs6ócar6óras6úile6úili_ab5r_ae5n_ag4ó_ag5r_ais3_am6á_an2a_an2á_an6i_an6ó_anc6_ard5_art4_aró5_as2t_as4ú_as6ó_at6á_ata6_ba6d_blí3_cha4_chí6_cil6_cli6_cnó5_dó5f_ead1_fí5g_fí5m_góf5_haí4_hir4_his4_hod6_hom2_híl3_húd4_iat6_ib6é_ibh5_ios3_ist6_lim5_lip5_lí5d_lí5g_lí6t_ma6r_ma6t_mam5_mhú6_nar5_naí3_neá6_nit6_nom6_ní5d_ní5m_oc4r_ogh6_om6a_ort4_rai6_ró5c_rúm5_sa6l_sca6_sim3_sí4o_só5f_tap5_ua4f_ua6i_ur5b_ál6t_ár2a_ár6m_éa6b_éar5_íos5_ór4áa2dófa3dhia3f6la3lára4stóa5bó_a5bóna5cróa5dhúa5ghia5rúta5tára6imha6masa6troa6tógabac6abh2tac1raac3réac5uaacae6ach1aach1rach1áach1úach3íacár5ad1alad1amad5ásadag6adhb1aeil3af6ráag2alag3riag3rúag3uaaic5raid1iailt2ain5íal1cóal3aíal3góal3uial6túala3balas3alt3eam1alam1anam3úiam4pram5utam5úrama3bamp1aamp1áan3dran3oian4maan5aían5oían5áran6agan6eaan6tuanac4anat6anc1aand3oandí6ang3aang3áanin5anód4ao4l1ao6r1aoch3aon3uaorg4aort4aos3tar1crar3úpar5ónar5ópar5úlarc1óarch6arm4óas1taas3coas3tias3túas5aías5toas5téasú5masúd6at1ráat3asat4uiat5ódata3matac6ats5aatá5tatá6iaí5óib3aigb3aimb3óidb4arrb4áltb6eárbamb6bar3bbar3úbat5abea6cbeif6beo3cbeo5mbh3imbh3ínbh4uabh5tíbhc6ábhlá6bhár6bhúm5bi3nébia3lbid5ibin5ibins3bint3bios5bist4bit5sblas3blim6bláf3bod3óbol4sbord3burd3burl1bust5bá5í6bó6s5bóth5búir5búis5c1idíc1igíc2áidc3bh6c3ighc3iú_c3iúlc3ra_c3s4mc3st4c4arlc4arsc4ratc4sicc4sigc4óipc5reác5rilc6arac6se_c6te_c6ánnc6éitca3dácal4mcar3úcard3cast6cat3ócat5ace3r4cea6bceo3mch1adch1m2ch1álch1ánch3núch3úscheá6chia6chil6cho4mchri6chua6chul5chus3chíl5chó1mchú6ichúl5ci3mécid5icin4dclim5clé6iclód4cnag5comh3con3ccon5gcorb3corn3cosc3crag5cri5bcri6tcros3cs4imcs5iscsi5dct4eoct4íoct6iúcua6mcuil3culc4cá4f3céal5cí6thcó4macóis3d1uitd3a3gd3arsd3idíd3inéd3land3oifd3reád4arád4áitd4éimd5idhd5áisda3stdab5adai5pdar6ddarg4darn4deat3dh4aodh4cidh4cádh5nudh5núdh6tedhas5dheá6dhip5dhob4dhor2dhur1dhí4odhó3fdhú3sdi5lédic5edist5dlí3bdman4do3brdo3dhdo5ledo5ridor2cdord3doth4dt6i6dtap5dua3mdual5duch6durd2dá3thdárt6déam5dí1ghdí3ledí3rédít6idó5m6dóth3dú3bhdú3scdú5rúe3s4ae3s4pe5n6iea5coea6dhead1áeaft5eag3óeain5earn3eas3aeib3éeid1ieilp5eips6eipt4eir2meirg3eist3eit3éeits3emhá6eo1gheo3lueo3steoi3feorn4eró3beá1imeá3ideá3iteáth2f4illf4óibf4óinf6an_f6éitfab3rfas4tfeo5mfhid5fho5bfhí4ofhí5gfhí5mfi3téfid5ifios3fir6mfisc3flít5fo3lefoil5foin6fol3ufost3fri3dfuad3fáir5fómh1fúst3g1eacg1racg1raíg1ó6fg1óimg3al_g3ra_g3uirg3óidg3óigg4ilig4láng5rasg6andg6eafg6lisgabh5gana3gaof3gard3gc6i6gcil6gcli6gcnó5gea4dgeit5gh2digh2lugh5c6ghd3ághis5gild5gios3gip5sgipt5giúm5giús3gl4i6glae1goin5gra6mgrá3mgrá4ngrú6igual5gáir5góin4h1aimh1laíh1na6h1ra_h1raíh1t2eh2p1eh2táih3ch2h3re_h3tarh4argh4c3íh4eath4ineh4rioh4rísh4rúph4íosh5bhah5bheh5th6h6amsh6arrh6nó_h6p5ih6úishab3rhag5rhai6chal5aham5óhamb6han4áhaof3har3úhat5úhc4ánhd3anhd3iúhea6chea6ghea6rheá1cheá6thfí5ghfí5mhibh5hid4éhil3bhim3éhip4ehir6nhit5shiúm5hiúr5hl6i6hlin4hlip5hm3anhm4adhnag5ho5leho5nuhod3ahod3óhof3ahoi4mhol3uhra6mhré6ihrí2ohrí3rhur5bhá5íohách1hí1ghhíol5hóp6ahós5ahóth1húst5hút5ói3ceii3chri3físi3mhai3seii5pléia3gria5fáia6táiag5óian5aiar3biarc6ib3éaib5iaib5iribh5éic4riic4sticim4id1iaid1inid1iúid1ínid1íoid3ídid3ígid4réidh1lidh1ridh3eidh3iidhc3if3írif6réig1ilig1ipig3iaigi3bil2scil5eáil5íoil6frilí6fim3ioim3éiimar6imb3limig6in5eain5icin5igindí6indó1iní6tior3dip5isir4trir5chir5idir5ipir5scir6tairt3oirír3is1tais5píisc1éist4rit1eait5aiit6réiuch3iú5imiúst4l1b4al1bhrl1bhál1ch2l1gh6l3b6íl3bhél3c4ál3ceil3oidl3úl6l4aihl4amol4asbl4b3ól4e5ll4eavl4ibhl4áibl4úpal5angl5cú5l5peil5pítl5s4el5s6ll5scll6aghl6mial6mí_l6áiml6éivla3l4la5múlae6clain4lais1lamp1lao3flat3álat3ólat5rlba5tlbh1ílbh3flc3eolc3imlc3itlc5idlc5inldúd4leif5lf5rélg6ráli3l6li3télias5liat6lin4slip4slist4lla3gllab6llam6lm4óglon5clp5iúlsc3elsc4ált4arltor6lus5tluí3olách5láin3lárt6ló3l4ló5mhlót3alóth3lú4f3lúca3lúm3alút3óm1ardm1in2m1isim1p2lm2ealm3arsm3artm3c4ím3idím3irím3éarm3ú6cm4alám5al_m5pé_m5éamm5éism6fe_ma3dáma3grmabh6mac5amam5ómant3mast4mba6dmblí3meá5cmh1t4mh4agmhis3mhur5mhuí6mhár5mhí3bmhúd6mi3némid5imilí6mint1mior5mirt3misc3mit6emodh5mor5dmor5nmorf1mors5mpar5mpis6muis5murd6mus3tmách1márt6mé5icmí3ghmí3rémí5grmí6namíbh6míos5mít6imúch3múin5n1gh6n1áidn1áiln3aern3g4én3ordn3tinn4b3en4c3én4c3ún4deán4ginn4óitn5cein5ch2n5cúnn5dean5gúsn5h6an5igín5sínn5tian5tisn5tá_n5uarn6b5in6cign6disn6fa_n6ró_na3crna3dána3grna3tóna5cónag3ónant1nata6nava5naít6nc1lonc3lunc5anncar5nd3ógnd6rónda6gndic5neat5neod5ng3ánng6iang6líng6órni3ténib6énin4snir4inir5bnist6nm5annn3t2no5lanoch6ns3eánsab6nsc6insc6rnsc6ánsú5mnsúd6nt3icnta3pntil4nua5tnuan6ná4f3néal5nío3to3daso3nóto3thoo3thío5dhio5dhío5dhóo5scéo5smáo6d5robht4oca3tocan4och1aoch1loch1roch1áoch1óoch3ioch5íocó5cod3alod3amodh1aodh1rodh3úodh6lof5raog5alogh2eoi6p5oid1ioift4oil5eoisc1oit1éol1úiol3eool3m2ol3úrolbh4olc3óom1anom3aoom3atomp6áon5grong3long3áonsc2ont2óont6eont6íopad6or1bhor3báor3neor4caor5cóor5nios3tios5amosa3tosar5osc1aosc1lost1óost3úotam4ots5óp4acap4acrp4te_p4éidp5c6íp5sisp6irtp6sa_past4peam6pear3phós3pi3dépi3lepid5ipios5pit3splim4poch5poin4pt3ispt4igpuin2punt3pít5ipóst4púin4púit6r1barr1dh4r1gh6r1mh6r1tarr1th2r1túnr2c1ir2d1er2d3rr2miúr2scnr2t1ir3bhrr3manr3mósr3nádr3násr3pánr3túir4c3ér4dí_r4dímr4dítr4g1lr4g3ér4m3ur4migr4mimr4mitr4p3er4p3ir4t5lr5gótr5pa_r5paír5sanr5tá_r5túmr6éasra3bóra3trra3tára5térag5oragh4rain4rb3amrb3asrb3earb4rírb5isrc3rárch4árch6irch6nreo1mri3néri3tari3téri5ríri5trrid3iridh4rinc1rlin6rm3alrm4ilrn3g4rn3iúrn5idrp3arrra3lrran4rrbh4rs3imrsc2árt3úcrua5bruad6ruai6réig3ríbh3rót5arú1ims1ch4s1crés1tags1tals2amhs3có_s3cóls3cóss3cúns3tógs4arls4cors4eats4ilfs4ilts4imés4ints4úits5cats6amss6at_s6atss6cigs6cí_s6cóis6eics6láns6tios6úigsa3bása3dása3fósa5frsa5tásalt3san2ásant4sar3bsar5csat5asc1eosc1imsc1rósc3itsc3úcsc6aosca6bseod3shar5ship5shor4shí4oshí6tshó5fshú5cshús5si5besib5ésidh6sin6ísis6csist4siúr5slí6tsmeá6snit4snua5so5ghso5nusobh6sof3asor4csorb5spi6dspor5spór6st1aíst1imst3asstai6sua6iséar3sí3bhsíol5só5mhsóin4súch6t1eáit1eált1ib2t1id4t1iú_t1áilt2eart3annt3eadt3ilít3init3inít3iúlt3rart3seot3áivt4allt4rátt4éitt5iltt5úidt6rúst6sait6áitta1góta3crta5notae5ntagh4tat5úteám5th5nóth6ísthós4ti1biti3diti3déti3f4ti5tétia5gtib5étir4itod5ótoin6tom6ator2ctor3ptrac6tros6trá5btrí1rtsa6ltuar5tuis3tur3btuío3tá6d5téal2tí4f3tóch5tú3m6u6t5áua1f2ua3luuad3áuais1uart4uch1auch3ruch3áuch3óui6p5uifé5uil3puim3puin5cuir3tuirn6uis5tuit3suit3éul3g4ul3m4ul4trul5p6un5gáunc1aunúd4ur3m4ur3t4ur6agurch4us3crus3tóus5tuusc3luí1oduí5tíuíth6uó3t6vach6vais5vard6vean6vear3vios5virg6volt3vuít5véar6véis5á1imiá3igíá3im_á3mará3nnaá3rolá4fa_á5r6éá5íreá6imháb4alábht6ácar5ách3lách5eách5iách5rách5áádh3aádh5úáib5éáil5báim5éáins4áirt3áisc1áit3sáit3éál4s3ám3anám3atán6gaár4taár5amár6caárt6rás3túé5ifíé5n6áé6amhé6im_éa1gréa1guéa2d1éalt3éast4éat3aéi6seéil5géint3éip4séisc1éit1séit3éí1bhaí1lití1n2aí1r2aí1s2pí1scaí1scrí3beaí3ceií3n4oí3n4áí3n4óí3reií3scéí4m3éí5bhrí5chaí5céií5gréí5r6uí5r6úí5stuí5ógaí6fe_í6le_íb3eoíbh1iíc3éaích6níd1íoíd3ídíd3ígíd3íníg5riíl1eaíl3igíl3imíl3isíl5iníl5iúími3tín3t4ín5aiío6cóíomh3íorg4íorn6íort6íot6rís3taísc5eíst5eó1faió3cheó3dheó3dhíó3fadó3l4eó3l4ió3l4íó3maró3n4oó5dhóó5gó_ó5l6éó5p6éó5íníó6ighóc5s6óch1aóch3úóch5róch5áói3péóib5éóid3ióin3tóisc3óist1óit3éóits3óm3atómh3áón2asóp6alór4maór4táórt2aórós5ós5amós6trósar5ósc3aót1aíótar3óth3áú3cheú3chíú3igíú3imiú3l4iú3r6uú3s4mú3stoú3thoú4mhnú5chrú5l6eú5p6rú5rúiú6p5aú6t1áúbh5aúc4ráúca3búch1aúch5lúint4úirt3úisc3úlú5lún3t2úng5uúng5áúra3búran6ús5ánúst3óút5óg", + 6 : "1g4raf2bh1eá2níomh3bh4id3c4ít_3c4ó1m3ceana3ceasm3ch4lo3ch4re3chrap3chrio3chóip3d4acs3d4eir3dh4ro3g4id_3ghrú63ginnt3graif3m4ít_3mharg3mhuir3p4at33s4an_3s4féa3s4íle3scior3scóip3stéig3t2íl13t4aga3v4ini4a3d4o4ach1l4adamh4adhro4aidhl4aitei4bh3ím4bhuit4d3ead4deann4deoir4liona4méar_4n3imi4righn4ta3to4tilít4traip4óireo5c6eai5c6ót35ceanó5champ5chóda5d6óic5f6ram5g6irt5g6lic5g6éas5galm65l6óip5m6ac_5m6óró5míre_5n6eot5n6óma5s6ao_5s6ing5salám5seáib5stáit5stát35t4eoc5t6ige5t6íol5teanú5tharr5thuig5thógt5uanla5v6ial6a3che6achri6achár6aigis6aisei6bh3iú6bhre_6deag36draim6g5ánt6gear_6ghrú_6innis6iseas6itean6loine6n5im_6n5ásc6parag6peann6raicn6t5iam6t5íti6talún6áinia6óf5ag6órais_ab4ai_ab6ar_ac6ad_ad6am_ag6ar_ag6úi_agh4a_ai6c5_aist4_al5g6_alm4ó_am6ac_an2ta_an6dr_an6fa_an6sa_ana5c_ang4l_aral4_aróc6_as6am_as6tú_ast3ó_bad3á_bal6b_beo5f_beo5g_bhlí3_brí3o_cach5_cad5á_caí5d_caí5m_caí5o_chnó5_clip5_cló5f_cnaí3_dlí5d_dlí5g_dlí5m_dlí5o_dó5im_ea6g3_earb5_fach3_feo5f_fí5dí_geat5_hag4ó_han2a_han6ó_hanc6_har2a_har6á_hart6_hat6á_head3_hib6é_hios5_hist3_hit6r_hoc4r_hogh6_hor5m_hort4_hua4f_hál6t_hár4a_hár6m_ia5it_in4ío_in6id_in6ín_in6ír_int6e_iosc6_iost4_lad5a_lag5á_lait5_lan5c_lao5n_lea6m_leas5_leo3c_lib5é_lint6_lí5mi_lí5od_lít5i_mad5a_man2t_mar5ú_mat3á_maí5d_mí5st_mí6oc_nair5_nais5_ndó5f_neád5_ngóf5_ní5gí_ní5od_ní5om_ní5on_ní6oc_oilt6_oir5t_ol6ac_or6ai_ost5a_pist6_rad5a_rad5ó_rat5á_reas5_reo5f_rí5dí_rí5gí_rí5mi_rí5od_rób5a_róch6_róst5_sal5a_scar5_siún4_sní5d_sní5g_sní5m_só5im_tan5g_tróf5_tsí6o_uaf5a_uil2e_uir6t_un6s5_ur3n4_áir6s_éart6_éim5í_íoch5_úr6áia1f2óna3b4ala3bh6ea3cáida3d4úra3fóiba3fóina3grama3láiba3mhasa3s4aea3s4óla4cha_a4d3óda6chlia6g5reab3óigab4artaba5caaba5dáabh6reabh6órac4adúac4aoiac4rasac6ardaca1s4ach3ógach5órachar5acra3fad3araad3arlad3rogad5artad5áilaeilg4af5airaf5artafa3dáafhol6afáil3ag5ruiag5áisagad3áagh5anai3filai3ginai5ciúaich6taidít5ailp3iain5téair4déairb4íairf3íaits3eal2annal4tófalabh4alait4alan4aalan5dalasc6am3araam4ánaam5allam5ónaama5sóamh5adan2d3áan3aitan4sanan5cé5an5gó_an5áisan6sinana3caandíb5anuas6anó3dóao3imiao5darao5im_ao5maraocht6aoin6sapa5dáar2f1óar3bhear3úilar4p3óar5as_ar6ac_ar6staara3búara3p4ara3tóara5cóara5sóarbh3aas5tuaas5tóras6arbas6tasas6óilasain4asal2tascar5ast3alasú3itat3óidat3óigat3óimat4agrat5arnat5rapat6sarata3p4ata5cáatam4áath6usatáth6atéad6b3aidíb5adarb6aitíba3dáiba5casbac6s5baist3bait3éban3d4bar1n2beil6tbeir5fbeoch4bh3aigbh5eambh6ricbh6réabhal6bbhar3bbhat5abheif6bheo3cbheo5gbhios5bhláf5bhual5bhust5bhéal5bhí5otbhí6thbhúir5bhúis5biosc6bla3grblad5ablead5bol4tábos5t6bpist6brad5ábrat5óbua3imbua5dabuair3buin6tbá5innbá5itíbárth5bí6th5bí6tigc2aisnc3eadác3iam_c3úla_c4illic4s3ítc6artac6s5ilc6teáica3máncab5alcae4d3caib5écain6dcair6bcait3écal5ancan3t2can5c6can5s6carbh4carn5ácas5tócea3súcear3bceas6tceil4tceit6sceá3n4ceá6f5ch1as1ch3arfch3áirch3ódhch3óg_ch3óigch4lárch4rí6ch5al_ch5obach6ritchal4mchar3bcharn5chast4chat5achat5ócheáf5chin5tchlé6ichlód6chomh3chon3cchon5gchorb5chorn5chros3chulc6ci3p4lci6p5écia6f5clad3óclad5ácloch5cló3dócneá5ccoirn4cona3mcona6ccor3t4cor6p1coran4crais4crea6bcrit5écriú5icroch3crost4créal3cuil6tcuilc6cur6l5céa3tácéalt6cóist4d4l3add5eagód6eanddair4ndalbh5dar5t4dbhin4deal5adeáth3dh2s3ádh4n3edh6c5adhasc6dhia5fdhint5dho5dhdho5rédhorn5dhua5mdhual5dhurd4dhí3rédhó3imdhó5indhú5lédhú5rúdia3mhdia5f6din6t5do3ghldo3mhido5chedo5lagdo5mhodo5mhúdo5r6édo5s6mdor6n3dorch3dosc4adró3l4dtan5gdtróf5duamh4duar5tducht5dun6s5dára5sdí4leadí6thedó5im_dú3l4ée3m4ace5m6aíe5ólace5ólaíea3matea3rúiea4g3aea4tá_ea5carea5có_each3óeal6p5ealt3áeamar4ean3d4ear1m2ear3f4earb3áei6bh5eic4sieilít6eimin3eini3ceir4bíeir6p5eir6steirm5éeitim6eo3dareo3fadeo3faieo3im_eo3itíeo3nnaeo5mareod5óreol3c4eol5g6eomh2aera3s4era5d6ethan5eá3inneáit4eeáit6if4e3l4f6ain_f6eadhfacht2faist3fal3c4faois3far3n4far6amfar6atfead5afhach3fhas6tfheo5ffhios5fho3dhfhoil5fhoin6fháil2fháir5fhí5dífhí5omfhómh3fiach5fiosc4fo3scrfo6d5afoirn4for3b6for3n6forch4frai3dféach5féalt6fíod3ófóint6fúith6g3inn_g3raigg3raitg3óinng3óra_g6a5p6ga3daoga3stága5b6agabht6gai3spgai3tégar1n2gar6túgcach5gcad5ágcaí5dgcaí5mgcaí5ogcin5tgclip5gcló5fgcnaí3gea3stgead3ógeal5ageal5bgeat5agh4de_gh4s3ágh6am_ghabh3ghd3acgheit5ghoin5ghrá3mghual5gháir5ghó6f5giost4gnó3l4grámh4gust5agéa5b6góint3h1t2úrh3eacnh3t4aeh4eangh4láirh4éadrh5dineh6eánaha3dáihac6s5hach5óhae5nnhagá5lhaic5íhain2thait3éhal5g6ham5athan3d4haral4hard3áhat5rahaí6tihbhuí6hd3aimhd5eamhd5innhd6eogheag5rheana6heat5áheat5óheift5heo3mhheod5óheáth5hfach3hfeo5fhfí5díhfí5omhghin5hin6ínhin6írhint4ehip6idhirim5hiús5thlac5áhlad3áhlad5ahlad5óhlas5thlim6phlé5amhm4ainhmad5óhn6eánhniú3chnua5chnó5l6ho3bróho5mhúhoilt6horan6hord3áhos6táhrad5áhrat5óhroch3hruac6hscar5hta5p6hur3n4háin4théim5íhí3leáhí5stihíod5óhíoll6híos5thó5im_hó6ma_hó6maíhóin4shóint6hóist6húd5aíhúin5ti3c4ídi3péidi3sinti5ch6ai6tínnia1t6ria3chlia3f4aia3igíia3imiia3iteia3lania3latia5daria5im_ia5innia5mariach3óiam4b3ian3g4iar3d2iar3t4iar5m6iarbh6iast5rib3éilib4eabib5éidibhin4ibhit4ibia5nic6iú_iceap4icé5anid3icíidh3bhidi3f4idí5ocif5in_ifin6tifini5igea5tileac2ili5béilia5nilé5anim3ideim3ireim3irnim3irtim5iscim5íríimi5géin2tí_in4scnin5íocin6girind3eáind3ibindíl5ineam6ioc5s6iol5g6iom3arion3c6iopa5diot6asipea3gipist6iream6irt6s5isear3iséal5it3eánitil4tiucht4iú5inniúir6siúiré5iúité5iúr4s3iús5tál1g2aml4agaml4aitél4ar3nl5bhanl5scidl6óiníla1g2ála3f4ála3f6óla3rúila5baslach5ólaghd6lai3l4lainc4laisc3laist6lan2d3las5tólasar3lbh3eolbh5adlbhin4lc3eanlca3l4ld5eanlea5gúlearb3leat5óleisc3leo6d5leomh3leách3lf5eanlga3dáli3bheli3mhili3tiúli5bí_li5m6éli5n6éliast6lic6s5lim5irlimp3ílint3eliost3liú3stliú5malla5balla5mállai3sllait4lm6óigloit5elorai5lsc5inlt3eoflt6airlt6racltra3llua3imlá5innláint4lé1if4lé3adhlé3itíléint6léit6slí3bhélí3sé5líth6ilúit5ém2aitim2eascm3a3f4m3a3rúm3a3tóm3ar6bm4óin_m5adarm5adh4m5péarm5péirm6óiníma3tagma5dasma5g6lmadhm5mai3témal5g6mam5ú5mar3m6mar6f5marbh3mat5ógmaí6timbad3ámbal6bmbeo5fmbeo5gmbrí3ombí5tímeal6tmeas5tmeo3nómh3asfmh4ad_mh4illmh4éalmh4úinmh6am_mh6at_mh6atsmhadh4mhais3mhar6bmhat3ámhat5ómhist6mhor5nmhor6cmhuis5mhus3tmhárt6mhí3rémhí6lemhíbh6mhó5mhmi3l4émi3t4imilít5min5semin5símir4c3mleat6mol5t6mon5c6mon6t5mong5ómorch5mp3allmp5éidmpi5semroch5muilc5muisc6mé5ighméin6tmí3lítmóint6múcht6n2s3áln2t1eán3abaín3c4ásn3ceasn3g4iln4aisen4c4s3n4diain4t3íln5cisín5céadn5céidn5d6ánn5g6únn5seacn5tearn5teá_n5áiscn6trasn6uas_na3bh4na3chlna3mhéna3stána5chrna5matna5tamnae5m6nail6tnalbh4namh5anao5nnnarb5anarbh6nbhan6nc5aigncarn6nchró5nd5is_nd5isendlí3ondlí5dndlí5gndlí5mnfair6ng4alóng6ealng6íneng6íocnga3dángeat5ni6m5énia5itnin6d5ninít5nlia5nnlé5amnlé5annna3b4nocht5noich4nroch5ns3annns4eánnsa5banseir5nsin6tnsá3itnt3eagnt4eadnt4eolnt4ín_nt4ínínt4íocnt5artnt5oidnt6eognt6íninta5móntai3bntra5bnua5danua5imnéalt4ní4th5ní6t5rnílim5nó1th2o1mh2eo3bh4eo3igí_o3mh6ío3s4páo3scrio3th4eo5bhréo5l6abo5lagho5láimo5mhilo5r6iao5scaoo6f3acoba3dáobhar3och3eooch3uaod3artodh5eooim3iroimp3éoint3éoir3d4oirn3íois1t4ol4g3aola1g6ola3dáola3f4olan5dom3aráoma5táomant4on5gabon5gúiona3b4ona3l4onam4aondu5song3óiong5ónontar3opa3laopa5dáor3mónor3oidor5póior5tasor6maíora3tóorb5adorch3óos4t3éosarn6osc3óiosc3úiosc5raosc5órost3aiost5adot4asaoth6asoth6rioth6usothar3oí4te_oíche5p4i3tép5s6imp6asamp6iteipa3p4ópaisi3par2s3par3d4par3n4par6tapea5stpeal5apearn6peil3bpein6tpeir5tphast6phat3rphoin2phonc5phuin4phóst6phúit6pic6s5piost6pirim5pis3tipist3eplé5amplé5anpló3m6pocht6point5poist5pol2agpol5c6pon4c3praoi5pré5ampré5idpróis5ps5eanpsain6pt3eanpéin6tpéir6spúins5r1m2adr2bh1lr2d1i6r3bairr3caisr3d4rér3g4asr3geadr3gintr3n4apr3t4alr3t4ilr3tanar4b3iar4d3íor4g3rur5baitr5bhiar5cisir5d4únr5d6aor5d6arr5góitr5n6ónr5pógar5s6ánr5úiner6alanr6cra_r6d5ídr6d5ígr6n5iar6t5úlr6áinir6éithra3g4ára3l4úra3matra3p4órad5ónraghs5raimh4raimp3rainc3rait3érait5srant4óras1t4rat3ógrata6mrb3ac4rb3adhrb3annrba3cárbh3asrbh3inrbh3ánrbh3ígrbh3íorbh3ítrbh5ídrbh6atrc4intrca3s4rch3acrch3rard5oidrd6airrdin5érea3táreag3rreas2treo3dóreá3irrf5eolrg3easrg5eamrga5dárghin5ri3ch4ri5ginri5leiriach3ribh6irint3érip4teris1t4rit5éarleat6rlé5anrm6airrn3eálrn4ínern6íniroim3érost3árs6ainrs6áinrt3eacrt3eamrt3eanrt4agárt5aíort5eagrt5úilrt6asórtha3trti3s4rua3darus4t5rusc3ará3íntrách5aré5adhré5iferé5igíréal2tréal5arí5chírí6therí6thiróist5rós6tárú3idírú3innrú3marrúst3as3c4aes3cears3t4irs3t4ícs3t4íss3tices4láins4téins5eagás5i5frs5ímeas6aisís6ileas6áilis6óines6óinísa3g4ása3lansa3r4ósail5bsal5atsat5rasc3raísc3um4sc4éimscach6scoir5seal5aseal6bsealt6sean5mseana6seas5tseic6tseift5seil6fseit5sshant6shib5éshiún4shnua5shní5dshní5gshní5msho5ghsho5thshorb5shua6ishí5bhshí6l5shó5imshó5mhshú5inshúch6si3f4ési5g6ésia5itsiach6simea5slac5áslag3áslag3ósma5lasmead5smear5so3mh4so5láiso5th6sorch5spad5aspad5ásport6sprae5spuir6st3aigst3ithst5amast6isesta5dástrae5stáin6sua3l4sáin6tséalt6sí4th5síoll6só5itísó5tacsú5im_sú5innsú5mart1s4eat3adh_t3eal_t3ealat3ealót3ileot3ineat3ist6t4eamot5aitít5ealtt6ráist6seanta3g4áta3mánta3s4lta3s4tta4chata4l5ata5dáita5p6ltaghd3tai3tétair2btal6c5tam4altan3gótan4t3tar1c2tar3g4tar5d6tart4atas5trtea3grtea5fath5am_th5eánth5in_tha6p5thagh4than3gtharc6thin6ithit3ethor4cthost5thros6thrá5bthu5sathuar5tháin5thé3ifthéal2thí6f5thío5tthóch5ti3tiútin5t4tin6d5tit5eatit5eátorch3tort5atos6t3tra6bótream4trost5truac4tsal5atsi6m5tsiún6tua5datur3n4tá6im_táir5tté6ightéa3latéach6tío5t6ua3chlua3idíua3marua3mhéua5nósua6fa_uabh6ruains6uairn6uaist2uait5sual3g4uala5tuar3g4uga5dáuin3t4uint5íuir5b4uirbh6uirs3tuirt4íuis3crun6sa_ur3d6úur5gónurach3urg5óiusc5aiust5acust5únuí3omauí3onnuí5l6euí5teáuío3dóvac3s4vaisc6veant5vearn6veil5bvéist6á3d4ará3idísá3th4eá6f3acácarn6ách4t3áf5airáf5araága5dááil3c6áilt3iáin3teáist3eáist3iár5aimárach3árt6aiárt6anás1t4aás5c6áé3if2ié3iteáé6ite_éab5róéag3óiéalbh6éam3atéar5g6éars5aébhrí3éi3ghnéi5deiéi5g6ééic4s3éil4t3éim5iréin4tééir2n3éist3eéist3iéit6irí1r2iaí3líthí3teasí4mhidí4tearí5bheoí6f5irí6f5isíbh3eiíbhuí4ícea3síf5eanío3c4áío4mheír2éirísc3iríst5inít5eaníth5isó3d4aró3igí_ó5mhaoó6b5aiócht6aódai5dóf5airóf5aitóga3l4ói4m5éóillí4óin5sióin5síóis6téóla5dáómh3asómh4aíón3as_ór4áidósarn6ót3airót5a3mót5aigóta1c4ú1ch2áú3idísú3l4agú3l4uaú3s4péú4mh3úú4sh3lú4áil_ú6itínúba5dáúbail4úcas4túch5ógúcht4óúil4t3úir2téúl6éimúmh3acúpa5t6úr6anaúra3dáúrabh4ús4airús6t3r", + 7 : "2d3óirs3bh4ear3bh4irt3bh4las3c4ar1b3c4eána3c4íte_3ch6rao3d4aing3d4airi3d4reor3m4íte_3s4féir3s4óin_4ai3mia4airisc4al4ath4g5amar4l1i1f44p3lag34t3éirs4tanna_4áir4g35chórai5chóras5d6aine5d6óigh5m6an5c5s6iúit5t6aig_5t6aige5thoin66aidear6anaige6d5iam_6da3l4ú6earta_6g5eadh6m5é5ac6t5iteo6tra5cá6ói1mh2_ach6ar_ad6aim_ail6te_ain3g4_air6ní_al2t5a_al6t5á_ala5m6_allag6_an6dór_an6lan_an6rai_anach6_ara5m6_ara5s6_aralt3_as6ail_as6al__as6pa__asc6ar_ast5ai_ast5aí_at5ar__beo5id_beo5im_bheo5f_bhrí3o_bhí5tí_breo5f_cacht6_caí5gí_chach5_chad5á_chan5á_chaí5d_chaí5m_chaí5o_chló5f_chnaí3_chóis5_cló5id_cló5im_dhlí3o_dhlí5d_dhlí5g_dhlí5m_dreo5f_dó5idí_dó5ití_eal4t3_eas3tó_eis4il_eisc3e_feo5im_fí5odh_fí5onn_ghlae3_ghrá6n_hab6ai_hab6ar_hac6ad_hag6ar_hain3g_hain3t_halm4ó_han4ta_han6fa_hana5c_hang4l_har6ó5_haróc6_has4ta_has6ai_has6am_hiosc6_hit6eo_hol6ac_huaf5a_huil4e_háir6s_héid4e_híoch5_im6ire_leab3ó_leoch4_lá5ití_lé5igí_lí5onn_mar5ta_mar6l5_maí5gí_maí5mi_maí5od_maí5on_maí5tí_mead5a_meat5á_mhad5a_mhaí5d_mhí6oc_mhúch5_ndó5im_ndó5in_neach6_och6t5_oir6ní_or6thu_os6ló__raf6t5_reo5id_reo5im_reo5in_réim5i_rí5oma_rí5onn_scad5á_scart6_siúnt3_slios5_sní5od_sní5on_steam5_sá5ití_só5idí_só5inn_tar5ta_thróf5_tua5im_téit5e_áir5ge_áir5gí_éa3g6ó_éad6ar_éi5d6r_íocht6a2d3óida2d3óima3graima3p4aita3t4anta4d3óigab3rad6ab4airtabra3daac4astóaca3t4úach4arfacharn6achart6ada5n6óafholt5afáilt6agh4aidai5s6ílai5t6ilail5bhíailc3eaailp3ínaim3iseains5eoair4b5rair4fínair5nínair5níoairis6tal6t5ódalú3ch4ama3d4úama3raíana5l6óana5m6óana5r6aanaist4anga3rúao5idísaoin3t2aplais6ar4s3álar5ú5s6ara3c6áara3g4aara5l4áaraic6íaróc6aras3tán_as5caraasa5c6aascart6ast4aí_at5a1l2atad5ánathrí5dathrí5mathrí5oaí3o3dóaí3onnaba5s6árbain5t4baisc5ebalbh5ábanais3bea5bh6beal5t6bear3bóbeir5tíbh3uithbha3g4ábha6d3ábhaist3bhalbh5bhar3t4bheil6tbheir5fbheoch4bhin6síbhlead5bhol6tábhrí3ocbhua5dabhua5imbhur2l3bhurd5ábhá5innbhárth5bhé5annbhéalt6bhói5s6bia5ta_bion5góbol6ta_bran3g4bran6d5bá5ite_bá5iteábít5eacbó5l6acc3eab5ac4t3eacc6s5ealc6s5tarc6t5eanc6t5eárcai5m4écain2t3cairbh5cais3t6calbh3acart6accea3stácead5ascean4tácearbh4ceast5aceast5óceir5m4ch4antóch4lasachacht6chaint3chan5c6charbh6chear3bchloch5choirn6chona5mchor5t6chor6p3chrost6chuil5cchuil6tchur6l5cis5teáclas6p5cleat5aclocht6cló5im_cló5itícoil4t3corant3crai3l4craist5crea5sccreab5acreach5crocht4crua5imcrá5inncrá5itícréalt4críoch5crú5itícsea5g6cuacht6cáin6ticár5ta_da3r4aoda5c6acda5c6aídai3ghndairbh5dear5badear5t6dearbh5deilbh5dhar3t4dhearb6dho5chedho5ghldho5s6mdho5thrdho5thudhosc6adhró5l6dhuamh6dhó5idídi3n4éidlío3dódo6th5adoch6tádoilbh3doir4n3dos3caídra5n6ódreo5itdtaist5dtua5imea3g4álea3s2trea5c6lóea5táireabh5t6eagh2d3eais6t3eal6táieal6táneam5aiteama3raearai5ceic6s5íeidh5n6eidh5t6eig4eaceil4t3ieil5teáein2t3eeir6figeirbh6ieirm5iseis5cireis5in4eithin6eiti5míeo3iteáf6raim5facht5afaisti3feis5c6fhacht4fhair5tfhal5c6fhead5afheo5imfheo5infhiosc6fhor5b6fhor5n6fhraim5fháilt3fhéach5fhí5odafhí5odhfhí5onnfiacht6fol6ta_frioch3fua5im_fuir2s3fáil2t3féacht6gar5ma_garbh5ágas3c4rgcacht6gcar6tágcaí5gígcaí5tígcló5idgcló5imgea3namgead5asghabht4gheal5aghin5tíghint6ighrámh4gin5t6ígrá5itíh3t2úirh3t4aicha3dán_ha5s6árhach6arhad6amhhag6úishaint5íhalbh3ahallag6halt5arhan3t4áhan6lanhan6raihan6sa_han6sachar3n4óhar5ma_hara5b6haralt3hart4achas6pa_has6tú_hasam6ahasc6arhat5ar_hbhain6hbheo5fhd3eannhd6eoighdeá5nnheanad5hear5bóhfair5thfeo5imhfeo5inhfhuad5hfhuaf6hfí5odahfí5odhhfí5onnhiat6achin4íonhin5teáhios3t4hiosc6áhipi5c6hir6im_hir6imehis5teáhit6eorhiúnt3óhleat5ahleá5d6hlé5igíhlé5imihléach6hló5im_hló5itíhm4aid_hm5ainnhniúch6hoch6táhol4agáhomai3ghon4c3óhorant5horch3ahost5achost5ánhramad6hrocht6hrua5cáhrú3itíhscart6ht4anachthor6thuil5cehí6th5ehó5l6anhú5ite_húch3t6i5n6éagi5s6ít_ia3idísia4mhaiiai3t4rialach3iceapt5icí5teaifinid6igea3s4igi3l4iil4bh5rilbh5inilea3cailea3cáilea5cóili3c4éimeach6imhead6ind3iaiind5ia_inea3móiniúch3int3eaniogad3áiosc6acirea5b6irea5máirea5móirscar5is3céimisc3eadisc3innisc5ealisc5eamit3eartithin6tithé5anits5eaniú5t6aciúch3t6l3c4aill4ai3nél5bhainl5ma5n6l6bh5idl6c5ántl6sc3aila3c4ánlach6táladh2m5lai3m4élai3tínlai5d6élain5cilao5innlao5irílao5itílao5nnalas6pa_lasarn4lbh3aitlbh5acálbh5eadlbh5eanlbh5ir_lbh5ithlea3tralea5m6áleir5c6li5b6illi5b6íoli5g6éaliant3alion4t5lla3c4állag6acllag6arloraic6lsc6eadluch6t5lá5iteálá5ití_lé3idíslé3itealé5imislí6ocháló5d6órló5dóirlú4mh3álú4mh5alúch3t4lúma5n6m1ar6c5m3i3r4ém3is3t6m3p4arnma3l6anma3r4adma5n6ammaint6imair6nemair6nímaist6emar6sa_maí5te_mbeo5idmbeo5immbeo5inmbreo5fmbí5dísmbí5mismbí5teámear5c6meat5ánmeir6f5mh4aid_mhais6cmhaist4mhar3m6mhar4f3mhar6camharbh5mhluad5mhon5c6mhon6t5mhong5ómhor6s5mhrí5ocmhuisc6mlua5damp3eannmrocht6mí3teacn3g4antn4s3áiln4t3iúrn5c6ar_n5eoirin5t6eánn6bh5aon6traisna3g4amna3l4ógna5maranai3l4inaist3enbhand5ndreo5fndó5itínea3g4ánea5ma_neá5chanfairt5ng4aintng6óid_ng6óidengair5tni5cínenlé3iminlé5igínrocht6nsá5innnsú5itínt5iúirnti3lítntrabh6nua3chónuais6lo3bh6rio3thaiso3tháiro5mharaobhard4och3t4íodhear6oim4p3íoimead5oir4bhíoir4nímoir4níooir4nítoir4p3íoir6niúoir6nídoir6nígoirn6eáol6aiméolai3téoma3l4óon6t5alona3g4óona5maiona6craontarn4or6s5aíora3dáiora3dánorthé3aos5t6únosai5l6oscó3l4ospair3pai5g6epana3m4para5b6pea3s4ópea5maipeacht6peilbh6phar5d6phar6s5pheil3bphis5t6phlé5anphoint3phol5c6phróis5phun4t3pháint5phéin6tphéir6spin6se_pion6t5plé5igíplé5imipol4aimpor3t4rpost5acpré5ad6pré5imipré5itípréach5páin4t5pór4t3ar2bh3eor3meascr3n4acar3t4earr3t4eá_r3tair_r4bh3itr4neálfr5c6isír5d6úinr5m6ainr5m6isir5t6ailr6bh5isr6d5ínnr6n5eamr6p5óg_r6s3eadra3n4amra5n6ómrabh5t6rai3mhírain5tírais3t4ran4t3árb5a5trrb5ais_rbh5uisrch5la_rcha3d6reast5areic5t6rg5ean4rghair5riacht4rias4t5rins3iúrion2t3rios3t4ris3c4érit5éirrlé5amarlé5igírlé5imirom4p3arost3acrost5alrost6órrra3chórshlua5rt6ainírthé5idrthéad6rua3imirus3c4árá3iteáré5ann_réi5mírrí3ochtrí6ch5eró5l6anrómh5airómh5arrú3itearú5ití_rúch6t5s3c4eogs3t6úins4tralas5ticigs5tile_s6a5mats6iligís6p5annsa5c6assair5d6saist3esbheir5sc3iúilsca5cháscor3b4scáin5tsealbh5seanad5seir4f3sfhear5shail5bsheal5ashean5msheas5tsheic4tsheil6fsheit5sshiúnt3shlios5shlíod5shní5odshní5onsho3mh6shua3l6shá5itíshéir6sshó5idíshó5innshó5itíshú5im_shú5marsiacht5sint5iúsios5t6sleá5d6sléach6slíod5ósmeach5smeart6soch6t5soir6bhspeach5st5eannstaist5sá5inn_sá5ite_séir4s5só5l6ansó5t6aísú5d6arsú5ite_sú5ití_t6annact6annaita5m6áitach6tátag5á5ltain4t3tair2n3tair6g3tairbh3tais5títaisc5etar5ta_tea3g4átea3lantea3m4áteas2t5thaghd3thair4bthair4nthair6gthaist5than2t3thar3n4thar5g6thea3lathor5páthrí3octhua5dathua5imtháir5tthéa3lathéach6ti5míneti5mínitib6éartipi5c6toir2n3trai6m5trea3matri3ghntriach6trua3cátrá5inntsal6v5tsiúnt5táir4s3téacht5téar5t6tóir6setóir6síua3igí_ua3imidua3imisua3inn_ua3iteáua3ití_uai5g6éuain5t4uair5tíualath6uamh6aruana5l6uar5taiuar5tanuic6i5suin6tínuins3iúuir3c4íul6t5asun3g4arun5ga3lun6s5aíur6l3álurca3m4urscar6us4t3alust5ailuthan5tá3itearáilt6eááin4teoéal5taréi3g4iléi3g4ríéi5g6iaéif4earéig3in_éilips3éin6teaéir4g3ií3onna_í4l5ithíghnaí6íleá5icíoga3dáír4eascó3itearó3iteá_óin6se_óis5teoóma3s4óómh5artós6aiseú3iteá_ú4l5agáú5itearúis3c4éúithi5súits3eá", + 8 : "3d4air4b3m4an3d63mh4ac5a3t4ainia4t3i1m4é5ch6aite5ch6raic5d6earb65g6eart_5mhol5t66ch5acha6g5eadar6t5íteas6traláib_ain6te__ais6te__an6lain_as6aim5_asa5m6a_bheo5id_bheo5im_bheo5in_bhreo5f_bhá5ití_bhí5dís_bhí5mis_bhí5oda_bhí5teá_breo5id_breo5im_char6tá_chaí5gí_chaí5tí_chló5id_chló5im_dhreo5f_dhó5ití_dreach5_dreo5id_dreo5im_dó5ite__feo5idí_ghair5t_hail6te_hair6ní_hais5ce_haist6i_hal4t3a_hal6t5á_hala5m6_has6al__heal4t3_heis6il_him6ire_háir5ge_háir5gí_héa3g6ó_héad6ar_héi5dea_híocht6_in6d5ia_in6ste__iomáin5_lach6t5_leat6aí_lé5ann__lí5omar_maí5oma_maí5teá_mhan4t3_mhar6l5_mhaí5gí_mhaí5mi_mhaí5od_mhaí5on_mhaí5tí_naío5l6_ndó5idí_neacht5_oir4n3e_oir6n5i_rua5im__rí6ocha_searbh5_sní5oma_tach6t5_uas6ala_uirthi5_áil6te__éi5geara4d3óinna5n6áisea5t6aintabh6aileacha6d5áaeilí5teagair5n6ain6teanair6bh3rairf5eanais5teogais6ti5saisi3n4éal4ainneal4f3airal6t5óidal6t5óimal6t5óinamhais6tanc4airearach6t5as6alaitas6t5aisasa5maitasta5r6óathrí5gíaío5l6anba5s6áirbascarn5beo5iteabhain3t4bheir5tíbhia5ta_bhia5tacbhin6s3ebhin6t5ebhion5góbhol6ta_bhran6d5bhá5iteábhó5l6acbia5t6acbia5t6aíbol6t5aíbrío3mh4bua5ite_caidh5necair6d5ícair6t5echair6d5chais5t6chearbh6cheas6t5cheir5m6chlas6p5chlocht6chreach5chrua5imchrá5innchrá5itíchríoch5chuacht6cineach5cis3t6incis5tearcreacht6cruacht6cul6t5aidagas5c6deil6te_dh6l5eandhear5badhear5t6dhearbh5dheilbh5dhlío5dódhoir4n5dhos5caídlam5pa_do5chaiddoch6t5adtach6t5dtrá5itídtéit5eadéidlia5ea3s4áirea4d3óineal4t3acealbh5aceam4p3lóean6táileil5tearein3t4eáeir5m6íteis6ean_eis6ilideisc5eaceo5iteareog4achtfaistic4fear5t6afeil6te_feo5iteafheis5c6fheo5idífhol6ta_fhuir4s3fhéacht6friocht4fua5iteafua6fairgair4n3egais5teagais5teágas5c6argcar6t5agcaí5teágcló5inngeal6ta_gharbh5ághrá5itígrama5d6grá5inn_ha5s6áirhad6aimhhaidh5nehain6tínhais5tichan6lainhar6s5achas6p5aíhast5aithaít5eachbheo5idhbheo5imhbheo5inheal6ta_heo5iteahfeo5idíhghair5thiach5t6hin4t5iúhin6d5iahin6ste_hineach5his3t6inhis5tearhléacht5hoch6t5ahost5áinhran5g6óhruacht6hrá3th4óhthorth5huil5c6ihéi5gearhéidlia5hó5l6aini5s6íte_ia3l4ainiacht5aíialacht4imeacht5inea5maíirscart6isc5eannisearbh6l4t3eannl6bh5án_lao5ire_lao5itealao5iteáleach6táleicead5lian4tacling6te_liú5d6arliú5ití_lámhach5lé3ad4arlé5imid_léalaim5mai3n4idmai5l6ítmain6t5ímaini3c4mais5teomaít5eacmbreo5idmbreo5immbreo5inmhain5temhain5timhar3t4amhar6c5rmhea5daimhea5dasmhead5armhear5c6mheas3t6mheir6f5mion4t5ana3ch4annach6ainnai5l6ínnais5teondreach5ndreo5idndreo5imndreo5inndó5ite_nea5s6árngear3t4noscail4nua5iteanór6t5asodhearm5oghair5toir6bhigoir6n5itois4t5ínois5c4eáomhair5ton6t5ailospairt4pair4n3epais3t6ipan6t5alparai3s4phana5m6pheilbh6phin6se_phion6t5phréach5phór6t5apléacht6pré5iteapréacht6r5n6óin_r6bh5easr6d5achtra3l4aíora5l6aícrais4eolrama5dacrama5daírbhá5charchar5t6rdhó5itíreo5ite_rla5m6ánrn5eoirern5eáiltrthé5igírthé5imirthé5itíruch3t4órábh4ailrío5mharrú3d4ar_s3c4airds5c6eoigs5eanna_sa3l4ainsaigh6d5sain6t5esc3ar3n4scréach5sghair5tshair5d6shearbh5sheir6f3shní5omashá5ite_shú5d6arshú5ití_sléacht5smeacht6so5chaidspair4n5sá5iteá_só5l6aint3ear3n4tais5teátaist5iltea5lainthach6t5thairbh5thairn5ethar5t6athead5astheas4t5thlua5dathoir4n3thrá5innthéacht5thóir6sethóir6sítsearbh5tua5iteatá5th6aruair3c4íuar5taí_urscart5á6im5iseéi3g4ealéi5d6reoéir6s5eáí4ch3ealí6th5oiníleá5chaór6t5air", + 9 : "5d6eannai5d6eannas_ain6t5ín_bhreo5id_bhreo5im_bhreo5in_bhá5ite__bhí5omar_car6t5ar_chaí5teá_chló5inn_chár5ta__dhreach5_dhreo5id_dhreo5im_dhreo5in_dhó5ite__fhrioch5_fhua5im__hain6te__hais5tea_hais5tig_hoir6n5i_háil6te__mair5tí__mar6s5ac_mar6s5ai_mhar6sa__mhaí5oma_mhaí5te__mhaí5teá_phor5t6r_shá5inn__spléach5_thrá5ití_théit5ea_áil6t5eaair4t5éisair6f5in_ais5t6ín_bas5c6ar6bhol6t5aíbhrío5mh4bhua5ite_bia5t6aigbua5itearchreacht6cim6p5ínícineacht6cleach6t5crua5iteacuach5taídheil6te_dho5chaideal6t5aigeil6t5eaceil6t5eanfhear5t6afheil6te_fhriocht6fhua5iteafua6f5araghair4n5eghais5teaghais5teághrá5inn_har6s5aigharai5s6íhia5t6aighia5t6aí_hineacht6hleach6t5hrua5iteahul6t5aisháint5eacioch5t4ógl4bh5áin_ldeighil6lua5itearlámhacht6mais5t6ínmear5t6aimhaini5c4mhion6ta_mlua5iteandreacht6nt5a5l6únnua5ch4anphais5t6iphréacht6rthé5itearua5itearscréacht6seach6t5ashaigh6d5sho5chaidshá5iteá_tais5tearthair6is_thua5iteauaith6i5sáis5t6íní", + 10 : "6t5a5l6úin_char6t5ar_cheil6te__dhreacht6_fhua6fair_fhua6fara_geal6t5aí_hais5t6eo_háil6t5ea_mhais6te__mhais6tí__mhion6t5a_séa5l6aincáin6t5eachais5t6eorhas5car6n5hrioch5t6áioch5t6óigmhion6t5aísheach6t5ashéa5l6ain" + }, + patternChars : "_abcdefghilmnoprstuvwxyzáéíóú", + patternArrayLength : 150059, + valueStoreLength : 29372 +}; From 0c83945f568f327541831adb381c28c66ed99c8b Mon Sep 17 00:00:00 2001 From: mnater Date: Fri, 11 Dec 2015 19:52:16 +0100 Subject: [PATCH 35/86] Add support for Irish --- mergeAndPack.html | 1 + 1 file changed, 1 insertion(+) diff --git a/mergeAndPack.html b/mergeAndPack.html index 9974707..76ff234 100644 --- a/mergeAndPack.html +++ b/mergeAndPack.html @@ -981,6 +981,7 @@

      mergeAndPack Eesti (Estonian)
    • +
    • From d21c37ca63ff2c993d7a274913bc8c71fced2d66 Mon Sep 17 00:00:00 2001 From: mnater Date: Fri, 11 Dec 2015 20:10:23 +0100 Subject: [PATCH 36/86] Add test for Irish --- testsuite/test6.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testsuite/test6.html b/testsuite/test6.html index 5a3ccd7..ac69427 100644 --- a/testsuite/test6.html +++ b/testsuite/test6.html @@ -22,7 +22,7 @@ if (parent != window) { Hyphenator.config({ 'onhyphenationdonecallback': function () { - var i, last = 25, t1, t2, r = true, + var i, last = 26, t1, t2, r = true, desc = document.getElementById('desc').firstChild.data, msg = { desc: desc, @@ -135,5 +135,8 @@

      ro

      et

      Tüpograafia ehk trükikunst on trükiste valmistamise oskus, täpsemini sõnastatult trükimärkide kujundamise ja paigutamise kunst ja tehnika.

      Tüpog|raa|fia ehk trü|ki|kunst on trükiste val|mis|ta|mise oskus, täp|se|mini sõnas|ta|tult trü|ki|mär|kide kujun|da|mise ja pai|gu|ta|mise kunst ja teh|nika.

      +

      ga

      +

      Dearadh foirmeacha na litreacha le húsáid mar chló-aghaidheanna, agus roghnú na gcló-aghaidheanna i gcomhair cáipéisí clóchurtha.

      +

      Dear|adh foirm|eacha na lit|reacha le húsáid mar chló-aghaidh|eanna, agus rogh|nú na gcló-aghaidh|eanna i gcomh|air cáip|éisí cló|chur|tha.

      \ No newline at end of file From 572a0867fe59587ddc9b79ca2c80f58b844a8c65 Mon Sep 17 00:00:00 2001 From: mnater Date: Fri, 11 Dec 2015 21:39:35 +0100 Subject: [PATCH 37/86] Add API.txt --- API.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 API.txt diff --git a/API.txt b/API.txt new file mode 100644 index 0000000..c09e1f4 --- /dev/null +++ b/API.txt @@ -0,0 +1,13 @@ +Hyphenator.config({ + classnames: { + cn1: { + hyphens: "none | auto | all", //default: auto + hyphenate-character: "auto | ", //default: soft hyphen + hyphenate-limit-chars: "auto | {1,3}", //default: 6 2 2 (values from patterns resp) + orphancontrol: "auto | [1-3]", //default: 1 + defaultLanguage: "auto | ", //default: auto (asks user) + unhide: "auto | wait | progressive" //default: wait + }, + ... + } +}); \ No newline at end of file From f75ee1c90d71081049d4087af8dff77534369b75 Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 14 Dec 2015 17:23:23 +0100 Subject: [PATCH 38/86] Add API for leftmin/rightmin --- Hyphenator.js | 39 +++++++++++++++++++++++++++++ testsuite/index.html | 3 ++- testsuite/test121.html | 2 +- testsuite/test122.html | 56 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 testsuite/test122.html diff --git a/Hyphenator.js b/Hyphenator.js index 2370409..f558546 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -591,6 +591,28 @@ Hyphenator = (function (window) { */ var min = 6; + /** + * @member {number} Hyphenator~leftmin + * @desc + * A number wich indicates the minimal length of characters before the first hyphenation. + * This value is only used if it is greater than the value in the pattern file. + * @default given by pattern file + * @access private + * @see {@link Hyphenator.config} + */ + var leftmin = 0; + + /** + * @member {number} Hyphenator~rightmin + * @desc + * A number wich indicates the minimal length of characters after the last hyphenation. + * This value is only used if it is greater than the value in the pattern file. + * @default given by pattern file + * @access private + * @see {@link Hyphenator.config} + */ + var rightmin = 0; + /** * @member {number} Hyphenator~orphanControl * @desc @@ -2079,6 +2101,12 @@ Hyphenator = (function (window) { if (enableReducedPatternSet) { lo.redPatSet = {}; } + if (leftmin > lo.leftmin) { + lo.leftmin = leftmin; + } + if (rightmin > lo.rightmin) { + lo.rightmin = rightmin; + } //add exceptions from the pattern file to the local 'exceptions'-obj if (lo.hasOwnProperty('exceptions')) { Hyphenator.addExceptions(lang, lo.exceptions); @@ -2108,6 +2136,7 @@ Hyphenator = (function (window) { lo.genRegExp = new RegExp('(' + wrd + ')|(' + url + ')|(' + mail + ')', 'gi'); lo.prepared = true; } + console.log(lo); } /**** @@ -3140,6 +3169,16 @@ Hyphenator = (function (window) { onAfterWordHyphenation = obj[key]; } break; + case 'leftmin': + if (assert('leftmin', 'number')) { + leftmin = obj[key]; + } + break; + case 'rightmin': + if (assert('rightmin', 'number')) { + rightmin = obj[key]; + } + break; default: onError(new Error('Hyphenator.config: property ' + key + ' not known.')); } diff --git a/testsuite/index.html b/testsuite/index.html index 25f2181..1574f43 100644 --- a/testsuite/index.html +++ b/testsuite/index.html @@ -195,7 +195,8 @@

      The Hyphenator Testsuite

      {exec: true, path: 'test118.html'}, {exec: true, path: 'test119.html'}, {exec: true, path: 'test120.html'}, - {exec: true, path: 'test121.html'} + {exec: true, path: 'test121.html'}, + {exec: true, path: 'test122.html'} ], testframe = document.getElementById('testframe'), currentTest = 1, total = 'passed'; diff --git a/testsuite/test121.html b/testsuite/test121.html index 89b05c5..1a7f0e4 100644 --- a/testsuite/test121.html +++ b/testsuite/test121.html @@ -38,7 +38,7 @@ -

      <<- index | <- Prev | Next ->

      +

      <<- index | <- Prev | Next ->

      Test 121

      Check issue with ligatures in OpenType-Fonts (issue #239)

      diff --git a/testsuite/test122.html b/testsuite/test122.html new file mode 100644 index 0000000..a83b818 --- /dev/null +++ b/testsuite/test122.html @@ -0,0 +1,56 @@ + + + + + Test 122 + + + + + +

      <<- index | <- Prev | Next ->

      +

      Test 122

      +

      Hyphenate one word restricted by leftmin = 3 and rightmin = 4

      + +

      abbaubar abbaubare abbaubares Abbaubarkeit

      +

      abbaubar abbau|bare abbau|bares Abbau|bar|keit

      + + \ No newline at end of file From 8a960700557d19d9b97bf7395a94b027a40f33ad Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 14 Dec 2015 18:03:26 +0100 Subject: [PATCH 39/86] Add leftmin/rightmin to mergeAndPack --- mergeAndPack.html | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/mergeAndPack.html b/mergeAndPack.html index 76ff234..66a46e2 100644 --- a/mergeAndPack.html +++ b/mergeAndPack.html @@ -643,6 +643,12 @@ $('minwordlength_btn').onclick = function () { toggleInfoBoxDisplay($('minwordlength_box'), this, true); }; + $('leftminlength_btn').onclick = function () { + toggleInfoBoxDisplay($('leftminlength_box'), this, true); + }; + $('rightminlength_btn').onclick = function () { + toggleInfoBoxDisplay($('rightminlength_box'), this, true); + }; $('defaultlanguage_btn').onclick = function () { toggleInfoBoxDisplay($('defaultlanguage_box'), this, true); }; @@ -750,6 +756,8 @@ var urlclassname = $('urlclassname').value; var donthyphenateclassname = $('donthyphenateclassname').value; var minwordlength = $('minwordlength').value; + var leftminlength = $('leftminlength').value; + var rightminlength = $('rightminlength').value; var defaultlanguage = $('defaultlanguage').value; var hyphenchar = $('hyphenchar').value; var urlhyphenchar = $('urlhyphenchar').value; @@ -792,6 +800,12 @@ if(minwordlength !== '') { config += 'minwordlength : '+minwordlength+',\n\t'; } + if(leftminlength !== '') { + config += 'leftmin : '+leftminlength+',\n\t'; + } + if(rightminlength !== '') { + config += 'rightmin : '+rightminlength+',\n\t'; + } if(defaultlanguage !== '') { config += 'defaultlanguage : \''+defaultlanguage+'\',\n\t'; } @@ -1027,6 +1041,17 @@

      mergeAndPack Don't hyphenate words shorter than this value (leave empty for default value 6) Show-Info Button

      A value lesser than 4 makes no sense. By increasing this value lesser words will be hyphenated, thus, there's a small speed gain.
      + +

      + Show-Info Button +

      +
      This value is only used if it is greater than the value in the pattern file.
      + +

      + Show-Info Button +

      +
      This value is only used if it is greater than the value in the pattern file.
      +

      From d56bc7b51e8f835aac624c0884b4194d43d269c2 Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 14 Dec 2015 23:14:47 +0100 Subject: [PATCH 40/86] Enhance layout --- mergeAndPack.html | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/mergeAndPack.html b/mergeAndPack.html index 66a46e2..48bc81b 100644 --- a/mergeAndPack.html +++ b/mergeAndPack.html @@ -1,10 +1,8 @@ - + Hyphenator – merge+pack - From 616f2f356fbf3fed9a77416d5f40b9cf24a05e1b Mon Sep 17 00:00:00 2001 From: mnater Date: Wed, 11 May 2016 15:24:51 +0200 Subject: [PATCH 48/86] Compound words Fixes #261 New setting 'compound': "auto": 'old' behaviour: factory-made -> fac­tory-made "all": factory-made -> fac­tory-[ZWSP]made "hyphen": factory-made -> factory-[ZWSP]made --- testsuite/test123.html | 59 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 testsuite/test123.html diff --git a/testsuite/test123.html b/testsuite/test123.html new file mode 100644 index 0000000..8950be8 --- /dev/null +++ b/testsuite/test123.html @@ -0,0 +1,59 @@ + + + + Hyphenator.js – Test 123 + + + + + + +

      <<- index | <- Prev | Next ->

      +

      Test 123

      +

      Hyphenate compound words only at a hyphen.

      +

      hyphenation-two

      +

      hyphenation-​two

      + + \ No newline at end of file From 2ce2fa7ba0bfa7e981152969a2869277f05e8a96 Mon Sep 17 00:00:00 2001 From: mnater Date: Wed, 11 May 2016 15:31:04 +0200 Subject: [PATCH 49/86] Compound words Fixes #261 New setting 'compound': "auto": 'old' behaviour: factory-made -> fac­tory-made "all": factory-made -> fac­tory-[ZWSP]made "hyphen": factory-made -> factory-[ZWSP]made --- Hyphenator.js | 73 +++++++++++++++++++++++++++++++++++------- testsuite/index.html | 4 ++- testsuite/test122.html | 2 +- 3 files changed, 65 insertions(+), 14 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index fab61fd..6014ad9 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -12,7 +12,7 @@ */ /* The following comment is for JSLint: */ -/*jslint browser: true*/ +/*jslint browser: true, multivar: true*/ /*global Hyphenator window*/ /** @@ -629,6 +629,19 @@ Hyphenator = (function (window) { */ var rightmin = 0; + /** + * @member {number} Hyphenator~rightmin + * @desc + * Control how compound words are hyphenated. + * "auto": factory-made -> fac-tory-made ('old' behaviour of Hyphenator.js) + * "all": factory-made -> fac-tory-[ZWSP]made ('made'.length < minWordLength) + * "hyphen": factory-made -> factory-[ZWSP]made (Zero Width Space inserted after '-' to provide line breaking opportunity) + * @default "auto" + * @access private + * @see {@link Hyphenator.config} + */ + var compound = "auto"; + /** * @member {number} Hyphenator~orphanControl * @desc @@ -2289,6 +2302,45 @@ Hyphenator = (function (window) { return r; }()); + /** + * @method Hyphenator~hyphenateCompound + * @desc + * Treats compound words accordingly to the 'compound' setting + * + * @param {Object} lo A language object (containing the patterns) + * @param {string} lang The language of the word + * @param {string} word The word + * @returns string The (hyphenated) compound word + * @access private + */ + function hyphenateCompound(lo, lang, word) { + var hw, parts, i = 0; + switch (compound) { + case "auto": + parts = word.split('-'); + while (i < parts.length) { + parts[i] = hyphenateWord(lo, lang, parts[i]); + i += 1; + } + hw = parts.join('-'); + break; + case "all": + parts = word.split('-'); + while (i < parts.length) { + parts[i] = hyphenateWord(lo, lang, parts[i]); + i += 1; + } + hw = parts.join('-' + zeroWidthSpace); + break; + case "hyphen": + hw = word.replace('-', '-' + zeroWidthSpace); + break; + default: + onError(new Error('Hyphenator.settings: compound setting "' + compound + '" not known.')); + } + return hw; + } + /** * @method Hyphenator~hyphenateWord * @desc @@ -2296,7 +2348,7 @@ Hyphenator = (function (window) { * * If there's already a {@link Hyphenator~hypen} in the word, the word is returned as it is. * If the word is in the exceptions list or in the cache, it is retrieved from it. - * If there's a '-' hyphenate the parts. + * If there's a '-' it calls Hyphenator~hyphenateCompound * The hyphenated word is returned and (if acivated) cached. * Both special Events onBeforeWordHyphenation and onAfterWordHyphenation are called for the word. * @param {Object} lo A language object (containing the patterns) @@ -2306,9 +2358,7 @@ Hyphenator = (function (window) { * @access private */ function hyphenateWord(lo, lang, word) { - var parts, - i = 0, - pattern = "", + var pattern = "", ww, wwlen, wwhp = wwhpStore, @@ -2339,13 +2389,7 @@ Hyphenator = (function (window) { } else if (lo.exceptions.hasOwnProperty(word)) { //the word is in the exceptions list hw = lo.exceptions[word].replace(/-/g, hyphen); } else if (word.indexOf('-') !== -1) { - //word contains '-' -> hyphenate the parts separated with '-' - parts = word.split('-'); - while (i < parts.length) { - parts[i] = hyphenateWord(lo, lang, parts[i]); - i += 1; - } - hw = parts.join('-'); + hw = hyphenateCompound(lo, lang, word); } else { ww = word.toLowerCase(); if (String.prototype.normalize) { @@ -3163,6 +3207,11 @@ Hyphenator = (function (window) { rightmin = obj[key]; } break; + case 'compound': + if (assert('compound', 'string')) { + compound = obj[key]; + } + break; default: onError(new Error('Hyphenator.config: property ' + key + ' not known.')); } diff --git a/testsuite/index.html b/testsuite/index.html index 1574f43..75fecf3 100644 --- a/testsuite/index.html +++ b/testsuite/index.html @@ -196,7 +196,9 @@

      The Hyphenator Testsuite

      {exec: true, path: 'test119.html'}, {exec: true, path: 'test120.html'}, {exec: true, path: 'test121.html'}, - {exec: true, path: 'test122.html'} + {exec: true, path: 'test122.html'}, + {exec: true, path: 'test123.html'} + ], testframe = document.getElementById('testframe'), currentTest = 1, total = 'passed'; diff --git a/testsuite/test122.html b/testsuite/test122.html index a83b818..b4d1b5d 100644 --- a/testsuite/test122.html +++ b/testsuite/test122.html @@ -46,7 +46,7 @@ -

      <<- index | <- Prev | Next ->

      +

      <<- index | <- Prev | Next ->

      Test 122

      Hyphenate one word restricted by leftmin = 3 and rightmin = 4

      From 7bf4d6b288a6adb23e4395f939ed6f64942b2139 Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 12 May 2016 03:14:35 +0200 Subject: [PATCH 50/86] Add new config props to localStorage --- Hyphenator.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Hyphenator.js b/Hyphenator.js index 6014ad9..bfe6723 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -2952,7 +2952,10 @@ Hyphenator = (function (window) { 'useCSS3hyphenation': css3, 'unhide': unhide, 'onbeforewordhyphenation': onBeforeWordHyphenation, - 'onafterwordhyphenation': onAfterWordHyphenation + 'onafterwordhyphenation': onAfterWordHyphenation, + 'leftmin': leftmin, + 'rightmin': rightmin, + 'compound': compound }; storage.setItem('config', window.JSON.stringify(settings)); } From 064eeff9dcea5018f300fb82027e3f2c5516ebb7 Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 16 May 2016 22:24:05 +0200 Subject: [PATCH 51/86] Respect minWordLength in hyphenateCompound --- Hyphenator.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index bfe6723..a287c6b 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -2319,7 +2319,9 @@ Hyphenator = (function (window) { case "auto": parts = word.split('-'); while (i < parts.length) { - parts[i] = hyphenateWord(lo, lang, parts[i]); + if (parts[i].length >= min) { + parts[i] = hyphenateWord(lo, lang, parts[i]); + } i += 1; } hw = parts.join('-'); @@ -2327,7 +2329,9 @@ Hyphenator = (function (window) { case "all": parts = word.split('-'); while (i < parts.length) { - parts[i] = hyphenateWord(lo, lang, parts[i]); + if (parts[i].length >= min) { + parts[i] = hyphenateWord(lo, lang, parts[i]); + } i += 1; } hw = parts.join('-' + zeroWidthSpace); From 3f9ef1efb59ee7c593cae342f700e79792bc85a8 Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 13 Jun 2016 15:50:55 +0200 Subject: [PATCH 52/86] Add test124.html --- testsuite/test123.html | 2 +- testsuite/test124.html | 64 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 testsuite/test124.html diff --git a/testsuite/test123.html b/testsuite/test123.html index 8950be8..7eb78a6 100644 --- a/testsuite/test123.html +++ b/testsuite/test123.html @@ -50,7 +50,7 @@ -

      <<- index | <- Prev | Next ->

      +

      <<- index | <- Prev | Next ->

      Test 123

      Hyphenate compound words only at a hyphen.

      hyphenation-two

      diff --git a/testsuite/test124.html b/testsuite/test124.html new file mode 100644 index 0000000..afeed0b --- /dev/null +++ b/testsuite/test124.html @@ -0,0 +1,64 @@ + + + + Hyphenator.js – Test 124 + + + + + + +

      <<- index | <- Prev | Next ->

      +

      Test 124

      +

      Use Loader to load Hyphenator, change content after 2s, hyphenate new content.

      + +

      Test1

      +

      A hyphenation algorithm is a set of rules that decides at which points a word can be broken over two lines with a hyphen.

      +

      Ref1

      +

      A hy|phen|ation al|go|rithm is a set of rules that de|cides at which points a word can be bro|ken over two lines with a hy|phen.

      + +

      Test2

      +

      A hyphenation algorithm is a set of rules that decides at which points a word can be broken over two lines with a hyphen.

      +

      Ref2

      +

      A hy|phen|ation al|go|rithm is a set of rules that de|cides at which points a word can be bro|ken over two lines with a hy|phen.

      +

      To allow more ef|fi|cient usage of paper, more reg|u|lar ap|pear|ance of right-side mar|gins with|out re|quir|ing spac|ing ad|just|ments, and to elim|i|nate the need to erase hand-writ|ten long words begun near the end of a line that do not fit, words may be di|vided at the near|est break|point be|tween syl|la|bles and a hy|phen in|serted to in|di|cate that the let|ters form a word frag|ment, not a word.

      + + \ No newline at end of file From 49e9595b837005dc88ed3b87c91fdcee201ff205 Mon Sep 17 00:00:00 2001 From: mnater Date: Tue, 21 Jun 2016 21:03:28 +0200 Subject: [PATCH 53/86] fixes #264 --- Hyphenator.js | 38 ++++++++++---------------------------- testsuite/test80.html | 6 ++++-- testsuite/test81.html | 6 ++++-- 3 files changed, 18 insertions(+), 32 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index a287c6b..25f7e57 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -2696,35 +2696,16 @@ Hyphenator = (function (window) { * @param {string} part - The sring where orphans have to be removed * @access private */ - function controlOrphans(part) { - var h, r; - switch (hyphen) { - case '|': - h = '\\|'; - break; - case '+': - h = '\\+'; - break; - case '*': - h = '\\*'; - break; - default: - h = hyphen; - } - //strip off blank space at the end (omitted closing tags) - part = part.replace(/[\s]*$/, ''); - if (orphanControl >= 2) { - //remove hyphen points from last word - r = part.split(' '); - r[1] = r[1].replace(new RegExp(h, 'g'), ''); - r[1] = r[1].replace(new RegExp(zeroWidthSpace, 'g'), ''); - r = r.join(' '); + function controlOrphans(ignore, leadingWhiteSpace, lastWord, trailingWhiteSpace) { + var h; + //escape hyphen + if (".\\+*?[^]$(){}=!<>|:-".indexOf(hyphen) !== -1) { + h = "\\" + hyphen; } - if (orphanControl === 3) { - //replace spaces by non breaking spaces - r = r.replace(/[\ ]+/g, String.fromCharCode(160)); + if (orphanControl === 3 && leadingWhiteSpace === " ") { + leadingWhiteSpace = String.fromCharCode(160); } - return r; + return leadingWhiteSpace + lastWord.replace(new RegExp(h + "|" + zeroWidthSpace, 'g'), '') + trailingWhiteSpace; } /** @@ -2765,7 +2746,8 @@ Hyphenator = (function (window) { && n.data.length >= min) { //longer then min n.data = n.data.replace(lo.genRegExp, hyphenate); if (orphanControl !== 1) { - n.data = n.data.replace(/[\S]+\ [\S]+[\s]*$/, controlOrphans); + //prevent last word from being hyphenated + n.data = n.data.replace(/(\ *)(\S+)(\s*)$/, controlOrphans); } } i += 1; diff --git a/testsuite/test80.html b/testsuite/test80.html index e8d50bb..a6f6e7b 100644 --- a/testsuite/test80.html +++ b/testsuite/test80.html @@ -50,8 +50,10 @@

      Test 80

      Orphancontrol level 2

      -

      «Wunderschönen guten Tag allerseits», rief Caspar fröhlich in den Raum hinein. Sein Vater aber grummelte: «Himmelherrgott, so viele Leute hatte ich nicht erwartet!»

      -

      «Wun|der|schö|nen guten Tag al|ler|seits», rief Cas|par fröh|lich in den Raum hin|ein. Sein Vater aber grum|mel|te: «Him|mel|herr|gott, so viele Leute hatte ich nicht erwartet!»

      +

      «Wunderschönen guten Tag allerseits», rief Caspar fröhlich in den Raum hinein. Sein Vater aber grummelte: «Himmelherrgott, so viele Leute hatte ich nicht erwartet!»
      + Quellennachweis: Weblink Einzelwort

      +

      «Wun|der|schö|nen guten Tag al|ler|seits», rief Cas|par fröh|lich in den Raum hin|ein. Sein Vater aber grum|mel|te: «Him|mel|herr|gott, so viele Leute hatte ich nicht erwartet!»
      + Quellennachweis: Weblink Einzelwort

      \ No newline at end of file diff --git a/testsuite/test81.html b/testsuite/test81.html index dd65a55..8d8aa96 100644 --- a/testsuite/test81.html +++ b/testsuite/test81.html @@ -51,8 +51,10 @@

      Test 81

      Orphancontrol level 3.

      -

      «Wunderschönen guten Tag allerseits», rief Caspar fröhlich in den Raum hinein. Sein Vater aber grummelte: «Himmelherrgott, so viele Leute hatte ich nicht erwartet!»

      -

      «Wun|der|schö|nen guten Tag al|ler|seits», rief Cas|par fröh|lich in den Raum hin|ein. Sein Vater aber grum|mel|te: «Him|mel|herr|gott, so viele Leute hatte ich nicht erwartet!»

      +

      «Wunderschönen guten Tag allerseits», rief Caspar fröhlich in den Raum hinein. Sein Vater aber grummelte: «Himmelherrgott, so viele Leute hatte ich nicht erwartet!»
      + Quellennachweis: Weblink Einzelwort

      +

      «Wun|der|schö|nen guten Tag al|ler|seits», rief Cas|par fröh|lich in den Raum hin|ein. Sein Vater aber grum|mel|te: «Him|mel|herr|gott, so viele Leute hatte ich nicht erwartet!»
      + Quellennachweis: Weblink Einzelwort

      \ No newline at end of file From c54dfad41b9a24648108e3f48f7e0d070181312b Mon Sep 17 00:00:00 2001 From: mnater Date: Tue, 21 Jun 2016 21:31:19 +0200 Subject: [PATCH 54/86] Small fixes - nicer escaping of hyphenchar in regexps - fixed tests after last commit --- Hyphenator.js | 30 ++++++------------------------ testsuite/test109.html | 3 ++- testsuite/test110.html | 3 ++- testsuite/test81.html | 5 +++-- testsuite/test89.html | 1 + 5 files changed, 14 insertions(+), 28 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index 25f7e57..2757c97 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -2492,31 +2492,13 @@ Hyphenator = (function (window) { */ function removeHyphenationFromElement(el) { var h, u, i = 0, n; - switch (hyphen) { - case '|': - h = '\\|'; - break; - case '+': - h = '\\+'; - break; - case '*': - h = '\\*'; - break; - default: - h = hyphen; + //escape hyphen + if (".\\+*?[^]$(){}=!<>|:-".indexOf(hyphen) !== -1) { + h = "\\" + hyphen; } - switch (urlhyphen) { - case '|': - u = '\\|'; - break; - case '+': - u = '\\+'; - break; - case '*': - u = '\\*'; - break; - default: - u = urlhyphen; + //escape hyphen + if (".\\+*?[^]$(){}=!<>|:-".indexOf(urlhyphen) !== -1) { + u = "\\" + urlhyphen; } n = el.childNodes[i]; while (!!n) { diff --git a/testsuite/test109.html b/testsuite/test109.html index 16e82f2..8430bf0 100644 --- a/testsuite/test109.html +++ b/testsuite/test109.html @@ -51,6 +51,7 @@

      Test 109

      Orphancontrol level 2 with no end tags

      «Wunderschönen guten Tag allerseits», rief Caspar fröhlich in den Raum hinein. Sein Vater aber grummelte: «Himmelherrgott, so viele Leute hatte ich nicht erwartet!» -

      «Wun|der|schö|nen guten Tag al|ler|seits», rief Cas|par fröh|lich in den Raum hin|ein. Sein Vater aber grum|mel|te: «Him|mel|herr|gott, so viele Leute hatte ich nicht erwartet!»

      +

      «Wun|der|schö|nen guten Tag al|ler|seits», rief Cas|par fröh|lich in den Raum hin|ein. Sein Vater aber grum|mel|te: «Him|mel|herr|gott, so viele Leute hatte ich nicht erwartet!» +

      \ No newline at end of file diff --git a/testsuite/test110.html b/testsuite/test110.html index 92e8332..1adc76e 100644 --- a/testsuite/test110.html +++ b/testsuite/test110.html @@ -51,6 +51,7 @@

      Test 110

      Orphancontrol level 3 with no end tags

      «Wunderschönen guten Tag allerseits», rief Caspar fröhlich in den Raum hinein. Sein Vater aber grummelte: «Himmelherrgott, so viele Leute hatte ich nicht erwartet!» -

      «Wun|der|schö|nen guten Tag al|ler|seits», rief Cas|par fröh|lich in den Raum hin|ein. Sein Vater aber grum|mel|te: «Him|mel|herr|gott, so viele Leute hatte ich nicht erwartet!»

      +

      «Wun|der|schö|nen guten Tag al|ler|seits», rief Cas|par fröh|lich in den Raum hin|ein. Sein Vater aber grum|mel|te: «Him|mel|herr|gott, so viele Leute hatte ich nicht erwartet!» +

      \ No newline at end of file diff --git a/testsuite/test81.html b/testsuite/test81.html index 8d8aa96..6392b8c 100644 --- a/testsuite/test81.html +++ b/testsuite/test81.html @@ -34,6 +34,7 @@ } else { msg.result = 'failed'; } + console.log(msg); parent.postMessage(JSON.stringify(msg), window.location.href); } }); @@ -52,9 +53,9 @@

      Test 81

      Orphancontrol level 3.

      «Wunderschönen guten Tag allerseits», rief Caspar fröhlich in den Raum hinein. Sein Vater aber grummelte: «Himmelherrgott, so viele Leute hatte ich nicht erwartet!»
      - Quellennachweis: Weblink Einzelwort

      + Quellennachweis: Weblink Einzelwort

      «Wun|der|schö|nen guten Tag al|ler|seits», rief Cas|par fröh|lich in den Raum hin|ein. Sein Vater aber grum|mel|te: «Him|mel|herr|gott, so viele Leute hatte ich nicht erwartet!»
      - Quellennachweis: Weblink Einzelwort

      + Quellennachweis: Weblink Einzelwort

      \ No newline at end of file diff --git a/testsuite/test89.html b/testsuite/test89.html index 47ae9c2..02666bf 100644 --- a/testsuite/test89.html +++ b/testsuite/test89.html @@ -25,6 +25,7 @@ -Moz-hyphens:auto; -webkit-hyphens:auto; -ms-hyphens:auto; + -o-hyphens:auto; } .hyph[lang='en'] { -webkit-locale: 'en'; From fbb04b0b1496815cbe2bb480a69c071ada0a6b9b Mon Sep 17 00:00:00 2001 From: mnater Date: Wed, 22 Jun 2016 13:12:40 +0200 Subject: [PATCH 55/86] Fix controlOrphans --- Hyphenator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hyphenator.js b/Hyphenator.js index 2757c97..0c32db4 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -2679,7 +2679,7 @@ Hyphenator = (function (window) { * @access private */ function controlOrphans(ignore, leadingWhiteSpace, lastWord, trailingWhiteSpace) { - var h; + var h = hyphen; //escape hyphen if (".\\+*?[^]$(){}=!<>|:-".indexOf(hyphen) !== -1) { h = "\\" + hyphen; From f5ec84dd03cb9e75dc43fd4d0d9f445be3780e92 Mon Sep 17 00:00:00 2001 From: Mathias Nater Date: Wed, 3 Aug 2016 23:02:35 +0200 Subject: [PATCH 56/86] fixes #267 --- Hyphenator.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Hyphenator.js b/Hyphenator.js index 0c32db4..2e602ab 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -2495,10 +2495,14 @@ Hyphenator = (function (window) { //escape hyphen if (".\\+*?[^]$(){}=!<>|:-".indexOf(hyphen) !== -1) { h = "\\" + hyphen; + } else { + h = hyphen; } //escape hyphen if (".\\+*?[^]$(){}=!<>|:-".indexOf(urlhyphen) !== -1) { u = "\\" + urlhyphen; + } else { + u = urlhyphen; } n = el.childNodes[i]; while (!!n) { @@ -2683,6 +2687,8 @@ Hyphenator = (function (window) { //escape hyphen if (".\\+*?[^]$(){}=!<>|:-".indexOf(hyphen) !== -1) { h = "\\" + hyphen; + } else { + h = hyphen; } if (orphanControl === 3 && leadingWhiteSpace === " ") { leadingWhiteSpace = String.fromCharCode(160); From cca7c8cf27459a6835251353e1d684866bd63882 Mon Sep 17 00:00:00 2001 From: Mathias Nater Date: Mon, 15 Aug 2016 21:41:16 +0200 Subject: [PATCH 57/86] add tests 124 and 125 --- testsuite/index.html | 4 ++- testsuite/test124.html | 2 +- testsuite/test125.html | 69 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 testsuite/test125.html diff --git a/testsuite/index.html b/testsuite/index.html index 75fecf3..bf3809c 100644 --- a/testsuite/index.html +++ b/testsuite/index.html @@ -197,7 +197,9 @@

      The Hyphenator Testsuite

      {exec: true, path: 'test120.html'}, {exec: true, path: 'test121.html'}, {exec: true, path: 'test122.html'}, - {exec: true, path: 'test123.html'} + {exec: true, path: 'test123.html'}, + {exec: false, path: 'test124.html'}, + {exec: true, path: 'test125.html'} ], testframe = document.getElementById('testframe'), diff --git a/testsuite/test124.html b/testsuite/test124.html index afeed0b..4d14e44 100644 --- a/testsuite/test124.html +++ b/testsuite/test124.html @@ -46,7 +46,7 @@ -

      <<- index | <- Prev | Next ->

      +

      <<- index | <- Prev | Next ->

      Test 124

      Use Loader to load Hyphenator, change content after 2s, hyphenate new content.

      diff --git a/testsuite/test125.html b/testsuite/test125.html new file mode 100644 index 0000000..faef10c --- /dev/null +++ b/testsuite/test125.html @@ -0,0 +1,69 @@ + + + + Hyphenator.js – Test 125 + + + + + + +

      <<- index | <- Prev | Next ->

      +

      Test 125

      +

      Check if turning hyphenation off/on works with escaped unicode (\u200a).

      + +

      To allow more efficient usage of paper, more regular appearance of right-side margins without requiring spacing adjustments, and to eliminate the need to erase hand-written long words begun near the end of a line that do not fit, words may be divided at the nearest breakpoint between syllables and a hyphen inserted to indicate that the letters form a word fragment, not a word.

      +

      To allow more efficient usage of paper, more regular appearance of right-side margins without requiring spacing adjustments, and to eliminate the need to erase hand-written long words begun near the end of a line that do not fit, words may be divided at the nearest breakpoint between syllables and a hyphen inserted to indicate that the letters form a word fragment, not a word.

      +

      To allow more ef fi cient usage of paper, more reg u lar ap pear ance of right-side mar gins with out re quir ing spac ing ad just ments, and to elim i nate the need to erase hand-writ ten long words begun near the end of a line that do not fit, words may be di vided at the near est break point be tween syl la bles and a hy phen in serted to in di cate that the let ters form a word frag ment, not a word.

      + + \ No newline at end of file From 3f2a03c6ae0f19ef550b5e45277177d5efe7a441 Mon Sep 17 00:00:00 2001 From: Mathias Nater Date: Mon, 15 Aug 2016 21:43:17 +0200 Subject: [PATCH 58/86] fixes #268 --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index fd48012..d270b25 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "Hyphenator", - "version": "5.0.0(devel)", + "version": "5.1.0", "main": "Hyphenator.js", "ignore": [ "favicon.ico", From 8a7d7202cfc02847b95317f2462b410b9bdbee6b Mon Sep 17 00:00:00 2001 From: Mathias Nater Date: Mon, 15 Aug 2016 22:18:08 +0200 Subject: [PATCH 59/86] update instructions --- mergeAndPack.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mergeAndPack.html b/mergeAndPack.html index 48bc81b..f91e795 100644 --- a/mergeAndPack.html +++ b/mergeAndPack.html @@ -1336,7 +1336,7 @@

      mergeAndPack

      You are using Hyphenator_Loader.js. Therefor you have to create two script files as described below:

      -

      Copy the packed script from the first output field below as is to a new text-file, give it a name (e.g. "hyphenator.js". Make sure this is the same name as you configured Hyphenator_Loader.js for.) and include it in your website (<script src="hyphenator.js" type="text/javascript"></script>).

      +

      Copy the packed script from the first output field below as is to a new text-file, give it a name (e.g. "hyphenator.js". Make sure this is the same name as you configured Hyphenator_Loader.js for). Since patterns are not packed in the script, the patternscode> subdirectory must be available, too.

      Note: You are not allowed to remove the licensing at the beginning of the script!

      From eb9bd7321edf84dddb0463d5dcb75100bc90c9f7 Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 8 Sep 2016 23:36:28 +0200 Subject: [PATCH 60/86] add tests --- testsuite/index.html | 5 +++- testsuite/test124.html | 46 ++++++++++++++++++++++++---- testsuite/test125.html | 68 ++++++++++++++++++++++++++++++++++++++++++ testsuite/test126.html | 55 ++++++++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 6 deletions(-) create mode 100644 testsuite/test125.html create mode 100644 testsuite/test126.html diff --git a/testsuite/index.html b/testsuite/index.html index 75fecf3..a73db50 100644 --- a/testsuite/index.html +++ b/testsuite/index.html @@ -197,7 +197,10 @@

      The Hyphenator Testsuite

      {exec: true, path: 'test120.html'}, {exec: true, path: 'test121.html'}, {exec: true, path: 'test122.html'}, - {exec: true, path: 'test123.html'} + {exec: true, path: 'test123.html'}, + {exec: true, path: 'test124.html'}, + {exec: true, path: 'test125.html'}, + {exec: true, path: 'test126.html'} ], testframe = document.getElementById('testframe'), diff --git a/testsuite/test124.html b/testsuite/test124.html index afeed0b..49b371f 100644 --- a/testsuite/test124.html +++ b/testsuite/test124.html @@ -33,22 +33,58 @@

      <<- index | <- Prev | Next ->

      Test 124

      -

      Use Loader to load Hyphenator, change content after 2s, hyphenate new content.

      +

      Use Loader to load Hyphenator, change content after 1s, hyphenate new content.

      Test1

      A hyphenation algorithm is a set of rules that decides at which points a word can be broken over two lines with a hyphen.

      @@ -59,6 +95,6 @@

      Test2

      A hyphenation algorithm is a set of rules that decides at which points a word can be broken over two lines with a hyphen.

      Ref2

      A hy|phen|ation al|go|rithm is a set of rules that de|cides at which points a word can be bro|ken over two lines with a hy|phen.

      -

      To allow more ef|fi|cient usage of paper, more reg|u|lar ap|pear|ance of right-side mar|gins with|out re|quir|ing spac|ing ad|just|ments, and to elim|i|nate the need to erase hand-writ|ten long words begun near the end of a line that do not fit, words may be di|vided at the near|est break|point be|tween syl|la|bles and a hy|phen in|serted to in|di|cate that the let|ters form a word frag|ment, not a word.

      +

      To allow more ef|fi|cient usage of paper, more reg|u|lar ap|pear|ance of right-side mar|gins with|out re|quir|ing spac|ing ad|just|ments, and to elim|i|nate the need to erase hand-writ|ten long words begun near the end of a line that do not fit, words may be di|vided at the near|est break|point be|tween syl|la|bles and a hy|phen in|serted to in|di|cate that the let|ters form a word frag|ment, not a word.

      \ No newline at end of file diff --git a/testsuite/test125.html b/testsuite/test125.html new file mode 100644 index 0000000..b1e71e0 --- /dev/null +++ b/testsuite/test125.html @@ -0,0 +1,68 @@ + + + + Hyphenator.js – Test 125 + + + + + + + +

      <<- index | <- Prev | Next ->

      +

      Test 125

      +

      Usage of CSS3 hyphenation for content that has been loaded by AJAX.

      +
      +

      +
      +

      Silbentrennung

      +

      +

      Das eng|li|sche Wort “Hy|phen|ation” lässt sich nicht un|be|dingt wört|lich mit «Sil|ben|tren|nung» über|set|zen.

      + + \ No newline at end of file diff --git a/testsuite/test126.html b/testsuite/test126.html new file mode 100644 index 0000000..689cc38 --- /dev/null +++ b/testsuite/test126.html @@ -0,0 +1,55 @@ + + + + Hyphenator.js – Test 126 + + + + + + + +

      <<- index | <- Prev | Next ->

      +

      Test 126

      +

      Load Hyphenator from cdn, patterns should load from there, too (check console)

      + +

      Hyphenation

      +

      Hy|phen|ation

      + + \ No newline at end of file From 65a763adf6fc839df83b63f0908a7796dfb0d0a2 Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 8 Sep 2016 23:37:51 +0200 Subject: [PATCH 61/86] Change getLocality, fixes #275 --- Hyphenator.js | 60 +++++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index 0c32db4..9627882 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -12,7 +12,7 @@ */ /* The following comment is for JSLint: */ -/*jslint browser: true, multivar: true*/ +/*jslint browser: true, multivar: true, single: true*/ /*global Hyphenator window*/ /** @@ -132,6 +132,8 @@ Hyphenator = (function (window) { return r; }()); + + /** * @member {Object} Hyphenator~locality * @desc @@ -141,33 +143,40 @@ Hyphenator = (function (window) { */ var locality = (function getLocality() { var r = { - isBookmarklet: false, - basePath: "//mnater.github.io/Hyphenator/", - isLocal: false - }, - scripts = contextWindow.document.getElementsByTagName('script'), - i = 0, - src, - len = scripts.length, - p, - currScript; - while (i < len) { - currScript = scripts[i]; - if (currScript.hasAttribute("src")) { - src = currScript.src; - p = src.indexOf("Hyphenator.js"); - if (p !== -1) { - r.basePath = src.substring(0, p); - if (src.indexOf("Hyphenator.js?bm=true") !== -1) { - r.isBookmarklet = true; - } - if (window.location.href.indexOf(r.basePath) !== -1) { - r.isLocal = true; - } + isBookmarklet: false, + basePath: "//mnater.github.io/Hyphenator/", + isLocal: false + }; + var fullPath; + function getBasePath(path) { + return path.substring(0, path.lastIndexOf("/") + 1); + } + function findCurrentScript() { + var scripts = contextWindow.document.getElementsByTagName('script'); + var num = scripts.length - 1; + var currScript; + var src; + while (num > 0) { + currScript = scripts[num]; + if (currScript.hasAttribute("src") && currScript.src.indexOf("Hyphenator") !== -1) { + src = currScript.src; break; } + num -= 1; } - i += 1; + return src; + } + if (!!document.currentScript) { + fullPath = document.currentScript.src; + } else { + fullPath = findCurrentScript(); + } + r.basePath = getBasePath(fullPath); + if (fullPath.indexOf("bm=true") !== -1) { + r.isBookmarklet = true; + } + if (window.location.href.indexOf(r.basePath) !== -1) { + r.isLocal = true; } return r; }()); @@ -2865,7 +2874,6 @@ Hyphenator = (function (window) { break; default: s = undefined; - break; } //check for private mode s.setItem('storageTest', '1'); From c88349b9d648eba5191325db07ee8b697fb9e00f Mon Sep 17 00:00:00 2001 From: mnater Date: Fri, 16 Sep 2016 23:31:24 +0200 Subject: [PATCH 62/86] fix test 125 --- testsuite/test125.html | 76 +++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/testsuite/test125.html b/testsuite/test125.html index 86f6f23..560315e 100644 --- a/testsuite/test125.html +++ b/testsuite/test125.html @@ -1,5 +1,5 @@ - + Hyphenator.js – Test 125 @@ -10,59 +10,59 @@ margin-right:25%; } #test { - background-color: #ffd6d6; + background-color: #ffd6d6; } #ref1 { - display: none; + display: none; } #ref2 { - background-color: #d6ffd6; + background-color: #d6ffd6; } -

      <<- index | <- Prev | Next ->

      +

      <<- index | <- Prev | Next ->

      Test 125

      Check if turning hyphenation off/on works with escaped unicode (\u200a).

      -

      To allow more efficient usage of paper, more regular appearance of right-side margins without requiring spacing adjustments, and to eliminate the need to erase hand-written long words begun near the end of a line that do not fit, words may be divided at the nearest breakpoint between syllables and a hyphen inserted to indicate that the letters form a word fragment, not a word.

      -

      To allow more efficient usage of paper, more regular appearance of right-side margins without requiring spacing adjustments, and to eliminate the need to erase hand-written long words begun near the end of a line that do not fit, words may be divided at the nearest breakpoint between syllables and a hyphen inserted to indicate that the letters form a word fragment, not a word.

      +

      To allow more efficient usage of paper, more regular appearance of right-side margins without requiring spacing adjustments, and to eliminate the need to erase hand-written long words begun near the end of a line that do not fit, words may be divided at the nearest breakpoint between syllables and a hyphen inserted to indicate that the letters form a word fragment, not a word.

      +

      To allow more efficient usage of paper, more regular appearance of right-side margins without requiring spacing adjustments, and to eliminate the need to erase hand-written long words begun near the end of a line that do not fit, words may be divided at the nearest breakpoint between syllables and a hyphen inserted to indicate that the letters form a word fragment, not a word.

      To allow more ef fi cient usage of paper, more reg u lar ap pear ance of right-side mar gins with out re quir ing spac ing ad just ments, and to elim i nate the need to erase hand-writ ten long words begun near the end of a line that do not fit, words may be di vided at the near est break point be tween syl la bles and a hy phen in serted to in di cate that the let ters form a word frag ment, not a word.

      \ No newline at end of file From 7cebe0257430cf0c198e9d3173ccc996d348a5b7 Mon Sep 17 00:00:00 2001 From: mnater Date: Sat, 17 Sep 2016 00:02:20 +0200 Subject: [PATCH 63/86] Fixes #276 --- mergeAndPack.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mergeAndPack.html b/mergeAndPack.html index f91e795..ea9a93b 100644 --- a/mergeAndPack.html +++ b/mergeAndPack.html @@ -565,6 +565,7 @@ window.onload = function(){ var ul = navigator.language ? navigator.language.slice(0,2) : navigator.userLanguage.slice(0,2); + var langBox; if(ul) { switch (ul) { case 'en': @@ -574,7 +575,10 @@ ul = 'el-monoton'; break; } - $(ul).checked = true; + langBox = $(ul); + if (langBox) { + $(ul).checked = true; + } } $('alllanguages').onclick = function(){ if(this.checked == true) { From fd47710a94315f0226564074f68da8ea94675865 Mon Sep 17 00:00:00 2001 From: rarila Date: Wed, 30 Nov 2016 10:29:08 +0100 Subject: [PATCH 64/86] Add package.json To start progress on #249 --- package.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..a6a058f --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "hyphenator.js", + "version": "5.1.0", + "description": "Client-side hyphenation of HTML-Documents", + "repository": { + "type": "git", + "url": "git+https://github.com/mnater/Hyphenator.git" + }, + "keywords": [ + "hyphenation" + ], + "author": "Mathias Nater", + "license": "MIT", + "bugs": { + "url": "https://github.com/mnater/Hyphenator/issues" + }, + "homepage": "https://github.com/mnater/Hyphenator#readme" +} From 96343df929211443a4169a2fdd6d0319adef8cde Mon Sep 17 00:00:00 2001 From: mnater Date: Thu, 1 Dec 2016 22:58:02 +0100 Subject: [PATCH 65/86] fixes #287 --- Hyphenator.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index 95a6026..b68fb9d 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -2134,9 +2134,9 @@ Hyphenator = (function (window) { } convertPatternsToArray(lo); if (String.prototype.normalize) { - wrd = '[\\w' + lo.specialChars + lo.specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + wrd = '[\\w' + lo.specialChars + lo.specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}(?!:\\/\\/)'; } else { - wrd = '[\\w' + lo.specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + wrd = '[\\w' + lo.specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}(?!:\\/\\/)'; } lo.genRegExp = new RegExp('(' + wrd + ')|(' + url + ')|(' + mail + ')', 'gi'); lo.prepared = true; @@ -2199,9 +2199,9 @@ Hyphenator = (function (window) { } //Replace genRegExp since it may have been changed: if (String.prototype.normalize) { - tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + Hyphenator.languages[lang].specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + Hyphenator.languages[lang].specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}(?!:\\/\\/)'; } else { - tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}(?!:\\/\\/)'; } Hyphenator.languages[lang].genRegExp = new RegExp('(' + tmp1 + ')|(' + url + ')|(' + mail + ')', 'gi'); if (enableCache) { From 77a4104646e61f3402ba3f00ba730dbf29fcbc3c Mon Sep 17 00:00:00 2001 From: mnater Date: Fri, 2 Dec 2016 00:04:40 +0100 Subject: [PATCH 66/86] hide test124 in Safari --- testsuite/index.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/testsuite/index.html b/testsuite/index.html index 3900333..8d56b0e 100644 --- a/testsuite/index.html +++ b/testsuite/index.html @@ -217,6 +217,12 @@

      The Hyphenator Testsuite

      tests[63] = {exec: false, path: 'test63.xhtml'}; } + if (/safari/i.test(navigator.userAgent) && !/chrome/i.test(navigator.userAgent)) { + tests[124] = {exec: false, path: 'test124.html'}; + } + + console.log(navigator.userAgent); + function addTestResult(name, desc, result) { var dl = document.getElementById('testresults'), template = document.getElementById('template').innerHTML; From c2b0782bc06b8ccb393f6661aaa7e8f9eeaada5a Mon Sep 17 00:00:00 2001 From: mnater Date: Fri, 2 Dec 2016 00:05:18 +0100 Subject: [PATCH 67/86] Set config for JSLint --- Hyphenator_Loader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hyphenator_Loader.js b/Hyphenator_Loader.js index 55268b8..4c8dfd8 100644 --- a/Hyphenator_Loader.js +++ b/Hyphenator_Loader.js @@ -16,7 +16,7 @@ */ /* The following comment is for JSLint: */ -/*jslint browser: true*/ +/*jslint browser: true multivar: true, single: true*/ /*global window Hyphenator*/ var Hyphenator_Loader = (function (window) { From 3991b970f2ed6df87248fc109e1dec44d5021506 Mon Sep 17 00:00:00 2001 From: mnater Date: Fri, 2 Dec 2016 00:10:13 +0100 Subject: [PATCH 68/86] fixes #290 --- Hyphenator.js | 4 ++-- testsuite/test13.html | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index b68fb9d..5fa7904 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -825,8 +825,8 @@ Hyphenator = (function (window) { * A string containing a insane RegularExpression to match URL's * @access private */ - var url = '(?:\\w*:\/\/)?(?:(?:\\w*:)?(?:\\w*)@)?(?:(?:(?:[\\d]{1,3}\\.){3}(?:[\\d]{1,3}))|(?:(?:www\\.|[a-zA-Z]\\.)?[a-zA-Z0-9\\-\\.]+\\.(?:[a-z]{2,4})))(?::\\d*)?(?:\/[\\w#!:\\.?\\+=&%@!\\-]*)*'; - // protocoll usr pwd ip or host tld port path + var url = '(?:\\w*:\/\/)?(?:(?:\\w*:)?(?:\\w*)@)?(?:(?:(?:[\\d]{1,3}\\.){3}(?:[\\d]{1,3}))|(?:(?:www\\.|[a-zA-Z]\\.)?[a-zA-Z0-9\\-\\.]+\\.(?:[a-z]{2,})))(?::\\d*)?(?:\/[\\w#!:\\.?\\+=&%@!\\-]*)*'; + // protocoll usr pwd ip or host tld port path /** * @member {string} Hyphenator~mail diff --git a/testsuite/test13.html b/testsuite/test13.html index e43c967..a6e835b 100644 --- a/testsuite/test13.html +++ b/testsuite/test13.html @@ -65,6 +65,7 @@

      Test 13

      http://radio1.ch/
      http://www.domain.com/?adid=b2plbm5pbmdzLjY1NDM1LjU0MDNAbmluZXNoYXJwLmFwbGl0cmFrLmNvbQ
      http://www.einsehrlangerdomainname.com/
      + http://www.domain.longtld/

      @@ -82,6 +83,7 @@

      Test 13

      http://•radio1.•ch/
      http://•www.•domain.•com/?•adi•d=b2p•lbm5•pbmd•zLjY•1NDM•1LjU•0MDN•Abml•uZXN•oYXJ•wLmF•wbGl•0cmF•rLmN•vbQ
      http://•www.•ein•sehr•lang•erdo•main•name.•com/
      + http://•www.•domain.•longtld/

      From 09ddbd72307306510a5807f08a963695b99e963b Mon Sep 17 00:00:00 2001 From: mnater Date: Fri, 2 Dec 2016 00:25:09 +0100 Subject: [PATCH 69/86] fixes #291 --- Hyphenator.js | 10 +++++-- testsuite/index.html | 3 +- testsuite/test126.html | 2 +- testsuite/test127.html | 65 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 testsuite/test127.html diff --git a/Hyphenator.js b/Hyphenator.js index 5fa7904..a212703 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -3394,7 +3394,7 @@ Hyphenator = (function (window) { /** * @method Hyphenator.toggleHyphenation * @desc - * Checks the current state of the ToggleBox and removes or does hyphenation. + * Checks the current state of Hyphenator.doHyphenation and removes or does hyphenation. * @access public */ function toggleHyphenation() { @@ -3405,7 +3405,9 @@ Hyphenator = (function (window) { removeHyphenationFromDocument(); Hyphenator.doHyphenation = false; storeConfiguration(); - toggleBox(); + if (displayToggleBox) { + toggleBox(); + } } else { if (!!css3hyphenateClassHandle) { css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, css3_h9n.property + ': auto;'); @@ -3413,7 +3415,9 @@ Hyphenator = (function (window) { Hyphenator.doHyphenation = true; hyphenateLanguageElements('*'); storeConfiguration(); - toggleBox(); + if (displayToggleBox) { + toggleBox(); + } } } diff --git a/testsuite/index.html b/testsuite/index.html index 8d56b0e..7176289 100644 --- a/testsuite/index.html +++ b/testsuite/index.html @@ -200,7 +200,8 @@

      The Hyphenator Testsuite

      {exec: true, path: 'test123.html'}, {exec: true, path: 'test124.html'}, {exec: true, path: 'test125.html'}, - {exec: true, path: 'test126.html'} + {exec: true, path: 'test126.html'}, + {exec: true, path: 'test127.html'} ], testframe = document.getElementById('testframe'), currentTest = 1, total = 'passed'; diff --git a/testsuite/test126.html b/testsuite/test126.html index 689cc38..365328d 100644 --- a/testsuite/test126.html +++ b/testsuite/test126.html @@ -45,7 +45,7 @@ -

      <<- index | <- Prev | Next ->

      +

      <<- index | <- Prev | Next ->

      Test 126

      Load Hyphenator from cdn, patterns should load from there, too (check console)

      diff --git a/testsuite/test127.html b/testsuite/test127.html new file mode 100644 index 0000000..3233073 --- /dev/null +++ b/testsuite/test127.html @@ -0,0 +1,65 @@ + + + + Hyphenator.js – Test 127 + + + + + + + +

      <<- index | <- Prev | Next ->

      +

      Test 127

      +

      Call togglehyphenation w/o toggleBox

      + +

      Hyphenation

      +

      Hy|phen|ation

      + + \ No newline at end of file From 2d4569ee8b3ebda46e39b702d70f0e5b2371ab3e Mon Sep 17 00:00:00 2001 From: mnater Date: Tue, 10 Jan 2017 11:15:44 +0100 Subject: [PATCH 70/86] Note --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a459e13..9584dc4 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ - This repository replaces https://code.google.com/p/hyphenator/ - Demo: http://mnater.github.io/Hyphenator/ +Note: Hyphenator.js has somewhat grown old. Have a look at its successor: https://github.com/mnater/Hyphenopoly + ## Overview Hyphenator.js is a free open source Javascript library that automatically hyphenates text on websites. It comes in handy as a _polyfill_ for legacy browsers that don't support CSS 3 hyphenation at all or for modern browsers that do hyphenation, but do not provide hyphenation dictionaries for a particular language. From 2495160263ea2ab5a185b610df78fc1394c0ac55 Mon Sep 17 00:00:00 2001 From: Aleksandr Andreev Date: Thu, 16 Feb 2017 15:50:24 +0300 Subject: [PATCH 71/86] Adding support for Church Slavonic --- Hyphenator.js | 1 + patterns/cu.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 patterns/cu.js diff --git a/Hyphenator.js b/Hyphenator.js index a212703..7574c36 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -83,6 +83,7 @@ Hyphenator = (function (window) { o('be', 'be.js', 1, 'Мова гэтага сайта не можа быць вызначаны аўтаматычна. Калі ласка пакажыце мову:'); o('ca', 'ca.js', 0, ''); o('cs', 'cs.js', 0, 'Jazyk této internetové stránky nebyl automaticky rozpoznán. Určete prosím její jazyk:'); + o('cu', 'cu.js', 1, 'Ꙗ҆зы́къ сегѡ̀ са́йта не мо́жетъ ѡ҆предѣле́нъ бы́ти. Прошꙋ́ тѧ ᲂу҆каза́ти ꙗ҆зы́къ:'); o('da', 'da.js', 0, 'Denne websides sprog kunne ikke bestemmes. Angiv venligst sprog:'); o('bn', 'bn.js', 4, ''); o('de', 'de.js', 0, 'Die Sprache dieser Webseite konnte nicht automatisch bestimmt werden. Bitte Sprache angeben:'); diff --git a/patterns/cu.js b/patterns/cu.js new file mode 100644 index 0000000..d5bef9e --- /dev/null +++ b/patterns/cu.js @@ -0,0 +1,30 @@ +// Created by Aleksandr Andreev and Mike Kroutikov (aleksandr.andreev (at) gmail.com) +// +// Based on the file: hyph_cu.tex +// See: https://github.com/slavonic/cu-tex/ +// Copyright (c) 2016 Aleksandr Andreev and Mike Kroutikov +// License: MIT +Hyphenator.languages['cu'] = { + leftmin : 1, + rightmin : 1, + specialChars : "а̀́̑҆̈веслѡмктꙋріднїѷѷⷠ҇ⷡⷢⷣⷤⷥⷦⷧⷨⷩⷪⷫⷬⷭⷮⷯⷰⷱⷲⷳⷴⷵⷶⷷⷸⷹⷺⷻⷼⷽⷾⷿꙴꙵꙶꙷꙸꙹꙺꙻ꙼꙽бишоѧхпѣчєгыжзю̆йьщцѝуфэѐёѕѯѳѹѻѽѿӓӥӧӭӱӹᲂꙍꙗ̇̾ъ҃ѱᲆⸯ꙾ꙿ︦︮︯", + patterns : { + 2 : "2й2ы2ѣ8̀8́8̆8̇8̈8̏8̑8̾8ъ8ь8҃8҆8҇8ᲆ8ⷠ8ⷡ8ⷢ8ⷣ8ⷤ8ⷥ8ⷦ8ⷧ8ⷨ8ⷩ8ⷪ8ⷫ8ⷬ8ⷭ8ⷮ8ⷯ8ⷰ8ⷱ8ⷲ8ⷳ8ⷴ8ⷵ8ⷶ8ⷷ8ⷸ8ⷹ8ⷺ8ⷻ8ⷼ8ⷽ8ⷾ8ⷿ8ⸯ8ꙴ8ꙵ8ꙶ8ꙷ8ꙸ8ꙹ8ꙺ8ꙻ8꙼8꙽ѕ2ѱ2ѳ2", + 3 : "1ба1бг1бж1бы1бѐ1бє1бі1бѝ1бѡ1бѣ1бꙋ1вѐ1ві1ге1гє1гѝ1гѡ1гѣ1гѵ1дѐ1дѵ1жы1жѧ1кѵ1мⷣ1пє1пѵ1сл1сщ1сі1сѵ1сѷ1тѵ1тѷ1фе1фо1фї1фѵ1фꙋ1хі1хї1хѝ1хѡ1хѣ1хꙋ1цр1цѐ1чо1чр1чы1чє1чі1чѧ1шы1шѐ1шє1шї1шѝ1шѣ1щы1щѡ1щѣ1ѕл1ѧв1ѯа1ѯе1ѯі1ѱа1ѱі1ѱѡ1ѱѵ1ѳа1ѳл1ѳо1ѳр1ѳс1ѳы1ѳї1ѳѵ1ѳꙋ1ѵы1ѵі1ѹ҆2ав2ат2ах2аⷩ2б_2бц2бч2вв2гⷭ2дⷧ2ен2ец2жъ2жⷭ2зь2й2ик2ир2къ2кⷮ2лв2лг2лд2лж2лк2лм2лн2лп2лч2лѐ2м҃2мⷬ2нб2нк2нр2нт2нч2нѳ2нⷣ2нⷴ2ол2ор2пп2пс2пш2пѐ2пⷬ2пⷭ2рб2рг2рд2рж2рз2рл2рм2рп2рр2рт2рх2с҃2тн2тⷭ2фъ2хн2цк2ц҃2чⷣ2шъ2ш҃2щъ2єн2і̑2їм2їс2ѧб2ѯт2ѯъ2ѳъ2ѵл2ѷм8а_8е_8и_8й_8о_8у_8ы_8э_8ю_8є_8і_8ѡ_8ѣ_8ѧ_8ѵ_8ѹ_8ѻ_8ѿ_8ᲂ_8ꙋ_8ꙍ_8ꙗ_8꙾88ꙿ88︦88︮88︯8_а8_б2_в2_г2_д2_е8_ж2_з2_и8_й8_к2_л2_м2_н2_о8_п2_р2_с2_т2_у8_ф2_х2_ц2_ч2_ш2_ы8_э8_ю8_ѐ8_ё8_є8_ѕ2_і8_ї8_ѝ8_ѣ8_ѧ8_ѳ2_ѵ8_ѻ8_ѽ8_ѿ1_ӓ8_ӥ8_ӧ8_ӭ8_ӱ8_ӹ8_ᲂ8_ꙋ8_ꙍ8_ꙗ8̀1б̀1ж̀2х́1а́1е́1и́1о́1ю́1є́1ї́1ѡ́1ѣ́1ѧ́1ѻ́1ꙋ́ѳ2̈1е̑1ц̑1щ̑2х̑ѵ1̾1е̾1и̾1н̾1ѧ̾1ꙋа1аа1га1ка1ца1ча1ша1іа1ꙋа2̀а2̑а2ⷡа2ⷤа2ⷭа2ⷱб2щбл2бр2б҃2в2ав2ев2жв2ив2кв2ыв2їв2ѣв2ѧв2ꙋв̾2вл2вц2в҃2г2аг2дг2иг2ог҃2д2ад2ед2мд2од2щд2ыд2їд2ѣд2ꙋдв2дл2е1ае1бе1ге1ее1же1ие1ке1ое1ще1юе1єе1ѧе1ѯе1ѱе2́е2ⷡе2ⷣе2ⷦе2ⷫел2ес2ех2е҆1ж2дж2еж2ꙋз1кз1хз1цз1чз2ез2из2ыз2ѣз2ѧзв2зр2и1пи1чи1ши1юи2́и2̑и2ⷤи2ⷨи2ⷯиф2й1тй1цй1чк2ак2вк2лк2ок2пк2тк2ѡк2ꙋкн2кы1л2ал2ел2ил2ол2ыл2юл2єл2їл2ѡл2ѣл2ѧл2ѷл2ꙋм2ам2ем2им2ым2їм2ѧмл2мп2мѷ1н2ан2ен2ин2он2ын2юн2ін2ѣн2ѧн2ꙋнѷ1о1ао1бо1до1оо1по1то1фо1хо1шо1ѐо1єо1іо1ѝо1ѧо1ѯо1ѱо1ѳо1ѹо1ꙋо2̀о2́о2̑о2ⷣо2ⷥо2ⷦо2ⷬо8уо҆1п2ап2еп2ип2оп2тп2ѣп2ѧп2ꙋпл2пн2пѷ1п҃2пⷣ2р2ар2ер2ир2ор2ыр2юр2єр2ір2їр2ѝр2ѡр2ѣр2ѧр2ѷр2ꙋрц2р҃2рⷣ2с2ас2бс2гс2ес2ис2оск2сн2сп2сх2т2ат2вт2ет2ит2мт2от2ыт2їт2ѡт2ѣт2ѧт2ꙋтк2т҃2тⷯ2фи1х2ех2их2оц2ец2єч2цч2ꙋщ2єы1вы1ды1зы1иы1пы1ты1щы2̀ы2́ы2̑ыс2ь1бь1гь1дь1жь1кь1нь1ть1ць1чь1ꙋь2вь2щьс2ю1ею1чю1ѧю2̀ю2́ю2тю̑1є1зє2́є2цєд1єт1єч1ї1аї1иї1ої1хї1цї1чї1ѐї1ѡї1ѳї2ѯїк2ѝ1дѡ1аѡ1зѡ1иѡ1кѡ1пѡ1фѡ1шѡ1іѡ1ѧѡ2́ѣ1бѣ1еѣ1иѣ1кѣ1цѣ1шѣ1щѣ1ѧѣ1ꙋѣ2̀ѣ2́ѣ2̑ѣс2ѧ1гѧ1дѧ1еѧ1рѧ1шѧ1ѧѧ2̀ѧ2́ѳѡ1ѳѷ1ѵ1ѯѵ2́ѵ̑1ѷ1еѷ1зѷ1нѷ1рѷ1хѷк2ѽ1лѿ1бѿ1дѿ1жѿ1иѿ1кѿ1пѿ1рѿ1хѿ1чѿ1шѿ1ѧ҃д2҃з2҃и2҃к2҃л2҃н2҃р2҃с2҃т2҆1а҆1г҆1е҆1к҆1т҆1х҆1ш҆1щ҆1ю҆1є҆1ѕ҆1ѡ҆1ѧ҆1ѯ҆1ѳ҆1ѻ҆2̀҆2́҆2̑҆2ц҆п2҆ч2҇а1҇к2҇л2҇н2҇о1҇р2҇т2҇ч2҇ш2҇ь1҇ї1҇ꙋ1ᲂ8уⷢї1ⷢ҇2ⷣб2ⷣн2ⷣц2ⷣч2ⷧ҇2ⷪ҇2ⷭ҇2ꙋ1иꙋ1мꙋ1нꙋ1фꙋ1цꙋ1чꙋ1шꙋ1іꙋ1ѧꙋ2́ꙋ2̑ꙗ1в", + 4 : "1аге1акі1б2е1б2и1б2о1б2ѧ1бла1бл҃1блꙋ1бща1бще1бщи1бї11в2м1в2т1в2ѷ1вав1вае1вай1вас1ваш1ваю1ваѡ1ваѧ1вѐ1вес1вещ1ви̑1вив1вил1вим1вис1вит1вих1виш1вищ1воа1вог1вой1вок1вол1вон1вос1воч1воѡ1вы́1вы̑1вый1вык1вєд1вїа1вїй1вѡ_1вѡв1вѡм1вѣе1вѣй1вѣс1вѣх1вѧ_1вѧ̀1вѧд1вѧш1г2в1г2м1г2т1г2ї1г2ꙋ1га̀1гаг1гае1гаж1гай1гаѧ1гаѳ1гда1гдѣ1ги_1гѝ1гиб1гим1гих1гла1го_1го̀1гое1гок1гом1гот1гоц1гою1гоѧ1гоѹ1гоѻ1д2и1д2ѝ1д2ѡ1д2ѧ1дав1даг1дае1дак1даш1даю1даѧ1дв҃1дѐ1деб1деж1дей1дем1ден1дец1дма1дми1дмы1дмѝ1до̀1до́1доб1дод1дое1дои1док1дол1дом1доп1дох1доч1доѯ1ды́1дыг1дый1дым1дых1дыѧ1ді̑1дїа1дїи1дїй1дїф1дїц1дїю1дїѐ1дїѝ1дїѡ1дѣ́1дѣ̑1дѣв1дѣд1дѣл1дѣм1дѣн1дѣх1дѣш1дѣѧ1дꙋ̑1дꙋе1дꙋж1дꙋй1дꙋх1дꙋю1дꙋѧ1ейж1екк1емж1емь1епі1епⷭ1ерⷭ1ж2а1ж2и1ж2р1ж2ї1жда1жде1жди1жды1ждє1ждѝ1ждѣ1ждѧ1ждꙋ1же_1жей1жен1жес1жет1жеш1жею1жєн1жєс1жꙋ_1жꙋс1з2а1з2о1з2ю1з2ѐ1з2є1з2і1з2ѝ1з2ѡ1зе_1зѐ1зек1зем1зен1зер1зеш1зѝ1зи́1зид1зы_1зы̀1зы̑1зыл1зѣ̀1зѣм1зѣх1зѧб1зꙋ_1зꙋе1и1ꙋ1иди1идѝ1изб1изг1изм1изс1исч1ихѣ1к2д1к2м1к2ѷ1каж1как1кал1кам1кан1кар1ках1каш1кеа1кеѱ1киб1кла1кле1кло1клѡ1ко̀1ков1ког1код1кой1коц1коѝ1коѧ1коѻ1кра1кро1крі1крѡ1крѣ1крꙋ1кта1кте1кто1ктю1кті1ктѡ1кїа1кїе1кѡ_1кѡн1кꙋ̀1кꙋп1л2ѵ1л2ѻ1лаа1лае1лай1лал1лар1лах1леб1леи1лею1леѯ1леѵ1либ1лив1лид1лил1лит1лич1лищ1лог1лоѳ1лых1люб1лєм1лєс1лєц1лїн1лїо1лїс1лїт1лїч1лїѐ1лїѝ1лїѡ1лѡ̀1лѣе1лѣй1лѣм1лѧй1лѧх1лѧщ1лѷе1лꙋа1лꙋе1лꙋй1лꙋк1лꙋм1лꙋч1лꙋѧ1лꙋⷩ1м2щ1м2ѡ1м2ꙋ1ма_1ман1маш1маі1маѧ1ме_1мел1мен1мет1меш1ми_1миж1мин1мищ1мла1млѐ1млⷭ1мо_1моб1мод1мое1мож1мои1мом1мон1моп1моф1мощ1моѳ1мт҃1мч҃1мы̑1мыв1мый1мым1мыс1мых1мыѧ1мєн1мі̑1мїа1мїе1мїй1мїр1мїѝ1мїѧ1мѣ́1мѣ̑1мѣи1мѣй1мѣм1мѣх1мѧ_1мѧ́1мѧр1н2є1н2ї1н2ѡ1н2ѵ1на_1наа1наг1над1наж1нак1нам1нач1наі1наѧ1наѳ1наꙋ1не_1не̑1неб1неи1нес1неш1нив1нил1нин1нич1ниш1нищ1ниⷯ1но_1ноа1ной1нок1ноф1ноч1нош1нощ1ною1ноѧ1ны̀1ный1ных1ныѧ1ню́1нюе1нюю1нюѧ1нї1нѣе1нѣи1нѣй1нѣх1нѧе1нѧт1нѧю1нѧѧ1нꙋ_1нꙋа1нꙋв1нꙋѧ1окт1онѵ1офѵ1офѷ1охі1п2ф1п2щ1п2ы1п2ї1пак1пар1паф1паѧ1пел1пен1пет1пец1пи́1пиц1пиш1пищ1пию1по_1пои1пок1пол1пор1пот1пою1поѝ1поѧ1пта1пте1птѣ1птѧ1пѣ_1пѣ́1пѣю1пѧт1пꙋ̀1пꙋ́1пꙋс1пꙋщ1раб1раф1рах1раѡ1рею1риц1рою1роѳ1рю_1рют1рєм1рєс1рєѝ1рїд1рїн1рїц1рѡд1рѡн1рѡп1рѡі1рѧ_1рѷн1рѷѱ1рꙋй1рꙋк1рꙋс1рꙋⷯ1с2ї1с2ѧ1с2ѳ1с2ꙋ1саа1сав1саж1саи1сан1саф1саш1сей1си̑1сиб1сив1сим1сит1сиф1сиц1сиш1скв1скї1сма1сме1смо1смы1смѝ1смѣ1снц1со_1со́1сог1сод1сож1сок1сор1соѧ1ст҃1сы_1сы̀1сыл1сып1сыщ1сѡ̀1сѡ́1сѣк1сѣн1сѣх1сѣщ1т2х1т2ѳ1таи1тай1там1таш1твѝ1тел1теш1тиш1тищ1тог1трє1трї1трѡ1трѧ1тєл1тєц1тїй1тїк1тїо1тїф1тїѐ1тїѝ1тѡв1тѡм1тѡн1тѣ̑1тѣш1тѧ̀1тѧ̑1тꙋе1тꙋн1ф2а1ф2л1ф2н1ф2ѡ1фї1фі̑1фѷ11х2в1х2л1ха̀1ха́1ха̑1хаа1хаи1хал1хѝ1хи́1хи̑1хищ1хо_1хое1хом1хоп1хоѻ1ц2в1цам1цѐ1цег1цею1цы̑1цыи1цєм1цї11цѣ́1цѣ̑1цѣй1цѣл1цꙋ̑1ч2а1ч2е1ч2и1ч2л1ч2ї1ч2ѝ1чтѝ1чтⷭ1чѣ11чꙋ̀1чꙋ́1чꙋж1чꙋщ1ш2а1ш2е1ш2и1ш2ꙋ1шї1щ2е1щ2и1щ2ї1щ2ѧ1щ2ꙋ1ща_1ща̀1щаг1щєм1щєс1ю́з1ютс1юще1ющъ1ющь1ющѧ1є́ю1єтн1єѵ11їнъ1їтѝ1їѳа1ѡ1г1ѡ1ч1ѡ́ѳ1ѡак1ѡкр1ѡпа1ѡпр1ѡсл1ѡсщ1ѧ1и1ѧ́в1ѧ́н1ѧ̑н1ѧ̑т1ѧ̑ю1ѧдѐ1ѧжд1ѧйс1ѧл11ѧмъ1ѧнн1ѧсн1ѧсъ1ѧсꙋ1ѯї11ѳї1ѳѧ11ѵ2а1ѵ2и1ѵ2о1ѵ2ꙋ1ѹ1х1ѻ1б1ѻ1к1ѻ1н1ѻ2ц1ѿ1е1ѿ1с1ᲂу҆1ꙋбі1ꙋкр1ꙋма1ꙋмъ1ꙋмѡ1ꙋмꙋ1ꙋсы1ꙋтр2а1е2а1и2а1ю2а1ѡ2а1ѧ2а́е2а́ж2а́з2а́т2а́х2а́ш2а́ю2а́ї2а́ѧ2а́ѵ2аго2адѐ2адѝ2адѧ2азд2азꙋ2амъ2анъ2арь2аст2б1б2б1м2б1х2б1ш2б2ъ2б̾12бвѐ2блъ2бль2бн22бръ2брь2бщн2бь12в1г2в2ъ2ваⷤ2вди2виг2виж2влъ2вль2внш2внъ2внї2внѧ2воѐ2воє2воѝ2воѧ2вс22вь12вѡи2вѣт2вⷣ22г1х2г1ч2гг҃2гдъ2глс2глъ2гль2гнъ2гнь2гⷣ22д1б2д1д2д1к2д1т2д1ч2д2ъ2двѣ2дею2дла2дмь2днс2дню2днї2днѡ2дою2дръ2дс22дх22е1ѡ2е2ⷨ2е́а2е́е2е́ч2екі2елп2елъ2ель2емѡ2емⷣ2еръ2етш2ешл2ж1б2ж1г2ж1к2ж1ц2ж1ш2ж2ь2ждш2ждъ2ждь2з2ъ2заи2звр2звъ2звѣ2зди2здн2здо2здъ2здь2здѝ2злс2злъ2знс2знъ2знь2знѡ2зра2зыг2зыщ2зѧ̀2и́в2и́ж2и́ц2и́ч2ида2итс2ицъ2иши2и҃22клс2клъ2кль2кнъ2кр҃2крⷭ2ктъ2кхъ2л1т2л1ф2л1ц2л1ш2л2ъ2лад2лаж2лач2лащ2лѐ2лео2лиж2лип2лх22люд2люч2лі̑2лѣб2лѧ̑2лѧг2л҃22лⷣ22м1м2м2ъ2мв22мль2мнъ2мнѡ2мок2мпї2мтъ2мча2мчї2мїю2мѣш2мѣщ2мѣѧ2мꙋщ2н1з2н2ъ2наб2нд22неє2нид2нм22ноб2нц22нѣꙋ2н҃22о1е2о1ж2о1и2о1ч2о1ю2о́м2о́р2о́с2о́ц2оде2одн2одѣ2окъ2омс2онт2опи2опо2опі2опѝ2опѣ2осѧ2ото2отꙋ2п1к2п1ц2п1ч2п2ъ2пѐ2плъ2пль2пнѡ2прь2прє2птр2р1н2р1ф2р1ч2р1ѳ2р2ъ2р2ⷭ2рв22реш2рит2рк22рс22рыѧ2рѧд2рѧс2рѷп2с1ч2с2ъ2скъ2слс2слъ2сль2смь2снъ2снь2спл2спр2сс22стс2стъ2схв2схо2сш22сын2сѣ̑2сѣм2т1д2т1т2т2ъ2т2ь2твъ2твь2теп2теф2тиг2тиж2тин2тлш2тоѧ2тръ2трь2тыд2тыж2тєз2тѡп2тѡѧ2тѣм2тꙋк2ф1ѳ2х1ж2х1ш2х2ъ2хаг2хаѧ2ц1т2ц2ъ2цеп2ч1к2ч2ь2чей2чн22чт҃2ч҃22ш1к2ш1ц2ш1ш2щ1н2ю́б2юст2ющѣ2є1ѝ2є́ч2і́а2і́л2їе2їм2їс2ї1е2ї1ю2ї1є2ї1ѝ2ї1ѧ2їа́2їѝ2їим2їих2ѡ́в2ѡнѵ2ѡпе2ѡпы2ѧ̑з2ѧ̑к2ѧзь2ѧзє2ѧсѐ2ѧтс2ѧтъ2ѵ1г2ѵ1д2ѵ1м2ѵ1н2ѵ1п2ѵ1т2ѵ1ф2ѵ1ѱ2ѵ1ѳ2ѵ2ъ2ѵ2ⷢ2ѵ́м2ѷм2ѵк22ѵр22ѵс22ѷ1ѱ2ѷпр2ѷпі2ꙋ1а2ꙋ1е2ꙋ1ю2ꙋ2̀2ꙋ2ⷧ2ꙋ2ⷩ2ꙋ2ⷯ2ꙋ́в2ꙋ́е2ꙋ́ж2ꙋ́п2ꙋ́х2ꙋ́ю2ꙋ́ѧ2ꙋ́ѳ2ꙋбы2ꙋбѡ2ꙋві2ꙋко2ꙋми2ꙋмі2ꙋмѝ2ꙋтс2ꙋтъ2ꙋть2ꙋши8аⷠ_8аⷡ_8аⷢ_8аⷣ_8аⷤ_8аⷥ_8аⷦ_8аⷧ_8аⷨ_8аⷩ_8аⷪ_8аⷫ_8аⷬ_8аⷭ_8аⷮ_8аⷯ_8аⷰ_8аⷱ_8аⷲ_8аⷳ_8аⷴ_8аⷵ_8аⷶ_8аⷷ_8аⷸ_8аⷹ_8аⷺ_8аⷻ_8аⷼ_8аⷽ_8аⷾ_8аⷿ_8аꙴ_8аꙵ_8аꙶ_8аꙷ_8аꙸ_8аꙹ_8аꙺ_8аꙻ_8а꙼_8а꙽_8еⷠ_8еⷡ_8еⷢ_8еⷣ_8еⷤ_8еⷥ_8еⷦ_8еⷧ_8еⷨ_8еⷩ_8еⷪ_8еⷫ_8еⷬ_8еⷭ_8еⷮ_8еⷯ_8еⷰ_8еⷱ_8еⷲ_8еⷳ_8еⷴ_8еⷵ_8еⷶ_8еⷷ_8еⷸ_8еⷹ_8еⷺ_8еⷻ_8еⷼ_8еⷽ_8еⷾ_8еⷿ_8еꙴ_8еꙵ_8еꙶ_8еꙷ_8еꙸ_8еꙹ_8еꙺ_8еꙻ_8е꙼_8е꙽_8й_8иⷠ_8иⷡ_8иⷢ_8иⷣ_8иⷤ_8иⷥ_8иⷦ_8иⷧ_8иⷨ_8иⷩ_8иⷪ_8иⷫ_8иⷬ_8иⷭ_8иⷮ_8иⷯ_8иⷰ_8иⷱ_8иⷲ_8иⷳ_8иⷴ_8иⷵ_8иⷶ_8иⷷ_8иⷸ_8иⷹ_8иⷺ_8иⷻ_8иⷼ_8иⷽ_8иⷾ_8иⷿ_8иꙴ_8иꙵ_8иꙶ_8иꙷ_8иꙸ_8иꙹ_8иꙺ_8иꙻ_8и꙼_8и꙽_8йⷠ_8йⷡ_8йⷢ_8йⷣ_8йⷤ_8йⷥ_8йⷦ_8йⷧ_8йⷨ_8йⷩ_8йⷪ_8йⷫ_8йⷬ_8йⷭ_8йⷮ_8йⷯ_8йⷰ_8йⷱ_8йⷲ_8йⷳ_8йⷴ_8йⷵ_8йⷶ_8йⷷ_8йⷸ_8йⷹ_8йⷺ_8йⷻ_8йⷼ_8йⷽ_8йⷾ_8йⷿ_8йꙴ_8йꙵ_8йꙶ_8йꙷ_8йꙸ_8йꙹ_8йꙺ_8йꙻ_8й꙼_8й꙽_8оⷠ_8оⷡ_8оⷢ_8оⷣ_8оⷤ_8оⷥ_8оⷦ_8оⷧ_8оⷨ_8оⷩ_8оⷪ_8оⷫ_8оⷬ_8оⷭ_8оⷮ_8оⷯ_8оⷰ_8оⷱ_8оⷲ_8оⷳ_8оⷴ_8оⷵ_8оⷶ_8оⷷ_8оⷸ_8оⷹ_8оⷺ_8оⷻ_8оⷼ_8оⷽ_8оⷾ_8оⷿ_8оꙴ_8оꙵ_8оꙶ_8оꙷ_8оꙸ_8оꙹ_8оꙺ_8оꙻ_8о꙼_8о꙽_8уⷠ_8уⷡ_8уⷢ_8уⷣ_8уⷤ_8уⷥ_8уⷦ_8уⷧ_8уⷨ_8уⷩ_8уⷪ_8уⷫ_8уⷬ_8уⷭ_8уⷮ_8уⷯ_8уⷰ_8уⷱ_8уⷲ_8уⷳ_8уⷴ_8уⷵ_8уⷶ_8уⷷ_8уⷸ_8уⷹ_8уⷺ_8уⷻ_8уⷼ_8уⷽ_8уⷾ_8уⷿ_8уꙴ_8уꙵ_8уꙶ_8уꙷ_8уꙸ_8уꙹ_8уꙺ_8уꙻ_8у꙼_8у꙽_8ыⷠ_8ыⷡ_8ыⷢ_8ыⷣ_8ыⷤ_8ыⷥ_8ыⷦ_8ыⷧ_8ыⷨ_8ыⷩ_8ыⷪ_8ыⷫ_8ыⷬ_8ыⷭ_8ыⷮ_8ыⷯ_8ыⷰ_8ыⷱ_8ыⷲ_8ыⷳ_8ыⷴ_8ыⷵ_8ыⷶ_8ыⷷ_8ыⷸ_8ыⷹ_8ыⷺ_8ыⷻ_8ыⷼ_8ыⷽ_8ыⷾ_8ыⷿ_8ыꙴ_8ыꙵ_8ыꙶ_8ыꙷ_8ыꙸ_8ыꙹ_8ыꙺ_8ыꙻ_8ы꙼_8ы꙽_8эⷠ_8эⷡ_8эⷢ_8эⷣ_8эⷤ_8эⷥ_8эⷦ_8эⷧ_8эⷨ_8эⷩ_8эⷪ_8эⷫ_8эⷬ_8эⷭ_8эⷮ_8эⷯ_8эⷰ_8эⷱ_8эⷲ_8эⷳ_8эⷴ_8эⷵ_8эⷶ_8эⷷ_8эⷸ_8эⷹ_8эⷺ_8эⷻ_8эⷼ_8эⷽ_8эⷾ_8эⷿ_8эꙴ_8эꙵ_8эꙶ_8эꙷ_8эꙸ_8эꙹ_8эꙺ_8эꙻ_8э꙼_8э꙽_8юⷠ_8юⷡ_8юⷢ_8юⷣ_8юⷤ_8юⷥ_8юⷦ_8юⷧ_8юⷨ_8юⷩ_8юⷪ_8юⷫ_8юⷬ_8юⷭ_8юⷮ_8юⷯ_8юⷰ_8юⷱ_8юⷲ_8юⷳ_8юⷴ_8юⷵ_8юⷶ_8юⷷ_8юⷸ_8юⷹ_8юⷺ_8юⷻ_8юⷼ_8юⷽ_8юⷾ_8юⷿ_8юꙴ_8юꙵ_8юꙶ_8юꙷ_8юꙸ_8юꙹ_8юꙺ_8юꙻ_8ю꙼_8ю꙽_8ѐ8_8ё8_8єⷠ_8єⷡ_8єⷢ_8єⷣ_8єⷤ_8єⷥ_8єⷦ_8єⷧ_8єⷨ_8єⷩ_8єⷪ_8єⷫ_8єⷬ_8єⷭ_8єⷮ_8єⷯ_8єⷰ_8єⷱ_8єⷲ_8єⷳ_8єⷴ_8єⷵ_8єⷶ_8єⷷ_8єⷸ_8єⷹ_8єⷺ_8єⷻ_8єⷼ_8єⷽ_8єⷾ_8єⷿ_8єꙴ_8єꙵ_8єꙶ_8єꙷ_8єꙸ_8єꙹ_8єꙺ_8єꙻ_8є꙼_8є꙽_8іⷠ_8іⷡ_8іⷢ_8іⷣ_8іⷤ_8іⷥ_8іⷦ_8іⷧ_8іⷨ_8іⷩ_8іⷪ_8іⷫ_8іⷬ_8іⷭ_8іⷮ_8іⷯ_8іⷰ_8іⷱ_8іⷲ_8іⷳ_8іⷴ_8іⷵ_8іⷶ_8іⷷ_8іⷸ_8іⷹ_8іⷺ_8іⷻ_8іⷼ_8іⷽ_8іⷾ_8іⷿ_8іꙴ_8іꙵ_8іꙶ_8іꙷ_8іꙸ_8іꙹ_8іꙺ_8іꙻ_8і꙼_8і꙽_8ї8_8ѝ8_8ѡⷠ_8ѡⷡ_8ѡⷢ_8ѡⷣ_8ѡⷤ_8ѡⷥ_8ѡⷦ_8ѡⷧ_8ѡⷨ_8ѡⷩ_8ѡⷪ_8ѡⷫ_8ѡⷬ_8ѡⷭ_8ѡⷮ_8ѡⷯ_8ѡⷰ_8ѡⷱ_8ѡⷲ_8ѡⷳ_8ѡⷴ_8ѡⷵ_8ѡⷶ_8ѡⷷ_8ѡⷸ_8ѡⷹ_8ѡⷺ_8ѡⷻ_8ѡⷼ_8ѡⷽ_8ѡⷾ_8ѡⷿ_8ѡꙴ_8ѡꙵ_8ѡꙶ_8ѡꙷ_8ѡꙸ_8ѡꙹ_8ѡꙺ_8ѡꙻ_8ѡ꙼_8ѡ꙽_8ѣⷠ_8ѣⷡ_8ѣⷢ_8ѣⷣ_8ѣⷤ_8ѣⷥ_8ѣⷦ_8ѣⷧ_8ѣⷨ_8ѣⷩ_8ѣⷪ_8ѣⷫ_8ѣⷬ_8ѣⷭ_8ѣⷮ_8ѣⷯ_8ѣⷰ_8ѣⷱ_8ѣⷲ_8ѣⷳ_8ѣⷴ_8ѣⷵ_8ѣⷶ_8ѣⷷ_8ѣⷸ_8ѣⷹ_8ѣⷺ_8ѣⷻ_8ѣⷼ_8ѣⷽ_8ѣⷾ_8ѣⷿ_8ѣꙴ_8ѣꙵ_8ѣꙶ_8ѣꙷ_8ѣꙸ_8ѣꙹ_8ѣꙺ_8ѣꙻ_8ѣ꙼_8ѣ꙽_8ѧⷠ_8ѧⷡ_8ѧⷢ_8ѧⷣ_8ѧⷤ_8ѧⷥ_8ѧⷦ_8ѧⷧ_8ѧⷨ_8ѧⷩ_8ѧⷪ_8ѧⷫ_8ѧⷬ_8ѧⷭ_8ѧⷮ_8ѧⷯ_8ѧⷰ_8ѧⷱ_8ѧⷲ_8ѧⷳ_8ѧⷴ_8ѧⷵ_8ѧⷶ_8ѧⷷ_8ѧⷸ_8ѧⷹ_8ѧⷺ_8ѧⷻ_8ѧⷼ_8ѧⷽ_8ѧⷾ_8ѧⷿ_8ѧꙴ_8ѧꙵ_8ѧꙶ_8ѧꙷ_8ѧꙸ_8ѧꙹ_8ѧꙺ_8ѧꙻ_8ѧ꙼_8ѧ꙽_8ѵⷠ_8ѵⷡ_8ѵⷢ_8ѵⷣ_8ѵⷤ_8ѵⷥ_8ѵⷦ_8ѵⷧ_8ѵⷨ_8ѵⷩ_8ѵⷪ_8ѵⷫ_8ѵⷬ_8ѵⷭ_8ѵⷮ_8ѵⷯ_8ѵⷰ_8ѵⷱ_8ѵⷲ_8ѵⷳ_8ѵⷴ_8ѵⷵ_8ѵⷶ_8ѵⷷ_8ѵⷸ_8ѵⷹ_8ѵⷺ_8ѵⷻ_8ѵⷼ_8ѵⷽ_8ѵⷾ_8ѵⷿ_8ѵꙴ_8ѵꙵ_8ѵꙶ_8ѵꙷ_8ѵꙸ_8ѵꙹ_8ѵꙺ_8ѵꙻ_8ѵ꙼_8ѵ꙽_8ѹⷠ_8ѹⷡ_8ѹⷢ_8ѹⷣ_8ѹⷤ_8ѹⷥ_8ѹⷦ_8ѹⷧ_8ѹⷨ_8ѹⷩ_8ѹⷪ_8ѹⷫ_8ѹⷬ_8ѹⷭ_8ѹⷮ_8ѹⷯ_8ѹⷰ_8ѹⷱ_8ѹⷲ_8ѹⷳ_8ѹⷴ_8ѹⷵ_8ѹⷶ_8ѹⷷ_8ѹⷸ_8ѹⷹ_8ѹⷺ_8ѹⷻ_8ѹⷼ_8ѹⷽ_8ѹⷾ_8ѹⷿ_8ѹꙴ_8ѹꙵ_8ѹꙶ_8ѹꙷ_8ѹꙸ_8ѹꙹ_8ѹꙺ_8ѹꙻ_8ѹ꙼_8ѹ꙽_8ѻⷠ_8ѻⷡ_8ѻⷢ_8ѻⷣ_8ѻⷤ_8ѻⷥ_8ѻⷦ_8ѻⷧ_8ѻⷨ_8ѻⷩ_8ѻⷪ_8ѻⷫ_8ѻⷬ_8ѻⷭ_8ѻⷮ_8ѻⷯ_8ѻⷰ_8ѻⷱ_8ѻⷲ_8ѻⷳ_8ѻⷴ_8ѻⷵ_8ѻⷶ_8ѻⷷ_8ѻⷸ_8ѻⷹ_8ѻⷺ_8ѻⷻ_8ѻⷼ_8ѻⷽ_8ѻⷾ_8ѻⷿ_8ѻꙴ_8ѻꙵ_8ѻꙶ_8ѻꙷ_8ѻꙸ_8ѻꙹ_8ѻꙺ_8ѻꙻ_8ѻ꙼_8ѻ꙽_8ѽ8_8ѽⷠ_8ѽⷡ_8ѽⷢ_8ѽⷣ_8ѽⷤ_8ѽⷥ_8ѽⷦ_8ѽⷧ_8ѽⷨ_8ѽⷩ_8ѽⷪ_8ѽⷫ_8ѽⷬ_8ѽⷭ_8ѽⷮ_8ѽⷯ_8ѽⷰ_8ѽⷱ_8ѽⷲ_8ѽⷳ_8ѽⷴ_8ѽⷵ_8ѽⷶ_8ѽⷷ_8ѽⷸ_8ѽⷹ_8ѽⷺ_8ѽⷻ_8ѽⷼ_8ѽⷽ_8ѽⷾ_8ѽⷿ_8ѽꙴ_8ѽꙵ_8ѽꙶ_8ѽꙷ_8ѽꙸ_8ѽꙹ_8ѽꙺ_8ѽꙻ_8ѽ꙼_8ѽ꙽_8ѿⷠ_8ѿⷡ_8ѿⷢ_8ѿⷣ_8ѿⷤ_8ѿⷥ_8ѿⷦ_8ѿⷧ_8ѿⷨ_8ѿⷩ_8ѿⷪ_8ѿⷫ_8ѿⷬ_8ѿⷭ_8ѿⷮ_8ѿⷯ_8ѿⷰ_8ѿⷱ_8ѿⷲ_8ѿⷳ_8ѿⷴ_8ѿⷵ_8ѿⷶ_8ѿⷷ_8ѿⷸ_8ѿⷹ_8ѿⷺ_8ѿⷻ_8ѿⷼ_8ѿⷽ_8ѿⷾ_8ѿⷿ_8ѿꙴ_8ѿꙵ_8ѿꙶ_8ѿꙷ_8ѿꙸ_8ѿꙹ_8ѿꙺ_8ѿꙻ_8ѿ꙼_8ѿ꙽_8ӓ8_8ӥ8_8ӧ8_8ӭ8_8ӱ8_8ӹ8_8ᲂу_8ᲂⷠ_8ᲂⷡ_8ᲂⷢ_8ᲂⷣ_8ᲂⷤ_8ᲂⷥ_8ᲂⷦ_8ᲂⷧ_8ᲂⷨ_8ᲂⷩ_8ᲂⷪ_8ᲂⷫ_8ᲂⷬ_8ᲂⷭ_8ᲂⷮ_8ᲂⷯ_8ᲂⷰ_8ᲂⷱ_8ᲂⷲ_8ᲂⷳ_8ᲂⷴ_8ᲂⷵ_8ᲂⷶ_8ᲂⷷ_8ᲂⷸ_8ᲂⷹ_8ᲂⷺ_8ᲂⷻ_8ᲂⷼ_8ᲂⷽ_8ᲂⷾ_8ᲂⷿ_8ᲂꙴ_8ᲂꙵ_8ᲂꙶ_8ᲂꙷ_8ᲂꙸ_8ᲂꙹ_8ᲂꙺ_8ᲂꙻ_8ᲂ꙼_8ᲂ꙽_8ꙋⷠ_8ꙋⷡ_8ꙋⷢ_8ꙋⷣ_8ꙋⷤ_8ꙋⷥ_8ꙋⷦ_8ꙋⷧ_8ꙋⷨ_8ꙋⷩ_8ꙋⷪ_8ꙋⷫ_8ꙋⷬ_8ꙋⷭ_8ꙋⷮ_8ꙋⷯ_8ꙋⷰ_8ꙋⷱ_8ꙋⷲ_8ꙋⷳ_8ꙋⷴ_8ꙋⷵ_8ꙋⷶ_8ꙋⷷ_8ꙋⷸ_8ꙋⷹ_8ꙋⷺ_8ꙋⷻ_8ꙋⷼ_8ꙋⷽ_8ꙋⷾ_8ꙋⷿ_8ꙋꙴ_8ꙋꙵ_8ꙋꙶ_8ꙋꙷ_8ꙋꙸ_8ꙋꙹ_8ꙋꙺ_8ꙋꙻ_8ꙋ꙼_8ꙋ꙽_8ꙍⷠ_8ꙍⷡ_8ꙍⷢ_8ꙍⷣ_8ꙍⷤ_8ꙍⷥ_8ꙍⷦ_8ꙍⷧ_8ꙍⷨ_8ꙍⷩ_8ꙍⷪ_8ꙍⷫ_8ꙍⷬ_8ꙍⷭ_8ꙍⷮ_8ꙍⷯ_8ꙍⷰ_8ꙍⷱ_8ꙍⷲ_8ꙍⷳ_8ꙍⷴ_8ꙍⷵ_8ꙍⷶ_8ꙍⷷ_8ꙍⷸ_8ꙍⷹ_8ꙍⷺ_8ꙍⷻ_8ꙍⷼ_8ꙍⷽ_8ꙍⷾ_8ꙍⷿ_8ꙍꙴ_8ꙍꙵ_8ꙍꙶ_8ꙍꙷ_8ꙍꙸ_8ꙍꙹ_8ꙍꙺ_8ꙍꙻ_8ꙍ꙼_8ꙍ꙽_8ꙗⷠ_8ꙗⷡ_8ꙗⷢ_8ꙗⷣ_8ꙗⷤ_8ꙗⷥ_8ꙗⷦ_8ꙗⷧ_8ꙗⷨ_8ꙗⷩ_8ꙗⷪ_8ꙗⷫ_8ꙗⷬ_8ꙗⷭ_8ꙗⷮ_8ꙗⷯ_8ꙗⷰ_8ꙗⷱ_8ꙗⷲ_8ꙗⷳ_8ꙗⷴ_8ꙗⷵ_8ꙗⷶ_8ꙗⷷ_8ꙗⷸ_8ꙗⷹ_8ꙗⷺ_8ꙗⷻ_8ꙗⷼ_8ꙗⷽ_8ꙗⷾ_8ꙗⷿ_8ꙗꙴ_8ꙗꙵ_8ꙗꙶ_8ꙗꙷ_8ꙗꙸ_8ꙗꙹ_8ꙗꙺ_8ꙗꙻ_8ꙗ꙼_8ꙗ꙽__а̀8_а́8_а̑8_а҆8_аⷠ8_аⷡ8_аⷢ8_аⷣ8_аⷤ8_аⷥ8_аⷦ8_аⷧ8_аⷨ8_аⷩ8_аⷪ8_аⷫ8_аⷬ8_аⷭ8_аⷮ8_аⷯ8_аⷰ8_аⷱ8_аⷲ8_аⷳ8_аⷴ8_аⷵ8_аⷶ8_аⷷ8_аⷸ8_аⷹ8_аⷺ8_аⷻ8_аⷼ8_аⷽ8_аⷾ8_аⷿ8_аꙴ8_аꙵ8_аꙶ8_аꙷ8_аꙸ8_аꙹ8_аꙺ8_аꙻ8_а꙼8_а꙽8_би2_вн2_вї1_вꙋ1_гї1_др2_дї1_ѐ8_е́8_ё8_е̑8_е҆8_еⷠ8_еⷡ8_еⷢ8_еⷣ8_еⷤ8_еⷥ8_еⷦ8_еⷧ8_еⷨ8_еⷩ8_еⷪ8_еⷫ8_еⷬ8_еⷭ8_еⷮ8_еⷯ8_еⷰ8_еⷱ8_еⷲ8_еⷳ8_еⷴ8_еⷵ8_еⷶ8_еⷷ8_еⷸ8_еⷹ8_еⷺ8_еⷻ8_еⷼ8_еⷽ8_еⷾ8_еⷿ8_еꙴ8_еꙵ8_еꙶ8_еꙷ8_еꙸ8_еꙹ8_еꙺ8_еꙻ8_е꙼8_е꙽8_зо1_зꙋ1_ѝ8_и́8_й8_и̑8_и҆8_иⷠ8_иⷡ8_иⷢ8_иⷣ8_иⷤ8_иⷥ8_иⷦ8_иⷧ8_иⷨ8_иⷩ8_иⷪ8_иⷫ8_иⷬ8_иⷭ8_иⷮ8_иⷯ8_иⷰ8_иⷱ8_иⷲ8_иⷳ8_иⷴ8_иⷵ8_иⷶ8_иⷷ8_иⷸ8_иⷹ8_иⷺ8_иⷻ8_иⷼ8_иⷽ8_иⷾ8_иⷿ8_иꙴ8_иꙵ8_иꙶ8_иꙷ8_иꙸ8_иꙹ8_иꙺ8_иꙻ8_и꙼8_и꙽8_й̀8_й́8_й̈8_й̑8_й҆8_йⷠ8_йⷡ8_йⷢ8_йⷣ8_йⷤ8_йⷥ8_йⷦ8_йⷧ8_йⷨ8_йⷩ8_йⷪ8_йⷫ8_йⷬ8_йⷭ8_йⷮ8_йⷯ8_йⷰ8_йⷱ8_йⷲ8_йⷳ8_йⷴ8_йⷵ8_йⷶ8_йⷷ8_йⷸ8_йⷹ8_йⷺ8_йⷻ8_йⷼ8_йⷽ8_йⷾ8_йⷿ8_йꙴ8_йꙵ8_йꙶ8_йꙷ8_йꙸ8_йꙹ8_йꙺ8_йꙻ8_й꙼8_й꙽8_ки2_кл2_ль2_лї1_лѷ1_не1_ню2_нї1_нꙋ2_о̀8_о́8_о̑8_о҆8_оⷠ8_оⷡ8_оⷢ8_оⷣ8_оⷤ8_оⷥ8_оⷦ8_оⷧ8_оⷨ8_оⷩ8_оⷪ8_оⷫ8_оⷬ8_оⷭ8_оⷮ8_оⷯ8_оⷰ8_оⷱ8_оⷲ8_оⷳ8_оⷴ8_оⷵ8_оⷶ8_оⷷ8_оⷸ8_оⷹ8_оⷺ8_оⷻ8_оⷼ8_оⷽ8_оⷾ8_оⷿ8_оꙴ8_оꙵ8_оꙶ8_оꙷ8_оꙸ8_оꙹ8_оꙺ8_оꙻ8_о꙼8_о꙽8_пї1_ри2_ст2_сє1_тл2_ть2_тї1_тѷ2_у̀8_у́8_у̑8_у҆8_уⷠ8_уⷡ8_уⷢ8_уⷣ8_уⷤ8_уⷥ8_уⷦ8_уⷧ8_уⷨ8_уⷩ8_уⷪ8_уⷫ8_уⷬ8_уⷭ8_уⷮ8_уⷯ8_уⷰ8_уⷱ8_уⷲ8_уⷳ8_уⷴ8_уⷵ8_уⷶ8_уⷷ8_уⷸ8_уⷹ8_уⷺ8_уⷻ8_уⷼ8_уⷽ8_уⷾ8_уⷿ8_уꙴ8_уꙵ8_уꙶ8_уꙷ8_уꙸ8_уꙹ8_уꙺ8_уꙻ8_у꙼8_у꙽8_фо2_фї1_хе1_хѡ1_ша1_щꙋ1_ы̀8_ы́8_ы̑8_ы҆8_ыⷠ8_ыⷡ8_ыⷢ8_ыⷣ8_ыⷤ8_ыⷥ8_ыⷦ8_ыⷧ8_ыⷨ8_ыⷩ8_ыⷪ8_ыⷫ8_ыⷬ8_ыⷭ8_ыⷮ8_ыⷯ8_ыⷰ8_ыⷱ8_ыⷲ8_ыⷳ8_ыⷴ8_ыⷵ8_ыⷶ8_ыⷷ8_ыⷸ8_ыⷹ8_ыⷺ8_ыⷻ8_ыⷼ8_ыⷽ8_ыⷾ8_ыⷿ8_ыꙴ8_ыꙵ8_ыꙶ8_ыꙷ8_ыꙸ8_ыꙹ8_ыꙺ8_ыꙻ8_ы꙼8_ы꙽8_э̀8_э́8_э̑8_э҆8_эⷠ8_эⷡ8_эⷢ8_эⷣ8_эⷤ8_эⷥ8_эⷦ8_эⷧ8_эⷨ8_эⷩ8_эⷪ8_эⷫ8_эⷬ8_эⷭ8_эⷮ8_эⷯ8_эⷰ8_эⷱ8_эⷲ8_эⷳ8_эⷴ8_эⷵ8_эⷶ8_эⷷ8_эⷸ8_эⷹ8_эⷺ8_эⷻ8_эⷼ8_эⷽ8_эⷾ8_эⷿ8_эꙴ8_эꙵ8_эꙶ8_эꙷ8_эꙸ8_эꙹ8_эꙺ8_эꙻ8_э꙼8_э꙽8_ю̀8_ю́8_ю̈8_ю̑8_ю҆8_юⷠ8_юⷡ8_юⷢ8_юⷣ8_юⷤ8_юⷥ8_юⷦ8_юⷧ8_юⷨ8_юⷩ8_юⷪ8_юⷫ8_юⷬ8_юⷭ8_юⷮ8_юⷯ8_юⷰ8_юⷱ8_юⷲ8_юⷳ8_юⷴ8_юⷵ8_юⷶ8_юⷷ8_юⷸ8_юⷹ8_юⷺ8_юⷻ8_юⷼ8_юⷽ8_юⷾ8_юⷿ8_юꙴ8_юꙵ8_юꙶ8_юꙷ8_юꙸ8_юꙹ8_юꙺ8_юꙻ8_ю꙼8_ю꙽8_є̀8_є́8_є̈8_є̑8_є҆8_єⷠ8_єⷡ8_єⷢ8_єⷣ8_єⷤ8_єⷥ8_єⷦ8_єⷧ8_єⷨ8_єⷩ8_єⷪ8_єⷫ8_єⷬ8_єⷭ8_єⷮ8_єⷯ8_єⷰ8_єⷱ8_єⷲ8_єⷳ8_єⷴ8_єⷵ8_єⷶ8_єⷷ8_єⷸ8_єⷹ8_єⷺ8_єⷻ8_єⷼ8_єⷽ8_єⷾ8_єⷿ8_єꙴ8_єꙵ8_єꙶ8_єꙷ8_єꙸ8_єꙹ8_єꙺ8_єꙻ8_є꙼8_є꙽8_і̀8_і́8_ї8_і̑8_і҆8_іⷠ8_іⷡ8_іⷢ8_іⷣ8_іⷤ8_іⷥ8_іⷦ8_іⷧ8_іⷨ8_іⷩ8_іⷪ8_іⷫ8_іⷬ8_іⷭ8_іⷮ8_іⷯ8_іⷰ8_іⷱ8_іⷲ8_іⷳ8_іⷴ8_іⷵ8_іⷶ8_іⷷ8_іⷸ8_іⷹ8_іⷺ8_іⷻ8_іⷼ8_іⷽ8_іⷾ8_іⷿ8_іꙴ8_іꙵ8_іꙶ8_іꙷ8_іꙸ8_іꙹ8_іꙺ8_іꙻ8_і꙼8_і꙽8_ѡ1с_ѣ̀8_ѣ́8_ѣ̈8_ѣ̑8_ѣ҆8_ѣⷠ8_ѣⷡ8_ѣⷢ8_ѣⷣ8_ѣⷤ8_ѣⷥ8_ѣⷦ8_ѣⷧ8_ѣⷨ8_ѣⷩ8_ѣⷪ8_ѣⷫ8_ѣⷬ8_ѣⷭ8_ѣⷮ8_ѣⷯ8_ѣⷰ8_ѣⷱ8_ѣⷲ8_ѣⷳ8_ѣⷴ8_ѣⷵ8_ѣⷶ8_ѣⷷ8_ѣⷸ8_ѣⷹ8_ѣⷺ8_ѣⷻ8_ѣⷼ8_ѣⷽ8_ѣⷾ8_ѣⷿ8_ѣꙴ8_ѣꙵ8_ѣꙶ8_ѣꙷ8_ѣꙸ8_ѣꙹ8_ѣꙺ8_ѣꙻ8_ѣ꙼8_ѣ꙽8_ѧ̀8_ѧ́8_ѧ̈8_ѧ̑8_ѧ҆8_ѧⷠ8_ѧⷡ8_ѧⷢ8_ѧⷣ8_ѧⷤ8_ѧⷥ8_ѧⷦ8_ѧⷧ8_ѧⷨ8_ѧⷩ8_ѧⷪ8_ѧⷫ8_ѧⷬ8_ѧⷭ8_ѧⷮ8_ѧⷯ8_ѧⷰ8_ѧⷱ8_ѧⷲ8_ѧⷳ8_ѧⷴ8_ѧⷵ8_ѧⷶ8_ѧⷷ8_ѧⷸ8_ѧⷹ8_ѧⷺ8_ѧⷻ8_ѧⷼ8_ѧⷽ8_ѧⷾ8_ѧⷿ8_ѧꙴ8_ѧꙵ8_ѧꙶ8_ѧꙷ8_ѧꙸ8_ѧꙹ8_ѧꙺ8_ѧꙻ8_ѧ꙼8_ѧ꙽8_ѳї1_ѵ̀8_ѵ́8_ѵ̈8_ѵ̑8_ѵ҆8_ѵⷠ8_ѵⷡ8_ѵⷢ8_ѵⷣ8_ѵⷤ8_ѵⷥ8_ѵⷦ8_ѵⷧ8_ѵⷨ8_ѵⷩ8_ѵⷪ8_ѵⷫ8_ѵⷬ8_ѵⷭ8_ѵⷮ8_ѵⷯ8_ѵⷰ8_ѵⷱ8_ѵⷲ8_ѵⷳ8_ѵⷴ8_ѵⷵ8_ѵⷶ8_ѵⷷ8_ѵⷸ8_ѵⷹ8_ѵⷺ8_ѵⷻ8_ѵⷼ8_ѵⷽ8_ѵⷾ8_ѵⷿ8_ѵꙴ8_ѵꙵ8_ѵꙶ8_ѵꙷ8_ѵꙸ8_ѵꙹ8_ѵꙺ8_ѵꙻ8_ѵ꙼8_ѵ꙽8_ѻ̀8_ѻ́8_ѻ̈8_ѻ̑8_ѻ҆8_ѻⷠ8_ѻⷡ8_ѻⷢ8_ѻⷣ8_ѻⷤ8_ѻⷥ8_ѻⷦ8_ѻⷧ8_ѻⷨ8_ѻⷩ8_ѻⷪ8_ѻⷫ8_ѻⷬ8_ѻⷭ8_ѻⷮ8_ѻⷯ8_ѻⷰ8_ѻⷱ8_ѻⷲ8_ѻⷳ8_ѻⷴ8_ѻⷵ8_ѻⷶ8_ѻⷷ8_ѻⷸ8_ѻⷹ8_ѻⷺ8_ѻⷻ8_ѻⷼ8_ѻⷽ8_ѻⷾ8_ѻⷿ8_ѻꙴ8_ѻꙵ8_ѻꙶ8_ѻꙷ8_ѻꙸ8_ѻꙹ8_ѻꙺ8_ѻꙻ8_ѻ꙼8_ѻ꙽8_ѽ̀8_ѽ́8_ѽ̈8_ѽ̑8_ѽ҆8_ѽⷠ8_ѽⷡ8_ѽⷢ8_ѽⷣ8_ѽⷤ8_ѽⷥ8_ѽⷦ8_ѽⷧ8_ѽⷨ8_ѽⷩ8_ѽⷪ8_ѽⷫ8_ѽⷬ8_ѽⷭ8_ѽⷮ8_ѽⷯ8_ѽⷰ8_ѽⷱ8_ѽⷲ8_ѽⷳ8_ѽⷴ8_ѽⷵ8_ѽⷶ8_ѽⷷ8_ѽⷸ8_ѽⷹ8_ѽⷺ8_ѽⷻ8_ѽⷼ8_ѽⷽ8_ѽⷾ8_ѽⷿ8_ѽꙴ8_ѽꙵ8_ѽꙶ8_ѽꙷ8_ѽꙸ8_ѽꙹ8_ѽꙺ8_ѽꙻ8_ѽ꙼8_ѽ꙽8_ᲂ̀8_ᲂ́8_ᲂ̈8_ᲂ̑8_ᲂ҆8_ᲂⷠ8_ᲂⷡ8_ᲂⷢ8_ᲂⷣ8_ᲂⷤ8_ᲂⷥ8_ᲂⷦ8_ᲂⷧ8_ᲂⷨ8_ᲂⷩ8_ᲂⷪ8_ᲂⷫ8_ᲂⷬ8_ᲂⷭ8_ᲂⷮ8_ᲂⷯ8_ᲂⷰ8_ᲂⷱ8_ᲂⷲ8_ᲂⷳ8_ᲂⷴ8_ᲂⷵ8_ᲂⷶ8_ᲂⷷ8_ᲂⷸ8_ᲂⷹ8_ᲂⷺ8_ᲂⷻ8_ᲂⷼ8_ᲂⷽ8_ᲂⷾ8_ᲂⷿ8_ᲂꙴ8_ᲂꙵ8_ᲂꙶ8_ᲂꙷ8_ᲂꙸ8_ᲂꙹ8_ᲂꙺ8_ᲂꙻ8_ᲂ꙼8_ᲂ꙽8_ꙋ̀8_ꙋ́8_ꙋ̈8_ꙋ̑8_ꙋ҆8_ꙋⷠ8_ꙋⷡ8_ꙋⷢ8_ꙋⷣ8_ꙋⷤ8_ꙋⷥ8_ꙋⷦ8_ꙋⷧ8_ꙋⷨ8_ꙋⷩ8_ꙋⷪ8_ꙋⷫ8_ꙋⷬ8_ꙋⷭ8_ꙋⷮ8_ꙋⷯ8_ꙋⷰ8_ꙋⷱ8_ꙋⷲ8_ꙋⷳ8_ꙋⷴ8_ꙋⷵ8_ꙋⷶ8_ꙋⷷ8_ꙋⷸ8_ꙋⷹ8_ꙋⷺ8_ꙋⷻ8_ꙋⷼ8_ꙋⷽ8_ꙋⷾ8_ꙋⷿ8_ꙋꙴ8_ꙋꙵ8_ꙋꙶ8_ꙋꙷ8_ꙋꙸ8_ꙋꙹ8_ꙋꙺ8_ꙋꙻ8_ꙋ꙼8_ꙋ꙽8_ꙍ̀8_ꙍ́8_ꙍ̈8_ꙍ̑8_ꙍ҆8_ꙍⷠ8_ꙍⷡ8_ꙍⷢ8_ꙍⷣ8_ꙍⷤ8_ꙍⷥ8_ꙍⷦ8_ꙍⷧ8_ꙍⷨ8_ꙍⷩ8_ꙍⷪ8_ꙍⷫ8_ꙍⷬ8_ꙍⷭ8_ꙍⷮ8_ꙍⷯ8_ꙍⷰ8_ꙍⷱ8_ꙍⷲ8_ꙍⷳ8_ꙍⷴ8_ꙍⷵ8_ꙍⷶ8_ꙍⷷ8_ꙍⷸ8_ꙍⷹ8_ꙍⷺ8_ꙍⷻ8_ꙍⷼ8_ꙍⷽ8_ꙍⷾ8_ꙍⷿ8_ꙍꙴ8_ꙍꙵ8_ꙍꙶ8_ꙍꙷ8_ꙍꙸ8_ꙍꙹ8_ꙍꙺ8_ꙍꙻ8_ꙍ꙼8_ꙍ꙽8_ꙗ̀8_ꙗ́8_ꙗ̈8_ꙗ̑8_ꙗ҆8_ꙗⷠ8_ꙗⷡ8_ꙗⷢ8_ꙗⷣ8_ꙗⷤ8_ꙗⷥ8_ꙗⷦ8_ꙗⷧ8_ꙗⷨ8_ꙗⷩ8_ꙗⷪ8_ꙗⷫ8_ꙗⷬ8_ꙗⷭ8_ꙗⷮ8_ꙗⷯ8_ꙗⷰ8_ꙗⷱ8_ꙗⷲ8_ꙗⷳ8_ꙗⷴ8_ꙗⷵ8_ꙗⷶ8_ꙗⷷ8_ꙗⷸ8_ꙗⷹ8_ꙗⷺ8_ꙗⷻ8_ꙗⷼ8_ꙗⷽ8_ꙗⷾ8_ꙗⷿ8_ꙗꙴ8_ꙗꙵ8_ꙗꙶ8_ꙗꙷ8_ꙗꙸ8_ꙗꙹ8_ꙗꙺ8_ꙗꙻ8_ꙗ꙼8_ꙗ꙽8́1ва́1ве́1ви́1во́1вы́1вє́1вї́1вѡ́1вѣ́1вѧ́1га́1ги́1го́1да́1де́1до́1дї́1дѣ́1дꙋ́1же́1жꙋ́1зе́1зи́1зы́1зѣ́1зѧ́1ка́1ки́1ко́1кр́1кї́1кѡ́1ла́1ле́1ли́1ло́1лы́1лю́1лє́1лї́1лѡ́1лѣ́1лѧ́1лꙋ́1ма́1ме́1мо́1мы́1мє́1мі́1мї́1мѣ́1мѧ́1на́1не́1ни́1но́1ны́1ню́1нѣ́1нѧ́1нꙋ́1па́1пе́1по́1пꙋ́1ра́1ре́1ри́1ро́1ры́1рю́1рї́1рѡ́1рѧ́1рꙋ́1са́1се́1си́1со́1сы́1сѣ́1та́1те́1ти́1то́1ты́1тє́1тї́1тѡ́1тѧ́1ха́1хо́1ца́1цꙋ́1ї́2гѓ2дм́2зл́2й1́2кх́2мт́б1н́б1ц́б1ч́б2р́ба1́бы1́бѣ1́бꙋ1́в1в́в1с́гл2́д1с́д2р́е2с́е2х́еж2́зд2́и1в́й1́ил2́л2д́л2х́н1ќн1ц́н1ч́о2м́п1с́п1ш́п2л́р1р́с1ш́с2ќс2л́с2т́т1н́ть1́хї2́хꙋ1́ч1н́чє1́чї1́шꙋ1́щѧ1́ї2ќїа1́їи1́ѧ1т́ѧв1́ѳо2́ѵ2ќѵ2с́ѵи1̑1вы̑1ги̑1др̑1ды̑1зы̑1и2̑1ки̑1ла̑1ли̑1ны̑1нѧ̑1ра̑1ри̑1ры̑1са̑1см̑1тв̑1ти̑1ю1̑1ѧ2̑2гг̑2й1̑2кл̑в1с̑гꙋ2̑ди1̑жї1̑за2̑й1̑ин1̑м1н̑нї1̑пї1̑р1с̑с1с̑с2л̑с2т̑т1н̑ч1н̑че1̑чи1̑чї1̑ща1̑ѧн1̾1ѡ1̾1ѻ1̾2с2̾и1м̾и́1̾не1̾ꙋ1в̾ꙋ́2а1б2а1ваа1веа1виа1выа1вѡа1вѣа1вѵа1вꙋа1даа1доа1дыа1діа1зеа1зиа1зыа1зѣа1лаа1леа1лиа1лоа1лыа1люа1ліа1лѝа1лѡа1лѣа1лѧа1маа1миа1моа1мыа1міа1мѝа1мѣа1ноа1ныа1нѐа1нѝа1нѣа1нѧа1нꙋа1раа1роа1рыа1рюа1рѐа1рєа1ріа1рѡа1рѣа1саа1сиа1соа1сыа1сѐа1сєа1сѝа1сѡа1сѣа1таа1тва1теа1тиа1тоа1тра1тыа1тіа1тѝа1тѡа1тѣа1тѧа1тꙋа1хаа1хиа1хоа1щ2а1ї1а1ѳ2а́1ца́1ѳа́7ѣа́г2а́к2а̑2ба̑ж2аа̑2абѣ2ав1вавѷ1ае1дае1саз1ваза2азѡ1аи1лаи1май1аи̑2аке1аки1акл2ал1дал1ман1дан1цапї1ар1вар1дар1кар1лар1мар1сар1тас1сафа2афї1ахꙋ1ацѣ2ач1начꙋ2ашꙋ2ащꙋ2аі́1аї1аїа1аѡ1наѳа2аѳо1аѵ1раѵ1са҆а1а҆к2а҆ѵ1б1ниб1нꙋб1цаб1цыб1цꙋб2диба1нба̑2баг2бе1сбе2хбет1бза2би1рби2мби̑1бин2бна1бне2бнї1бо1нбо1рбо1щбое2бож2бос2бша1бшꙋ1бы1мбє́2бі́2бї1бѡ1лбѡ̑1бѣ1дбѣ1лбѣ1сбѣ1тбѧ2тбꙋ1рбꙋ̑1в1вав1выв1вꙋв2вев2дѡв2п2в2сав2сев2сив2сюв2сѐв2сѝв2сѣв2сꙋв2х2в2їв2ѝ1ва1двал2вах2вго1ве1ввжи1вза1взи1ви1рви1фвѝ1вмѣ1вно1во1вво1рвож2воз1впе1вро2врꙋ1вша1вшꙋ1вы1свєн1вї1квї1нвї1свѧ1чв҃о1в҃ы1га1вга1лга1мга̑1ге1дгее2геѡ2гко1го1лгоп2гоꙋ1грї2грѷ1грꙋ1гст2гша1гше1гшї1гї1ггѵ́1г҃о1гꙋ2тгꙋ́1гꙋ̑1гꙋю1д2вед2вєд2вꙋд2лѧд2нѐд2їд̾ꙋ1да1мдбѣ2де1сди1лди1нди1рди1фдис2дка1дко1дна1днꙋ1до1рдоꙋ1дпо1дпꙋ1дша1дшꙋ1дїо1дѡ1ндѡ2мдѧ1хдѧ2тдѧз2дѵ́2дꙋ1бдꙋ2те1вае1вие1вое1вые1вєе1вѡе1вѣе1вѧе1вꙋе1дае1дее1дме1дое1дые1дѣе1зее1зѧе1лае1лее1лое1лые1люе1лєе1лѝе1лѣе1мае1мие1мое1мые1нае1нее1ние1ное1ные1нѐе1ніе1нѝе1нѣе1нѧе1нꙋе1п2е1рае1рее1рое1рые1рюе1ріе1рїе1рѝе1рѧе1рꙋе1сае1сие1сне1сое1спе1сые1сѐе1сєе1сѝе1сѡе1сѣе1тае1тее1тые1тѣе1тꙋе1ф2е1цае1цые1цꙋе1чѐе1чⷭе1ш2е1ѕ2е1ѳ2е1ѻ1е1ѿ1е1ꙋ1е2̑2е2й1е́1ѯе́п2е́ю1е́ѵ2е̑н1еа1меа̑1ебѣ2ев1сега1ед1сед1хедр2ее1сез1ꙋеи1меи1теи́1ей1еиз1ека2екꙋ2ен1мен1цео1непи1епо1ер1бер1вер1гер1кер1сер1херн2есї1ефа2еч1неши1еѡ1деѡ1реѧ́1еѯа2еѳо2еѵ1кеѵ1реѵ1сеѻр2жа1мжа2тжа2хжа̑1жи1вжи̑1жка1жко1жна1жно1жнї1жнѧ1жро2жрꙋ2жша1жше1жїѧ1жꙋ́1з1лиз1лѣз1нѣз1рꙋз1ꙋ̑з̾и1за1вза1дза1лза1мза1сзак2збе1згн2зго1зе1взжи1зза1ззо1зи1рзко1зо1взо2мзои1зос2зпа1зпи2зрѧ2зсе1зсы1зсї1зхо1зцѣ1зши1зшꙋ1зє́2зєм1зї1зѡ1рзѡ́1зѣ̑1и1б2и1веи1вии1вои1выи1вѝи1вѡи1вꙋи1д2и1ж2и1зыи1зѣи1каи1кии1кли1кои1кри1кти1кіи1кѝи1кѡи1кѣи1лаи1леи1лии1лои1лѡи1лѣи1лѧи1лꙋи1маи1мии1мои1мыи1мѣи1неи1нои1ныи1ніи1нѝи1нѣи1нѧи1раи1рои1рєи1ріи1рѝи1рѣи1рѧи1саи1таи1тви1теи1тии1три1тыи1тѐи1тєи1тіи1тѝи1хаи1хои1ц2и1щ2и1ѡ1и1ѳ2ѝ1ди́1фи́1ши́с2й1тй1цй1чи̑1дибо2ив1сидо2идї1из1лиза2изо1ипї1ир1гис1сисї1ифа2их1тихꙋ2ица2ицє1ицѣ2ич1ниш2лише2ишꙋ2ию́1и҆1ли҆1ми҆г2иꙋ́2й1д2й1ж2й1м2й1н2й1с2й1ш2йде2йдꙋ2йне1йно1йню1йнї1йнѧ1йнꙋ1йст2йте1йче1йша1йшꙋ1к2нѧк2р2к2ѷква2кво1ке1ске2лкер1ки1нкка1кша1кше1кє́2кѡ1лкѡ1рл1вал1вел1выл1вѣл1вꙋл1гал1гил1дел1дєл1кил1кіл1кѝл1кѡл1мал1мил1мыл1мѣл1нел1нил1нол1ныл1пел1піл1пѝл1пѡл1пѣл2жал2жил2жѝл2жꙋл2їлак2лам2лас2лв1сле1чле2хлев2ли1клли1лн1цлнї1ло1нло1рло1щлоб2лом2лпї1лфа1лфе2лхї1лцѣ2лч1нлче2лчї1лшꙋ1лє1влѣ2хлѧ2тлѷ1клѻр1л҃о1лꙋ1бм1вам2г2м2з2м2нѐм2нѧм2чⷭм2їма1ѯмаѵ1ме2смеж2ми1мми1рми̑1мма1мот2мро2мрꙋ2мфа1мфе1мфї1мша1мше1мшї1мшꙋ1мщꙋ2мє́2мѡ1лмѡ̑1мѡи1мѣ1нмѷ1мѷг2мꙋ̑1н1дан1ден1дін1дѣн1ман1мен1мин1мѝн1мѣн1рѐн1тан1тин1тін1тїн1тѡн1тѣн1цєн1ѳин1ѳін2кан2кѝн2кѡн2кꙋна1вна1лна1снае1нди2не1вне1лне2хне2цнег2нео1ник2нна1нне1нно1нню1ннѧ1ннꙋ1но1лнож2ноп2нот2нст2нсї1нч1ннче2нша1нше1ншꙋ1нї1кнї1мнї1ннїо1нѣ̑1нѳї2нѷ1о1вао1вио1воо1выо1вєо1вѡо1вѣо1г2о1зио1зыо1зѣо1зѧо1к2о1лао1лео1лио1лоо1лыо1люо1лєо1ліо1лїо1лѝо1лѡо1лѣо1лѧо1лꙋо1мео1мио1мто1мчо1мыо1мѣо1нао1нео1нио1ноо1ныо1нѐо1ніо1нѝо1нѧо1нꙋо1рао1рео1роо1рыо1рюо1рєо1ріо1рѝо1рѡо1рѣо1рѧо1рꙋо1сао1смо1соо1сыо1сѝо1сѣо1ц2о1щао1щєо1щѝо1ї1о1ѡ1о1ѻ1о1ᲂуо2й1о́к2о́ї2о̑л1оа1моб2роби1ого1од1сод2водї1одꙋ2ое1вое1дое1созд2озн2ои1мои1той1ои̑2ол1вол1гол1кол1нол1пол1хол1чон1дон1кон1мон1рон1цон1чонї1оо́2ор1вор1дор1жор1лор1сор1тос1сос2лосї1от1ноть1офа2ох1нохе2охꙋ1оша2ошꙋ2ощї1ощꙋ2оє́1оі́2ої1оѧ1зоѳе2оѹ҆1оꙋ1боꙋ1воꙋ1тоꙋ1хп1пап1пеп2нѝп2сѝпа1хпе1спи1нпит2пка1пки2пко1пкꙋ1по1щпож2поп2пох2поꙋ1при1прї1прꙋ2пцы1пцѣ2пще1пы́2пє́2пї1кпї1лпї1мпѣ1спѣ̑1пѵ́1пѷ1р1вар1влр1вор1выр1гар1гир1гір1дар1дер1дор1дыр1дєр1дір1дѣр1ждр1жер1жєр1жꙋр1зер1зир1кар1квр1кїр1кѡр1кѣр1лир1мар1мер1мир1мор1мѝр1пар1пер1пир1пѝр1пѣр1пѧр1рар1сар1сир1сѣр1тар1тер1тор1тыр1тір1тїр1хар1хир2глр2плр2пⷣр2щ1р2ѷра1дра1лра1мрб1нрбе2рбѣ2ре1лре1срее1реж2реи1рек2рем2рет2реѡ1рза2рзѡ1ри1кри1хри̑1рив2рню1рнѧ1рнꙋ1ро1лро1щрод2рое2рож2роп2рот2рп1српї2рт1нрхї1рхꙋ2рче1ршꙋ1ры̑1рѣ1лрѣ1срѣ1трѧ1нрѳе2рѳо1рѵ́1р҃ї1рꙋ1дрꙋ1зс1скс1сѡс2кѡс2лес2лис2лыс2люс2лєс2лѝс2лѡс2лѣс2лѧс2м2с2сѣс2їса1дса1тса1хсаꙋ2сва1сга1се1все1лсе1мсе1ссе1чсег2си1рсми1смѧ1сне2сно1снї1со1всо1лсое1сои2сом2соꙋ2сри2сро2ссѷ1ст2лсчи1сша1сшї1сю́1сі̑2сї1ксї1нсї1псї1ссїо1сѳе2сꙋ1рсꙋ̑1сꙋе1сꙋм2т1нит1ніт2лют2лѧт2р2т2сѣт2їта1дта1ртаѵ1твї1твѡ1тде1те1сте1чте2хтек2тем1ти1хтнї1то1нто1щтод2том2тос2тот2тох2тст2тха1тхо1тхї2тцѣ2тча2тша2тшы1тще1ты2хть1стю́1тї1лтї1мтї1нтѣ1лтѳе2тꙋ1дтꙋ̑2фа1вфа1мфа1нфе1вфе1лфе1сфла1фло1фнꙋ2фо1вфо2мфра2фре2фрꙋ1фѡ1тфѳо2фѷ1фꙋ́2фꙋ̑2ха1нха1рхво2хо1щход2хож2хре1хри1хро1хрї1хрѷ1хст2хї1мхї1схї2кхѡ1тхꙋ1дхꙋ1лц1киц1кїцто2цы́1цє́2цїо2цⷣе1цꙋ́2ч1нач1ноч1ныч1нѣч2тєч2тꙋч2їча1вча1лча1мче1лче2мчет2чи1вчи1нчи2лчи2хчи̑1чле1чнї1что2чша1чше1чши2чі́1ч҃е1ч҃ї2чꙋ̑2ш1лєш1лѧша1нша2мше1лше1сше1хшее1шет2ши1вши1рши2лши2хшла2шна1шно1шню1шнѧ1шце1шша1шшꙋ1шы2мшїи1шꙋю1ще1сще2хщее1щи1тщнꙋ1щст2щша1щше1щы2мщїи1щꙋ2тщꙋ́1щꙋю1ъ1д2ы1г2ы1ж2ы1коы1л2ы1маы1миы1ниы1нюы1нѣы1реы1риы1рюы1рєы1рѣы1рѧы1скы1соы1сѡы1хаы1ѧ1ы2й1ы́1цы́2вы́к2ы́с2ы̑1бы̑2мы̑ч1ы̑ш1ыдо2ыза2ызы1ый1ыла2ын1мыпа2ыр1мытї1ыш1лыша2ыше2ыщꙋ2ь1з2ь1меь1миь1мѝь1скь1ш2ь2мыь2мѣь2мꙋь2п2ьво2ьде1ьзꙋ1ька1ькї1ькꙋ1ьна1ьно1ьнї1ьнꙋ1ьст2ьте1ьтє1ьтѧ1ьче1ьша1ьшꙋ1ьꙋ́1ю1даю1дею1дмю1дію1с2ю1щ2ю1ю1ю́1жю́2лю́ю1юд1сюче2юща1ющꙋ1ю҆1рє1ває1выє1лиє1мыє1ниє1ныє1с2є́2цєнї1єст2є҆1фє҆г2ѕла2ѕмї1ѕѣ1лѕѣ́2і́1фі́1ці́1чі́2пі́2ѯі́2ѳі́г2і́и1і́к2ї1аї1иї1ої1хї1цї1чї1ѐї1ѡї1ѳї2ѯїк2і̑2кі̑р1і҆г2і҆к2ї1в2ї1гаї1гиї1д2ї1кеї1кої1ктї1кії1кѡї1леї1лиї1лії1маї1неї1ної1раї1реї1саї1сеї1сєї1сѡї1т2ї1ф2ї1ѷ1ї2й1їа1дїа1мїа1нївї1їдї1їе2мїи1нїи1тїй1їи̑2їн1дїн1тїо1мїо1нїп1пїпї1їр1сїс1сїтѷ1їтꙋ2їє́1їѡ1нїѡ1сїѳе2ѝдѣ1ѡ1ваѡ1веѡ1выѡ1вꙋѡ1даѡ1діѡ1лиѡ1лыѡ1ліѡ1лѡѡ1лѣѡ1мыѡ1мѣѡ1мѵѡ1наѡ1неѡ1ниѡ1ныѡ1ніѡ1нꙋѡ1раѡ1роѡ1рыѡ1рꙋѡ1тиѡ1тыѡ1тіѡ1ѷ1ѡ́1пѡ́1чѡ̑1тѡ̑м1ѡбо1ѡбѣ2ѡбꙋ1ѡго2ѡзо2ѡи1сѡи́2ѡр1сѡс1сѡсї1ѡі́1ѡѧ́1ѡ҆1мѡ҆1пѡ҆1рѡ҆1чѡ҆к2ѣ1ваѣ1виѣ1г2ѣ1даѣ1доѣ1дыѣ1ж2ѣ1леѣ1лиѣ1лєѣ1лѝѣ1лѡѣ1лѣѣ1лѧѣ1маѣ1меѣ1миѣ1ниѣ1нѝѣ1нѣѣ1нѧѣ1піѣ1пѝѣ1рєѣ1рѧѣ1сиѣ1снѣ1сѝѣ1сѡѣ1сѣѣ1таѣ1теѣ1тиѣ1тоѣ1тѐѣ1тіѣ1тѝѣ1тꙋѣ1хаѣ1хиѣ1хоѣ1чѐѣ1ю1ѣ2й1ѣ́1цѣ́з2ѣ́с2ѣ́є1ѣ̑1вѣ̑с2ѣ̑ш1ѣбо2ѣго2ѣдѡ2ѣй1ѣка2ѣкꙋ2ѣн1цѣн1чѣнї1ѣсѧ1ѣхꙋ2ѣцѣ2ѣче2ѣша2ѣщꙋ2ѣꙋ́1ѧ1ваѧ1виѧ1ж2ѧ1миѧ1ниѧ1ныѧ1нѝѧ1с2ѧ1таѧ1теѧ1тиѧ1тоѧ1тыѧ1тіѧ1тѝѧ1тѣѧ1тꙋѧ1цаѧ1цыѧ1щ2ѧ1ю1ѧ2̑1ѧ2й1ѧ́1цѧ́1чѧ́1шѧ́1щѧв1сѧго1ѧдо1ѧдꙋ2ѧем1ѧй1ѧре2ѧт1нѧть1ѧч1нѧщї1ѧщѧ1ѧ҆̀1ѯе1нѯї1ѱа́2ѱі́2ѱѵ́1ѳа1вѳа1лѳа1нѳеа1ѳеѡ2ѳле1ѳо1лѳо1нѳо2вѳо́1ѳра2ѳсї1ѳїс2ѳѷ1ѳꙋ́1ѵ1клѵ1кіѵ1лаѵ1леѵ1лꙋѵ1раѵ1рыѵ1ріѵ1рѡѵ1рѣѵ1сеѵ2ктѵ́1сѵ́1фѵ́п2ѷ1еѷ1зѷ1нѷ1рѷ1хѷк2ѵ̑р2ѵа1рѵа́2ѵди1ѵдо1ѵдї1ѵи1нѵно2ѵнї1ѵо́2ѵст2ѵсї1ѵсѷ1ѵтѷ1ѵ҆1пѵ҆а1ѷ1гдѷ1каѷ1кеѷ1ктѷ1л2ѷ1п2ѷе1лѷе́2ѷза2ѷла2ѷм1вѷна1ѷри2ѷро1ѷрї1ѷхї1ѹ҆1лѹ҆1пѹ҆̀1ѹ҆г2ѹ҆с2ѹ҆т2ѻбо1ѻке1ѻнꙋ2ѻте2ѻ҆1нѻ҆1пѻ҆г2ѻ҆к2ѻ҆т2ѿ1в2ѿ1г2ѿ1л2ѿ1м2ѿ1н2ѿ1т2ѿ1ѻ1ѿбѣ1ѿе́2ѿже1ѿи1мѿи1тѿи́1ѿкꙋ2ѿлꙋ1ѿме1ѿмы1ѿне2ѿню2ѿпа1ѿре1ѿри2ѿсе2ѿто2ѿчꙋ1ѿше2҃а1в҃а1т҃а2л҃а2х҃а́1҃а̑1҃го1҃е1с҃ен1҃ер1҃ло2҃лє1҃не2҃нї1҃о1л҃о1н҃о1р҃о1с҃оꙋ1҃ре2҃рї1҃се2҃ст2҃сѡ1҃ше2҃є́2҃і́1҃ѣ́2҃ꙋ́1҆1бщ҆1ве҆1ви҆1вы҆1вѝ҆1вѣ҆1вѧ҆1вѵ҆1д2҆1ж2҆1зи҆1зы҆1ла҆1ле҆1ли҆1ло҆1лі҆1лї҆1лѝ҆1ма҆1ме҆1ми҆1мл҆1мо҆1мы҆1мѣ҆1на҆1не҆1ни҆1но҆1ны҆1ні҆1нѝ҆1нѣ҆1па҆1пе҆1пл҆1по҆1пі҆1пѡ҆1ра҆1ре҆1ри҆1ро҆1рѧ҆1са҆1си҆1см҆1сѝ҆1сѣ҆1фі҆1ї1҆1ꙋ́҆1ꙋс҆2чт҆́1к҆́1т҆́1ш҆́2л҆́б2҆́г2҆́и1҆́с2҆́ю1҆а1д҆а̑1҆б1н҆в1в҆г2г҆г2л҆г2н҆дї1҆е2с҆ер2҆з1в҆з1л҆зо2҆ке1҆кї2҆кѷ1҆л1м҆л1п҆м1в҆н1д҆н1т҆н1ц҆н1ѳ҆нї1҆пї1҆р1д҆р1к҆р1п҆р1с҆р1т҆р1х҆с1с҆с2л҆сї1҆сѷ2҆т2л҆т2ц҆ше1҆шꙋ2҆щѧ2҆є́1҆ѡ1н҆ѡ1р҆ѡ1с҆ѡ́1҆ѯа1҆ѳа1҆ѵ1к҆ѵ1л҆ѵ1р҆ѵ1с҆ѻр1҇е1в҇и́1҇ко2҇лї1҇нї1҇нꙋ1҇ро2҇ть1҇тї1҇ша1҇ше1҇ї1ⷢї1ⷣна1ⷣне2ⷣнї1ⷣтї1ⷣце2ꙋ1брꙋ1выꙋ1г2ꙋ1даꙋ1деꙋ1доꙋ1дыꙋ1діꙋ1дѣꙋ1ж2ꙋ1зиꙋ1к2ꙋ1леꙋ1п2ꙋ1с2ꙋ1тиꙋ1хоꙋ1щ2ꙋ2й1ꙋ́1цꙋ́ф2ꙋ́ї1ꙋ̑1бꙋ̑1кꙋа́1ꙋб1нꙋе́1ꙋи2мꙋи́2ꙋй1ꙋка2ꙋкꙋ2ꙋл1вꙋна2ꙋно2ꙋпа2ꙋпо1ꙋр1вꙋр1гꙋр1тꙋсї1ꙋх1нꙋчꙋ2ꙋша2ꙋшꙋ2ꙋщє1ꙋщї1ꙋщѧ1ꙋщꙋ1ꙋі́2ꙗ҆1пꙗ҆1рꙗ҆̀1", + 5 : "1а1ні1а́мь1а́ню1а̑нѧ1алле1ам1в1амер1анні1анꙋа1арѡ̑1б2дѣ1б2з21б2лѝ1б2ре1б2ри1б2ро1б2ры1б2рѧ1бли́1ближ1блим1блис1блю́1блѧ_1блѧ̀1блѧ̑1блѧг1бра_1бра̀1бра̑1браг1браж1браз1бран1браѧ1брє11брї11брѣ_1брѣй1брѣс1брѣт1брꙋ̀1брꙋю1бщї21в2до1в2ды1в2ді1в2дѣ1в2дꙋ1в2з21в2ла1в2лі1в2лѣ1в2р21в2ча1в2ѷ1ва1т1ва́е1ва́й1ва́м1ва́ю1ва́ѧ1ва̑р1ва̑ю1вагѡ1вай1вак21валъ1вани1ванн1ванї1варс1варъ1вары1варѝ1варѡ1варѧ1вахо1вахꙋ1вда_1ве1л1ве1т1ве1ч1ве́а1ве́д1ве́и1ве́к1ве́м1ве́с1ве́т1ве́ц1ведд1веди1ведо1ведꙋ1вена1вене1вени1венц1вера1верз1вери1верш1веръ1верꙋ1вецъ1ви1н1ви́д1ви́м1ви́н1ви́р1ви́ц1ви́ш1вирї1вича1вичю1вичѣ1вичꙋ1влек1влеч1влещ1вна̀1внег1внѡ́1внѣ̀1внꙋ̀1во́л1во́н1во́т1во́ю1вовѣ1вода1води1воды1водѝ1водѣ1вое_1вожꙋ1возб1возв1возг1возм1возн1возс1возш1вомꙋ1воп21воро1вот21вца́1вче́1вый1выма1вє́с1вї1м1вїй1вѡ́л1вѡ́р1вѡ́т1вѣ́д1вѣ́е1вѣ́ж1вѣ́й1вѣ́м1вѣ́н1вѣ́ц1вѣ̑д1вѣ̑к1вѣ̑с1вѣ̑т1вѣд21вѣй1вѣмъ1вѣрѧ1вѣщє1вѧ1х1вѧ́ш1вѧ́щ1вѧзе1вѧтс1вѧтъ1вѧть1вѧщи1вѧщы1вѧщї1вѵ́п1вꙋ1д1вꙋ1х1вꙋ́_1вꙋ́л1вꙋ́т1вꙋю_1г2гі1г2ли1г2лі1г2лѡ1г2лѣ1г2лѧ1г2но1г2ні1г2нѝ1г2нѣ1г2нѧ1г2р21г2ца1г2ї1га1с1га1т1га́в1га́е1га́й1га́л1га́м1га́н1га́п1га́т1га́ю1га́ѳ1га̑т1гай1гдо21ги1с1ги́б1ги́з1ги̑21глот1гне́1гнед1гнез1гнен1гнеп1гнер1гнец1гниц1гнꙋш1го́_1го́д1го́р1го́х1го́ш1го́ю1гоб21гова1гови1говм1гогл1гогр1годи1годо1годꙋ1гож21гопи1гопл1гопѣ1гори1горо1горч1горї1госв1госѧ1гох21гоча1гоѡч1гоᲂу1гоꙋв1гі́а1гі́е1гі́и1гі́ю1гі̑11д2ви1д2ри1д2ро1д2ры1д2рі1д2рѡ1д2рꙋ1да1д1да1р1да1т1да́й1да́к1да́м1да́р1да̑р1да̑т1дайт1дала1дале1далъ1далї1дама1данъ1данї1дахꙋ1два̀1двор1де1в1де2х1де́а1де́б1де́ж1де́и1де́р1де́с1де́т1де́ц1де́ю1де́є1де́ѡ1дей1дер11деса1десе1десн1десы1десѐ1десѝ1десѣ1десѧ1дета1дете1деѡ́1дме11дмо21дне́1днеа1днеє1днол1днос1дны_1днꙋе1днꙋи1до1н1дове1дово1довы1дож21дос21дот21доꙋм1дра_1дра̀1драг1драж1драѧ1дре_1ды2р1дый1дє́ж1дє́и1дє́й1ді́д1ді́и1ді́м1ді́с1ді́ѳ1дїа1дїи1дїй1дїф1дїц1дїю1дїѐ1дїѝ1дїѡ1дї1г1дїѐ1дїе́1дїѧ̀1дїѧ́1дѣ1с1дѣ1т1дꙋ́е1дꙋ́х1дꙋ́ш1дꙋи21дꙋш21е1рѡ1е́мы1е́мь1е́ѵк1евск1един1езек1ейж1емаѧ1еми_1емою1емїи1ерꙋс1ессе1етас1етес1еꙋго1ж2жи1ж2ї1ждо11же1л1же2м1же́й1же́с1жей1жє́м1жꙋ́с1жꙋт11з2рю1з2рѝ1з2ї11зва̀1зва́1зван1зда̑1здѣ_1зе1с1зе́й1зе́н1зе́ю1зи1т1злат1злащ1зна̀1зна́1знав1знет1знех1знод1знꙋ́1зри_1зрим1зрит1зриш1зрѣ̀1зрѧ̀1зрѧт1зы1к1зы́й1зы́к1зы́ц1зы́ч1зыди1зѧ́б1зѧ́м1зѧ́щ1зꙋ́е1зꙋ́ѧ1зꙋме1зꙋми1зꙋмл1зꙋмѝ1зꙋю21и1лю1и1мѝ1и́мш1и̑мш1идꙋ21илев1илем1иль_1ильт1илѧ_1имен1имѝ1имод1имꙋ̀1имꙋ́1ине_1ини_1инст1инѡв1испѡ1иха_1ичнѡ1ка1в1ка1д1ка1т1ка́в1ка́е1ка́з1ка́й1ка́п1ка́р1ка́ѳ1ка̑в1каго1каѧ́1квї21ке́и1ке́к1ке́с1ки́т1ки́ф1кли́1клис1клиц1клю11клїй1клѧ21ко1л1ко́з1ко́и1ко́л1ко́н1ко́с1ко́х1ко́ш1ко́ѧ1коег1коей1коем1кож21кои11комч1кона1коне1коно1конъ1коны1конє1коні1конꙋ1копѣ1кори1корм1косн1косы1косѣ1коть1коꙋ11крыв1ктє11ктї11кхе21кі́а1кі́и1кі́м1кі́н1кїа1кїе1кі̑й1кѡ́н1кѡ́т1кѡ̑11кѡва1кѡве1кѡвл1кѡво1кѡвꙋ1кꙋ1т1кꙋ́е1кꙋ́и1кꙋ́й1кꙋ́л1кꙋ́м1кꙋ́н1кꙋ́т1кꙋст1кꙋша1ла́_1ла́а1ла́е1ла́й1ла́р1ла́ю1ла́ѣ1ла́ѧ1лавш1лавъ1лай1лакт1лама1лами1ламъ1ланн1ланї1ласѧ1лате1лаю11лаѧй1ле́а1ле́е1ле́и1ле́с1ле́х1леа11легл1лежи1лежѐ1лезв1лемѡ1леса1лесн1лесы1лесѐ1лесє1лесѝ1лесѣ1лете1летс1летѣ1летѧ1леце1лецъ1леѡ21ли2х1ли́в1ли́л1ли́н1ли́с1ли́х1ли́ц1ли́ч1ли́ш1ли̑т1ли̑ч1ли̑щ1лико1лимс1лимт1линг1лини1лины1линѡ1лице1лиши1ло1л1ло́_1ло́г1ло́ж1ло́м1лобы1лова1ловс1ловъ1ловы1лові1ловѣ1ловꙋ1лодъ1ложа1ложи1ложꙋ1ломе1ломѡ1лоро1лорꙋ1лос21лы̑_1лю́_1лю́б1лю́с1лютс1люща1лющи1лющы1лющї1лющꙋ1лє́з1лєны1лі́м1лі́н1лі́п1лїн1лїо1лїс1лїт1лїч1лїѐ1лїѝ1лїѡ1лї1к1лї1л1лї1м1лїа̀1лїан1лїѐ1лїев1лїѝ1лїи́1лїим1лїин1лїпп1лїю̀1лїѧ_1лїѧ̑1лѡ́в1лѡ́г1лѡ́с1лѡть1лѡтї1лѣ1в1лѣ́з1лѣ́л1лѣ́т1лѣ́х1лѣ̑_1лѣ̑з1лѣжа1лѣже1лѣй1лѣпи1лѧ1н1лѧ1ц1лѧ́щ1лѧй1лѧтс1лѷка1лꙋ́е1лꙋ́й1лꙋ́ф1лꙋ́ю1лꙋ́ї1лꙋ̑_1лꙋ̑ч1лꙋй1м2лє1м2лѝ1м2пе1м2р21ма1л1ма1с1ма́_1ма́й1ма́н1ма́р1ма́с1ма́х1ма́ю1ма́ѧ1ма̑11маг21мамъ1мамы1марі1мат21ме1в1ме2м1ме́а1ме́в1ме́е1ме́й1ме́н1ме́т1мерш1мерщ1меръ1меѡ21ми1л1ми́_1ми́в1ми́л1ми́н1ми́х1ми́ш1мира1мирѝ1млѐ1млю̀1млѧ̀1множ1мо́г1мо́ж1мо́л1мо́м1мо́с1мо́щ1мов21мога1моге1мого1могꙋ1мола1моли1молч1молю1молѝ1мос21моты1мотꙋ1мый1мыш11мі́а1мі́и1мі́р1мі́ю1мїа1мїе1мїй1мїр1мїѝ1мїѧ1мї1л1мї1н1мї1с1мїи_1мїѝ1мїй1мїѡ11мѣ1в1мѣне1мѣнѝ1мѧ1н1мѧти1мѧтн1мѧтс1мѧть1мѧтї1мѵ́л1на1н1на1т1на1ѯ1на́д1на́и1на́к1на́р1на́ѳ1на̑11нави1насс1наст1насѧ1не1ѵ1не́_1не́а1не́и1не́н1не́ц1нева1невѣ1него1негъ1неди1неді1недѣ1немо1немп1немс1немꙋ1нени1нено1ненꙋ1непо1неѡ́1неѡп1ни1р1ни́_1ни́м1ни́н1ни́р1ни́х1ни́ч1ни́ш1нико1никѣ1нисі1нисѧ1нитс1нитъ1ниха1нихо1нихс1нихꙋ1ницꙋ1но1н1но1р1но́в1но́с1но́щ1но́ї1нови1новл1новъ1новы1нові1новѝ1новѡ1новѧ1новꙋ1ногд1ногр1ноде1нодꙋ1ное21ножд1ной1нолѣ1нома1номе1номо1номъ1номы1номꙋ1нопи1нопл1нопр1носи1носѧ1нота1нотв1ноєѵ1ны̑_1ны̑м1ный1ныма1ні́г1ні́и1ні́к1ні́л1ні́н1ні́с1ні́ч1нѣ́_1нѣ́м1нѣ́х1нѣми1нѧ1н1нѧ2х1нѧ́е1нѧ́й1нѧ́ю1нѧ́ѧ1нѧго1нѧгѡ1нꙋ1р1нꙋ2л1нꙋ2х1нꙋ́_1нꙋ́е1нꙋ́и1нꙋ́х1нꙋич1нꙋти1нꙋтъ1нꙋю_1о́пѣ1овою1огно1огні1опе́1п2ла1п2ли1п2ло1п2лы1п2лі1п2лѣ1п2р21п2ї1па1в1па1л1па́е1па́л1па́м1па́р1па́т1па́ѵ1па̑11пада1падн1падъ1падѐ1падѝ1падѣ1падꙋ1пе1в1пе1ч1пе́в1пе́л1пе́м1пе́р1пе́щ1перв1пере1перн1перѧ1пи1р1пи1с1пи̑11пино1пины1пинѣ1пинꙋ1питъ1пле_1плет1плещ1плю_1плют1плѧ_1плѧм1пны́1по́й1по́л1по́м1по́н1по́с1побѣ1поді1подѡ1пое21пожр1поч21пто21пі́и1пі́с1пѡ1в1пѡ́в1пѡ́н1пѡ̑21пѣ1л1пѧ́ш1ра́р1ра́ѯ1раві1раек1разл1разр1разс1рала1рапо1рапї1раск1расл1ратр1ре́к1ре́ѳ1рева1ревн1рей_1реко1рекі1рекꙋ1ремї1ренъ1рень1ресь1реті1ретї1рехъ1рецъ1речѐ1речє1рещи1ри́н1ри́х1ри̑_1ри̑г1ри̑м1рина1ро́д1ро́е1ро́ж1роде1роди1родн1родѝ1родѧ1рожд1роно1ронѡ1ропѣ1ропꙋ1ротв1ротѣ1ротꙋ1рохи1ры́г1ры́ѧ1рю́11рє́м1рє́н1рєѝ1рі́а1рі́и1рі́м1рі́ю1рі́ѧ1рїд1рїн1рїц1рї1л1рїин1рїкъ1рїсе1рїсє1рїтѡ1рѡ2с1рѡ́к1рѡ̑11рѡма1рѣ2ч1рѣ́_1рѣ́е1рѣ́й1рѣ̑й1рѧ́д1рѷн1рѷѱ1рѷ1м1рѷ2к1рꙋ1в1рꙋ́л1рꙋ́х1рꙋ́ш1рꙋ́ю1рꙋ́ѳ1рꙋ̑с1рꙋем1рꙋет1рꙋеш1рꙋй1рꙋмы1рꙋче1рꙋющ1рꙋѧ_1рꙋѧй1с2в21с2ка1с2ке1с2ки1с2ко1с2кр1с2кі1с2кѣ1с2нѝ1с2пѝ1с2пѡ1с2р21с2та1с2ти1с2ты1с2тѐ1с2ті1с2тѡ1с2тѣ1с2тѧ1с2тꙋ1с2ха1с2хꙋ1са́_1са́в1са́н1са́ф1са́х1са́ю1са́є1са́ѵ1се́а1се́е1се́и1се́о1се́р1се́є1сей1селѡ1сенъ1серъ1сехъ1сецъ1сеѡ́1си1к1си1х1си2л1си́в1си́л1си́м1си́ш1скꙋ_1скꙋд1скꙋю1смѝ1смꙋ11сна̀1сна́1сней1снех1снец1сниц1сно́1сноб1снож1сноп1снос1снот1снїю1со1н1соб21сове1совѡ1сомꙋ1соп21сот21соч21спа́1спе_1спи́1спод1спож1спѣ̀1спѣш1ства1стве1стви1ствы1ствє1ствї1ствѣ1сте_1стей1стен1стес1стех1стла1сто_1стоб1стов1стод1стое1стож1стои1сток1стол1стом1стон1стот1стоф1стох1стош1стою1стоѡ1стоѧ1стоѱ1стра1стри1стро1стры1стрѐ1стрі1стрѝ1стрѣ1стрѵ1схи_1сцы̀1сы1р1сы́_1сы́п1сє́й1сѡ1т1сѣ1д1сѣ1т1сѣ1ч1сѣ́д1сѣ́к1т2кн1т2лѝ1т2цє1т2цꙋ1т2чѐ1т2чꙋ1т2щ21та1л1та1т1та2х1та́п1та̑ѧ1тава1тавш1тавъ1таго1тана1танн1танꙋ1таре1тарю1тарѝ1тарѧ1таю_1тают1тваг1твар1твер1тви_1твѝ1твор1твос1твый1твым1твых1твыѧ1те́ж1те́п1текꙋ1тера1терб1терг1тере1терз1тери1терн1терс1теры1терь1тері1терї1теск1тецъ1течѐ1ти́р1ти̑_1ти̑л1тила1тлѣ̑1то́п1то́х1то́ш1то́ю1това1тово1товъ1товы1товѣ1тода1тодн1тодї1толѝ1толѧ1толꙋ1тоні1топе1топи1топѝ1топѧ1торж1торн1торѣ1тост1тотв1точа1точи1точє1точѝ1тоща1тощѝ1тоꙋ21тре_1треб1трен1треп1трил1тро_1трок1троп1трос1троф1троц1троч1тры_1трї1трꙋб1трꙋж1тца_1тцы_1тцы̀1тцѣ̀1тча_1тчах1тчее1тчей1тчею1ты́м1ты́х1ты́ѧ1ты̑_1ты̑ѧ1тыма1тє́й1тє́ц1тєск1ті́а1ті́ч1ті́ю1ті́ѡ1тїй1тїк1тїо1тїф1тїѐ1тїѝ1ті̑11тї1п1тїа_1тїѐ1тїе́1тїею1тїѝ1тїй1тїих1тїю̀1тїѧ̀1тїѧг1тїѧм1тїѧх1тѡ́н1тѡлі1тѣ1с1тѣ2р1тѣ́в1тѣ́л1тѣ́м1тѧ1з1тѧ́й1тѧ́ш1тѧже1ф2р21фі́в1фі́и1фі́л1фі́м1фі́н1х2ма1х2р21х2ті1хи2м1хо1в1хо1л1хо1с1хо2р1хо́м1хода1ходв1хот21ца1р1ца2х1ца́_1ца́е1ца́р1ца́х1ца́ѧ1це1в1це1н1це1с1це́в1цемѣ1цє́м1цєва1цї11цѣ2м1цѣ2х1цѣй1ч2ти1ч2ю11что̀1чⷭ҇т1чꙋ1д1ш2ѧ11щ2ї1ща1в1ща1д1ща1м1ща1н1ща2х1ща́в1ща́е1ща́ю1щаѧ11ю1ж21ю́тс1ю́ща1ю́ще1ю́щи1ю́щѧ1ющас1ющаѧ1ющис1ющих1ющыѧ1ющїи1ющїѧ1ющꙋс1ющꙋю1є́нѣ1єма_1і́мв1і́нт1їнъ1їтѝ1їѳа1ї1лѧ1ї1ны1їина1їно_1їтѝ1ѡ1б21ѡ1де1ѡ́дь1ѡа1с1ѡа́д1ѡа́н1ѡа́с1ѡи́л1ѡнаѳ1ѡпи21ѡра́1ѡрꙋ́1ѡрꙋж1ѡстр1ѡсѧ́1ѡсꙋ11ѧ1на1ѧ́2р1ѧ́ла1ѧ́ли1ѧ́са1ѧ́тѣ1ѧ́хо1ѧ́ши1ѧдѐ1ѧнї11ѧса_1ѧша11ѳе1м1ѳе́ю1ѳі́а1ѳі́м1ѳі̑11ѵ2е21ѵ2ї11ѷ1сє1ѷпо11ѻ1г21ѻ1т21ᲂу1х1ꙋ1ве1ꙋ1вѣ1ꙋ1вѧ1ꙋ1дє1ꙋ1ха1ꙋ́зъ1ꙋ́лї1ꙋ́лꙋ1ꙋ́мн1ꙋ́нї1ꙋ́чи1ꙋ̑ди1ꙋ̑мн1ꙋгас1ꙋгот1ꙋдоб1ꙋказ1ꙋкло1ꙋклѡ1ꙋмев1ꙋмо21ꙋмы_1ꙋмѣ_1ꙋмѣв1ꙋсо́1ꙋстї2а1де2а1дѣ2а1ж22а1на2а1ни2а1п22а1ре2а1ри2а1рѝ2а1рѧ2а1ф22а2й12а́1п2а́2ѯ2а́ї2а̑х12адѝ2аз1л2анї12асѧ12б1ви2б1вѝ2б1де2б1лє2б1с22бвѐ2в1ли2в1ны2в1цє2в1ш22внї2воѐ2вчї12вѣ1л2г1к22г1с22г1цѣ2г1ш22г2лы2г2лꙋ2г2ъ12га1р2гн1ц2гн1ч2д1г22д1з22д1нѝ2д1п22д1ц22д1ш22д2̾12д2ь12де1л2днї2др1с2е1ве2е1ді2е1ли2е1лѡ2е1лѧ2е1ме2е1мѝ2е1мѣ2е1се2е1ск2е1тв2е1ти2е1тр2е1тѐ2е1тє2е1ті2е1тѝ2е1тѧ2е1хо2е́1ѳ2е́2ц2е́є22екї12ем1н2емѝ2етѐ2еше22ж1н22ж1с22жд1н2жд1с2з1б22з1ве2з1ви2з1вл2з1во2з1вы2з1вѝ2з1вꙋ2з1г22з1де2з1ж22з1з22з1ле2з1ло2з1лю2з1лѡ2з1м22з1ны2з1п22з1с22з1ш22з2̾12зд2р2здꙋ22зи1м2зы1с2и1ва2и1г22и̑1г2ища22к1к22к1с22к1ш22кен12кно12кꙋ1д2л1л22л1с22л2з12л2ь12лее22лѣ1д2лѣ1н2лѧ1м2лѧ1ч2м1ж22м1на2м1ны2м1ні2м1нꙋ2м1с22м1ф22м1ш22м1ѱ22м2ь12ма2х2мнї12мпї2мчї2мїю2мѣ1с2н1г22н1н22н1с22н1ш22н2ь12неа12нѣ1д2нѧ1з2о1ве2о1вѝ2о1вꙋ2о1ма2о1мо2о1си2о́1ш2овѝ2опї12ос2т2п1лє2п1ни2п1нѣ2пнї12пѣш22р1ца2р1цє2р1цѣ2р1цꙋ2р1ш22р2ь12ри1л2рим22риш22рѡ1т2рѧ1ц2рѧ2т2рѷп2рѷ1с2рꙋ2т2с1пн2с1ца2с1цѣ2с2ь12спы12спї12спѧ22спꙋ12ст1н2сть12сѡ1в2т1кї2т1ло2т1лы2т1лѡ2т1с22т1ш22ти1р2тка22тѡ1д2тѡ2р2тѣ1н2ф1с22х1мѝ2х1с22ч1та2ч1ш22ча2х2чей2ш1ли2ш1н22щ1в22щ1с22щ1ш22щ2ь12ще1в2є1ѝ2єм1н2ї1ю2ї1є2ї1ѝ2ї1ѧ2їа́2їѝ2їим2їих2ї1ка2ї1ки2ї1ла2ї1лї2їлї2їн1б2ѡ1ма2ѧ1зе2ѧ1зѧ2ѧ́2б2ѧ̑с22ѧза22ѧсе22ѧсо12ѷ1ѱ2ѷпр2ѷпі2ѷс1с2ꙋ1ви2ꙋ1те2ꙋ1ті2ꙋ1тѝ2ꙋм2н2ꙋмѧ22ꙋса12ꙋтѝ8а̀8_8а́8_8а̑8_8аⷠ҇_8аⷡ҇_8аⷢ҇_8аⷣ҇_8аⷤ҇_8аⷥ҇_8аⷦ҇_8аⷧ҇_8аⷨ҇_8аⷩ҇_8аⷪ҇_8аⷫ҇_8аⷬ҇_8аⷭ҇_8аⷮ҇_8аⷯ҇_8аⷰ҇_8аⷱ҇_8аⷲ҇_8аⷳ҇_8аⷴ҇_8аⷵ҇_8аⷶ҇_8аⷷ҇_8аⷸ҇_8аⷹ҇_8аⷺ҇_8аⷻ҇_8аⷼ҇_8аⷽ҇_8аⷾ҇_8аⷿ҇_8аꙴ҇_8аꙵ҇_8аꙶ҇_8аꙷ҇_8аꙸ҇_8аꙹ҇_8аꙺ҇_8аꙻ҇_8а꙼҇_8а꙽҇_8ѐ8_8е́8_8ё8_8е̑8_8еⷠ҇_8еⷡ҇_8еⷢ҇_8еⷣ҇_8еⷤ҇_8еⷥ҇_8еⷦ҇_8еⷧ҇_8еⷨ҇_8еⷩ҇_8еⷪ҇_8еⷫ҇_8еⷬ҇_8еⷭ҇_8еⷮ҇_8еⷯ҇_8еⷰ҇_8еⷱ҇_8еⷲ҇_8еⷳ҇_8еⷴ҇_8еⷵ҇_8еⷶ҇_8еⷷ҇_8еⷸ҇_8еⷹ҇_8еⷺ҇_8еⷻ҇_8еⷼ҇_8еⷽ҇_8еⷾ҇_8еⷿ҇_8еꙴ҇_8еꙵ҇_8еꙶ҇_8еꙷ҇_8еꙸ҇_8еꙹ҇_8еꙺ҇_8еꙻ҇_8е꙼҇_8е꙽҇_8ѝ8_8и́8_8йⷠ_8йⷡ_8йⷢ_8йⷣ_8йⷤ_8йⷥ_8йⷦ_8йⷧ_8йⷨ_8йⷩ_8йⷪ_8йⷫ_8йⷬ_8йⷭ_8йⷮ_8йⷯ_8йⷰ_8йⷱ_8йⷲ_8йⷳ_8йⷴ_8йⷵ_8йⷶ_8йⷷ_8йⷸ_8йⷹ_8йⷺ_8йⷻ_8йⷼ_8йⷽ_8йⷾ_8йⷿ_8йꙴ_8йꙵ_8йꙶ_8йꙷ_8йꙸ_8йꙹ_8йꙺ_8йꙻ_8й꙼_8й꙽_8и̑8_8иⷠ҇_8иⷡ҇_8иⷢ҇_8иⷣ҇_8иⷤ҇_8иⷥ҇_8иⷦ҇_8иⷧ҇_8иⷨ҇_8иⷩ҇_8иⷪ҇_8иⷫ҇_8иⷬ҇_8иⷭ҇_8иⷮ҇_8иⷯ҇_8иⷰ҇_8иⷱ҇_8иⷲ҇_8иⷳ҇_8иⷴ҇_8иⷵ҇_8иⷶ҇_8иⷷ҇_8иⷸ҇_8иⷹ҇_8иⷺ҇_8иⷻ҇_8иⷼ҇_8иⷽ҇_8иⷾ҇_8иⷿ҇_8иꙴ҇_8иꙵ҇_8иꙶ҇_8иꙷ҇_8иꙸ҇_8иꙹ҇_8иꙺ҇_8иꙻ҇_8и꙼҇_8и꙽҇_8й̀8_8й́8_8й̈8_8й̑8_8йⷠ҇_8йⷡ҇_8йⷢ҇_8йⷣ҇_8йⷤ҇_8йⷥ҇_8йⷦ҇_8йⷧ҇_8йⷨ҇_8йⷩ҇_8йⷪ҇_8йⷫ҇_8йⷬ҇_8йⷭ҇_8йⷮ҇_8йⷯ҇_8йⷰ҇_8йⷱ҇_8йⷲ҇_8йⷳ҇_8йⷴ҇_8йⷵ҇_8йⷶ҇_8йⷷ҇_8йⷸ҇_8йⷹ҇_8йⷺ҇_8йⷻ҇_8йⷼ҇_8йⷽ҇_8йⷾ҇_8йⷿ҇_8йꙴ҇_8йꙵ҇_8йꙶ҇_8йꙷ҇_8йꙸ҇_8йꙹ҇_8йꙺ҇_8йꙻ҇_8й꙼҇_8й꙽҇_8о̀8_8о́8_8о̑8_8оⷠ҇_8оⷡ҇_8оⷢ҇_8оⷣ҇_8оⷤ҇_8оⷥ҇_8оⷦ҇_8оⷧ҇_8оⷨ҇_8оⷩ҇_8оⷪ҇_8оⷫ҇_8оⷬ҇_8оⷭ҇_8оⷮ҇_8оⷯ҇_8оⷰ҇_8оⷱ҇_8оⷲ҇_8оⷳ҇_8оⷴ҇_8оⷵ҇_8оⷶ҇_8оⷷ҇_8оⷸ҇_8оⷹ҇_8оⷺ҇_8оⷻ҇_8оⷼ҇_8оⷽ҇_8оⷾ҇_8оⷿ҇_8оꙴ҇_8оꙵ҇_8оꙶ҇_8оꙷ҇_8оꙸ҇_8оꙹ҇_8оꙺ҇_8оꙻ҇_8о꙼҇_8о꙽҇_8у̀8_8у́8_8у̑8_8уⷠ҇_8уⷡ҇_8уⷢ҇_8уⷣ҇_8уⷤ҇_8уⷥ҇_8уⷦ҇_8уⷧ҇_8уⷨ҇_8уⷩ҇_8уⷪ҇_8уⷫ҇_8уⷬ҇_8уⷭ҇_8уⷮ҇_8уⷯ҇_8уⷰ҇_8уⷱ҇_8уⷲ҇_8уⷳ҇_8уⷴ҇_8уⷵ҇_8уⷶ҇_8уⷷ҇_8уⷸ҇_8уⷹ҇_8уⷺ҇_8уⷻ҇_8уⷼ҇_8уⷽ҇_8уⷾ҇_8уⷿ҇_8уꙴ҇_8уꙵ҇_8уꙶ҇_8уꙷ҇_8уꙸ҇_8уꙹ҇_8уꙺ҇_8уꙻ҇_8у꙼҇_8у꙽҇_8ы̀8_8ы́8_8ы̑8_8ыⷠ҇_8ыⷡ҇_8ыⷢ҇_8ыⷣ҇_8ыⷤ҇_8ыⷥ҇_8ыⷦ҇_8ыⷧ҇_8ыⷨ҇_8ыⷩ҇_8ыⷪ҇_8ыⷫ҇_8ыⷬ҇_8ыⷭ҇_8ыⷮ҇_8ыⷯ҇_8ыⷰ҇_8ыⷱ҇_8ыⷲ҇_8ыⷳ҇_8ыⷴ҇_8ыⷵ҇_8ыⷶ҇_8ыⷷ҇_8ыⷸ҇_8ыⷹ҇_8ыⷺ҇_8ыⷻ҇_8ыⷼ҇_8ыⷽ҇_8ыⷾ҇_8ыⷿ҇_8ыꙴ҇_8ыꙵ҇_8ыꙶ҇_8ыꙷ҇_8ыꙸ҇_8ыꙹ҇_8ыꙺ҇_8ыꙻ҇_8ы꙼҇_8ы꙽҇_8э̀8_8э́8_8э̑8_8эⷠ҇_8эⷡ҇_8эⷢ҇_8эⷣ҇_8эⷤ҇_8эⷥ҇_8эⷦ҇_8эⷧ҇_8эⷨ҇_8эⷩ҇_8эⷪ҇_8эⷫ҇_8эⷬ҇_8эⷭ҇_8эⷮ҇_8эⷯ҇_8эⷰ҇_8эⷱ҇_8эⷲ҇_8эⷳ҇_8эⷴ҇_8эⷵ҇_8эⷶ҇_8эⷷ҇_8эⷸ҇_8эⷹ҇_8эⷺ҇_8эⷻ҇_8эⷼ҇_8эⷽ҇_8эⷾ҇_8эⷿ҇_8эꙴ҇_8эꙵ҇_8эꙶ҇_8эꙷ҇_8эꙸ҇_8эꙹ҇_8эꙺ҇_8эꙻ҇_8э꙼҇_8э꙽҇_8ю̀8_8ю́8_8ю̈8_8ю̑8_8юⷠ҇_8юⷡ҇_8юⷢ҇_8юⷣ҇_8юⷤ҇_8юⷥ҇_8юⷦ҇_8юⷧ҇_8юⷨ҇_8юⷩ҇_8юⷪ҇_8юⷫ҇_8юⷬ҇_8юⷭ҇_8юⷮ҇_8юⷯ҇_8юⷰ҇_8юⷱ҇_8юⷲ҇_8юⷳ҇_8юⷴ҇_8юⷵ҇_8юⷶ҇_8юⷷ҇_8юⷸ҇_8юⷹ҇_8юⷺ҇_8юⷻ҇_8юⷼ҇_8юⷽ҇_8юⷾ҇_8юⷿ҇_8юꙴ҇_8юꙵ҇_8юꙶ҇_8юꙷ҇_8юꙸ҇_8юꙹ҇_8юꙺ҇_8юꙻ҇_8ю꙼҇_8ю꙽҇_8є̀8_8є́8_8є̈8_8є̑8_8єⷠ҇_8єⷡ҇_8єⷢ҇_8єⷣ҇_8єⷤ҇_8єⷥ҇_8єⷦ҇_8єⷧ҇_8єⷨ҇_8єⷩ҇_8єⷪ҇_8єⷫ҇_8єⷬ҇_8єⷭ҇_8єⷮ҇_8єⷯ҇_8єⷰ҇_8єⷱ҇_8єⷲ҇_8єⷳ҇_8єⷴ҇_8єⷵ҇_8єⷶ҇_8єⷷ҇_8єⷸ҇_8єⷹ҇_8єⷺ҇_8єⷻ҇_8єⷼ҇_8єⷽ҇_8єⷾ҇_8єⷿ҇_8єꙴ҇_8єꙵ҇_8єꙶ҇_8єꙷ҇_8єꙸ҇_8єꙹ҇_8єꙺ҇_8єꙻ҇_8є꙼҇_8є꙽҇_8і̀8_8і́8_8ї8_8і̑8_8іⷠ҇_8іⷡ҇_8іⷢ҇_8іⷣ҇_8іⷤ҇_8іⷥ҇_8іⷦ҇_8іⷧ҇_8іⷨ҇_8іⷩ҇_8іⷪ҇_8іⷫ҇_8іⷬ҇_8іⷭ҇_8іⷮ҇_8іⷯ҇_8іⷰ҇_8іⷱ҇_8іⷲ҇_8іⷳ҇_8іⷴ҇_8іⷵ҇_8іⷶ҇_8іⷷ҇_8іⷸ҇_8іⷹ҇_8іⷺ҇_8іⷻ҇_8іⷼ҇_8іⷽ҇_8іⷾ҇_8іⷿ҇_8іꙴ҇_8іꙵ҇_8іꙶ҇_8іꙷ҇_8іꙸ҇_8іꙹ҇_8іꙺ҇_8іꙻ҇_8і꙼҇_8і꙽҇_8ѡ̀8_8ѡ́8_8ѡ̈8_8ѡ̑8_8ѡⷠ҇_8ѡⷡ҇_8ѡⷢ҇_8ѡⷣ҇_8ѡⷤ҇_8ѡⷥ҇_8ѡⷦ҇_8ѡⷧ҇_8ѡⷨ҇_8ѡⷩ҇_8ѡⷪ҇_8ѡⷫ҇_8ѡⷬ҇_8ѡⷭ҇_8ѡⷮ҇_8ѡⷯ҇_8ѡⷰ҇_8ѡⷱ҇_8ѡⷲ҇_8ѡⷳ҇_8ѡⷴ҇_8ѡⷵ҇_8ѡⷶ҇_8ѡⷷ҇_8ѡⷸ҇_8ѡⷹ҇_8ѡⷺ҇_8ѡⷻ҇_8ѡⷼ҇_8ѡⷽ҇_8ѡⷾ҇_8ѡⷿ҇_8ѡꙴ҇_8ѡꙵ҇_8ѡꙶ҇_8ѡꙷ҇_8ѡꙸ҇_8ѡꙹ҇_8ѡꙺ҇_8ѡꙻ҇_8ѡ꙼҇_8ѡ꙽҇_8ѣ̀8_8ѣ́8_8ѣ̈8_8ѣ̑8_8ѣⷠ҇_8ѣⷡ҇_8ѣⷢ҇_8ѣⷣ҇_8ѣⷤ҇_8ѣⷥ҇_8ѣⷦ҇_8ѣⷧ҇_8ѣⷨ҇_8ѣⷩ҇_8ѣⷪ҇_8ѣⷫ҇_8ѣⷬ҇_8ѣⷭ҇_8ѣⷮ҇_8ѣⷯ҇_8ѣⷰ҇_8ѣⷱ҇_8ѣⷲ҇_8ѣⷳ҇_8ѣⷴ҇_8ѣⷵ҇_8ѣⷶ҇_8ѣⷷ҇_8ѣⷸ҇_8ѣⷹ҇_8ѣⷺ҇_8ѣⷻ҇_8ѣⷼ҇_8ѣⷽ҇_8ѣⷾ҇_8ѣⷿ҇_8ѣꙴ҇_8ѣꙵ҇_8ѣꙶ҇_8ѣꙷ҇_8ѣꙸ҇_8ѣꙹ҇_8ѣꙺ҇_8ѣꙻ҇_8ѣ꙼҇_8ѣ꙽҇_8ѧ̀8_8ѧ́8_8ѧ̈8_8ѧ̑8_8ѧⷠ҇_8ѧⷡ҇_8ѧⷢ҇_8ѧⷣ҇_8ѧⷤ҇_8ѧⷥ҇_8ѧⷦ҇_8ѧⷧ҇_8ѧⷨ҇_8ѧⷩ҇_8ѧⷪ҇_8ѧⷫ҇_8ѧⷬ҇_8ѧⷭ҇_8ѧⷮ҇_8ѧⷯ҇_8ѧⷰ҇_8ѧⷱ҇_8ѧⷲ҇_8ѧⷳ҇_8ѧⷴ҇_8ѧⷵ҇_8ѧⷶ҇_8ѧⷷ҇_8ѧⷸ҇_8ѧⷹ҇_8ѧⷺ҇_8ѧⷻ҇_8ѧⷼ҇_8ѧⷽ҇_8ѧⷾ҇_8ѧⷿ҇_8ѧꙴ҇_8ѧꙵ҇_8ѧꙶ҇_8ѧꙷ҇_8ѧꙸ҇_8ѧꙹ҇_8ѧꙺ҇_8ѧꙻ҇_8ѧ꙼҇_8ѧ꙽҇_8ѵ̀8_8ѵ́8_8ѵ̈8_8ѵ̑8_8ѵⷠ҇_8ѵⷡ҇_8ѵⷢ҇_8ѵⷣ҇_8ѵⷤ҇_8ѵⷥ҇_8ѵⷦ҇_8ѵⷧ҇_8ѵⷨ҇_8ѵⷩ҇_8ѵⷪ҇_8ѵⷫ҇_8ѵⷬ҇_8ѵⷭ҇_8ѵⷮ҇_8ѵⷯ҇_8ѵⷰ҇_8ѵⷱ҇_8ѵⷲ҇_8ѵⷳ҇_8ѵⷴ҇_8ѵⷵ҇_8ѵⷶ҇_8ѵⷷ҇_8ѵⷸ҇_8ѵⷹ҇_8ѵⷺ҇_8ѵⷻ҇_8ѵⷼ҇_8ѵⷽ҇_8ѵⷾ҇_8ѵⷿ҇_8ѵꙴ҇_8ѵꙵ҇_8ѵꙶ҇_8ѵꙷ҇_8ѵꙸ҇_8ѵꙹ҇_8ѵꙺ҇_8ѵꙻ҇_8ѵ꙼҇_8ѵ꙽҇_8ѹ̀8_8ѹ́8_8ѹ̈8_8ѹ̑8_8ѹⷠ҇_8ѹⷡ҇_8ѹⷢ҇_8ѹⷣ҇_8ѹⷤ҇_8ѹⷥ҇_8ѹⷦ҇_8ѹⷧ҇_8ѹⷨ҇_8ѹⷩ҇_8ѹⷪ҇_8ѹⷫ҇_8ѹⷬ҇_8ѹⷭ҇_8ѹⷮ҇_8ѹⷯ҇_8ѹⷰ҇_8ѹⷱ҇_8ѹⷲ҇_8ѹⷳ҇_8ѹⷴ҇_8ѹⷵ҇_8ѹⷶ҇_8ѹⷷ҇_8ѹⷸ҇_8ѹⷹ҇_8ѹⷺ҇_8ѹⷻ҇_8ѹⷼ҇_8ѹⷽ҇_8ѹⷾ҇_8ѹⷿ҇_8ѹꙴ҇_8ѹꙵ҇_8ѹꙶ҇_8ѹꙷ҇_8ѹꙸ҇_8ѹꙹ҇_8ѹꙺ҇_8ѹꙻ҇_8ѹ꙼҇_8ѹ꙽҇_8ѻ̀8_8ѻ́8_8ѻ̈8_8ѻ̑8_8ѻⷠ҇_8ѻⷡ҇_8ѻⷢ҇_8ѻⷣ҇_8ѻⷤ҇_8ѻⷥ҇_8ѻⷦ҇_8ѻⷧ҇_8ѻⷨ҇_8ѻⷩ҇_8ѻⷪ҇_8ѻⷫ҇_8ѻⷬ҇_8ѻⷭ҇_8ѻⷮ҇_8ѻⷯ҇_8ѻⷰ҇_8ѻⷱ҇_8ѻⷲ҇_8ѻⷳ҇_8ѻⷴ҇_8ѻⷵ҇_8ѻⷶ҇_8ѻⷷ҇_8ѻⷸ҇_8ѻⷹ҇_8ѻⷺ҇_8ѻⷻ҇_8ѻⷼ҇_8ѻⷽ҇_8ѻⷾ҇_8ѻⷿ҇_8ѻꙴ҇_8ѻꙵ҇_8ѻꙶ҇_8ѻꙷ҇_8ѻꙸ҇_8ѻꙹ҇_8ѻꙺ҇_8ѻꙻ҇_8ѻ꙼҇_8ѻ꙽҇_8ѽ̀8_8ѽ́8_8ѽ̈8_8ѽ̑8_8ѽⷠ҇_8ѽⷡ҇_8ѽⷢ҇_8ѽⷣ҇_8ѽⷤ҇_8ѽⷥ҇_8ѽⷦ҇_8ѽⷧ҇_8ѽⷨ҇_8ѽⷩ҇_8ѽⷪ҇_8ѽⷫ҇_8ѽⷬ҇_8ѽⷭ҇_8ѽⷮ҇_8ѽⷯ҇_8ѽⷰ҇_8ѽⷱ҇_8ѽⷲ҇_8ѽⷳ҇_8ѽⷴ҇_8ѽⷵ҇_8ѽⷶ҇_8ѽⷷ҇_8ѽⷸ҇_8ѽⷹ҇_8ѽⷺ҇_8ѽⷻ҇_8ѽⷼ҇_8ѽⷽ҇_8ѽⷾ҇_8ѽⷿ҇_8ѽꙴ҇_8ѽꙵ҇_8ѽꙶ҇_8ѽꙷ҇_8ѽꙸ҇_8ѽꙹ҇_8ѽꙺ҇_8ѽꙻ҇_8ѽ꙼҇_8ѽ꙽҇_8ѿ̀8_8ѿ́8_8ѿ̈8_8ѿ̑8_8ѿⷠ҇_8ѿⷡ҇_8ѿⷢ҇_8ѿⷣ҇_8ѿⷤ҇_8ѿⷥ҇_8ѿⷦ҇_8ѿⷧ҇_8ѿⷨ҇_8ѿⷩ҇_8ѿⷪ҇_8ѿⷫ҇_8ѿⷬ҇_8ѿⷭ҇_8ѿⷮ҇_8ѿⷯ҇_8ѿⷰ҇_8ѿⷱ҇_8ѿⷲ҇_8ѿⷳ҇_8ѿⷴ҇_8ѿⷵ҇_8ѿⷶ҇_8ѿⷷ҇_8ѿⷸ҇_8ѿⷹ҇_8ѿⷺ҇_8ѿⷻ҇_8ѿⷼ҇_8ѿⷽ҇_8ѿⷾ҇_8ѿⷿ҇_8ѿꙴ҇_8ѿꙵ҇_8ѿꙶ҇_8ѿꙷ҇_8ѿꙸ҇_8ѿꙹ҇_8ѿꙺ҇_8ѿꙻ҇_8ѿ꙼҇_8ѿ꙽҇_8ᲂ̀8_8ᲂ́8_8ᲂ̈8_8ᲂ̑8_8ᲂу̀_8ᲂу́_8ᲂу̑_8ᲂуⷠ_8ᲂуⷡ_8ᲂуⷢ_8ᲂуⷣ_8ᲂуⷤ_8ᲂуⷥ_8ᲂуⷦ_8ᲂуⷧ_8ᲂуⷨ_8ᲂуⷩ_8ᲂуⷪ_8ᲂуⷫ_8ᲂуⷬ_8ᲂуⷭ_8ᲂуⷮ_8ᲂуⷯ_8ᲂуⷰ_8ᲂуⷱ_8ᲂуⷲ_8ᲂуⷳ_8ᲂуⷴ_8ᲂуⷵ_8ᲂуⷶ_8ᲂуⷷ_8ᲂуⷸ_8ᲂуⷹ_8ᲂуⷺ_8ᲂуⷻ_8ᲂуⷼ_8ᲂуⷽ_8ᲂуⷾ_8ᲂуⷿ_8ᲂуꙴ_8ᲂуꙵ_8ᲂуꙶ_8ᲂуꙷ_8ᲂуꙸ_8ᲂуꙹ_8ᲂуꙺ_8ᲂуꙻ_8ᲂу꙼_8ᲂу꙽_8ᲂⷠ҇_8ᲂⷡ҇_8ᲂⷢ҇_8ᲂⷣ҇_8ᲂⷤ҇_8ᲂⷥ҇_8ᲂⷦ҇_8ᲂⷧ҇_8ᲂⷨ҇_8ᲂⷩ҇_8ᲂⷪ҇_8ᲂⷫ҇_8ᲂⷬ҇_8ᲂⷭ҇_8ᲂⷮ҇_8ᲂⷯ҇_8ᲂⷰ҇_8ᲂⷱ҇_8ᲂⷲ҇_8ᲂⷳ҇_8ᲂⷴ҇_8ᲂⷵ҇_8ᲂⷶ҇_8ᲂⷷ҇_8ᲂⷸ҇_8ᲂⷹ҇_8ᲂⷺ҇_8ᲂⷻ҇_8ᲂⷼ҇_8ᲂⷽ҇_8ᲂⷾ҇_8ᲂⷿ҇_8ᲂꙴ҇_8ᲂꙵ҇_8ᲂꙶ҇_8ᲂꙷ҇_8ᲂꙸ҇_8ᲂꙹ҇_8ᲂꙺ҇_8ᲂꙻ҇_8ᲂ꙼҇_8ᲂ꙽҇_8ꙋ̀8_8ꙋ́8_8ꙋ̈8_8ꙋ̑8_8ꙋⷠ҇_8ꙋⷡ҇_8ꙋⷢ҇_8ꙋⷣ҇_8ꙋⷤ҇_8ꙋⷥ҇_8ꙋⷦ҇_8ꙋⷧ҇_8ꙋⷨ҇_8ꙋⷩ҇_8ꙋⷪ҇_8ꙋⷫ҇_8ꙋⷬ҇_8ꙋⷭ҇_8ꙋⷮ҇_8ꙋⷯ҇_8ꙋⷰ҇_8ꙋⷱ҇_8ꙋⷲ҇_8ꙋⷳ҇_8ꙋⷴ҇_8ꙋⷵ҇_8ꙋⷶ҇_8ꙋⷷ҇_8ꙋⷸ҇_8ꙋⷹ҇_8ꙋⷺ҇_8ꙋⷻ҇_8ꙋⷼ҇_8ꙋⷽ҇_8ꙋⷾ҇_8ꙋⷿ҇_8ꙋꙴ҇_8ꙋꙵ҇_8ꙋꙶ҇_8ꙋꙷ҇_8ꙋꙸ҇_8ꙋꙹ҇_8ꙋꙺ҇_8ꙋꙻ҇_8ꙋ꙼҇_8ꙋ꙽҇_8ꙍ̀8_8ꙍ́8_8ꙍ̈8_8ꙍ̑8_8ꙍⷠ҇_8ꙍⷡ҇_8ꙍⷢ҇_8ꙍⷣ҇_8ꙍⷤ҇_8ꙍⷥ҇_8ꙍⷦ҇_8ꙍⷧ҇_8ꙍⷨ҇_8ꙍⷩ҇_8ꙍⷪ҇_8ꙍⷫ҇_8ꙍⷬ҇_8ꙍⷭ҇_8ꙍⷮ҇_8ꙍⷯ҇_8ꙍⷰ҇_8ꙍⷱ҇_8ꙍⷲ҇_8ꙍⷳ҇_8ꙍⷴ҇_8ꙍⷵ҇_8ꙍⷶ҇_8ꙍⷷ҇_8ꙍⷸ҇_8ꙍⷹ҇_8ꙍⷺ҇_8ꙍⷻ҇_8ꙍⷼ҇_8ꙍⷽ҇_8ꙍⷾ҇_8ꙍⷿ҇_8ꙍꙴ҇_8ꙍꙵ҇_8ꙍꙶ҇_8ꙍꙷ҇_8ꙍꙸ҇_8ꙍꙹ҇_8ꙍꙺ҇_8ꙍꙻ҇_8ꙍ꙼҇_8ꙍ꙽҇_8ꙗ̀8_8ꙗ́8_8ꙗ̈8_8ꙗ̑8_8ꙗⷠ҇_8ꙗⷡ҇_8ꙗⷢ҇_8ꙗⷣ҇_8ꙗⷤ҇_8ꙗⷥ҇_8ꙗⷦ҇_8ꙗⷧ҇_8ꙗⷨ҇_8ꙗⷩ҇_8ꙗⷪ҇_8ꙗⷫ҇_8ꙗⷬ҇_8ꙗⷭ҇_8ꙗⷮ҇_8ꙗⷯ҇_8ꙗⷰ҇_8ꙗⷱ҇_8ꙗⷲ҇_8ꙗⷳ҇_8ꙗⷴ҇_8ꙗⷵ҇_8ꙗⷶ҇_8ꙗⷷ҇_8ꙗⷸ҇_8ꙗⷹ҇_8ꙗⷺ҇_8ꙗⷻ҇_8ꙗⷼ҇_8ꙗⷽ҇_8ꙗⷾ҇_8ꙗⷿ҇_8ꙗꙴ҇_8ꙗꙵ҇_8ꙗꙶ҇_8ꙗꙷ҇_8ꙗꙸ҇_8ꙗꙹ҇_8ꙗꙺ҇_8ꙗꙻ҇_8ꙗ꙼҇_8ꙗ꙽҇__а҆̀8_а҆́8_а҆̈8_а҆̑8_аⷠ҇8_аⷡ҇8_аⷢ҇8_аⷣ҇8_аⷤ҇8_аⷥ҇8_аⷦ҇8_аⷧ҇8_аⷨ҇8_аⷩ҇8_аⷪ҇8_аⷫ҇8_аⷬ҇8_аⷭ҇8_аⷮ҇8_аⷯ҇8_аⷰ҇8_аⷱ҇8_аⷲ҇8_аⷳ҇8_аⷴ҇8_аⷵ҇8_аⷶ҇8_аⷷ҇8_аⷸ҇8_аⷹ҇8_аⷺ҇8_аⷻ҇8_аⷼ҇8_аⷽ҇8_аⷾ҇8_аⷿ҇8_аꙴ҇8_аꙵ҇8_аꙶ҇8_аꙷ҇8_аꙸ҇8_аꙹ҇8_аꙺ҇8_аꙻ҇8_а꙼҇8_а꙽҇8_ба́1_би́1_биш1_бле1_бро1_брѧ1_бѧ́1_ва1в_ва1л_ва1н_ва1х_ва̑1_вдо1_ве1д_ве1н_ви1т_ви́1_ви̑1_вис1_вле1_вое1_врї1_вче1_вє́1_вї1_вїа1_вѣ1р_вѣ1т_ге1л_глꙋ1_грѧ1_гї1_гꙋ1б_да1в_да1л_ди1м_ди1с_до1с_дол1_дох1_дро1_ды1х_дї1_дѡ1р_дѣ1в_дѣ1л_дꙋ1х_е҆̀8_е҆́8_е҆̈8_е҆̑8_еⷠ҇8_еⷡ҇8_еⷢ҇8_еⷣ҇8_еⷤ҇8_еⷥ҇8_еⷦ҇8_еⷧ҇8_еⷨ҇8_еⷩ҇8_еⷪ҇8_еⷫ҇8_еⷬ҇8_еⷭ҇8_еⷮ҇8_еⷯ҇8_еⷰ҇8_еⷱ҇8_еⷲ҇8_еⷳ҇8_еⷴ҇8_еⷵ҇8_еⷶ҇8_еⷷ҇8_еⷸ҇8_еⷹ҇8_еⷺ҇8_еⷻ҇8_еⷼ҇8_еⷽ҇8_еⷾ҇8_еⷿ҇8_еꙴ҇8_еꙵ҇8_еꙶ҇8_еꙷ҇8_еꙸ҇8_еꙹ҇8_еꙺ҇8_еꙻ҇8_е꙼҇8_е꙽҇8_же1н_же1с_жи1л_жи1т_жє1н_за1н_за1х_зер1_й̀8_й́8_й̈8_й̑8_й҆8_йⷠ8_йⷡ8_йⷢ8_йⷣ8_йⷤ8_йⷥ8_йⷦ8_йⷧ8_йⷨ8_йⷩ8_йⷪ8_йⷫ8_йⷬ8_йⷭ8_йⷮ8_йⷯ8_йⷰ8_йⷱ8_йⷲ8_йⷳ8_йⷴ8_йⷵ8_йⷶ8_йⷷ8_йⷸ8_йⷹ8_йⷺ8_йⷻ8_йⷼ8_йⷽ8_йⷾ8_йⷿ8_йꙴ8_йꙵ8_йꙶ8_йꙷ8_йꙸ8_йꙹ8_йꙺ8_йꙻ8_й꙼8_й꙽8_и҆̀8_и҆́8_и҆̈8_и҆̑8_иⷠ҇8_иⷡ҇8_иⷢ҇8_иⷣ҇8_иⷤ҇8_иⷥ҇8_иⷦ҇8_иⷧ҇8_иⷨ҇8_иⷩ҇8_иⷪ҇8_иⷫ҇8_иⷬ҇8_иⷭ҇8_иⷮ҇8_иⷯ҇8_иⷰ҇8_иⷱ҇8_иⷲ҇8_иⷳ҇8_иⷴ҇8_иⷵ҇8_иⷶ҇8_иⷷ҇8_иⷸ҇8_иⷹ҇8_иⷺ҇8_иⷻ҇8_иⷼ҇8_иⷽ҇8_иⷾ҇8_иⷿ҇8_иꙴ҇8_иꙵ҇8_иꙶ҇8_иꙷ҇8_иꙸ҇8_иꙹ҇8_иꙺ҇8_иꙻ҇8_и꙼҇8_и꙽҇8_й҆̀8_й҆́8_й҆̈8_й҆̑8_йⷠ҇8_йⷡ҇8_йⷢ҇8_йⷣ҇8_йⷤ҇8_йⷥ҇8_йⷦ҇8_йⷧ҇8_йⷨ҇8_йⷩ҇8_йⷪ҇8_йⷫ҇8_йⷬ҇8_йⷭ҇8_йⷮ҇8_йⷯ҇8_йⷰ҇8_йⷱ҇8_йⷲ҇8_йⷳ҇8_йⷴ҇8_йⷵ҇8_йⷶ҇8_йⷷ҇8_йⷸ҇8_йⷹ҇8_йⷺ҇8_йⷻ҇8_йⷼ҇8_йⷽ҇8_йⷾ҇8_йⷿ҇8_йꙴ҇8_йꙵ҇8_йꙶ҇8_йꙷ҇8_йꙸ҇8_йꙹ҇8_йꙺ҇8_йꙻ҇8_й꙼҇8_й꙽҇8_ка̑1_ко1в_ко1м_кое1_кѡн1_ла1в_ли̑1_лї1_лѷ1_ма1н_ма1т_мам1_ме1н_ме1т_мер1_мле1_мо1н_мо1с_мо1щ_мор1_мы̑1_мѧ1т_на1м_на1х_неѡ1_ни1в_ни1к_ны́1_ню́1_нї1_нѡ́1_нѣ1м_нѧ́1_о҆̀8_о҆́8_о҆̈8_о҆̑8_оⷠ҇8_оⷡ҇8_оⷢ҇8_оⷣ҇8_оⷤ҇8_оⷥ҇8_оⷦ҇8_оⷧ҇8_оⷨ҇8_оⷩ҇8_оⷪ҇8_оⷫ҇8_оⷬ҇8_оⷭ҇8_оⷮ҇8_оⷯ҇8_оⷰ҇8_оⷱ҇8_оⷲ҇8_оⷳ҇8_оⷴ҇8_оⷵ҇8_оⷶ҇8_оⷷ҇8_оⷸ҇8_оⷹ҇8_оⷺ҇8_оⷻ҇8_оⷼ҇8_оⷽ҇8_оⷾ҇8_оⷿ҇8_оꙴ҇8_оꙵ҇8_оꙶ҇8_оꙷ҇8_оꙸ҇8_оꙹ҇8_оꙺ҇8_оꙻ҇8_о꙼҇8_о꙽҇8_па1д_па1с_пе1л_пе1т_пе1ц_пер1_пи1т_пї1_пѣв1_ра1х_рас1_ро1в_роз1_рѡ1м_рѡс1_рѣ̑1_рꙋ̑1_сен1_слѧ1_сма1_смо1_спо1_сты1_стѡ1_сї1м_сѣ̑1_сѣн1_сѧ́1_та̑1_те1ц_ти1м_то1м_тор1_трї1_трѧ1_ты́1_тї1_тѵ́1_тѷ2_у҆̀8_у҆́8_у҆̈8_у҆̑8_уⷠ҇8_уⷡ҇8_уⷢ҇8_уⷣ҇8_уⷤ҇8_уⷥ҇8_уⷦ҇8_уⷧ҇8_уⷨ҇8_уⷩ҇8_уⷪ҇8_уⷫ҇8_уⷬ҇8_уⷭ҇8_уⷮ҇8_уⷯ҇8_уⷰ҇8_уⷱ҇8_уⷲ҇8_уⷳ҇8_уⷴ҇8_уⷵ҇8_уⷶ҇8_уⷷ҇8_уⷸ҇8_уⷹ҇8_уⷺ҇8_уⷻ҇8_уⷼ҇8_уⷽ҇8_уⷾ҇8_уⷿ҇8_уꙴ҇8_уꙵ҇8_уꙶ҇8_уꙷ҇8_уꙸ҇8_уꙹ҇8_уꙺ҇8_уꙻ҇8_у꙼҇8_у꙽҇8_фор1_фї1_фѡ́1_хал1_че1т_чє́1_шє́1_ы҆̀8_ы҆́8_ы҆̈8_ы҆̑8_ыⷠ҇8_ыⷡ҇8_ыⷢ҇8_ыⷣ҇8_ыⷤ҇8_ыⷥ҇8_ыⷦ҇8_ыⷧ҇8_ыⷨ҇8_ыⷩ҇8_ыⷪ҇8_ыⷫ҇8_ыⷬ҇8_ыⷭ҇8_ыⷮ҇8_ыⷯ҇8_ыⷰ҇8_ыⷱ҇8_ыⷲ҇8_ыⷳ҇8_ыⷴ҇8_ыⷵ҇8_ыⷶ҇8_ыⷷ҇8_ыⷸ҇8_ыⷹ҇8_ыⷺ҇8_ыⷻ҇8_ыⷼ҇8_ыⷽ҇8_ыⷾ҇8_ыⷿ҇8_ыꙴ҇8_ыꙵ҇8_ыꙶ҇8_ыꙷ҇8_ыꙸ҇8_ыꙹ҇8_ыꙺ҇8_ыꙻ҇8_ы꙼҇8_ы꙽҇8_э҆̀8_э҆́8_э҆̈8_э҆̑8_эⷠ҇8_эⷡ҇8_эⷢ҇8_эⷣ҇8_эⷤ҇8_эⷥ҇8_эⷦ҇8_эⷧ҇8_эⷨ҇8_эⷩ҇8_эⷪ҇8_эⷫ҇8_эⷬ҇8_эⷭ҇8_эⷮ҇8_эⷯ҇8_эⷰ҇8_эⷱ҇8_эⷲ҇8_эⷳ҇8_эⷴ҇8_эⷵ҇8_эⷶ҇8_эⷷ҇8_эⷸ҇8_эⷹ҇8_эⷺ҇8_эⷻ҇8_эⷼ҇8_эⷽ҇8_эⷾ҇8_эⷿ҇8_эꙴ҇8_эꙵ҇8_эꙶ҇8_эꙷ҇8_эꙸ҇8_эꙹ҇8_эꙺ҇8_эꙻ҇8_э꙼҇8_э꙽҇8_ю҆̀8_ю҆́8_ю҆̈8_ю҆̑8_юⷠ҇8_юⷡ҇8_юⷢ҇8_юⷣ҇8_юⷤ҇8_юⷥ҇8_юⷦ҇8_юⷧ҇8_юⷨ҇8_юⷩ҇8_юⷪ҇8_юⷫ҇8_юⷬ҇8_юⷭ҇8_юⷮ҇8_юⷯ҇8_юⷰ҇8_юⷱ҇8_юⷲ҇8_юⷳ҇8_юⷴ҇8_юⷵ҇8_юⷶ҇8_юⷷ҇8_юⷸ҇8_юⷹ҇8_юⷺ҇8_юⷻ҇8_юⷼ҇8_юⷽ҇8_юⷾ҇8_юⷿ҇8_юꙴ҇8_юꙵ҇8_юꙶ҇8_юꙷ҇8_юꙸ҇8_юꙹ҇8_юꙺ҇8_юꙻ҇8_ю꙼҇8_ю꙽҇8_є҆̀8_є҆́8_є҆̈8_є҆̑8_єⷠ҇8_єⷡ҇8_єⷢ҇8_єⷣ҇8_єⷤ҇8_єⷥ҇8_єⷦ҇8_єⷧ҇8_єⷨ҇8_єⷩ҇8_єⷪ҇8_єⷫ҇8_єⷬ҇8_єⷭ҇8_єⷮ҇8_єⷯ҇8_єⷰ҇8_єⷱ҇8_єⷲ҇8_єⷳ҇8_єⷴ҇8_єⷵ҇8_єⷶ҇8_єⷷ҇8_єⷸ҇8_єⷹ҇8_єⷺ҇8_єⷻ҇8_єⷼ҇8_єⷽ҇8_єⷾ҇8_єⷿ҇8_єꙴ҇8_єꙵ҇8_єꙶ҇8_єꙷ҇8_єꙸ҇8_єꙹ҇8_єꙺ҇8_єꙻ҇8_є꙼҇8_є꙽҇8_і҆̀8_і҆́8_і҆̈8_і҆̑8_іⷠ҇8_іⷡ҇8_іⷢ҇8_іⷣ҇8_іⷤ҇8_іⷥ҇8_іⷦ҇8_іⷧ҇8_іⷨ҇8_іⷩ҇8_іⷪ҇8_іⷫ҇8_іⷬ҇8_іⷭ҇8_іⷮ҇8_іⷯ҇8_іⷰ҇8_іⷱ҇8_іⷲ҇8_іⷳ҇8_іⷴ҇8_іⷵ҇8_іⷶ҇8_іⷷ҇8_іⷸ҇8_іⷹ҇8_іⷺ҇8_іⷻ҇8_іⷼ҇8_іⷽ҇8_іⷾ҇8_іⷿ҇8_іꙴ҇8_іꙵ҇8_іꙶ҇8_іꙷ҇8_іꙸ҇8_іꙹ҇8_іꙺ҇8_іꙻ҇8_і꙼҇8_і꙽҇8_ѡби1_ѣ҆̀8_ѣ҆́8_ѣ҆̈8_ѣ҆̑8_ѣⷠ҇8_ѣⷡ҇8_ѣⷢ҇8_ѣⷣ҇8_ѣⷤ҇8_ѣⷥ҇8_ѣⷦ҇8_ѣⷧ҇8_ѣⷨ҇8_ѣⷩ҇8_ѣⷪ҇8_ѣⷫ҇8_ѣⷬ҇8_ѣⷭ҇8_ѣⷮ҇8_ѣⷯ҇8_ѣⷰ҇8_ѣⷱ҇8_ѣⷲ҇8_ѣⷳ҇8_ѣⷴ҇8_ѣⷵ҇8_ѣⷶ҇8_ѣⷷ҇8_ѣⷸ҇8_ѣⷹ҇8_ѣⷺ҇8_ѣⷻ҇8_ѣⷼ҇8_ѣⷽ҇8_ѣⷾ҇8_ѣⷿ҇8_ѣꙴ҇8_ѣꙵ҇8_ѣꙶ҇8_ѣꙷ҇8_ѣꙸ҇8_ѣꙹ҇8_ѣꙺ҇8_ѣꙻ҇8_ѣ꙼҇8_ѣ꙽҇8_ѧ҆̀8_ѧ҆́8_ѧ҆̈8_ѧ҆̑8_ѧⷠ҇8_ѧⷡ҇8_ѧⷢ҇8_ѧⷣ҇8_ѧⷤ҇8_ѧⷥ҇8_ѧⷦ҇8_ѧⷧ҇8_ѧⷨ҇8_ѧⷩ҇8_ѧⷪ҇8_ѧⷫ҇8_ѧⷬ҇8_ѧⷭ҇8_ѧⷮ҇8_ѧⷯ҇8_ѧⷰ҇8_ѧⷱ҇8_ѧⷲ҇8_ѧⷳ҇8_ѧⷴ҇8_ѧⷵ҇8_ѧⷶ҇8_ѧⷷ҇8_ѧⷸ҇8_ѧⷹ҇8_ѧⷺ҇8_ѧⷻ҇8_ѧⷼ҇8_ѧⷽ҇8_ѧⷾ҇8_ѧⷿ҇8_ѧꙴ҇8_ѧꙵ҇8_ѧꙶ҇8_ѧꙷ҇8_ѧꙸ҇8_ѧꙹ҇8_ѧꙺ҇8_ѧꙻ҇8_ѧ꙼҇8_ѧ꙽҇8_ѯе́1_ѳї1_ѵ҆̀8_ѵ҆́8_ѵ҆̈8_ѵ҆̑8_ѵⷠ҇8_ѵⷡ҇8_ѵⷢ҇8_ѵⷣ҇8_ѵⷤ҇8_ѵⷥ҇8_ѵⷦ҇8_ѵⷧ҇8_ѵⷨ҇8_ѵⷩ҇8_ѵⷪ҇8_ѵⷫ҇8_ѵⷬ҇8_ѵⷭ҇8_ѵⷮ҇8_ѵⷯ҇8_ѵⷰ҇8_ѵⷱ҇8_ѵⷲ҇8_ѵⷳ҇8_ѵⷴ҇8_ѵⷵ҇8_ѵⷶ҇8_ѵⷷ҇8_ѵⷸ҇8_ѵⷹ҇8_ѵⷺ҇8_ѵⷻ҇8_ѵⷼ҇8_ѵⷽ҇8_ѵⷾ҇8_ѵⷿ҇8_ѵꙴ҇8_ѵꙵ҇8_ѵꙶ҇8_ѵꙷ҇8_ѵꙸ҇8_ѵꙹ҇8_ѵꙺ҇8_ѵꙻ҇8_ѵ꙼҇8_ѵ꙽҇8_ѻ҆̀8_ѻ҆́8_ѻ҆̈8_ѻ҆̑8_ѻⷠ҇8_ѻⷡ҇8_ѻⷢ҇8_ѻⷣ҇8_ѻⷤ҇8_ѻⷥ҇8_ѻⷦ҇8_ѻⷧ҇8_ѻⷨ҇8_ѻⷩ҇8_ѻⷪ҇8_ѻⷫ҇8_ѻⷬ҇8_ѻⷭ҇8_ѻⷮ҇8_ѻⷯ҇8_ѻⷰ҇8_ѻⷱ҇8_ѻⷲ҇8_ѻⷳ҇8_ѻⷴ҇8_ѻⷵ҇8_ѻⷶ҇8_ѻⷷ҇8_ѻⷸ҇8_ѻⷹ҇8_ѻⷺ҇8_ѻⷻ҇8_ѻⷼ҇8_ѻⷽ҇8_ѻⷾ҇8_ѻⷿ҇8_ѻꙴ҇8_ѻꙵ҇8_ѻꙶ҇8_ѻꙷ҇8_ѻꙸ҇8_ѻꙹ҇8_ѻꙺ҇8_ѻꙻ҇8_ѻ꙼҇8_ѻ꙽҇8_ѽ҆̀8_ѽ҆́8_ѽ҆̈8_ѽ҆̑8_ѽⷠ҇8_ѽⷡ҇8_ѽⷢ҇8_ѽⷣ҇8_ѽⷤ҇8_ѽⷥ҇8_ѽⷦ҇8_ѽⷧ҇8_ѽⷨ҇8_ѽⷩ҇8_ѽⷪ҇8_ѽⷫ҇8_ѽⷬ҇8_ѽⷭ҇8_ѽⷮ҇8_ѽⷯ҇8_ѽⷰ҇8_ѽⷱ҇8_ѽⷲ҇8_ѽⷳ҇8_ѽⷴ҇8_ѽⷵ҇8_ѽⷶ҇8_ѽⷷ҇8_ѽⷸ҇8_ѽⷹ҇8_ѽⷺ҇8_ѽⷻ҇8_ѽⷼ҇8_ѽⷽ҇8_ѽⷾ҇8_ѽⷿ҇8_ѽꙴ҇8_ѽꙵ҇8_ѽꙶ҇8_ѽꙷ҇8_ѽꙸ҇8_ѽꙹ҇8_ѽꙺ҇8_ѽꙻ҇8_ѽ꙼҇8_ѽ꙽҇8_ᲂ҆̀8_ᲂ҆́8_ᲂ҆̈8_ᲂ҆̑8_ᲂⷠ҇8_ᲂⷡ҇8_ᲂⷢ҇8_ᲂⷣ҇8_ᲂⷤ҇8_ᲂⷥ҇8_ᲂⷦ҇8_ᲂⷧ҇8_ᲂⷨ҇8_ᲂⷩ҇8_ᲂⷪ҇8_ᲂⷫ҇8_ᲂⷬ҇8_ᲂⷭ҇8_ᲂⷮ҇8_ᲂⷯ҇8_ᲂⷰ҇8_ᲂⷱ҇8_ᲂⷲ҇8_ᲂⷳ҇8_ᲂⷴ҇8_ᲂⷵ҇8_ᲂⷶ҇8_ᲂⷷ҇8_ᲂⷸ҇8_ᲂⷹ҇8_ᲂⷺ҇8_ᲂⷻ҇8_ᲂⷼ҇8_ᲂⷽ҇8_ᲂⷾ҇8_ᲂⷿ҇8_ᲂꙴ҇8_ᲂꙵ҇8_ᲂꙶ҇8_ᲂꙷ҇8_ᲂꙸ҇8_ᲂꙹ҇8_ᲂꙺ҇8_ᲂꙻ҇8_ᲂ꙼҇8_ᲂ꙽҇8_ꙋ҆̀8_ꙋ҆́8_ꙋ҆̈8_ꙋ҆̑8_ꙋⷠ҇8_ꙋⷡ҇8_ꙋⷢ҇8_ꙋⷣ҇8_ꙋⷤ҇8_ꙋⷥ҇8_ꙋⷦ҇8_ꙋⷧ҇8_ꙋⷨ҇8_ꙋⷩ҇8_ꙋⷪ҇8_ꙋⷫ҇8_ꙋⷬ҇8_ꙋⷭ҇8_ꙋⷮ҇8_ꙋⷯ҇8_ꙋⷰ҇8_ꙋⷱ҇8_ꙋⷲ҇8_ꙋⷳ҇8_ꙋⷴ҇8_ꙋⷵ҇8_ꙋⷶ҇8_ꙋⷷ҇8_ꙋⷸ҇8_ꙋⷹ҇8_ꙋⷺ҇8_ꙋⷻ҇8_ꙋⷼ҇8_ꙋⷽ҇8_ꙋⷾ҇8_ꙋⷿ҇8_ꙋꙴ҇8_ꙋꙵ҇8_ꙋꙶ҇8_ꙋꙷ҇8_ꙋꙸ҇8_ꙋꙹ҇8_ꙋꙺ҇8_ꙋꙻ҇8_ꙋ꙼҇8_ꙋ꙽҇8_ꙍ҆̀8_ꙍ҆́8_ꙍ҆̈8_ꙍ҆̑8_ꙍⷠ҇8_ꙍⷡ҇8_ꙍⷢ҇8_ꙍⷣ҇8_ꙍⷤ҇8_ꙍⷥ҇8_ꙍⷦ҇8_ꙍⷧ҇8_ꙍⷨ҇8_ꙍⷩ҇8_ꙍⷪ҇8_ꙍⷫ҇8_ꙍⷬ҇8_ꙍⷭ҇8_ꙍⷮ҇8_ꙍⷯ҇8_ꙍⷰ҇8_ꙍⷱ҇8_ꙍⷲ҇8_ꙍⷳ҇8_ꙍⷴ҇8_ꙍⷵ҇8_ꙍⷶ҇8_ꙍⷷ҇8_ꙍⷸ҇8_ꙍⷹ҇8_ꙍⷺ҇8_ꙍⷻ҇8_ꙍⷼ҇8_ꙍⷽ҇8_ꙍⷾ҇8_ꙍⷿ҇8_ꙍꙴ҇8_ꙍꙵ҇8_ꙍꙶ҇8_ꙍꙷ҇8_ꙍꙸ҇8_ꙍꙹ҇8_ꙍꙺ҇8_ꙍꙻ҇8_ꙍ꙼҇8_ꙍ꙽҇8_ꙗ҆̀8_ꙗ҆́8_ꙗ҆̈8_ꙗ҆̑8_ꙗⷠ҇8_ꙗⷡ҇8_ꙗⷢ҇8_ꙗⷣ҇8_ꙗⷤ҇8_ꙗⷥ҇8_ꙗⷦ҇8_ꙗⷧ҇8_ꙗⷨ҇8_ꙗⷩ҇8_ꙗⷪ҇8_ꙗⷫ҇8_ꙗⷬ҇8_ꙗⷭ҇8_ꙗⷮ҇8_ꙗⷯ҇8_ꙗⷰ҇8_ꙗⷱ҇8_ꙗⷲ҇8_ꙗⷳ҇8_ꙗⷴ҇8_ꙗⷵ҇8_ꙗⷶ҇8_ꙗⷷ҇8_ꙗⷸ҇8_ꙗⷹ҇8_ꙗⷺ҇8_ꙗⷻ҇8_ꙗⷼ҇8_ꙗⷽ҇8_ꙗⷾ҇8_ꙗⷿ҇8_ꙗꙴ҇8_ꙗꙵ҇8_ꙗꙶ҇8_ꙗꙷ҇8_ꙗꙸ҇8_ꙗꙹ҇8_ꙗꙺ҇8_ꙗꙻ҇8_ꙗ꙼҇8_ꙗ꙽҇8̀1ми1́1бли́1бра́1брѣ́1в2д́1вꙋ1́1д2в́1дре́1ды2́1дї́1жє1́1зда́1здѣ́1зри́1зрѧ́1клї́1кї́1кꙋ1́1лї́1ми1́1пи2́1пле́1плю́1пѡ1́1пѣ1́1рє1́1рї́1рѣ2́1рѷ2́1с2х́1спе́1ств́1сте́1сто́1твє́1твѣ́1тре́1тро́1тры́1трѣ́1трꙋ́1тча́1тї́1тѣ2́1тꙋ1́1х2м́1хи2́1це1́1цы1́1цѣ2́1чꙋ1́1ща1́1щє1́1ѳе1́2в1н́2в1ч́2м1н́2м1п́2п1н́2р1ц́2т1ќ2т1л́2т1ц́2ч1т́бно1́бро1́брѧ1́бща1́в1лє́в1ца́ва1с́вае1́вдо1́вед1́влю1́вне1́внѧ1́внꙋ1́во1с́вше1́г1ло́г1нꙋ́гни1́гра1́ди1в́дно1́дѡ1в́ема1́емо1́емꙋ1́ет1н́ете1́жнꙋ1́з1вѣ́з1др́з1нꙋ́з1ра́з1ꙋм́зво1́зе1р́зни1́иче1́иша1́кни1́кры1́крꙋ1́ла1с́ли1н́лє1м́м1ли́м1лѧ́мна1́мно1́мнꙋ1́мѡ1щ́нми1́ннї1́нꙋи1́ово1́пла1́пло1́р1ве́р1дї́рда1́рди1́ре1д́рма1́рна1́рне1́ро1в́рта1́рша1́рше1́рꙋю1́с1но́с1нꙋ́с1пѧ́с1са́с1цы́сав1́сли1́слѣ1́смо1́сни1́стꙋ1́сше1́таи1́тво1́ти1м́тла1́тли1́тна1́тне1́тнꙋ1́то1р́тцы1́тѧ1н́хї2́чат1́че1в́че1с́чи1с́чї1́шне1́щна1́щно1́ї2ќїа1́їи1́ї1л2́ѧти1̑1ва1̑1внѣ̑1да1̑1до1̑1дї1̑1дѣ2̑1дꙋ1̑1зни̑1ка1̑1кї1̑1ло1̑1лы1̑1лї1̑1ма1̑1мы1̑1ни1̑1п2л̑1па2̑1пи1̑1сни̑1та1̑1ты1̑1тї1̑2д1н̑2жд1̑2п1н̑гꙋб1̑даю1̑дни1̑дны1̑днї1̑дѣн1̑жны1̑жї1̑зан1̑зны1̑йши1̑лла1̑мны1̑нї1̑пкї1̑пни1̑пны1̑пї1̑рна1̑тна1̑тны1̑чна1̑чї1̾ꙋ́м1̾ꙋго1̾ꙋмѣ1а1во1а1вї1а1дї1а1дꙋ2а1знаа1лї1а1лꙋ2а1ме1а1мї1а1не2а1ню2а1рї1а1рѷ1а1рꙋ2а1се2а1стра1стѝа1т2ла1т2ча1тї1а1х2та1ѵ́1а2в1да2в1на2г1га2д1на2м1па2м1ча2с1на́1гла́1зра́1кла́в1ца́ва1а́да1а́з1ва́з1ꙋа́ка1а́л1ма́ла1а́лꙋ1а́м1ва́м1ла́мє1а́мꙋ1а́н1ма́н1та́нѧ1а́по1а́р1ва́р1га́с1на́с1па́ти1а́чи1а́ша1а́щꙋ1а́ѵ1ра̑1п2а̑2р1а̑2ч1а̑в1на̑с1наа́1набо1лабы̑1абꙋ́1ав1лєаво́1аврї1авше1авї1авѵ́1авѷ1авꙋ́1агда1аго1раго́1агра1агрѧ1ада̑1ади1вадно1адо1садї1ае2к1ае́1шаеди1аесѣ1аз1драз1дыаз1дѣазах1азди1азо1раи́1таи̑н1аимо1айшї1ака́1ака̑1ако1вако1нако1ракос1акѡ1вала1лала1мала1хали1нали̑1аллї1алю́1алї1ама1рамо1вамо1мамї1амꙋ́1анас1аннї1ано1вано́1ані́1анѡ1нанꙋ́1апе1тапе́1апер1апи́1апре1апі́1апї1ара1сардо1аре1маркї1аро1вартї1арє1марі́1арї1арїи1ас1лоас1пеас1пѧас1твас1тласпи1ассї1асє́1асі́1ата1вата1ната́1ата̑1ате́1ати1лато1сато́1атрї1аты̑1аті́1атї1атꙋ́1афї1афѵ́1аха1лаха́1ахі́1ахѡ́1аче1сачер1ашє́1ашꙋ́1аща́1ающї1аїа1аѧ́1таѧ́ю1аѯа́1аѳі́1а҆1з2а҆1ска҆1ста҆́1ба҆́1ма҆́л1а҆́н1а҆дѡ1а҆кꙋ1а҆ме1а҆мо1а҆ра1аꙋ́1таꙋ́1чб1ла̀б1лекб1ленб1лечб1лю̀б1лющб1немб1нетб1новб1ны_б1нѣ_б1нѣмб1ратб1рꙋ́б1рꙋгба1в2ба́1нба́1сба́1тба́1чба́1шбве́1бви́1бди́1бе1р2бе2з1бза́1бзꙋ́1би1с2би́1дби́1нби́1сби́1цбила1бити1биша1бла1дбле1мблєн1бно1мбнї1бо1з2бо́1збо́1кбо́1цбор1цбою́1бре1мбре1тбро1нбрѧ́1бско1бсто1бхо́1бща́1бще́1бы́1дбы́1шбы̑1нбє́с1бѡ́1гбѡ́р1бѣ́1жбѣ́1лбѣ́1мбѣ́1шбѣдо1бѣто1бѧ́1хбѧще1бꙋ2з1бꙋ́1дв1во_в1да́в1лю̀в1лѧ_в1на1в1неев1ни_в1никв1нихв1ницв1нодв1номв1нѧгв1нꙋюв1ст2в1ца_в1цы̀в2ло1в2сы1ва1ства́1два́1жва́1тва́1шва̑1швати1ваша1ваше1вают1вва́1вве1двве1сввер1вво́1ве1стве2з1ве́1чвеле1венї1вер1дверо1взы́1ви̑н1вила1вима1вимо1вити1вице1виша1вла1двла1свлѣ́1влѧ́1вма́1вмѣ́1вне1мвне́1во2ш1во́з1вод1нвое1мвозо1вона1вор1цвоси1восо1воца1воче1впа1двра1звра̑1вре1двре1мвро́1все1нвсе1рвсе1хвсе1цвсеѡ1вска1вскї1всѧ́1всꙋ́1вто1рвче1рвшаѧ1вше1мвы́1мвы́1нвє́1тві́1квї1квї1мвї1нвї1свї2л1вѣ́1швѣ̑ч1вѣко1вѣто1вѧ1з2вѧче1вѵ́1твѷ2с1в҃и́1вꙋе1мвꙋхо1г1ло_г1немг1нетг1ни_г2лѷ1га́1ггаа́1гама1гда1лгда́1гдо́1гдѣ́1ге2н1ге́р1геде1гер1мги́1нги̑з1гкѵ́1гла1вгла1сгло́1глї1глѧ́1гма́1гнї2го1в2го1с2го́1мгоиз1голꙋ1гона1госꙋ1гочє1гоѧв1гра1нгра̑1гре1мгре́1гро1мгрі́1грї2грѷ1гха́1гшї1гї1ггѡ1с2гѡ́1жгѡ́д1гѡ́р1гꙋб1лд1возд1лагд1лежд1насд1немд1ни_д1ни́д1нихд1ноєд1ны́д1нымд1ню_д1нѣмд1разд1рекд1речд1со2д1ст2д1хо2д2нѐд̾ѧв1да́1гда́1дда́1шда́є1дав1лдако1даро1дати1два1ндва́1две1рдвє́1двѣ1мдгла1дгрѧ1дебе1ди́1сди́1щди̑1мди̑в1див1лдиво1дима1димо1дино1дкло1дла̑1дма́1дми́1дмо́1днев1до1в2до́1вдо́1гдо́1сдоб1лдобо1дои́1дом1ндома1домо1доче1дпи́1дпро1дре1мдро1вдро1мдро1ндрї1дрѡ́1дрѣ́1дска1дско1дте́1дхо́1дше1мдше́1дщє́1ды́1кды́1нды́1шдїо1дѡна1дѣ́1ждѣ́1сдѣ́1тдѣ́1шдѣто1дѧ́1хдꙋ́1лдꙋ́1сдꙋ̑ж1дꙋим1дꙋща1е1вние1вное1дꙋ2е1з2ре1зи1е1зы2е1лї1е1лꙋ1е1мї1е1ню1е1ри2е1рє1е1рѣ1е1стве1стее1стое1стре1хи1е1це2е1цѣ2е1чꙋ2е2з1ве2з1де2з1не2р1це́1зре́1зꙋе́1тве́бе1е́в1ле́ви1е́г1це́дї1е́е1ве́жа1е́з1де́з1не́за1е́зо1е́ко1е́м1ве́н1ме́на1е́но1е́нї1е́нꙋ1е́р1бе́с1не́са1е́те1е́ти1е́ши1е́щї1еа1з2еа́н1еб1лееб1люебе1лебо́1ев1леев1лѧева1сева́1ева̑1еве1деве1реве1севзы1еви̑1ево1невол1евос1евра1евы1мевє́1евѣ1севѧ1тевѧ́1еги́1его́1егра1егре1егрѣ1егѡ́1егꙋ1бед1воед1вѣед1наед1ниед1ныед1нѣед1нꙋед1раеда̑1еди̑1еднї1едо1медо1седох1едѣ1лее́н1еза1хезды1езе́1езна1езне1езо́1езпо1еи1спека́1еко1некї1ела̑1ели̑1ело1велю1белю́1елє1нема́1еме1неми1немо1ремол1емощ1емї1емѡщ1емѧ́1ена1дене1сенеѡ1ени1хено1вено1ментї1енѧ́1ео́1гео́1део́1пео́1фео́н1епе1тепре1епро1епі́1епѣ́1ер1ж2ер1з2ер1твераз1ерво1ерна1ерп1лері́1ерї1керїн1ерѡ1нерѧ́1еско1ескꙋ1еслꙋ1есо1месож1еспа1есса1есї1есѡ́1ета̑1етер1ето́1еты1реты́1етї1етꙋ́1еча1тече1речи1сечна1еще́1ещи́1еѡ1с2еѡ́р1еꙋвѧ1еꙋга1жа́1жжа́1шжа́1щжда1нжда́1ждеѡ1жди1вждшї1ждє́1же2з1же2р1женї1жже́1жжи́1жи1з2жи1с2жи́1нжи́1сжив1лжити1жице1жиша1жне1мжнї1жро́1жска1жско1жє́р1жїѧ1ж҃е́1з1ва_з1вамз1вѣ_з1вѣ̑з1вѣщз1дназ1дныз1днѣз1днꙋз1дꙋ́з1ла̀з1лагз1лꙋ1з1не́з1невз1негз1носз1нꙋтз1расз1ращз1речз1рещз1ринз1рѣшз1ꙋ́мз1ꙋмыз2ꙋ1бз̾ѧ1вза1р2за1т2за́1мза́1сза́1шза́ѧ1за̑1нза̑д1зан1тзапе1запо1захо1заꙋ́1зби́1збла1збле1збо1лзве1дзве1сзвер1зви1тзвла1зво1лзвы́1згнꙋ1згре1здо́1зды1хздѣ1лзе́р1зже1нзи1н2зи́1дзи́1жзи́1сзла́1зла̑1зле1тзли1взма́1зми́1змо1взно1взны1мзо2ч1зото1зпо́1зпро1зска1зско1зсло1зсмо1зсто1зсї1зсѣ́1зсꙋ1дзсꙋ́1зче́1зчи́1зы́1дзы́1тзыко1зѡ1с2зѧ́1сзꙋ̑м1и1вї1и1вѣ1и1вѧ2и1зваи1зи1и1зрѣи1кꙋ2и1лї1и1ме1и1на2и1ни2и1нꙋ2и1ре2и1ри2и1рї1и1с2ки1с2ни1с2ти1со2и1спѣи1то2и1тї1и1тꙋ1и2в1ни2к1ни2м1ти2с1ли2с1хѝдѣ1и́1бли́1зви́1зри́1зꙋи́1ски́1сни́1три́1тчи́бо1и́ва1и́во1и́вї1и́г1ни́зо1и́к1ни́ка1и́ли1и́лї1и́ма1и́н1ми́на1и́ни1и́нї1и́рї1и́си1и́сѧ1и́та1и́тї1и́че1и́ша1и́щꙋ1й1д2й1ж2й1м2й1н2й1с2й1ш2йде2йдꙋ2йне1йно1йню1йнї1йнѧ1йнꙋ1йст2йте1йче1йша1йшꙋ1и̑1р2и̑1с2и̑1т2и̑2ж1иба́1ибо́1ив1люив1лѧива́1иве1диве1сиво1миво1ниво1сившы1ивї1ига́1иги́1игла1иго1рида́1иди́1идї1идѣ́1идꙋ́1ижє́1из1неиз1рииза̑1изла1изло1ика́1икло1ила1сила́1или́1или̑1ило1силѧ́1илꙋ́1ими́1имѣ́1инин1иннї1ино1вино1мині́1инѧ́1ипа1дипа́1ипї1ипїо1ипѣ1вира́1ирен1иро1нирї1ирѧ́1иса̑1исво1исвѧ1исса1исте1исі́1исї1ите1цитро1итрї1итї1ифле1ихо́1ица́1ице1миче1сиче́1ичє́1иши1нище1тиѳа́1и҆1н2и҆́1би҆́1ги҆́1ди҆́1жи҆́1ри҆́1си҆́з1и҆з1ди҆з1ри҆лї1и҆с1пйнї1йска1йско1йскꙋ1ка1з2ка́1гка́1жка́1шкали1ката1квер1кді́1ке́1ѵке́л1кеса1ки1т2ки2р1кибы1ккли1кла1нкле1вклї1пкни1тко2з1ко́1жков1нков1сколє1корѡ1крае1крен1кро1вкро1мкро1нкта́1кте1нкто1мкто́1ктї1ктѡ́1кє́л1кѡ́1скѡ́з1кѡ́р1кѵ́1лкѷ2м1кꙋ́1фкꙋсо1л1вї1л1го1л1же2л1ка2л1ко1л1мї1л1на2л1нѧ2л1нꙋ2л1па2л1пѝл1по2л1пꙋ2л1чꙋ1л2в1нл2п1нла1т2ла2ѵ1ла́1шла́ѵ1ла̑1сла̑в1ла̑д1лав1лладо1лан1тлато1лаща1лвї1лдє́1ле́1пле́1щле́т1леве1лезо1лерї1лзно1лзше1ли́1рлимо1лле́1ллї1нллѵ́1лма1тлна́1лнеч1лни1слно́1лнє́1лнї1лнїи1лнїѧ1лнѧ́1лнѧт1лнꙋ́1ло1з2лов1ллоги1лпни1лпї1лхї1лче́1лчи1тлчє́1лчї1лы́1шлы́в1лі́1влі́1длїко1лїо́1лїса1лѡ́ж1лѣ́1слѣ̑д1лѧ́1длѧще1лѵ́1плѵ́1рлѵ́м1лѷ1кл҃ко1лꙋ́1шлꙋ̑ж1м1ле_м1лемм1летм1лешм1ли_м1лютм1лѧ_м1никм1нѣ_м2нѐм2ню2ма́1гма́1мма́1тмага1мала1мано1мате1мва́1ме́м1мено1мер1тмеч1тми́1жми́1мми́1цмило1мимо1миро1мла1дмла́1мле́1млє́1ммѡ́1мна́1мно́1мні́1мнї1мнѡ́1мнꙋ́1мо1влмо1скмо́1рмое1ммопо1мпе1рмре́1мро́1мрє́1мска1мско1мфї1мшї1мще́1мы́ш1мі́є1мїи́1мїлї1мїса1мїха1мѡ2р1мѡ́ж1мѡ́л1мѣ́1тмѣ́1шмѣ̑1нмѣ̑д1мѣ̑р1мѣѧ́1мѷг2мꙋ1д2мꙋ́1чмꙋ́1ѳмꙋ́и1мꙋси1н1дран1дрен1ды1н1дї1н1дꙋ2н1ко2н1рѐн1те1н1то2н1ца̀н1це́н1цемн1цы̀н1цѣ2н1цꙋ̀н1цꙋ́н2кѝна1з2на1р2на1ѵ2на́1зна́1шна́ч1наа́1навꙋ1нази1наи́1налѧ1напе1нари1наса1нахо1начи1нди́1ндро1ндї1ндꙋ́1не1д2не́1бне́1гне́1рнебы1нев1нневе1нели1нене1нерꙋ1несѣ1нетѣ1ни́1дни́1зни́ж1ниво1нице1ниша1нище1нна́1нни1ннни́1ннꙋю1но1с2но́1зно́1кножи1нона1ноте1ноче1ноще1ноѧв1нска1нско1нскꙋ1нсї1нта́1нтѡ1ннтѡ́1нчи́1нє́ч1нї1кнї1мнї1ннїо1нї2г1нїе1внїка1нїма1нїне1нїѧ1мнѡ́1гнѡ́1жнѣ́1кнѣ́1тнѣ́ч1нѣ́ш1нѧ́1жнѧ́1хнѧти1нѳи́1нѳї2нꙋ́1шо1в2чо1вѧ2о1знао1зрио1зрѣо1зрѧо1лѷ1о1м2ло1м2по1мнѣо1мѧ1о1ню2о1ри2о1рцыо1рї1о1рѷ1о1с2цо1се2о1стео1стло1стоо1стѝо2в1цо2д1ло2ж1жо2з1во2с1но2с1хо2ш1ло́1гно́1дро́1спо́бо1о́бѧ1о́в1ло́в1цо́га1о́з1но́з1ро́ка1о́лч1о́лє1о́лѣ1о́ма1о́мꙋ1о́н1до́р1до́р1жо́р1ло́р1со́ра1о́ри1о́рм1о́рꙋ1о́с1но́с1цо́тї1о́ц1ко́ша1о́щї1о́ї2об1лѧоба́1обо1сов1люов1лєов1лѧов1ноов1нѣов1нꙋова1сове1дове1совер1ови1вово1лово1совто1ові́1огло1ого́1огрѣ1од1наод1ноод1ныод̾и1ода1водво1одо1содох1одро1одрꙋ1оды́1одї1одѣ1водѣ̑1одꙋх1ое́1ное́1шоеди1оже1ноже1соз1дѣоз1дꙋоз1неоз1ниоз1нооз1раозвѣ1озже1ози́1озор1озсо1ои2с1ои́1дои́1соиз1воиз1нока1рокла1око1воко1рокри1окрꙋ1оле1соле1толи1воли̑1оллї1оло1молю1болі́1олїн1олѣ̑1олѧ́1олѷ1ома́1оми1номо1ломо1номо1щомра1омы1сомы́1оню́1онї1онѧ́1онѵ́1оп1лѧопа1допа1ропер1опи1топро1опї1ор1м2орас1ордї1оре1норе1хорто1орє́1орї1орѡ1норѣ́1орѣ̑1ос1клос1плос1пꙋоса́1оси̑1осі́1осї1осꙋ1дотер1отов1отѣ̑1офа́1охі́1оцѣ1лоче1ноче1соче1точи1точно1оша́1оше1ношє́1ощни1ощї1ою́1доѧ́1жоѧ́в1оѧв1лоᲂу҆1оꙋме1п1лю̀п1нымп1пи1п1ст2п2нѝп2сѝп2ше1па1т2па2г1па2м1па2н1па́1жпа́1кпако1пара1пари1пас1лпаѧ́1пе́1ппе́1спела1пелє1пи́1щпла1мпло1мплї1плѡт1пнет1по1з2по́1жпо́1зпо́1ппо́1тпо́1хпо́1чпове1под1нподе1поже1пола1полї1попа1попе1попи1попꙋ1пора1поре1порꙋ1посы1почꙋ1поща1пра1ѯпра̑1пре1зпре1мпре1нпре1тпре1хпри́1про1впро1зпро1мпро1нпрєн1прї1прїѡ1прѣ́1прѧ́1прꙋ́1пта́1пти̑1пфі́1пє́н1пє́р1пї1кпї1лпї1мпї1с2пїо́1пѡ́1тпѡ̑н1пѣ́1тпѣ́ѧ1пѣше1пꙋ1т2р1венр1вї1р1вѣ1р1вꙋ1р1го2р1дꙋ1р1з2ꙋр1зы2р1ко2р1кїр1кꙋ2р1ла1р1м2лр1мї1р1се2р1скꙋр1со1р1стор1твар1твер1твир1твор1твыр1твєр1твїр1твѣр1твꙋр1ти2р1тꙋ1р1хо1р1цы_р2б1лр2г1нр2д1нр2з2лр2м1нр2м1чр2т1кр2це2ра1т2ра̑1вра̑1жра̑1лра̑з1ра̑ш1рав1лраз1нрамо1расѡ1рато1рбѣ́1рбѧ́1рва́1рве́1рвле1рво1зрвї1ргнꙋ1ргі́1рда1лрди1срди1трды́1рдѧ́1ре1в2ре1мнре1р2ре1ч2ре́1жре́1зре́1лре́1пре́1чред1вред1лред1рредо1рела1релю1рене1рже1сржет1рзе́1рзно1рзо́1ри1влри1з2ри1н2ри1с2ри́1дри́1жри́1щризы1рика1рили1рими1ркѵ́1рли́1рлин1рма1нрма́1рмо1лрмꙋ́1рна́1рне1мрншї1ро1зрро1р2ро1с2ро́1лро́1нро́1про́1хробо1ровѣ1рое́1рои́1рока1роли1ролї1ромо1рон1трона1ропо1росо1ротѧ1роче1роѧ́1рп1люрпа1српа́1рпї2рпѧ́1рсе́1ртна1ртно1ртнꙋ1рты1мртѵ́1рфѵ́1рхї1рца́1рчи́1рша́1рше1мры́1сры́1тры́1шрько1рєни1рі́1крі́1хрї1с2рїи1мрѡ́1срѣ1з2рѣ́1жрѣ́1зрѣ́1нрѣ́1срѧ́1мрѧ́1хрѧ́з1рѧ́ю1рѳе́1р҃ї1рꙋ1б2рꙋ́1зрꙋ́1прꙋ̑1прꙋцѣ1с1кꙋшс1ло̀с1лꙋ̀с1нетс1но̀с1нꙋ̀с1нꙋтс1нꙋюс1са_с1се2с1со2с1ст2с1течс1тлѣс1цы_с2лї1са́1тса́1шса́р1са̑д1сава1саи́1сала1сало1санꙋ1сата1саха1саша1сбꙋ́1сви́1свы́1сві́1свѧ1тсвѵ́1се1д2се1з2се́1все́1ссе́1шсебо1сева1севе1сегꙋ1секо1сена1сене1сеца1си́1рси́1тси́1цсице1ска̑1скон1скри1скі̑1сле1зслен1сли1мсли1нслы́1слєн1сма1мсма1рсма́1смер1смо1лснис1снї1со1с2со́1ссо́1цсо́п1соза1созы1соиз1соло1сони1сопо1соче1сочи1соѧ́1спол1спре1спро1спрѧ1спѣ1всра1ссрав1сраи1сре1дсри́1срѧ́1сса́1сска1сскꙋ1ссо́1ссѡ́1ссѣ́1ссѷ1став1стан1сте1цстер1сти̑1стї1схи́1сцѣ1лсча̑1счер1сше1мсшї1сі́1лсі́1мсі́1нсї1ксї1нсї1псї1ссїо1сѡ1с2сѡ́1жсѡ́1зсѡ́1ксѡ́с1сѣ́1всѣ́ю1сѣ̑1тсѧ2ч1сѧ́1дсѧ́з1сѧто1сѧща1сѧще1сꙋ2б1сꙋ́1хсꙋ́1шсꙋ́ю1сꙋще1т1ка̀т1лагт1лаѧт1ли_т1лѣ_т1неет1номт1ню1т1нѣ_т1нѣ̀т1нꙋют1цѣ_т2ле1та1с2та́1дта́1жта́1кта́1тта́1шта̑1нта̑в1тав1лтакѡ1тан1ттаѧ́1тва1мтвен1твич1твї1твꙋ́1те́1бте́1лте́1чтезо1тели1тенї1ти́1жти́1нти́1стива1тино1тити1тихо1тиша1тиши1тка́1тла́1тли1втма́1тмо1ртмо́1тне́1тно́1тны̑1тні́1тнї1тнꙋ́1то́1жто́е1то́т1то́ѧ1тов1нтов1стоже1толю1топо1точ1нтраг1тре1мтрез1три1втрєн1трѡ́1тхї2тча́1ты́1сты́д1ты̑н1ті́1гті́1мтї1лтї1мтї1нтїнї1тѡ́и1тѣ́1стѣ̑1нтѷ2м1т҃о1мтꙋ́1нтꙋ́1чтꙋ́1щтꙋ̑д1тꙋ̑п1фа1л2фа́1вфара1фе1р2фе2ѵ1фе́1сфле́1фнꙋ́1фран1фро́1фрон1фрї1кфска1фі́р1фї1л2фїла1фѡ́1кфѡ́1тфѵ́1рфꙋ2л1фꙋ2р1х1но1х1ти1х2не2ха́1мха́1рха́ю1ха̑1нхана1хара1хва1лхе1в2хе1р2херꙋ1хи́1рхи́1тхи́н1хи́щ1хи̑н1холю1хопа1хра1нхрї1хрѷ1хска1хстѣ1хті́1хї1мхї1схї2кхїсе1хѡ́1мхꙋ́1дц1ка1ц1ко1ц1кїцвѣ1тце2р1це́р1цего1цеса1цїо2цѣ1в2ч1нетч1никч1ницч1нꙋ1ч1то_ча1с2ча́1мча́1нча́1шча̑1тчало1часо1че1з2че́1жче́1шче́з1чево1чело1чено1ченї1чер1тчерм1черї1чи́1счи́щ1чино1чити1чиша1чноа1чнї1чнꙋю1чта̑1чтє́1чюде1чє1н2чє́1лчє́в1чє́р1ч҃ї2чꙋ̑д1чꙋдо1ша1с2ша́1нша́1шша́в1ша́л1ша́є1шаго1шагѡ1ше2в1ше́1сше́в1шело1шемо1шемꙋ1шенї1ши1с2ши́1пши́1сши́р1широ1шити1шлє́1шшым1шє́1сшє́в1шїи1шꙋ́1сшꙋ́ю1шꙋще1ща́1сща́1шща́1щщаго1ще1д2ще́1сщебо1щемꙋ1щенї1щи1с2щи́1сщна́1щно1мщно́1щшаѧ1щє́1рщє́т1щїи1ы1не1ы1но1ы1ро1ы1рї1ы2к1ны́1кны́1щ2ы́2г1ы́2п1ы́б1лы́лї1ы́нї1ы́те1ы́ти1ы́ты1ы́тї1ы́че1ы́чи1ы́ше1ы̑1с2ы̑2в1ыва́1ыва̑1ыдѣ́1ыза́1ыко1выко́1ыла́1ыпа́1ыре1дыре1нысѡ́1ытї1ытꙋ́1ыха̑1ыша́1ыше́1ыща́1ыщи́1ь1ствь2мо2ьбо́1ьво́1ькї1ьмо́1ьнї1ьска1ьскꙋ1ьшаѧ1ьшым1ю1до2ю2б1вю2б1лю́1с2ю́1щ2ю́б1лю́дї1ю́дꙋ1ю́та1ю́то1ю́щꙋ1юбо1мюди́1юдо́1юче́1ю҆́1жю҆́1нє1ма1є́1брє́1ж2є́1п2є́2д1є́2з1є́би1є́лю1є́лї1є́нї1є́р1дє́р1сє́с1нє́че1єва́1єдни1єнни1єнї1єска1єскї1єтна1єчны1єѵрѡ1є҆1в2є҆1з2є҆1с2є҆́1вє҆́1жє҆́л1є҆́м1є҆ка1є҆ре1є҆ѧ́1ѕвѣ̑1ѕла̑1ѕло1вѕмї1і́1смі́н1ді́ни1і́нꙋ1і́р1мі́ро1і́с1сі́то1і́тѧ1і́че1і́є1вї1в2ї1гаї1гиї1д2ї1кеї1кої1ктї1кії1кѡї1леї1лиї1лії1маї1неї1ної1раї1реї1саї1сеї1сєї1сѡї1т2ї1ф2ї1ѷ1ї2й1їа1дїа1мїа1нївї1їдї1їе2мїи1нїи1тїй1їи̑2їн1дїн1тїо1мїо1нїп1пїпї1їр1сїс1сїтѷ1їтꙋ2їє́1їѡ1нїѡ1сїѳе2і̑1с2і҆1м2і҆1с2і҆2з1і҆2н1і҆́1ді҆́н1і҆а́1і҆дѡ1і҆са1ї1кї1ї1ло1ї1лꙋ1ї1ме1ї1мо1ї1мї1ї1на2ї1па2ї1ро1ї1со1ї1стеї1стої1стрї1ѷ1ї2г1гїа́1дїве́1ївї1їги́1їдї1їе1р2їе́1шїи1с2їи́1дїи́1нїи̑м1їка1нїки́1їко1нїко́1їкто1їкї1їл1в2їла1рїле́1їллї1їлїп1їман1їне́1їноа1їнтї1їо1с2їо́1пїпї1їпїо1їс2т2їса1вїсі́1їті́1їтѷ1їфа́1їха́1їхи́1їхи̑1їча́1їѧ1в2їѧ́1сѡ1во2ѡ1вѣ1ѡ1дї1ѡ1ло1ѡ1мо2ѡ1ри2ѡ1то1ѡ1тї1ѡ1ѷ1ѡ́1брѡ́1ждѡ́1здѡ́ва1ѡ́ви1ѡ́га1ѡ́гї1ѡ́же1ѡ́жї1ѡ́з1нѡ́и1хѡ́ин1ѡ́ка1ѡ́л1гѡ́л1нѡ́ли1ѡ́лї1ѡ́мї1ѡ́р1бѡ́р1дѡ́р1сѡ́с1нѡ́с1сѡ́ча1ѡби1тѡби́1ѡбли1ѡбрꙋ1ѡбѣ́1ѡв1люѡв1лѧѡва́1ѡгор1ѡді́1ѡдї1ѡли́1ѡлі́1ѡлѣ́1ѡма́1ѡні́1ѡпи́1ѡпре1ѡре́1ѡри́1ѡров1ѡры́1ѡсвѧ1ѡсї1ѡтї1ѡчи́1ѡ҆1з2ѡ҆1с2ѡ҆́1бѡ҆гꙋ1ѡ҆до1ѡ҆дꙋ1ѡ҆за1ѡ҆ка1ѡ҆мо1ѡ҆па1ѡ҆ро1ѡ҆сѣ1ѣ1в2нѣ1де2ѣ1дї2ѣ1дꙋ2ѣ1з2рѣ1ла2ѣ1ло1ѣ1лꙋ2ѣ1на2ѣ1не2ѣ1но2ѣ1па2ѣ1пи2ѣ1по2ѣ1ре2ѣ1ро1ѣ1со2ѣ1стеѣ1стѝѣ2в1цѣ2д1нѣ2з1дѣ2к1нѣ2п1лѣ2т1лѣ2х1мѣ́1влѣ́1гдѣ́1ктѣ́в1цѣ́ви1ѣ́г1нѣ́до1ѣ́дї1ѣ́дꙋ1ѣ́жи1ѣ́за1ѣ́ка1ѣ́ко1ѣ́ли1ѣ́н1мѣ́пї1ѣ́р1сѣ́ро1ѣ́рї1ѣ́со1ѣ́та1ѣ́чи1ѣ́ще1ѣ̑1снѣ̑2п1ѣ̑ст1ѣви́1ѣга́1ѣдне1ѣдню1ѣдо́1ѣже́1ѣки́1ѣко́1ѣла́1ѣле1сѣло́1ѣлѣ́1ѣлѧ́1ѣнї1ѣнѧ́1ѣпа́1ѣпі́1ѣрѧ́1ѣта́1ѣто1вѣто1лѣто1рѣха́1ѣше1мѣшє́1ѣще1нѧ1не2ѧ1нꙋ2ѧ1тї1ѧ1це1ѧ2б1лѧ2т1кѧ́да1ѧ́до1ѧ́зл1ѧ́ка1ѧ́н1мѧ́т1чѧ́ти1ѧ́то1ѧ́тї1ѧ́че1ѧ́ша1ѧ́ше1ѧба́1ѧбе́1ѧв1леѧва́1ѧви́1ѧги́1ѧда́1ѧдꙋ̑1ѧзꙋ́1ѧни́1ѧны́1ѧса́1ѧсꙋ́1ѧта́1ѧта̑1ѧти̑1ѧтна1ѧті́1ѧтї1ѧца́1ѧче1сѧче́1ѧща́1ѧщен1ѧщї1ѧюще1ѧ҆1з2ѯа2н1ѯа́1рѯакꙋ1ѯапо1ѯено1ѱа́л1ѳа2г1ѳа2д1ѳа2ѵ1ѳала1ѳе1р2ѳео́1ѳера1ѳеѡ́1ѳоло1ѳсї1ѳїс2ѳїфа1ѳѵ́1мѵ1ка2ѵ1ло2ѵ1ре2ѵ1рї1ѵ1стрѵ2ї1ѵ́1птѵ́нї1ѵ́те1ѷ1гдѷ1каѷ1кеѷ1ктѷ1л2ѷ1п2ѷе1лѷе́2ѷза2ѷла2ѷм1вѷна1ѷри2ѷро1ѷрї1ѷхї1ѵа́н1ѵге́1ѵдї1ѵло́1ѵма́1ѵме́1ѵно́1ѵнї1ѵпра1ѵрі́1ѵрї1ѵрѡ́1ѵсе́1ѵсї1ѵсѷ1ѵті́1ѵтѷ1ѵфро1ѵѳа́1ѵѳѵ́1ѵ҆2с1ѵ҆пе1ѵ҆по1ѷ1г2нѷ1ме1ѷ1мї1ѷ2м1пѷзан1ѷка1рѷке́1ѷкто1ѷлі́1ѷмпї1ѷно́1ѷпі́1ѷрї1ѷсо́1ѷхї1ѹ҆1б2ѹ҆1в2ѹ҆1з2ѹ҆1м2ѹ҆1скѹ҆1спѹ҆́1бѹ҆́1нѹ҆́1хѹ҆́1чѹ҆га1ѹ҆ко1ѹ҆не1ѹ҆ни1ѹ҆по1ѹ҆та1ѹ҆то1ѻгне1ѻнꙋ́1ѻр1д2ѻрꙋ́1ѻтро1ѻ҆1в2ѻ҆1з2ѻ҆1с2ѻ҆б1рѻ҆бо1ѻ҆ди1ѻ҆ка1ѿва1лѿвер1ѿвра1ѿго́1ѿе́м1ѿкро1ѿкꙋ́1ѿне́1ѿра1сѿра́1ѿри́1ѿсе́1ѿсто1ѿто́1ѿтꙋ́1ѿхо́1ѿча́1ѿча̑1҃га́1҃е́1с҃и́1в҃и́1с҃и́1ц҃и́1ч҃неч1҃нї1҃о1в2҃о1з2҃о́в1҃оиз1҃олю1҃она1҃оне1҃оѧв1҃рне1҃рни1҃рї1҃тво1҃ше́1҃ща́1҃ще́1҃ы́1н҃є́н1҆1в2д҆1в2н҆1в2ц҆1в2ч҆1во1҆1вї1҆1вꙋ1҆1зе1҆1и1с҆1лѷ2҆1лꙋ1҆1м2н҆1м2п҆1мї1҆1мѧ2҆1нꙋ2҆1пи2҆1пꙋ1҆1рї1҆1рѡ1҆1рꙋ2҆1с2н҆1се2҆1скл҆1со2҆1спа҆1спи҆1сы1҆1чꙋ1҆1ї1҆1ꙋ1в҆1ꙋ1д҆1ꙋ1л҆1ꙋ̑1҆2б1в҆2б1д҆2в1л҆2с1х҆2с1ц҆2т1ч҆́1бл҆́1бр҆́1вц҆́1гц҆́1зр҆́1ск҆́1сн҆́1сп҆́1щ2҆́2ц1҆́ва1҆́ве1҆́во1҆́вї1҆́дї1҆́з1д҆́з1н҆́зе1҆́л1ч҆́мо1҆́мѧ1҆́н1д҆́на1҆́ни1҆́нѡ1҆́нꙋ1҆́р1т҆а1р2҆а2м1҆а́1к҆анꙋ1҆б1рꙋ҆ба́1҆би1т҆бла1҆бли1҆бни1҆бол1҆бре1҆бѡ́1҆вва1҆ве1н҆вї1҆вѣ1р҆глѣ1҆гор1҆гро1҆да1л҆дав1҆до1л҆дє́1҆дї1҆дѡ1л҆дѣ1в҆дѣ́1҆дꙋ́1҆е1з2҆езе1҆еро1҆ерꙋ1҆жи́1҆з1н2҆з1ра҆з1рѧ҆з̾ꙋ1҆зви1҆зже1҆зи́1҆зли1҆змо1҆зне1҆знꙋ1҆зсꙋ1҆зі́1҆ка1л҆кле1҆кло1҆ко1в҆кро1҆крꙋ1҆кте1҆кї2҆кѵ́1҆кѷ1҆л1в2҆ла1р҆ла́1҆лве1҆лез1҆леѵ1҆ли́1҆ли̑1҆лма1҆лїи1҆лїо1҆лѷ2҆ме1н҆мо1в҆мо1н҆мпе1҆мра1҆мѣ̑1҆мѧ́1҆мꙋ́1҆на́1҆нем1҆ни1с҆ни́1҆нтї1҆ні́1҆нї1҆нѵ́1҆нꙋ́1҆па1с҆пе1р҆пи́1҆пле1҆по1р҆по́1҆пол1҆поѧ1҆про1҆прѣ1҆пі́1҆пї1҆р1г2҆р1м2҆ра1в҆ра1з҆рда1҆ре1т҆рпа1҆рѧ́1҆с1по҆с1пꙋ҆с1тл҆с1то҆свѣ1҆свѧ1҆ски1҆смо1҆стꙋ1҆сцѣ1҆сі́1҆сї1҆сѣ1н҆сѣ́1҆сѣк1҆сѷ2҆сѷг1҆сꙋ1д҆сꙋ́1҆та́1҆ти́1҆то1л҆то́1҆тѣ́1҆фе́1҆фрї1҆ха́1҆хі́1҆ча́1҆че1н҆че1с҆чи1с҆чре1҆чє́1҆ши́1҆шꙋ́1҆ще́1҆ѡна1҆ѧ2з1҆ѧ́1ж҆ѧ́з1҆ѵрѡ1҆ꙋ́1д҆ꙋ́1л҆ꙋ́1н҇лі́1҇лї1҇на́1҇но1м҇но́1҇нї1҇рди1҇рдї1҇ро́1҇ти́1҇то1в҇то1м҇тои1҇тї1҇тѡ́1҇че1сᲂу҆1лᲂу҆1пᲂу҆̀1ᲂу҆г2ᲂу҆с2ᲂу҆т2ⷣбно1ⷣнї1ⷣте́1ⷣтї1ꙋ1д2рꙋ1дї1ꙋ1дꙋ2ꙋ1ре1ꙋ1ри2ꙋ1ро2ꙋ1троꙋ2д1нꙋ2з1дꙋ2з1нꙋ2ш1лꙋ́бо1ꙋ́гꙋ1ꙋ́жї1ꙋ́ко1ꙋ́нѧ1ꙋ́р1тꙋ́ре1ꙋ́рж1ꙋ́с1сꙋ́ча1ꙋ́че1ꙋ́ше1ꙋ́щꙋ1ꙋ́ї1ꙋ̑2в1ꙋ̑2н1ꙋ̑2с1ꙋб1люꙋба́1ꙋби1нꙋбны1ꙋбнꙋ1ꙋбо́1ꙋвше1ꙋга́1ꙋда́1ꙋден1ꙋдо1лꙋдро1ꙋдї1ꙋдѣ1вꙋемо1ꙋете1ꙋзі́1ꙋко1вꙋко1нꙋко1сꙋкра1ꙋкі́1ꙋле́1ꙋмі́1ꙋпа́1ꙋров1ꙋсо1мꙋсто1ꙋстѡ1ꙋсї1ꙋтї1ꙋха́1ꙋцѣ1лꙋче1нꙋчє́1ꙋше1тꙋща́1ꙋще́1ꙋщї1ꙋѧ́1мꙍ҆̑1лꙗви́1ꙗ҆1з2ꙗ҆1с2ꙗ҆́1мꙗ҆́1р", + 6 : "1а̑2м11ален11б2лѝ1б2лї11б2рѡ21бле1в1бле1с1блег11блю1д1брї11брѣй1бщї21ва́1г1ва́й1ва́є11ва̑1н1ванї1варѝ1ве́1ш1вед1н1вен1т1ви́1ч1вирї1вле1ц1вы1ш21вє́1л1вє́н11вѡ́1д1вѣ́й1вѧ́1с1вѧ́1х1вѧ́д11вѧщї1вѵ́1л1вꙋ́1щ1вꙋ́р11г2ле11г2лї11г2на21г2нѝ1г2ню21г2нї21га1д21га́1х1га́1ш1га́й1ги́1т1гнеѡ11гни́11го1з21го1н21го́1ж1го́1н1го́1с1го́ф11гопо11горї1д2рї11д2рѣ21да1с21да́й1дайт1далї1данї1де́1к1де́1ш1де́ч11десѝ1длен11дне1с1дно1в1дрен11дє́ч11ді́1т1ді́е11дї1г1дїѐ1дїе́1дїѧ̀1дїѧ́1дꙋ́1г1дꙋ́1з1дꙋ́1щ1дꙋ́ж11емо1м1емы1м1еро1в1еро1м1ет1но1ет1ны1же́й1жє́1с1з2нї11з2рѝ1з2ꙋт11здан11зе2т11зе́й1зре́11зы́б11зы́й1и1лє11и1се21и2с1ц1из1ни1изы́11искꙋ11ка1с21ка́1к1ка́1м1ка́й1ка́ю11ка̑1з1ка̑н11квї21ке1д21ке́1р1ке́м11ки́1р1клик11клїй1ко1ст1ко́1п1кое́11коей1копи11коре11корꙋ11кры1м1кі́1т1кі́с11кїи21кі̑й1кї2л11кї2н11кꙋ2з11кꙋ́1р1кꙋ́1щ1ла́й1ланї1лати11лаѧй1ле1р21ле́1р1ле́1ч1ле́б11ле́ж11лежѐ1лема11лемо11лемꙋ11лен1т1лесѐ1лесѝ1ли́1б1ли́1щ1ли̑1к1ли̑1м1люще11лющї1лє́с11лі́1т1лї1к1лї1л1лї1м1лїа̀1лїан1лїѐ1лїев1лїѝ1лїи́1лїим1лїин1лїпп1лїю̀1лїѧ_1лїѧ̑1лѡ1с21лѡтї1лѣ́1ш1лѣ́ж11лѧ́1с1лѷ2м11лꙋ́1в1лꙋ́1н1лꙋ́й1лꙋ́ч11лꙋ́ї1м2лѝ1ма́1ж1ма́1з1ма́1ш1ма́й1марѧ11ме1д21ме́1л1ме́з11ме́й1ме́ц11мерї11ми1с21ми1т21ми́1с1ми́1т1мирѝ1мли́11мни1т1мо1з21мо́1к1море11мы́н11мє́н11мі́1н1мї1л1мї1н1мї1с1мїи_1мїѝ1мїй1мїѡ11мѣнѝ1мѧтї1не2ж11не́1ж1не́1л1не́ч11нена11ни́1с1ни̑в11нис1п1нити11но́1д1но́1ф1но́ї1ново11нопо11ны́1н1нѣ2ш11нѧ́й1нꙋ́1д1нꙋ́1с1нꙋ́1ф1нꙋ́ѧ11п2лї11п2лѡ21п2лꙋ11п2не21па́1г1па́1ч1па́ю11падѐ1падѝ1пасї11пе́1з1пле1в1пле1м1пле1н1по1в21по1м21по1с21по́й1пі́1н1пі́1т1пѧ́1с1пѧ́л11ра́ї11рапї1реде11рей_1ремї1рена11ренї11речѐ1ри́1ц1ри́ч11ро́1ц1ров1н1ров1с1родо11рі́е11рї1л1рїин1рїкъ1рїсе1рїсє1рїтѡ1рїе1в1рѣ́й1рѣ̑1ч1рѣ̑й1рѷ1м1рѷ2к1рꙋ́т11рꙋ́ч11рꙋѧй1с2нѝ1с2пѝ1с2тѐ1с2тє11с2тї11с2це11са1л21са1р21са1с21са́1с1са́ї11са̑1н1се́1ѵ1сера11си1с21си́1с1склї11сней1снен11сни̑11сны́11снїю1со1з21со1мн1спа1с1спи1т1ствї1стей1сто1с1стрѐ1сы́1т1сє́1н1сє́й1т2лѝ1т2це21т2чѐ1т2чи21та́1г1тарѝ1тве1ц1твый1твѣ́11те1т21тер1м1теро11течѐ1ти1с21ти́1д1ти́1з1ти̑1н1тив1л1тиво11тими11тлан11тли́11то1з21то́1з1тов1л1тодї1толе11толѝ1тона11топ1л1тосо11тощѝ1тре1ц1тчей1тє́1ч1тє́й1ті́е11тї1п1тїа_1тїѐ1тїе́1тїею1тїѝ1тїй1тїих1тїю̀1тїѧ̀1тїѧг1тїѧм1тїѧх1тїлї11тїно11тѡ́1к1тѣ́1т1тѣ́1ш1тѣ́ю11тѧ2т11тѧ́1х1тѧ́й1тꙋ2р11тꙋ́е11тꙋ́ю11хи1т21хо́1щ1хо́в11ходо11ца́1л1ца́1т1ца́1ш1ца́ю11це́1т1цꙋ́з11что́11ща1с21ща́1м1ща́1х1ща́д11щє1н21щє́н11ющїи1ющїѧ1є́мы11ї1лѧ1ї1ны1їина1їно_1їтѝ1ѡ1с2к1ѡ1са11ѡ1сѣ11ѡ́р1г1ѡа2н11ѧ1зы21ѧ2з1в1ѧ́з1в1ѧнї11ѳи́1с1ѳі́1с1ѷ1сє1ѷпо11ѷ1се21ѻ1рꙋ21ꙋ1лї11ꙋ́лї1ꙋ́мї11ꙋ́нї1ꙋмѣ̑11ꙋстї2а2з1р2анї12б1ло12в1ню12ви1з22вчї12вѣ2з12д1ло12д1нѝ2д1нѧ12е1м2л2е1мѧ22е1т2к2е1т2л2е1то22е1тї12е1тѡ12е2м1п2з1д2в2з1дї12з1лї12к1не22ли1с22ли2з12м1не12м1па22м1по12м1ти12не1з22не1р22ни2з12п1на12п1но12п1нꙋ12пе2ѵ12пнї12рѷ1с2с2т1ц2спї12т1ки22т1ко12т1кї2т1кꙋ22т1лї12т1лꙋ12те1з22ты1н22тє1н22х1мѝ2є1мї12ї1ка2ї1ки2ї1ла2ї1лї2їлї2їн1б2ѡ1ре22ѧ1з2ꙋ2ѧ̑2ж12ѷс1с2ѷ1со22ꙋ1тї12ꙋ2м1л8а҆̀8_8а҆́8_8а҆̈8_8а҆̑8_8е҆̀8_8е҆́8_8е҆̈8_8е҆̑8_8й̀8_8й́8_8й̈8_8й̑8_8йⷠ҇_8йⷡ҇_8йⷢ҇_8йⷣ҇_8йⷤ҇_8йⷥ҇_8йⷦ҇_8йⷧ҇_8йⷨ҇_8йⷩ҇_8йⷪ҇_8йⷫ҇_8йⷬ҇_8йⷭ҇_8йⷮ҇_8йⷯ҇_8йⷰ҇_8йⷱ҇_8йⷲ҇_8йⷳ҇_8йⷴ҇_8йⷵ҇_8йⷶ҇_8йⷷ҇_8йⷸ҇_8йⷹ҇_8йⷺ҇_8йⷻ҇_8йⷼ҇_8йⷽ҇_8йⷾ҇_8йⷿ҇_8йꙴ҇_8йꙵ҇_8йꙶ҇_8йꙷ҇_8йꙸ҇_8йꙹ҇_8йꙺ҇_8йꙻ҇_8й꙼҇_8й꙽҇_8и҆̀8_8и҆́8_8и҆̈8_8и҆̑8_8й҆̀8_8й҆́8_8й҆̈8_8й҆̑8_8о҆̀8_8о҆́8_8о҆̈8_8о҆̑8_8ствъ_8у҆̀8_8у҆́8_8у҆̈8_8у҆̑8_8ы҆̀8_8ы҆́8_8ы҆̈8_8ы҆̑8_8э҆̀8_8э҆́8_8э҆̈8_8э҆̑8_8ю҆̀8_8ю҆́8_8ю҆̈8_8ю҆̑8_8є҆̀8_8є҆́8_8є҆̈8_8є҆̑8_8і҆̀8_8і҆́8_8і҆̈8_8і҆̑8_8ѡ҆̀8_8ѡ҆́8_8ѡ҆̈8_8ѡ҆̑8_8ѣ҆̀8_8ѣ҆́8_8ѣ҆̈8_8ѣ҆̑8_8ѧ҆̀8_8ѧ҆́8_8ѧ҆̈8_8ѧ҆̑8_8ѵ҆̀8_8ѵ҆́8_8ѵ҆̈8_8ѵ҆̑8_8ѹ҆̀8_8ѹ҆́8_8ѹ҆̈8_8ѹ҆̑8_8ѻ҆̀8_8ѻ҆́8_8ѻ҆̈8_8ѻ҆̑8_8ѽ҆̀8_8ѽ҆́8_8ѽ҆̈8_8ѽ҆̑8_8ѿ҆̀8_8ѿ҆́8_8ѿ҆̈8_8ѿ҆̑8_8ᲂӱ8_8ᲂу҆̀_8ᲂу҆́_8ᲂу҆̈_8ᲂу҆̑_8ᲂуⷠ҇_8ᲂуⷡ҇_8ᲂуⷢ҇_8ᲂуⷣ҇_8ᲂуⷤ҇_8ᲂуⷥ҇_8ᲂуⷦ҇_8ᲂуⷧ҇_8ᲂуⷨ҇_8ᲂуⷩ҇_8ᲂуⷪ҇_8ᲂуⷫ҇_8ᲂуⷬ҇_8ᲂуⷭ҇_8ᲂуⷮ҇_8ᲂуⷯ҇_8ᲂуⷰ҇_8ᲂуⷱ҇_8ᲂуⷲ҇_8ᲂуⷳ҇_8ᲂуⷴ҇_8ᲂуⷵ҇_8ᲂуⷶ҇_8ᲂуⷷ҇_8ᲂуⷸ҇_8ᲂуⷹ҇_8ᲂуⷺ҇_8ᲂуⷻ҇_8ᲂуⷼ҇_8ᲂуⷽ҇_8ᲂуⷾ҇_8ᲂуⷿ҇_8ᲂуꙴ҇_8ᲂуꙵ҇_8ᲂуꙶ҇_8ᲂуꙷ҇_8ᲂуꙸ҇_8ᲂуꙹ҇_8ᲂуꙺ҇_8ᲂуꙻ҇_8ᲂу꙼҇_8ᲂу꙽҇_8ᲂ҆̀8_8ᲂ҆́8_8ᲂ҆̈8_8ᲂ҆̑8_8ꙋ҆̀8_8ꙋ҆́8_8ꙋ҆̈8_8ꙋ҆̑8_8ꙍ҆̀8_8ꙍ҆́8_8ꙍ҆̈8_8ꙍ҆̑8_8ꙍ҆̑ⷠ_8ꙍ҆̑ⷡ_8ꙍ҆̑ⷢ_8ꙍ҆̑ⷣ_8ꙍ҆̑ⷤ_8ꙍ҆̑ⷥ_8ꙍ҆̑ⷦ_8ꙍ҆̑ⷧ_8ꙍ҆̑ⷨ_8ꙍ҆̑ⷩ_8ꙍ҆̑ⷪ_8ꙍ҆̑ⷫ_8ꙍ҆̑ⷬ_8ꙍ҆̑ⷭ_8ꙍ҆̑ⷮ_8ꙍ҆̑ⷯ_8ꙍ҆̑ⷰ_8ꙍ҆̑ⷱ_8ꙍ҆̑ⷲ_8ꙍ҆̑ⷳ_8ꙍ҆̑ⷴ_8ꙍ҆̑ⷵ_8ꙍ҆̑ⷶ_8ꙍ҆̑ⷷ_8ꙍ҆̑ⷸ_8ꙍ҆̑ⷹ_8ꙍ҆̑ⷺ_8ꙍ҆̑ⷻ_8ꙍ҆̑ⷼ_8ꙍ҆̑ⷽ_8ꙍ҆̑ⷾ_8ꙍ҆̑ⷿ_8ꙍ҆̑ꙴ_8ꙍ҆̑ꙵ_8ꙍ҆̑ꙶ_8ꙍ҆̑ꙷ_8ꙍ҆̑ꙸ_8ꙍ҆̑ꙹ_8ꙍ҆̑ꙺ_8ꙍ҆̑ꙻ_8ꙍ҆̑꙼_8ꙍ҆̑꙽_8ꙗ҆̀8_8ꙗ҆́8_8ꙗ҆̈8_8ꙗ҆̑8__врї1_вїа1_й҆̀8_й҆́8_й҆̈8_й҆̑8_йⷠ҇8_йⷡ҇8_йⷢ҇8_йⷣ҇8_йⷤ҇8_йⷥ҇8_йⷦ҇8_йⷧ҇8_йⷨ҇8_йⷩ҇8_йⷪ҇8_йⷫ҇8_йⷬ҇8_йⷭ҇8_йⷮ҇8_йⷯ҇8_йⷰ҇8_йⷱ҇8_йⷲ҇8_йⷳ҇8_йⷴ҇8_йⷵ҇8_йⷶ҇8_йⷷ҇8_йⷸ҇8_йⷹ҇8_йⷺ҇8_йⷻ҇8_йⷼ҇8_йⷽ҇8_йⷾ҇8_йⷿ҇8_йꙴ҇8_йꙵ҇8_йꙶ҇8_йꙷ҇8_йꙸ҇8_йꙹ҇8_йꙺ҇8_йꙻ҇8_й꙼҇8_й꙽҇8_сї1м_трї1_ꙍ҆̑̀8_ꙍ҆̑́8_ꙍ҆̑̈8_ꙍ҆̑̑8_ꙍ҆̑҆8_ꙍ҆̑ⷠ8_ꙍ҆̑ⷡ8_ꙍ҆̑ⷢ8_ꙍ҆̑ⷣ8_ꙍ҆̑ⷤ8_ꙍ҆̑ⷥ8_ꙍ҆̑ⷦ8_ꙍ҆̑ⷧ8_ꙍ҆̑ⷨ8_ꙍ҆̑ⷩ8_ꙍ҆̑ⷪ8_ꙍ҆̑ⷫ8_ꙍ҆̑ⷬ8_ꙍ҆̑ⷭ8_ꙍ҆̑ⷮ8_ꙍ҆̑ⷯ8_ꙍ҆̑ⷰ8_ꙍ҆̑ⷱ8_ꙍ҆̑ⷲ8_ꙍ҆̑ⷳ8_ꙍ҆̑ⷴ8_ꙍ҆̑ⷵ8_ꙍ҆̑ⷶ8_ꙍ҆̑ⷷ8_ꙍ҆̑ⷸ8_ꙍ҆̑ⷹ8_ꙍ҆̑ⷺ8_ꙍ҆̑ⷻ8_ꙍ҆̑ⷼ8_ꙍ҆̑ⷽ8_ꙍ҆̑ⷾ8_ꙍ҆̑ⷿ8_ꙍ҆̑ꙴ8_ꙍ҆̑ꙵ8_ꙍ҆̑ꙶ8_ꙍ҆̑ꙷ8_ꙍ҆̑ꙸ8_ꙍ҆̑ꙹ8_ꙍ҆̑ꙺ8_ꙍ҆̑ꙻ8_ꙍ҆̑꙼8_ꙍ҆̑꙽8́1блѧ1́1брꙋ1́1дра1́1плѧ1́1рѷ2́1спо1́1три1́2д1н2́б1лю1́з1на1́з1но1́ннї1́с1на1́ї1л2̑1дї1̑1кї1̑1лї1̑1тї1̑в1ни1̑днї1̑з1на1̑йши1̑пкї1̑с1на1а1рѷ1аврї1айшї1айшї1аллї1аннї1аркї1артї1арїи1ас1па1ассї1атрї1ающї1б1ле1цб1лѧ́1бы́7выв1да̑1в1лю́1в1лєн1венї1вскї1вї2л1вѷ2с1г1нꙋ1тг2лѷ1д1ва1рд1на́1д1но1мд1но́1е1дне1е1лї1е́дї1е́нї1е́щї1ед1ва1ед1ла1ед1но1еднї1ентї1ерї1керїн1ждшї1женї1з1да1лз1дне1з1дно1з1ни1кз1ни́1з1нис1з1но1ми1зно1и1лї1и́вї1и́лї1и́нї1и́рї1и́тї1йнї1йска1йско1йскꙋ1иннї1ипїо1итрї1и҆лї1клї1пкѷ2м1л1мї1лерї1ллї1нлнїи1лнїѧ1лїко1лїо́1лїса1лѷ2м1м1но1ммїи́1мїлї1мїса1мїха1мїлї1нї2г1нїе1внїка1нїма1нїне1нїѧ1мо1вне1о1рѷ1о1спи1о2з1л2о́тї1о́щї1оз1до1оз1ды1оллї1олїн1ордї1ос1пе1п1лѧ́1полї1прїѡ1пї1с2пїо́1р1з2н2р1мї1р1твїрншї1ролї1рї1с2рїи1мс1ни1кс1па1дс2лї1тенї1тїнї1тїнї1тѷ2м1фрї1кфї1л2фїла1хїсе1ч1не1мченї1черї1чис7лечис7лѣшенї1щенї1ы1рї1ы́лї1ы́нї1ы́тї1ю́дї1є́лї1є́нї1єскї1ї1кї1ї1ло1ї1лꙋ1ї1ме1ї1мо1ї1мї1ї1на2ї1па2ї1ро1ї1со1ї1стеї1стої1стрї1ѷ1ї2г1гїа́1дїве́1ївї1їги́1їдї1їе1р2їе́1шїи1с2їи́1дїи́1нїи̑м1їка1нїки́1їко1нїко́1їкто1їкї1їл1в2їла1рїле́1їллї1їлїп1їман1їне́1їноа1їнтї1їо1с2їо́1пїпї1їпїо1їс2т2їса1вїсі́1їті́1їтѷ1їфа́1їха́1їхи́1їхи̑1їча́1їѧ1в2їѧ́1сї1мї1їллї1їлїп1їнтї1їпїо1ѡ1с2т2ѡ́гї1ѡ́жї1ѡ́лї1ѡ́мї1ѣ1дї2ѣ1сто1ѣ́дї1ѣ́пї1ѣ́рї1ѧ́тї1ѳїфа1ѵ́нї1ѷ1г2нѷ1ме1ѷ1мї1ѷ2м1пѷзан1ѷка1рѷке́1ѷкто1ѷлі́1ѷмпї1ѷно́1ѷпі́1ѷрї1ѷсо́1ѷхї1ѷ1мї1ѷмпї1ѿ7нн҃ѣ҆1мї1҆1рї1҆1спѣ1҆́вї1҆́дї1҆з1да1҆з1ре1҆з1ри1҆лїи1҆лїо1҆нтї1҆сѷг1҆фрї1҇рдї1ᲂу҆1б2ᲂу҆1в2ᲂу҆1з2ᲂу҆1м2ᲂу҆1скᲂу҆1спᲂу҆́1бᲂу҆́1нᲂу҆́1хᲂу҆́1чᲂу҆га1ᲂу҆ко1ᲂу҆не1ᲂу҆ни1ᲂу҆по1ᲂу҆та1ᲂу҆то1ꙋ1трꙋ1ꙋ́жї1", + 7 : "1б2лї11ет1на11з2нї11из1ре11кї2л11кї2н11мерї11пасї11ра́ї11ренї11рїе1в1са́ї11склї11тїлї11тїно11тїлї11ѷ1се21ꙋ1лї11ꙋ́мї12з1дї12з1лї12т1лї12є1мї12ѷ1со28й҆̀8_8й҆́8_8й҆̈8_8й҆̑8_8ꙍ҆̑̀8_8ꙍ҆̑́8_8ꙍ҆̑̈8_8ꙍ҆̑̑8_8ꙍ҆̑ⷠ҇_8ꙍ҆̑ⷡ҇_8ꙍ҆̑ⷢ҇_8ꙍ҆̑ⷣ҇_8ꙍ҆̑ⷤ҇_8ꙍ҆̑ⷥ҇_8ꙍ҆̑ⷦ҇_8ꙍ҆̑ⷧ҇_8ꙍ҆̑ⷨ҇_8ꙍ҆̑ⷩ҇_8ꙍ҆̑ⷪ҇_8ꙍ҆̑ⷫ҇_8ꙍ҆̑ⷬ҇_8ꙍ҆̑ⷭ҇_8ꙍ҆̑ⷮ҇_8ꙍ҆̑ⷯ҇_8ꙍ҆̑ⷰ҇_8ꙍ҆̑ⷱ҇_8ꙍ҆̑ⷲ҇_8ꙍ҆̑ⷳ҇_8ꙍ҆̑ⷴ҇_8ꙍ҆̑ⷵ҇_8ꙍ҆̑ⷶ҇_8ꙍ҆̑ⷷ҇_8ꙍ҆̑ⷸ҇_8ꙍ҆̑ⷹ҇_8ꙍ҆̑ⷺ҇_8ꙍ҆̑ⷻ҇_8ꙍ҆̑ⷼ҇_8ꙍ҆̑ⷽ҇_8ꙍ҆̑ⷾ҇_8ꙍ҆̑ⷿ҇_8ꙍ҆̑ꙴ҇_8ꙍ҆̑ꙵ҇_8ꙍ҆̑ꙶ҇_8ꙍ҆̑ꙷ҇_8ꙍ҆̑ꙸ҇_8ꙍ҆̑ꙹ҇_8ꙍ҆̑ꙺ҇_8ꙍ҆̑ꙻ҇_8ꙍ҆̑꙼҇_8ꙍ҆̑꙽҇__раз7ꙋм_ꙍ҆̑҆̀8_ꙍ҆̑҆́8_ꙍ҆̑҆̈8_ꙍ҆̑҆̑8_ꙍ҆̑ⷠ҇8_ꙍ҆̑ⷡ҇8_ꙍ҆̑ⷢ҇8_ꙍ҆̑ⷣ҇8_ꙍ҆̑ⷤ҇8_ꙍ҆̑ⷥ҇8_ꙍ҆̑ⷦ҇8_ꙍ҆̑ⷧ҇8_ꙍ҆̑ⷨ҇8_ꙍ҆̑ⷩ҇8_ꙍ҆̑ⷪ҇8_ꙍ҆̑ⷫ҇8_ꙍ҆̑ⷬ҇8_ꙍ҆̑ⷭ҇8_ꙍ҆̑ⷮ҇8_ꙍ҆̑ⷯ҇8_ꙍ҆̑ⷰ҇8_ꙍ҆̑ⷱ҇8_ꙍ҆̑ⷲ҇8_ꙍ҆̑ⷳ҇8_ꙍ҆̑ⷴ҇8_ꙍ҆̑ⷵ҇8_ꙍ҆̑ⷶ҇8_ꙍ҆̑ⷷ҇8_ꙍ҆̑ⷸ҇8_ꙍ҆̑ⷹ҇8_ꙍ҆̑ⷺ҇8_ꙍ҆̑ⷻ҇8_ꙍ҆̑ⷼ҇8_ꙍ҆̑ⷽ҇8_ꙍ҆̑ⷾ҇8_ꙍ҆̑ⷿ҇8_ꙍ҆̑ꙴ҇8_ꙍ҆̑ꙵ҇8_ꙍ҆̑ꙶ҇8_ꙍ҆̑ꙷ҇8_ꙍ҆̑ꙸ҇8_ꙍ҆̑ꙹ҇8_ꙍ҆̑ꙺ҇8_ꙍ҆̑ꙻ҇8_ꙍ҆̑꙼҇8_ꙍ҆̑꙽҇8айшї1во8дна́во8дно́во8дны́вѣст7вожа́7тважа́7твыжа́7твꙋжи́7зниис7полнис7хо́дис7хождис7черпкос7новкос7нꙋ́мїлї1па́7сцѣтїнї1ї1мї1їллї1їлїп1їнтї1їпїо1ѷ1мї1ѷмпї1ꙋка7за́", + 8 : "1тїлї18ꙍ҆̑҆̀8_8ꙍ҆̑҆́8_8ꙍ҆̑҆̈8_8ꙍ҆̑҆̑8__а҆с7сѷр_вос7пѣв_зе́7мле_зе́7млю_и҆с7кꙋс_и҆с7тек_мес7сі́_по7злащ_при7льп_раз7ꙋ́м_ѡ҆б7лещ_ѡ҆б7ращ_ѻ҆́т8ча_ѻ҆́т8че_ѿ7всю́дбоѧ́7знивоз8да́нвѣст7вꙋ́дне8внꙋ́дрѣ́7влеис7цѣ́льис7цѣ̑лькел7сі́йклѧ́т7ваклѧ́т7воклѧ́т7выклѧ́т7вѣклѧ́т7вꙋкос7не́ткос7ни́тне7зра́чне8с7тѝ_нов7ле́нра8с7падра8с7палрас7пнѝтер8п7лѧтре8б7лѧче7с8тѝ_ѡбра7зꙋ́", + 9 : "_а҆кта́7ꙋ_а҆с7сѷр_вос7пѣ́в_вос7трꙋб_и҆с7кꙋ́с_и҆с7те́к_и҆са́7їе_и҆са́7їѧ_по7всю́д_по7чне́т_пѣ́7с8не_пѣ́7с8ни_пѣ́7с8ню_пѣ́7с8нѣ_ра8с7тлѝ_ра8с7тлѧ_ра8с7точ_сла7сте́_со7з8ва́_і҆ес7се́_ѡ҆7бра́з_ѡ҆7брѣ́л_ѡ҆7брѣ́т_ѡ҆б7ле́к_ѡ҆б7ра́т_ѡ҆б7ра́щ_ѡ҆б7рѣ́з_ѵ҆с7сѡ́п_ѹ҆7стрембла́з7ненболѣ́7знеболѣ́7зниве́тхо7мꙋвѣ́8ст7водви́8г7лажи8в7ле́нкел7сі́йклѧ́т7венколос7са́моли́7твамоли́7твомоли́7твымоли́7твѣмоли́7твꙋне8с7ла̀_не8с7ло̀_не8с7тѝ_ра8с7та́ѧра8с7творра8с7терзсла́8в7люсре́7д8неста́в7лю_тер8п7лю̀ца́р7стваца́р7ствоца́р7ствїца́р7ствѣца́р7ствꙋче7с8тѝ_ѹ҆7сте́нъ", + 10 : "_во7с8прѧн_вос7трꙋ́б_гри́7в8на_гри́7в8ны_гри̑7в8ны_гри̑7в8нѣ_и҆с7корен_и҆с8то́тн_и҆са́7їе_и҆са́7їѧ_ме7т8не́н_наза7ре́т_по8д7но́г_по8д7но́ж_по́7ж8нет_по́7ж8нꙋт_по́7м8нит_при́7т8ча_при́7т8че_при́7т8чи_про7з8ва̀_про́7стрꙋ_прїе́м7ле_прїе́м7ли_прїе́м7лю_прїе́м7лѣ_прїе́м7лѧ_ра8с7тлѝ_ра8с7тлѣ́_стра7сте́_че8ст7вов_че8ст7вꙋ́_ѡ҆бра7зꙋ́_ѳес7салон_ѻ҆́т7расл_ᲂу҆7стремве́7тсѣмъ_ло7ви́7твало7ви́7твыло7ви́7твꙋмоли́7твенпра́з7дникпра́з7дницра8с7ка́етра8с7ка́ѧнра8с7простра8с7то́ргра8с7то́ржре́7в8ностсла́8в7ленспа8с7ла̀_спа8с7ло̀_ста́8в7ленстраж7бы̑_сынов8ле́нтре8б7ле́нтре8б7лю̀_ца́р7ствї", + 11 : "_а҆рїа́7д8н_во7с8прѧ́н_вос7трепет_и҆зба́7вле_и҆зба́7влю_и҆с7ка́пав_полꙋ́7д8не_полꙋ́7д8ни_пото8п7лѧ́_пре7ль8ща́_прїе́м7ле_прїе́м7ли_прїе́м7лю_прїе́м7лѣ_прїе́м7лѧ_ѡ҆8т7ве́рг_ѡ҆8т7ве́рж_ѡ҆8т7ры́гн_ѻ҆б7ра́дова҆́нгел7ми_вис7сарїѡ́ндости́8г7лаᲂу҆7сте́нъ", + 12 : "_а҆рїа́7д8н_вос7тре́пет_пото8п7ле́н_пре7ль8сти́_сподо8б7лѧ́_ѡ҆8б7ра́доввис7сарїѡ́нкова́р7ство_мї7ли́с7сенъсїл7ве́7стрꙋє҆ѵел7пі́стъ", + 13 : "_а҆вес7салѡ́м_мел7хїседе́ккле7о7па́7трамї7ли́с7сенъсїл7ве́7стрꙋ", + 14 : "_мел7хїседе́к", + 17 : "пре7вы́7спрєн7нѧѧ" + }, + patternChars : "_̀́̆̇̈̏̑̾абвгдежзийклмнопрстуфхцчшщъыьэюѐёєѕіїѝѡѣѧѯѱѳѵѷѹѻѽѿ҃҆҇ӓӥӧӭӱӹᲂᲆⷠⷡⷢⷣⷤⷥⷦⷧⷨⷩⷪⷫⷬⷭⷮⷯⷰⷱⷲⷳⷴⷵⷶⷷⷸⷹⷺⷻⷼⷽⷾⷿⸯꙋꙍꙗꙴꙵꙶꙷꙸꙹꙺꙻ꙼꙽꙾ꙿ︦︮︯", + patternArrayLength : 934205, + valueStoreLength : 58319 +}; From 2843f62e1ac4c434dd2a6dab6c6e0ef56ce2d65d Mon Sep 17 00:00:00 2001 From: mnater Date: Sat, 4 Mar 2017 23:43:28 +0100 Subject: [PATCH 72/86] update jslint --- Hyphenator.js | 4 +- testsuite/files/jslint.js | 3375 +++++++++++++++++++++---------------- 2 files changed, 1905 insertions(+), 1474 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index a212703..68f973b 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -1262,7 +1262,7 @@ Hyphenator = (function (window) { * @access public */ function hyphenateURL(url) { - var tmp = url.replace(/([:\/\.\?#&\-_,;!@]+)/gi, '$&' + urlhyphen), + var tmp = url.replace(/([:\/.?#&\-_,;!@]+)/gi, '$&' + urlhyphen), parts = tmp.split(urlhyphen), i = 0; while (i < parts.length) { @@ -2744,7 +2744,7 @@ Hyphenator = (function (window) { n.data = n.data.replace(lo.genRegExp, hyphenate); if (orphanControl !== 1) { //prevent last word from being hyphenated - n.data = n.data.replace(/(\ *)(\S+)(\s*)$/, controlOrphans); + n.data = n.data.replace(/(\u0020*)(\S+)(\s*)$/, controlOrphans); } } i += 1; diff --git a/testsuite/files/jslint.js b/testsuite/files/jslint.js index 5ad98b7..f948261 100755 --- a/testsuite/files/jslint.js +++ b/testsuite/files/jslint.js @@ -1,5 +1,5 @@ // jslint.js -// 2015-11-16 +// 2017-02-07 // Copyright (c) 2015 Douglas Crockford (www.JSLint.com) // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -22,7 +22,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -// jslint is a function that takes 3 arguments: +// jslint(source, option_object, global_array) is a function that takes 3 +// arguments. The second two arguments are optional. // source A text to analyze, a string or an array of strings. // option_object An object whose keys correspond to option names. @@ -33,13 +34,15 @@ // of valuable information. It can be used to generate reports. The object // contains: +// directives: an array of directive comment tokens. // edition: the version of JSLint that did the analysis. +// exports: the names exported from the module. +// froms: an array of strings representing each of the imports. // functions: an array of objects that represent all of the functions // declared in the file. // global: an object representing the global object. Its .context property // is an object containing a property for each global variable. // id: "(JSLint)" -// imports: an array of strings representing each of the imports. // json: true if the file is a JSON text. // lines: an array of strings, the source. // module: true if an import or export statement was used. @@ -50,7 +53,7 @@ // tokens: an array of objects representing the tokens in the file. // tree: the token objects arranged in a tree. // warnings: an array of warning objects. A warning object can contain: -// name: 'JSLintError' +// name: "JSLintError" // column: A column number in the file. // line: A line number in the file. // code: A warning code string. @@ -76,54 +79,56 @@ // 5. Check the whitespace between the tokens. // jslint can also examine JSON text. It decides that a file is JSON text if -// the first token is '[' or '{'. Processing of JSON text is much simpler than +// the first token is "[" or "{". Processing of JSON text is much simpler than // the processing of JavaScript programs. Only the first three phases are // required. // WARNING: JSLint will hurt your feelings. /*property - a, and, arity, b, bad_assignment_a, bad_character_number_a, - bad_directive_a, bad_get, bad_module_name_a, bad_option_a, bad_property_a, - bad_set, bitwise, block, body, browser, c, calls, catch, charAt, - charCodeAt, closer, closure, code, column, concat, constant, context, - couch, create, d, dead, devel, directive, disrupt, dot, duplicate_a, - edition, ellipsis, else, empty_block, es6, eval, every, expected_a_at_b_c, - expected_a_b, expected_a_b_from_c_d, expected_a_before_b, - expected_digits_after_a, expected_four_digits, expected_identifier_a, - expected_line_break_a_b, expected_regexp_factor_a, expected_space_a_b, - expected_statements_a, expected_string_a, expected_type_string_a, - expression, extra, flag, for, forEach, free, from, fud, fudge, function, - function_in_loop, functions, g, global, i, id, identifier, import, imports, - inc, indexOf, infix_in, init, initial, isArray, isNaN, join, json, keys, - label, label_a, lbp, led, length, level, line, lines, live, loop, m, - margin, match, maxerr, maxlen, message, misplaced_a, misplaced_directive_a, - module, naked_block, name, names, nested_comment, new, node, not_label_a, - nud, ok, open, option, out_of_scope_a, parameters, pop, property, push, - qmark, quote, redefinition_a_b, replace, reserved_a, role, search, - signature, slash_equal, slice, some, sort, split, statement, stop, strict, - subscript_a, switch, test, this, thru, toString, todo_comment, tokens, - too_long, too_many, tree, type, u, unclosed_comment, unclosed_mega, - unclosed_string, undeclared_a, unexpected_a, unexpected_a_after_b, + a, and, arity, assign, b, bad_assignment_a, bad_directive_a, bad_get, + bad_module_name_a, bad_option_a, bad_property_a, bad_set, bitwise, block, + body, browser, c, calls, catch, charAt, charCodeAt, closer, closure, code, + column, complex, concat, constant, context, couch, create, d, dead, + default, devel, directive, directives, disrupt, dot, duplicate_a, edition, + ellipsis, else, empty_block, es6, escape_mega, eval, every, expected_a, + expected_a_at_b_c, expected_a_b, expected_a_b_from_c_d, + expected_a_before_b, expected_digits_after_a, expected_four_digits, + expected_identifier_a, expected_line_break_a_b, expected_regexp_factor_a, + expected_space_a_b, expected_statements_a, expected_string_a, + expected_type_string_a, exports, expression, extra, finally, flag, for, + forEach, free, from, froms, fud, fudge, function, function_in_loop, + functions, g, global, i, id, identifier, import, inc, indexOf, infix_in, + init, initial, isArray, isNaN, join, json, keys, label, label_a, lbp, led, + length, level, line, lines, live, loop, m, margin, match, maxerr, maxlen, + message, misplaced_a, misplaced_directive_a, missing_browser, missing_m, + module, multivar, naked_block, name, names, nested_comment, new, node, + not_label_a, nr, nud, number_isNaN, ok, open, option, out_of_scope_a, + parameters, pop, property, push, qmark, quote, redefinition_a_b, replace, + reserved_a, role, search, signature, single, slice, some, sort, split, + statement, stop, strict, subscript_a, switch, test, this, thru, toString, + todo_comment, tokens, too_long, too_many, too_many_digits, tree, try, type, + u, unclosed_comment, unclosed_mega, unclosed_string, undeclared_a, + unexpected_a, unexpected_a_after_b, unexpected_a_before_b, unexpected_at_top_level_a, unexpected_char_a, unexpected_comment, unexpected_directive_a, unexpected_expression_a, unexpected_label_a, - unexpected_parens, unexpected_space_a_b, - unexpected_statement_a, unexpected_trailing_space, unexpected_typeof_a, - uninitialized_a, unreachable_a, unregistered_property_a, unsafe, unused_a, - use_spaces, used, value, var_loop, var_switch, variable, warning, warnings, - weird_condition_a, weird_expression_a, weird_loop, weird_relation_a, white, - wrap_assignment, wrap_condition, wrap_immediate, wrap_regexp, wrap_unary, - wrapped, writable, y + unexpected_parens, unexpected_space_a_b, unexpected_statement_a, + unexpected_trailing_space, unexpected_typeof_a, uninitialized_a, + unreachable_a, unregistered_property_a, unsafe, unused_a, use_double, + use_spaces, use_strict, used, value, var_loop, var_switch, variable, + warning, warnings, weird_condition_a, weird_expression_a, weird_loop, + weird_relation_a, white, wrap_assignment, wrap_condition, wrap_immediate, + wrap_parameter, wrap_regexp, wrap_unary, wrapped, writable, y */ var jslint = (function JSLint() { - 'use strict'; + "use strict"; function empty() { // The empty function produces a new empty object that inherits nothing. This is // much better than {} because confusions around accidental method names like -// 'constructor' are completely avoided. +// "constructor" are completely avoided. return Object.create(null); } @@ -146,36 +151,54 @@ var jslint = (function JSLint() { bitwise: true, browser: [ - 'Audio', 'clearInterval', 'clearTimeout', 'document', 'event', - 'FormData', 'history', 'Image', 'localStorage', 'location', 'name', - 'navigator', 'Option', 'screen', 'sessionStorage', 'setInterval', - 'setTimeout', 'Storage', 'XMLHttpRequest' + "Audio", + "clearInterval", + "clearTimeout", + "document", + "event", + "FileReader", + "FormData", + "history", + "Image", + "localStorage", + "location", + "name", + "navigator", + "Option", + "screen", + "sessionStorage", + "setInterval", + "setTimeout", + "Storage", + "XMLHttpRequest" ], couch: [ - 'emit', 'getRow', 'isArray', 'log', 'provides', 'registerType', - 'require', 'send', 'start', 'sum', 'toJSON' + "emit", "getRow", "isArray", "log", "provides", "registerType", + "require", "send", "start", "sum", "toJSON" ], devel: [ - 'alert', 'confirm', 'console', 'Debug', 'opera', 'prompt', 'WSH' + "alert", "confirm", "console", "prompt" ], es6: [ - 'ArrayBuffer', 'DataView', 'Float32Array', 'Float64Array', - 'Generator', 'GeneratorFunction', 'Int8Array', 'Int16Array', - 'Int32Array', 'Intl', 'Map', 'Promise', 'Proxy', 'Reflect', - 'Set', 'Symbol', 'System', 'Uint8Array', 'Uint8ClampedArray', - 'Uint16Array', 'Uint32Array', 'WeakMap', 'WeakSet' + "ArrayBuffer", "DataView", "Float32Array", "Float64Array", + "Generator", "GeneratorFunction", "Int8Array", "Int16Array", + "Int32Array", "Intl", "Map", "Promise", "Proxy", "Reflect", + "Set", "Symbol", "System", "Uint8Array", "Uint8ClampedArray", + "Uint16Array", "Uint32Array", "WeakMap", "WeakSet" ], eval: true, for: true, fudge: true, maxerr: 10000, maxlen: 10000, + multivar: true, node: [ - 'Buffer', 'clearImmediate', 'clearInterval', 'clearTimeout', - 'console', 'exports', 'global', 'module', 'process', - 'require', 'setImmediate', 'setInterval', 'setTimeout', - '__dirname', '__filename' + "Buffer", "clearImmediate", "clearInterval", "clearTimeout", + "console", "exports", "global", "module", "process", "querystring", + "require", "setImmediate", "setInterval", "setTimeout", + "__dirname", "__filename" ], + single: true, this: true, white: true }; @@ -184,92 +207,92 @@ var jslint = (function JSLint() { // This is the set of infix operators that require a space on each side. - '!=': true, - '!==': true, - '%': true, - '%=': true, - '&': true, - '&=': true, - '&&': true, - '*': true, - '*=': true, - '+=': true, - '-=': true, - '/': true, - '/=': true, - '<': true, - '<=': true, - '<<': true, - '<<=': true, - '=': true, - '==': true, - '===': true, - '=>': true, - '>': true, - '>=': true, - '>>': true, - '>>=': true, - '>>>': true, - '>>>=': true, - '^': true, - '^=': true, - '|': true, - '|=': true, - '||': true + "!=": true, + "!==": true, + "%": true, + "%=": true, + "&": true, + "&=": true, + "&&": true, + "*": true, + "*=": true, + "+=": true, + "-=": true, + "/": true, + "/=": true, + "<": true, + "<=": true, + "<<": true, + "<<=": true, + "=": true, + "==": true, + "===": true, + "=>": true, + ">": true, + ">=": true, + ">>": true, + ">>=": true, + ">>>": true, + ">>>=": true, + "^": true, + "^=": true, + "|": true, + "|=": true, + "||": true }; var bitwiseop = { // These are the bitwise operators. - '~': true, - '^': true, - '^=': true, - '&': true, - '&=': true, - '|': true, - '|=': true, - '<<': true, - '<<=': true, - '>>': true, - '>>=': true, - '>>>': true, - '>>>=': true + "~": true, + "^": true, + "^=": true, + "&": true, + "&=": true, + "|": true, + "|=": true, + "<<": true, + "<<=": true, + ">>": true, + ">>=": true, + ">>>": true, + ">>>=": true }; var opener = { // The open and close pairs. - '(': ')', // paren - '[': ']', // bracket - '{': '}', // brace - '${': '}' // mega + "(": ")", // paren + "[": "]", // bracket + "{": "}", // brace + "${": "}" // mega }; var relationop = { // The relational operators. - '!=': true, - '!==': true, - '==': true, - '===': true, - '<': true, - '<=': true, - '>': true, - '>=': true + "!=": true, + "!==": true, + "==": true, + "===": true, + "<": true, + "<=": true, + ">": true, + ">=": true }; var standard = [ // These are the globals that are provided by the ES5 language standard. - 'Array', 'Boolean', 'Date', 'decodeURI', 'decodeURIComponent', - 'encodeURI', 'encodeURIComponent', 'Error', 'EvalError', 'Function', - 'isFinite', 'isNaN', 'JSON', 'Math', 'Number', 'Object', 'parseInt', - 'parseFloat', 'RangeError', 'ReferenceError', 'RegExp', 'String', - 'SyntaxError', 'TypeError', 'URIError' + "Array", "Boolean", "Date", "decodeURI", "decodeURIComponent", + "encodeURI", "encodeURIComponent", "Error", "EvalError", "isFinite", + "JSON", "Math", "Number", "Object", "parseInt", "parseFloat", + "RangeError", "ReferenceError", "RegExp", "String", "SyntaxError", + "TypeError", "URIError" ]; var bundle = { @@ -283,7 +306,6 @@ var jslint = (function JSLint() { and: "The '&&' subexpression should be wrapped in parens.", bad_assignment_a: "Bad assignment to '{a}'.", - bad_character_number_a: "Bad character code: '{a}'", bad_directive_a: "Bad directive '{a}'.", bad_get: "A get function takes no parameters.", bad_module_name_a: "Bad module name '{a}'.", @@ -292,7 +314,9 @@ var jslint = (function JSLint() { bad_set: "A set function takes one parameter.", duplicate_a: "Duplicate '{a}'.", empty_block: "Empty block.", - es6: "Unexpected ES6 feature.", + es6: "Unexpected ES6 feature '{a}'.", + escape_mega: "Unexpected escapement in mega literal.", + expected_a: "Expected '{a}'.", expected_a_at_b_c: "Expected '{a}' at column {b}, not column {c}.", expected_a_b: "Expected '{a}' and instead saw '{b}'.", expected_a_b_from_c_d: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", @@ -312,24 +336,28 @@ var jslint = (function JSLint() { label_a: "'{a}' is a statement label.", misplaced_a: "Place '{a}' at the outermost level.", misplaced_directive_a: "Place the '/*{a}*/' directive before the first statement.", + missing_browser: "/*global*/ requires the Assume a browser option.", + missing_m: "Expected 'm' flag on a multiline regular expression.", naked_block: "Naked block.", nested_comment: "Nested comment.", not_label_a: "'{a}' is not a label.", + number_isNaN: "Use Number.isNaN function to compare with NaN.", out_of_scope_a: "'{a}' is out of scope.", redefinition_a_b: "Redefinition of '{a}' from line {b}.", reserved_a: "Reserved name '{a}'.", - slash_equal: "A regular expression literal can be confused with '/='.", subscript_a: "['{a}'] is better written in dot notation.", todo_comment: "Unexpected TODO comment.", too_long: "Line too long.", too_many: "Too many warnings.", + too_many_digits: "Too many digits.", unclosed_comment: "Unclosed comment.", unclosed_mega: "Unclosed mega literal.", unclosed_string: "Unclosed string.", undeclared_a: "Undeclared '{a}'.", unexpected_a: "Unexpected '{a}'.", unexpected_a_after_b: "Unexpected '{a}' after '{b}'.", - unexpected_at_top_level_a: "Unexpected '{a}' at top level.", + unexpected_a_before_b: "Unexpected '{a}' before '{b}'.", + unexpected_at_top_level_a: "Expected '{a}' to be in a function.", unexpected_char_a: "Unexpected character '{a}'.", unexpected_comment: "Unexpected comment.", unexpected_directive_a: "When using modules, don't use directive '/*{a}'.", @@ -345,7 +373,9 @@ var jslint = (function JSLint() { unregistered_property_a: "Unregistered property name '{a}'.", unsafe: "Unsafe character '{a}'.", unused_a: "Unused '{a}'.", + use_double: "Use double quotes, not single quotes.", use_spaces: "Use spaces, not tabs.", + use_strict: "This function needs a \"use strict\" pragma.", var_loop: "Don't declare variables in a loop.", var_switch: "Don't declare variables in a switch.", weird_condition_a: "Weird condition '{a}'.", @@ -358,6 +388,7 @@ var jslint = (function JSLint() { "parentheses to assist the reader in understanding that the " + "expression is the result of a function, and not the " + "function itself.", + wrap_parameter: "Wrap the parameter in parens.", wrap_regexp: "Wrap this regexp in parens to avoid confusion.", wrap_unary: "Wrap the unary expression in parens." }; @@ -365,44 +396,47 @@ var jslint = (function JSLint() { // Regular expression literals: // supplant {variables} - var rx_supplant = /\{([^{}]*)\}/g, + var rx_supplant = /\{([^{}]*)\}/g; // carriage return, carriage return linefeed, or linefeed - rx_crlf = /\n|\r\n?/, + var rx_crlf = /\n|\r\n?/; // unsafe characters that are silently deleted by one or more browsers - rx_unsafe = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/, + var rx_unsafe = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; // identifier - rx_identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/, - rx_bad_property = /^_|\$|Sync$|_$/, + var rx_identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/; + var rx_module = /^[a-zA-Z0-9_$:.@\-\/]+$/; + var rx_bad_property = /^_|\$|Sync\$|_$/; // star slash - rx_star_slash = /\*\//, + var rx_star_slash = /\*\//; // slash star - rx_slash_star = /\/\*/, + var rx_slash_star = /\/\*/; // slash star or ending slash - rx_slash_star_or_slash = /\/\*|\/$/, + var rx_slash_star_or_slash = /\/\*|\/$/; // uncompleted work comment - rx_todo = /\b(?:todo|TO\s?DO|HACK)\b/, + var rx_todo = /\b(?:todo|TO\s?DO|HACK)\b/; // tab - rx_tab = /\t/g, + var rx_tab = /\t/g; // directive - rx_directive = /^(jslint|property|global)\s*(.*)$/, - rx_directive_part = /^([a-zA-Z$_][a-zA-Z0-9$_]*)\s*(?::\s*(true|false|[0-9]+)\s*)?(?:,\s*)?(.*)$/, + var rx_directive = /^(jslint|property|global)\s+(.*)$/; + var rx_directive_part = /^([a-zA-Z$_][a-zA-Z0-9$_]*)\s*(?::\s*(true|false|[0-9]+)\s*)?(?:,\s*)?(.*)$/; // token (sorry it is so long) - rx_token = /^((\s+)|([a-zA-Z_$][a-zA-Z0-9_$]*)|[(){}\[\]\?,:;'"~`]|=(?:==?|>)?|\.+|\/[=*\/]?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|[\^%]=?|&[&=]?|\|[\|=]?|>{1,3}=?|<)?|\.+|\/[=*\/]?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|[\^%]=?|&[&=]?|\|[|=]?|>{1,3}=?|<= 'a' && string <= 'z\uffff') || - (string >= 'A' && string <= 'Z\uffff'); + return (string >= "a" && string <= "z\uffff") || + (string >= "A" && string <= "Z\uffff"); } function supplant(string, object) { @@ -414,34 +448,35 @@ var jslint = (function JSLint() { }); } - var anon = "anonymous", // The guessed name for anonymous functions. - blockage, // The current block. - block_stack, // The stack of blocks. - declared_globals, // The object containing the global declarations. - directive_mode, // true if directives are still allowed. - early_stop, // true if JSLint cannot finish. - export_mode, // true if an export statement was seen. - fudge, // true if the natural numbers start with 1. - functionage, // The current function. - functions, // The array containing all of the functions. - global, // The global object, the outermost context. - imports, // The array collecting all import-from strings. - json_mode, // true if parsing JSON. - lines, // The array containing source lines. - module_mode, // true if import or export was used. - next_token, // The next token to be examined in the parse. - option, // The options parameter. - property, // The object containing the tallied property names. - mega_mode, // true if currently parsing a megastring literal. - stack, // The stack of functions. - syntax, // The object containing the parser. - token, // The current token being examined in the parse. - token_nr, // The number of the next token. - tokens, // The array of tokens. - tenure, // The predefined property registry. - tree, // The abstract parse tree. - var_mode, // true if using var, false if using let. - warnings; // The array collecting all generated warnings. + var anon = "anonymous"; // The guessed name for anonymous functions. + var blockage; // The current block. + var block_stack; // The stack of blocks. + var declared_globals; // The object containing the global declarations. + var directives; // The directive comments. + var directive_mode; // true if directives are still allowed. + var early_stop; // true if JSLint cannot finish. + var exports; // The exported names and values. + var froms; // The array collecting all import-from strings. + var fudge; // true if the natural numbers start with 1. + var functionage; // The current function. + var functions; // The array containing all of the functions. + var global; // The global object; the outermost context. + var json_mode; // true if parsing JSON. + var lines; // The array containing source lines. + var module_mode; // true if import or export was used. + var next_token; // The next token to be examined in the parse. + var option; // The options parameter. + var property; // The object containing the tallied property names. + var mega_mode; // true if currently parsing a megastring literal. + var stack; // The stack of functions. + var syntax; // The object containing the parser. + var token; // The current token being examined in the parse. + var token_nr; // The number of the next token. + var tokens; // The array of tokens. + var tenure; // The predefined property registry. + var tree; // The abstract parse tree. + var var_mode; // true if using var; false if using let. + var warnings; // The array collecting all generated warnings. // Error reportage functions: @@ -452,7 +487,7 @@ var jslint = (function JSLint() { if (the_token === undefined) { the_token = next_token; } - return (the_token.id === '(string)' || the_token.id === '(number)') + return (the_token.id === "(string)" || the_token.id === "(number)") ? String(the_token.value) : the_token.id; } @@ -483,7 +518,7 @@ var jslint = (function JSLint() { // resembles an exception. var warning = { // ~~ - name: 'JSLintError', + name: "JSLintError", column: column, line: line, code: code @@ -502,9 +537,10 @@ var jslint = (function JSLint() { } warning.message = supplant(bundle[code] || code, warning); warnings.push(warning); - return (typeof option.maxerr === 'number' && - warnings.length === option.maxerr) - ? stop_at('too_many', line, column) + return ( + typeof option.maxerr === "number" && + warnings.length === option.maxerr + ) ? stop_at("too_many", line, column) : warning; } @@ -542,12 +578,12 @@ var jslint = (function JSLint() { // Similar to warn and stop_at. If the token already had a warning, that // warning will be replaced with this new one. It is likely that the stopping -// warning will be the most meaningful. +// warning will be the more meaningful. if (the_token === undefined) { the_token = next_token; } - the_token.warning = undefined; + delete the_token.warning; throw warn(code, the_token, a, b, c, d); } @@ -570,16 +606,18 @@ var jslint = (function JSLint() { : source.split(rx_crlf); tokens = []; - var char, // a popular character - column = 0, // the column number of the next character - from, // the starting column number of the token - line = -1, // the line number of the next character - previous = global, // the previous token including comments - prior = global, // the previous token excluding comments - mega_from, // the starting column of megastring - mega_line, // the starting line of megastring - snippet, // a piece of string - source_line; // the current line source string + var char; // a popular character + var column = 0; // the column number of the next character + var first; // the first token + var from; // the starting column number of the token + var line = -1; // the line number of the next character + var nr = 0; // the next token number + var previous = global; // the previous token including comments + var prior = global; // the previous token excluding comments + var mega_from; // the starting column of megastring + var mega_line; // the starting line of megastring + var snippet; // a piece of string + var source_line; // the current line source string function next_line() { @@ -595,24 +633,24 @@ var jslint = (function JSLint() { at = source_line.search(rx_tab); if (at >= 0) { if (!option.white) { - warn_at('use_spaces', line, at + 1); + warn_at("use_spaces", line, at + 1); } - source_line = source_line.replace(rx_tab, ' '); + source_line = source_line.replace(rx_tab, " "); } at = source_line.search(rx_unsafe); if (at >= 0) { warn_at( - 'unsafe', + "unsafe", line, column + at, - 'U+' + source_line.charCodeAt(at).toString(16) + "U+" + source_line.charCodeAt(at).toString(16) ); } if (option.maxlen && option.maxlen < source_line.length) { - warn_at('too_long', line, source_line.length); - } else if (!option.white && source_line.slice(-1) === ' ') { + warn_at("too_long", line, source_line.length); + } else if (!option.white && source_line.slice(-1) === " ") { warn_at( - 'unexpected_trailing_space', + "unexpected_trailing_space", line, source_line.length - 1 ); @@ -642,15 +680,23 @@ var jslint = (function JSLint() { // matched an expected value. if (match !== undefined && char !== match) { - return stop_at('expected_a_b', line, column, match, char); + return stop_at( + (char === "") + ? "expected_a" + : "expected_a_b", + line, + column - 1, + match, + char + ); } if (source_line) { char = source_line.charAt(0); source_line = source_line.slice(1); snippet += char; } else { - char = ''; - snippet += ' '; + char = ""; + snippet += " "; } column += 1; return char; @@ -667,7 +713,7 @@ var jslint = (function JSLint() { column -= 1; snip(); } else { - char = ''; + char = ""; } return char; } @@ -680,10 +726,10 @@ var jslint = (function JSLint() { source_line = result[2]; snippet += char; } else { - char = ''; + char = ""; if (!quiet) { warn_at( - 'expected_digits_after_a', + "expected_digits_after_a", line, column, snippet @@ -694,44 +740,48 @@ var jslint = (function JSLint() { } function escape(extra) { - switch (next_char('\\')) { - case '\\': - case '\'': - case '"': - case '/': - case ':': - case '=': - case '|': - case 'b': - case 'f': - case 'n': - case 'r': - case 't': - case ' ': + switch (next_char("\\")) { + case "\\": + case "/": + case "b": + case "f": + case "n": + case "r": + case "t": break; - case 'u': - if (next_char('u') === '{') { + case "u": + if (next_char("u") === "{") { + if (json_mode) { + warn_at("unexpected_a", line, column - 1, char); + } if (some_digits(rx_hexs) > 5) { - warn_at('too_many_digits', line, column - 1); + warn_at("too_many_digits", line, column - 1); } if (!option.es6) { - warn_at('es6', line, column); + warn_at("es6", line, column, "u{"); } - if (next_char() !== '}') { - stop_at('expected_a_before_b', line, column, '}', char); + if (next_char() !== "}") { + stop_at("expected_a_before_b", line, column, "}", char); } + next_char(); return; } back_char(); if (some_digits(rx_hexs, true) < 4) { - warn_at('expected_four_digits', line, column - 1); + warn_at("expected_four_digits", line, column - 1); } break; - case '': - return stop_at('unclosed_string', line, column); + case "": + return stop_at("unclosed_string", line, column); default: - if (extra && extra.indexOf(char) < 0) { - warn_at('unexpected_a_after_b', line, column, char, '\\'); + if (!extra || extra.indexOf(char) < 0) { + warn_at( + "unexpected_a_before_b", + line, + column - 2, + "\\", + char + ); } } next_char(); @@ -742,17 +792,19 @@ var jslint = (function JSLint() { // Make the token object and append it to the tokens list. var the_token = { + from: from, id: id, identifier: !!identifier, - from: from, - thru: column, - line: line + line: line, + nr: nr, + thru: column }; - tokens.push(the_token); + tokens[nr] = the_token; + nr += 1; // Directives must appear before the first statement. - if (id !== '(comment)') { + if (id !== "(comment)" && id !== ";") { directive_mode = false; } @@ -763,7 +815,7 @@ var jslint = (function JSLint() { } // If this token is an identifier that touches a preceding number, or -// a '/', comment, or regular expression literal that touches a preceding +// a "/", comment, or regular expression literal that touches a preceding // comment or regular expression literal, then give a missing space warning. // This warning is not suppressed by option.white. @@ -771,24 +823,24 @@ var jslint = (function JSLint() { previous.line === line && previous.thru === from && ( - (id === '(comment)' || id === '(regexp)' || id === '/') && + (id === "(comment)" || id === "(regexp)" || id === "/") && ( - previous.id === '(comment)' || - previous.id === '(regexp)' + previous.id === "(comment)" || + previous.id === "(regexp)" ) ) ) { warn( - 'expected_space_a_b', + "expected_space_a_b", the_token, artifact(previous), artifact(the_token) ); } - if (previous.id === '.' && id === '(number)') { - warn('expected_a_before_b', previous, '0', '.'); + if (previous.id === "." && id === "(number)") { + warn("expected_a_before_b", previous, "0", "."); } - if (prior.id === '.' && the_token.identifier) { + if (prior.id === "." && the_token.identifier) { the_token.dot = true; } @@ -797,16 +849,16 @@ var jslint = (function JSLint() { previous = the_token; // The prior token is a previous token that was not a comment. The prior token -// is used to disambiguate '/', which can mean division or regular expression +// is used to disambiguate "/", which can mean division or regular expression // literal. - if (previous.id !== '(comment)') { + if (previous.id !== "(comment)") { prior = previous; } return the_token; } - function directive(the_comment, body) { + function parse_directive(the_comment, body) { // JSLint recognizes three directives that can be encoded in comments. This // function processes one item, and calls itself recursively to process the @@ -814,60 +866,68 @@ var jslint = (function JSLint() { var result = body.match(rx_directive_part); if (result) { - var allowed, - name = result[1], - value = result[2]; + var allowed; + var name = result[1]; + var value = result[2]; switch (the_comment.directive) { - case 'jslint': + case "jslint": allowed = allowed_option[name]; switch (typeof allowed) { - case 'boolean': - case 'object': + case "boolean": + case "object": switch (value) { - case 'true': - case '': + case "true": + case "": case undefined: option[name] = true; if (Array.isArray(allowed)) { populate(declared_globals, allowed, false); } break; - case 'false': + case "false": option[name] = false; break; default: - warn('bad_option_a', the_comment, name + ':' + value); + warn( + "bad_option_a", + the_comment, + name + ":" + value + ); } break; - case 'number': + case "number": if (isFinite(+value)) { option[name] = +value; } else { - warn('bad_option_a', the_comment, name + ':' + value); + warn( + "bad_option_a", + the_comment, + name + ":" + value + ); } break; default: - warn('bad_option_a', the_comment, name); + warn("bad_option_a", the_comment, name); } break; - case 'property': + case "property": if (tenure === undefined) { tenure = empty(); } tenure[name] = true; break; - case 'global': + case "global": if (value) { - warn('bad_option_a', the_comment, name + ':' + value); + warn("bad_option_a", the_comment, name + ":" + value); } declared_globals[name] = false; module_mode = the_comment; break; } - return directive(the_comment, result[3]); + return parse_directive(the_comment, result[3]); } if (body) { - return stop('bad_directive_a', the_comment, body); + return stop("bad_directive_a", the_comment, body); } } @@ -876,21 +936,22 @@ var jslint = (function JSLint() { // Make a comment object. Comments are not allowed in JSON text. Comments can // include directives and notices of incompletion. - var the_comment = make('(comment)', snippet); + var the_comment = make("(comment)", snippet); if (Array.isArray(snippet)) { - snippet = snippet.join(' '); + snippet = snippet.join(" "); } if (!option.devel && rx_todo.test(snippet)) { - warn('todo_comment', the_comment); + warn("todo_comment", the_comment); } var result = snippet.match(rx_directive); if (result) { if (!directive_mode) { - warn_at('misplaced_directive_a', line, from, result[1]); + warn_at("misplaced_directive_a", line, from, result[1]); } else { the_comment.directive = result[1]; - directive(the_comment, result[2]); + parse_directive(the_comment, result[2]); } + directives.push(the_comment); } return the_comment; } @@ -899,35 +960,35 @@ var jslint = (function JSLint() { // Parse a regular expression literal. - var result, - u_mode = false, - value; + var multi_mode = false; + var result; + var value; function quantifier() { // Match an optional quantifier. switch (char) { - case '?': - case '*': - case '+': + case "?": + case "*": + case "+": next_char(); break; - case '{': + case "{": if (some_digits(rx_digits, true) === 0) { - warn_at('expected_a', line, column, '0'); + warn_at("expected_a", line, column, "0"); } - if (next_char() === ',') { + if (next_char() === ",") { some_digits(rx_digits, true); next_char(); } - next_char('}'); + next_char("}"); break; default: return; } - if (char === '?') { - next_char('?'); + if (char === "?") { + next_char("?"); } } @@ -936,25 +997,24 @@ var jslint = (function JSLint() { // Match a character in a character class. switch (char) { - case '\\': - escape(); + case "\\": + escape("BbDdSsWw-[]^"); return true; - case '[': - case ']': - case '/': - case '^': - case '-': - case '|': - case '': + case "[": + case "]": + case "/": + case "^": + case "-": + case "": return false; - case '`': + case "`": if (mega_mode) { - warn_at('unexpected_a', line, column, '`'); + warn_at("unexpected_a", line, column, "`"); } next_char(); return true; - case ' ': - warn_at('expected_a_before_b', line, column, '\\', ' '); + case " ": + warn_at("expected_a_before_b", line, column, "\\", " "); next_char(); return true; default: @@ -963,18 +1023,23 @@ var jslint = (function JSLint() { } } - function range() { + function ranges() { // Match a range of subclasses. if (subklass()) { - if (char === '-') { - next_char('-'); + if (char === "-") { + next_char("-"); if (!subklass()) { - return stop_at('unexpected_a', line, column - 1, '-'); + return stop_at( + "unexpected_a", + line, + column - 1, + "-" + ); } } - return range(); + return ranges(); } } @@ -982,12 +1047,25 @@ var jslint = (function JSLint() { // Match a class. - next_char('['); - if (char === '^') { - next_char('^'); + next_char("["); + if (char === "^") { + next_char("^"); } - range(); - next_char(']'); + (function classy() { + ranges(); + if (char !== "]" && char !== "") { + warn_at( + "expected_a_before_b", + line, + column, + "\\", + char + ); + next_char(); + return classy(); + } + }()); + next_char("]"); } function choice() { @@ -996,54 +1074,72 @@ var jslint = (function JSLint() { // Match a group that starts with left paren. - next_char('('); - if (char === '?') { - next_char('?'); + next_char("("); + if (char === "?") { + next_char("?"); switch (char) { - case ':': - case '=': - case '!': + case ":": + case "=": + case "!": next_char(); break; default: - next_char(':'); + next_char(":"); } - } else if (char === ':') { - warn_at('expected_a_before_b', line, column, '?', ':'); + } else if (char === ":") { + warn_at("expected_a_before_b", line, column, "?", ":"); } choice(); - next_char(')'); + next_char(")"); } function factor() { switch (char) { - case '[': + case "[": klass(); return true; - case '\\': - escape('BbDdSsWw^${}[]().|*+?'); + case "\\": + escape("BbDdSsWw^${}[]():=!.-|*+?"); return true; - case '(': + case "(": group(); return true; - case '/': - case '|': - case ']': - case ')': - case '}': - case '{': - case '?': - case '+': - case '*': - case '': + case "?": + case "+": + case "*": + case "}": + case "{": + warn_at("expected_a_before_b", line, column - 1, "\\", char); + break; + case "/": + case "|": + case "]": + case ")": + case "": return false; - case '`': + case "`": if (mega_mode) { - warn_at('unexpected_a', line, column, '`'); + warn_at("unexpected_a", line, column - 1, "`"); } break; - case ' ': - warn_at('expected_a_before_b', line, column, '\\', ' '); + case " ": + warn_at( + "expected_a_b", + line, + column - 1, + "\\s", + " " + ); + break; + case "$": + if (source_line.charAt(0) !== "/") { + multi_mode = true; + } + break; + case "^": + if (snippet !== "^") { + multi_mode = true; + } break; } next_char(); @@ -1056,15 +1152,15 @@ var jslint = (function JSLint() { return sequence(true); } if (!follow) { - warn_at('expected_regexp_factor_a', line, column, char); + warn_at("expected_regexp_factor_a", line, column, char); } } // Match a choice (a sequence that can be followed by | and another choice). sequence(); - if (char === '|') { - next_char('|'); + if (char === "|") { + next_char("|"); return choice(); } } @@ -1072,10 +1168,10 @@ var jslint = (function JSLint() { // Scan the regexp literal. Give a warning if the first character is = because // /= looks like a division assignment operator. - snippet = ''; + snippet = ""; next_char(); - if (char === '=') { - warn_at('expected_a_before_b', line, column, '\\', '='); + if (char === "=") { + warn_at("expected_a_before_b", line, column, "\\", "="); } choice(); @@ -1083,22 +1179,30 @@ var jslint = (function JSLint() { snip(); value = snippet; - next_char('/'); + next_char("/"); // Process dangling flag letters. var allowed = { - g: true, - i: true, - m: true, - u: u_mode, - y: option.es6 - }, - flag = empty(); + g: true, + i: true, + m: true, + u: 6, + y: 6 + }; + var flag = empty(); (function make_flag() { if (is_letter(char)) { - if (allowed[char] !== true) { - warn_at('unexpected_a', line, column, char); + switch (allowed[char]) { + case true: + break; + case 6: + if (!option.es6) { + warn_at("es6", line, column, char); + } + break; + default: + warn_at("unexpected_a", line, column, char); } allowed[char] = false; flag[char] = true; @@ -1106,16 +1210,16 @@ var jslint = (function JSLint() { return make_flag(); } }()); - if (u_mode && !flag.u) { - warn_at('expected_a_before_b', line, column, 'u', char); - } back_char(); - if (char === '/' || char === '*') { - return stop_at('unexpected_a', line, from, char); + if (char === "/" || char === "*") { + return stop_at("unexpected_a", line, from, char); } - result = make('(regexp)', char); + result = make("(regexp)", char); result.flag = flag; result.value = value; + if (multi_mode && !flag.m) { + warn_at("missing_m", line, column); + } return result; } @@ -1124,26 +1228,26 @@ var jslint = (function JSLint() { // Make a string token. var the_token; - snippet = ''; + snippet = ""; next_char(); return (function next() { switch (char) { case quote: snip(); - the_token = make('(string)', snippet); + the_token = make("(string)", snippet); the_token.quote = quote; return the_token; - case '\\': - escape(); + case "\\": + escape(quote); break; - case '': - return stop_at('unclosed_string', line, column); - case '`': + case "": + return stop_at("unclosed_string", line, column); + case "`": if (mega_mode) { - warn_at('unexpected_a', line, column, '`'); + warn_at("unexpected_a", line, column, "`"); } - next_char('`'); + next_char("`"); break; default: next_char(); @@ -1153,13 +1257,13 @@ var jslint = (function JSLint() { } function frack() { - if (char === '.') { + if (char === ".") { some_digits(rx_digits); next_char(); } - if (char === 'E' || char === 'e') { + if (char === "E" || char === "e") { next_char(); - if (char !== '+' && char !== '-') { + if (char !== "+" && char !== "-") { back_char(); } some_digits(rx_digits); @@ -1168,20 +1272,20 @@ var jslint = (function JSLint() { } function number() { - if (snippet === '0') { + if (snippet === "0") { switch (next_char()) { - case '.': + case ".": frack(); break; - case 'b': + case "b": some_digits(rx_bits); next_char(); break; - case 'o': + case "o": some_digits(rx_octals); next_char(); break; - case 'x': + case "x": some_digits(rx_hexs); next_char(); break; @@ -1195,12 +1299,12 @@ var jslint = (function JSLint() { // unexpected is going on. if ( - (char >= '0' && char <= '9') || - (char >= 'a' && char <= 'z') || - (char >= 'A' && char <= 'Z') + (char >= "0" && char <= "9") || + (char >= "a" && char <= "z") || + (char >= "A" && char <= "Z") ) { return stop_at( - 'unexpected_a_after_b', + "unexpected_a_after_b", line, column - 1, snippet.slice(-1), @@ -1208,23 +1312,23 @@ var jslint = (function JSLint() { ); } back_char(); - return make('(number)', snippet); + return make("(number)", snippet); } function lex() { - var array, - i = 0, - j = 0, - last, - result, - the_token; + var array; + var i = 0; + var j = 0; + var last; + var result; + var the_token; if (!source_line) { source_line = next_line(); from = 0; return (source_line === undefined) ? (mega_mode) - ? stop_at('unclosed_mega', mega_line, mega_from) - : make('(end)') + ? stop_at("unclosed_mega", mega_line, mega_from) + : make("(end)") : lex(); } from = column; @@ -1237,7 +1341,12 @@ var jslint = (function JSLint() { // result[5] rest if (!result) { - return stop_at('unexpected_char_a', line, column, source_line.charAt(0)); + return stop_at( + "unexpected_char_a", + line, + column, + source_line.charAt(0) + ); } snippet = result[1]; @@ -1268,24 +1377,29 @@ var jslint = (function JSLint() { // The token is a single or double quote string. - case '\'': - case '"': + case "\"": return string(snippet); -// The token is a megastring. We don't allow any kind if mega nesting. + case "'": + if (!option.single) { + warn_at("use_double", line, column); + } + return string(snippet); - case '`': +// The token is a megastring. We don't allow any kind of mega nesting. + + case "`": if (mega_mode) { - return stop_at('expected_a_b', line, column, '}', '`'); + return stop_at("expected_a_b", line, column, "}", "`"); } - snippet = ''; + snippet = ""; mega_from = from; mega_line = line; mega_mode = true; // Parsing a mega literal is tricky. First make a ` token. - make('`'); + make("`"); from += 1; // Then loop, building up a string, possibly from many lines, until seeing @@ -1298,9 +1412,9 @@ var jslint = (function JSLint() { // If neither ` nor ${ is seen, then the whole line joins the snippet. if (at < 0) { - snippet += source_line + '\n'; + snippet += source_line + "\n"; return (next_line() === undefined) - ? stop_at('unclosed_mega', mega_line, mega_from) + ? stop_at("unclosed_mega", mega_line, mega_from) : part(); } @@ -1310,28 +1424,31 @@ var jslint = (function JSLint() { snippet += source_line.slice(0, at); column += at; source_line = source_line.slice(at); - make('(string)', snippet).quote = '`'; - snippet = ''; + if (source_line.charAt(0) === "\\") { + stop_at("escape_mega", line, at); + } + make("(string)", snippet).quote = "`"; + snippet = ""; // If ${, then make tokens that will become part of an expression until // a } token is made. - if (source_line.charAt(0) === '$') { + if (source_line.charAt(0) === "$") { column += 2; - make('${'); + make("${"); source_line = source_line.slice(2); (function expr() { var id = lex().id; - if (id === '{') { + if (id === "{") { return stop_at( - 'expected_a_b', + "expected_a_b", line, column, - '}', - '{' + "}", + "{" ); } - if (id !== '}') { + if (id !== "}") { return expr(); } }()); @@ -1341,48 +1458,48 @@ var jslint = (function JSLint() { source_line = source_line.slice(1); column += 1; mega_mode = false; - return make('`'); + return make("`"); // The token is a // comment. - case '//': + case "//": snippet = source_line; - source_line = ''; + source_line = ""; the_token = comment(snippet); if (mega_mode) { - warn('unexpected_comment', the_token, '`'); + warn("unexpected_comment", the_token, "`"); } return the_token; // The token is a /* comment. - case '/*': + case "/*": array = []; - if (source_line.charAt(0) === '/') { - warn_at('unexpected_a', line, column + i, '/'); + if (source_line.charAt(0) === "/") { + warn_at("unexpected_a", line, column + i, "/"); } (function next() { - if (source_line > '') { + if (source_line > "") { i = source_line.search(rx_star_slash); if (i >= 0) { return; } j = source_line.search(rx_slash_star); if (j >= 0) { - warn_at('nested_comment', line, column + j); + warn_at("nested_comment", line, column + j); } } array.push(source_line); source_line = next_line(); if (source_line === undefined) { - return stop_at('unclosed_comment', line, column); + return stop_at("unclosed_comment", line, column); } return next(); }()); snippet = source_line.slice(0, i); j = snippet.search(rx_slash_star_or_slash); if (j >= 0) { - warn_at('nested_comment', line, column + j); + warn_at("nested_comment", line, column + j); } array.push(snippet); column += i + 2; @@ -1391,13 +1508,13 @@ var jslint = (function JSLint() { // The token is a slash. - case '/': + case "/": // The / can be a division operator or the beginning of a regular expression // literal. It is not possible to know which without doing a complete parse. // We want to complete the tokenization before we begin to parse, so we will // estimate. This estimator can fail in some cases. For example, it cannot -// know if '}' is ending a block or ending an object literal, so it can +// know if "}" is ending a block or ending an object literal, so it can // behave incorrectly in that case; it is not meaningful to divide an // object, so it is likely that we can get away with it. We avoided the worst // cases by eliminating automatic semicolon insertion. @@ -1405,48 +1522,51 @@ var jslint = (function JSLint() { if (prior.identifier) { if (!prior.dot) { switch (prior.id) { - case 'return': + case "return": return regexp(); - case '(begin)': - case 'case': - case 'delete': - case 'in': - case 'instanceof': - case 'new': - case 'typeof': - case 'void': - case 'yield': + case "(begin)": + case "case": + case "delete": + case "in": + case "instanceof": + case "new": + case "typeof": + case "void": + case "yield": the_token = regexp(); - return stop('unexpected_a', the_token); + return stop("unexpected_a", the_token); } } } else { last = prior.id.charAt(prior.id.length - 1); - if ('(,=:?['.indexOf(last) >= 0) { + if ("(,=:?[".indexOf(last) >= 0) { return regexp(); } - if ('!&|{};~+-*%/^<>'.indexOf(last) >= 0) { + if ("!&|{};~+-*%/^<>".indexOf(last) >= 0) { the_token = regexp(); - warn('wrap_regexp', the_token); + warn("wrap_regexp", the_token); return the_token; } } - if (source_line.charAt(0) === '/') { + if (source_line.charAt(0) === "/") { column += 1; source_line = source_line.slice(1); - snippet = '/='; - warn_at('unexpected_a', line, column, '/='); + snippet = "/="; + warn_at("unexpected_a", line, column, "/="); } break; } return make(snippet); } + first = lex(); + json_mode = first.id === "{" || first.id === "["; + // This is the only loop in JSLint. It will turn into a recursive call to lex // when ES6 has been finished and widely deployed and adopted. while (true) { - if (lex().id === '(end)') { + if (lex().id === "(end)") { break; } } @@ -1472,20 +1592,25 @@ var jslint = (function JSLint() { // Tally the property name. If it is a string, only tally strings that conform // to the identifier rules. - if (id === '(string)') { + if (id === "(string)") { id = name.value; if (!rx_identifier.test(id)) { return id; } - } else { - if (!name.identifier) { - return stop('expected_identifier_a', name); + } else if (id === "`") { + if (name.value.length === 1) { + id = name.value[0].value; + if (!rx_identifier.test(id)) { + return id; + } } + } else if (!name.identifier) { + return stop("expected_identifier_a", name); } // If we have seen this name before, increment its count. - if (typeof property[id] === 'number') { + if (typeof property[id] === "number") { property[id] += 1; // If this is the first time seeing this property name, and if there is a @@ -1495,11 +1620,11 @@ var jslint = (function JSLint() { } else { if (tenure !== undefined) { if (tenure[id] !== true) { - warn('unregistered_property_a', name); + warn("unregistered_property_a", name); } } else { if (name.identifier && rx_bad_property.test(id)) { - warn('bad_property_a', name); + warn("bad_property_a", name); } } property[id] = 1; @@ -1513,9 +1638,9 @@ var jslint = (function JSLint() { var cadet = tokens[token_nr]; token_nr += 1; - if (cadet.id === '(comment)') { + if (cadet.id === "(comment)") { if (json_mode) { - warn('unexpected_a', cadet); + warn("unexpected_a", cadet); } return dispense(); } else { @@ -1527,8 +1652,8 @@ var jslint = (function JSLint() { // Look ahead one token without advancing. - var old_token_nr = token_nr, - cadet = dispense(true); + var old_token_nr = token_nr; + var cadet = dispense(true); token_nr = old_token_nr; return cadet; } @@ -1539,9 +1664,9 @@ var jslint = (function JSLint() { // Attempt to give helpful names to anonymous functions. - if (token.identifier && token.id !== 'function') { + if (token.identifier && token.id !== "function") { anon = token.id; - } else if (token.id === '(string)' && rx_identifier.test(token.value)) { + } else if (token.id === "(string)" && rx_identifier.test(token.value)) { anon = token.value; } @@ -1549,9 +1674,9 @@ var jslint = (function JSLint() { if (id !== undefined && next_token.id !== id) { return (match === undefined) - ? stop('expected_a_b', next_token, id, artifact()) + ? stop("expected_a_b", next_token, id, artifact()) : stop( - 'expected_a_b_from_c_d', + "expected_a_b_from_c_d", next_token, id, artifact(match), @@ -1564,7 +1689,7 @@ var jslint = (function JSLint() { token = next_token; next_token = dispense(); - if (next_token.id === '(end)') { + if (next_token.id === "(end)") { token_nr -= 1; } } @@ -1572,80 +1697,93 @@ var jslint = (function JSLint() { // Parsing of JSON is simple: function json_value() { + var negative; function json_object() { - var brace = next_token, - object = empty(); - advance('{'); - if (next_token.id !== '}') { + var brace = next_token; + var object = empty(); + var properties = []; + brace.expression = properties; + advance("{"); + if (next_token.id !== "}") { (function next() { - if (next_token.quote !== '"') { - warn('unexpected_a', next_token, next_token.quote); + var name; + var value; + if (next_token.quote !== "\"") { + warn("unexpected_a", next_token, next_token.quote); } - advance('(string)'); + name = next_token; + advance("(string)"); if (object[token.value] !== undefined) { - warn('duplicate_a', token); - } else if (token.value === '__proto__') { - warn('bad_property_name_a', token); + warn("duplicate_a", token); + } else if (token.value === "__proto__") { + warn("bad_property_a", token); } else { object[token.value] = token; } - advance(':'); - json_value(); - if (next_token.id === ',') { - advance(','); + advance(":"); + value = json_value(); + value.label = name; + properties.push(value); + if (next_token.id === ",") { + advance(","); return next(); } }()); } - advance('}', brace); + advance("}", brace); + return brace; } function json_array() { var bracket = next_token; - advance('['); - if (next_token.id !== ']') { + var elements = []; + bracket.expression = elements; + advance("["); + if (next_token.id !== "]") { (function next() { - json_value(); - if (next_token.id === ',') { - advance(','); + elements.push(json_value()); + if (next_token.id === ",") { + advance(","); return next(); } }()); } - advance(']', bracket); + advance("]", bracket); + return bracket; } switch (next_token.id) { - case '{': - json_object(); - break; - case '[': - json_array(); - break; - case 'true': - case 'false': - case 'null': + case "{": + return json_object(); + case "[": + return json_array(); + case "true": + case "false": + case "null": advance(); - break; - case '(number)': + return token; + case "(number)": if (!rx_JSON_number.test(next_token.value)) { - warn('unexpected_a'); + warn("unexpected_a"); } advance(); - break; - case '(string)': - if (next_token.quote !== '"') { - warn('unexpected_a', next_token, next_token.quote); + return token; + case "(string)": + if (next_token.quote !== "\"") { + warn("unexpected_a", next_token, next_token.quote); } advance(); - break; - case '-': - advance('-'); - advance('(number)'); - break; + return token; + case "-": + negative = next_token; + negative.arity = "unary"; + advance("-"); + advance("(number)"); + negative.expression = token; + return negative; default: - stop('unexpected_a'); + stop("unexpected_a"); } } @@ -1661,8 +1799,8 @@ var jslint = (function JSLint() { // Reserved words may not be enrolled. - if (syntax[id] !== undefined && id !== 'ignore') { - warn('reserved_a', name); + if (syntax[id] !== undefined && id !== "ignore") { + warn("reserved_a", name); } else { // Has the name been enrolled in this context? @@ -1670,7 +1808,7 @@ var jslint = (function JSLint() { var earlier = functionage.context[id]; if (earlier) { warn( - 'redefinition_a_b', + "redefinition_a_b", name, name.id, earlier.line + fudge @@ -1686,17 +1824,17 @@ var jslint = (function JSLint() { } }); if (earlier) { - if (id === 'ignore') { - if (earlier.role === 'variable') { - warn('unexpected_a', name); + if (id === "ignore") { + if (earlier.role === "variable") { + warn("unexpected_a", name); } } else { if (( - role !== 'exception' || - earlier.role !== 'exception' - ) && role !== 'parameter') { + role !== "exception" || + earlier.role !== "exception" + ) && role !== "parameter") { warn( - 'redefinition_a_b', + "redefinition_a_b", name, name.id, earlier.line + fudge @@ -1732,7 +1870,8 @@ var jslint = (function JSLint() { // process leds (infix operators) until the bind powers cause it to stop. It // returns the expression's parse tree. - var left, the_symbol; + var left; + var the_symbol; // Statements will have already advanced, so advance now only if the token is // not the first of a statement, @@ -1745,9 +1884,9 @@ var jslint = (function JSLint() { left = the_symbol.nud(); } else if (token.identifier) { left = token; - left.arity = 'variable'; + left.arity = "variable"; } else { - return stop('unexpected_a', token); + return stop("unexpected_a", token); } (function right() { the_symbol = syntax[next_token.id]; @@ -1768,33 +1907,33 @@ var jslint = (function JSLint() { // Parse the condition part of a do, if, while. - var the_paren = next_token, - the_value; + var the_paren = next_token; + var the_value; the_paren.free = true; - advance('('); + advance("("); the_value = expression(0); - advance(')'); + advance(")"); if (the_value.wrapped === true) { - warn('unexpected_a', the_paren); + warn("unexpected_a", the_paren); } switch (the_value.id) { - case '?': - case '~': - case '&': - case '|': - case '^': - case '<<': - case '>>': - case '>>>': - case '+': - case '-': - case '*': - case '/': - case '%': - case 'typeof': - case '(number)': - case '(string)': - warn('unexpected_a', the_value); + case "?": + case "~": + case "&": + case "|": + case "^": + case "<<": + case ">>": + case ">>>": + case "+": + case "-": + case "*": + case "/": + case "%": + case "typeof": + case "(number)": + case "(string)": + warn("unexpected_a", the_value); break; } return the_value; @@ -1802,11 +1941,11 @@ var jslint = (function JSLint() { function is_weird(thing) { return ( - thing.id === '(regexp)' || - thing.id === '{' || - thing.id === '=>' || - thing.id === 'function' || - (thing.id === '[' && thing.arity === 'unary') + thing.id === "(regexp)" || + thing.id === "{" || + thing.id === "=>" || + thing.id === "function" || + (thing.id === "[" && thing.arity === "unary") ); } @@ -1826,44 +1965,49 @@ var jslint = (function JSLint() { if (Array.isArray(b)) { return false; } - if (a.id === '(number)' && b.id === '(number)') { + if (a.id === "(number)" && b.id === "(number)") { return a.value === b.value; } - var a_string, b_string; - if (a.id === '(string)') { + var a_string; + var b_string; + if (a.id === "(string)") { a_string = a.value; - } else if (a.id === '`' && a.constant) { + } else if (a.id === "`" && a.constant) { a_string = a.value[0]; } - if (b.id === '(string)') { + if (b.id === "(string)") { b_string = b.value; - } else if (b.id === '`' && b.constant) { + } else if (b.id === "`" && b.constant) { b_string = b.value[0]; } - if (typeof a_string === 'string') { + if (typeof a_string === "string") { return a_string === b_string; } if (is_weird(a) || is_weird(b)) { return false; } if (a.arity === b.arity && a.id === b.id) { - if (a.id === '.') { + if (a.id === ".") { return are_similar(a.expression, b.expression) && are_similar(a.name, b.name); } switch (a.arity) { - case 'unary': + case "unary": return are_similar(a.expression, b.expression); - case 'binary': - return a.id !== '(' && - are_similar(a.expression[0], b.expression[0]) && - are_similar(a.expression[1], b.expression[1]); - case 'ternary': - return are_similar(a.expression[0], b.expression[0]) && - are_similar(a.expression[1], b.expression[1]) && - are_similar(a.expression[2], b.expression[2]); - case 'function': - case 'regexp': + case "binary": + return ( + a.id !== "(" && + are_similar(a.expression[0], b.expression[0]) && + are_similar(a.expression[1], b.expression[1]) + ); + case "ternary": + return ( + are_similar(a.expression[0], b.expression[0]) && + are_similar(a.expression[1], b.expression[1]) && + are_similar(a.expression[2], b.expression[2]) + ); + case "function": + case "regexp": return false; default: return true; @@ -1876,18 +2020,18 @@ var jslint = (function JSLint() { // Try to match a semicolon. - if (next_token.id === ';') { - advance(';'); + if (next_token.id === ";") { + advance(";"); } else { warn_at( - 'expected_a_b', + "expected_a_b", token.line, token.thru, - ';', + ";", artifact(next_token) ); } - anon = 'anonymous'; + anon = "anonymous"; } function statement() { @@ -1896,23 +2040,23 @@ var jslint = (function JSLint() { // have use for one. A statement can be one of the standard statements, or // an assignment expression, or an invocation expression. - var first, - the_label, - the_statement, - the_symbol; + var first; + var the_label; + var the_statement; + var the_symbol; advance(); - if (token.identifier && next_token.id === ':') { + if (token.identifier && next_token.id === ":") { the_label = token; - if (the_label.id === 'ignore') { - warn('unexpected_a', the_label); + if (the_label.id === "ignore") { + warn("unexpected_a", the_label); } - advance(':'); + advance(":"); switch (next_token.id) { - case 'do': - case 'for': - case 'switch': - case 'while': - enroll(the_label, 'label', true); + case "do": + case "for": + case "switch": + case "while": + enroll(the_label, "label", true); the_label.init = true; the_label.dead = false; the_statement = statement(); @@ -1921,7 +2065,7 @@ var jslint = (function JSLint() { return the_statement; default: advance(); - warn('unexpected_label_a', the_label); + warn("unexpected_label_a", the_label); } } @@ -1939,8 +2083,8 @@ var jslint = (function JSLint() { // It is an expression statement. the_statement = expression(0, true); - if (the_statement.wrapped && the_statement.id !== '(') { - warn('unexpected_a', first); + if (the_statement.wrapped && the_statement.id !== "(") { + warn("unexpected_a", first); } semicolon(); } @@ -1959,17 +2103,17 @@ var jslint = (function JSLint() { (function next(disrupt) { var a_statement; switch (next_token.id) { - case '}': - case 'case': - case 'default': - case 'else': - case '(end)': + case "}": + case "case": + case "default": + case "else": + case "(end)": break; default: a_statement = statement(); array.push(a_statement); if (disrupt) { - warn('unreachable_a', a_statement); + warn("unreachable_a", a_statement); } return next(a_statement.disrupt); } @@ -1982,7 +2126,7 @@ var jslint = (function JSLint() { // Some features should not be at the outermost level. if (functionage === global) { - warn('unexpected_at_top_level_a', thing); + warn("unexpected_at_top_level_a", thing); } } @@ -1991,60 +2135,52 @@ var jslint = (function JSLint() { // Some features must be at the most outermost level. if (blockage !== global) { - warn('misplaced_a', the_thing); + warn("misplaced_a", the_thing); } } function block(special) { // Parse a block, a sequence of statements wrapped in braces. -// special 'body' The block is a function body. -// 'ignore' No warning on an empty block. -// 'naked' No advance. -// undefined Not special. +// special "body" The block is a function body. +// "ignore" No warning on an empty block. +// "naked" No advance. +// undefined An ordinary block. - var stmts, the_block; - if (special !== 'naked') { - advance('{'); + var stmts; + var the_block; + if (special !== "naked") { + advance("{"); } the_block = token; - the_block.arity = 'statement'; - the_block.body = special === 'body'; + the_block.arity = "statement"; + the_block.body = special === "body"; -// All top level function bodies should include the 'use strict' pragma unless -// the whole file is strict. +// All top level function bodies should include the "use strict" pragma unless +// the whole file is strict or the file is a module or the function parameters +// use es6 syntax. - if (the_block.body && stack.length <= 1 && !global.strict) { - if ( - next_token.id === '(string)' || - next_token.value === 'use strict' - ) { - next_token.statement = true; - functionage.strict = true; - advance('(string)'); - advance(';'); - } else { - warn( - 'expected_a_before_b', - next_token, - (next_token.id === '`') - ? '\'' - : 'use strict', - artifact(next_token) - ); - } + if ( + special === "body" && + stack.length === 1 && + next_token.value === "use strict" + ) { + the_block.strict = next_token; + next_token.statement = true; + advance("(string)"); + advance(";"); } stmts = statements(); the_block.block = stmts; if (stmts.length === 0) { - if (!option.devel && special !== 'ignore') { - warn('empty_block', the_block); + if (!option.devel && special !== "ignore") { + warn("empty_block", the_block); } the_block.disrupt = false; } else { the_block.disrupt = stmts[stmts.length - 1].disrupt; } - advance('}'); + advance("}"); return the_block; } @@ -2056,11 +2192,11 @@ var jslint = (function JSLint() { // v if ( - the_thing.id !== '.' && - (the_thing.id !== '[' || the_thing.arity !== 'binary') && - the_thing.arity !== 'variable' + the_thing.id !== "." && + the_thing.arity !== "variable" && + (the_thing.id !== "[" || the_thing.arity !== "binary") ) { - warn('bad_assignment_a', the_thing); + warn("bad_assignment_a", the_thing); return false; } return true; @@ -2078,11 +2214,11 @@ var jslint = (function JSLint() { if ( !left.identifier && ( - left.arity !== 'binary' || - (id !== '.' && id !== '(' && id !== '[') + left.arity !== "binary" || + (id !== "." && id !== "(" && id !== "[") ) ) { - warn('unexpected_a', right); + warn("unexpected_a", right); return false; } return true; @@ -2113,29 +2249,29 @@ var jslint = (function JSLint() { var the_symbol = symbol(id, 20); the_symbol.led = function (left) { - var the_token = token, - right; - the_token.arity = 'assignment'; + var the_token = token; + var right; + the_token.arity = "assignment"; right = expression(20 - 1); - if (id === '=' && left.arity === 'variable') { + if (id === "=" && left.arity === "variable") { the_token.names = left; the_token.expression = right; } else { the_token.expression = [left, right]; } switch (right.arity) { - case 'assignment': - case 'pre': - case 'post': - warn('unexpected_a', right); + case "assignment": + case "pre": + case "post": + warn("unexpected_a", right); break; } if ( option.es6 && - left.arity === 'unary' && - (left.id === '[' || left.id === '{') + left.arity === "unary" && + (left.id === "[" || left.id === "{") ) { - warn('expected_a_before_b', left, 'const', left.id); + warn("expected_a_before_b", left, "const", left.id); } else { mutation_check(left); } @@ -2149,7 +2285,8 @@ var jslint = (function JSLint() { // Make a constant symbol. var the_symbol = symbol(id); - the_symbol.nud = (typeof value === 'function') + the_symbol.constant = true; + the_symbol.nud = (typeof value === "function") ? value : function () { token.constant = true; @@ -2170,7 +2307,7 @@ var jslint = (function JSLint() { var the_symbol = symbol(id, bp); the_symbol.led = function (left) { var the_token = token; - the_token.arity = 'binary'; + the_token.arity = "binary"; if (f !== undefined) { return f(left); } @@ -2187,7 +2324,7 @@ var jslint = (function JSLint() { var the_symbol = symbol(id, 150); the_symbol.led = function (left) { token.expression = left; - token.arity = 'post'; + token.arity = "post"; mutation_check(token.expression); return token; }; @@ -2201,7 +2338,7 @@ var jslint = (function JSLint() { var the_symbol = symbol(id); the_symbol.nud = function () { var the_token = token; - the_token.arity = 'pre'; + the_token.arity = "pre"; the_token.expression = expression(150); mutation_check(the_token.expression); return the_token; @@ -2216,8 +2353,8 @@ var jslint = (function JSLint() { var the_symbol = symbol(id); the_symbol.nud = function () { var the_token = token; - the_token.arity = 'unary'; - if (typeof f === 'function') { + the_token.arity = "unary"; + if (typeof f === "function") { return f(); } the_token.expression = expression(150); @@ -2232,7 +2369,7 @@ var jslint = (function JSLint() { var the_symbol = symbol(id); the_symbol.fud = function () { - token.arity = 'statement'; + token.arity = "statement"; return f(); }; return the_symbol; @@ -2244,11 +2381,11 @@ var jslint = (function JSLint() { var the_symbol = symbol(id1, 30); the_symbol.led = function (left) { - var the_token = token, - second = expression(20); + var the_token = token; + var second = expression(20); advance(id2); - token.arity = 'ternary'; - the_token.arity = 'ternary'; + token.arity = "ternary"; + the_token.arity = "ternary"; the_token.expression = [left, second, expression(10)]; return the_token; }; @@ -2259,180 +2396,154 @@ var jslint = (function JSLint() { syntax = empty(); - symbol('}'); - symbol(')'); - symbol(']'); - symbol(','); - symbol(';'); - symbol(':'); - symbol('*/'); - symbol('await'); - symbol('case'); - symbol('catch'); - symbol('class'); - symbol('default'); - symbol('else'); - symbol('enum'); - symbol('finally'); - symbol('implements'); - symbol('interface'); - symbol('package'); - symbol('private'); - symbol('protected'); - symbol('public'); - symbol('static'); - symbol('super'); - symbol('void'); - symbol('yield'); - - constant('(number)', 'number'); - constant('(regexp)', 'regexp'); - constant('(string)', 'string'); - constant('arguments', 'object', function () { - warn('unexpected_a', token); + symbol("}"); + symbol(")"); + symbol("]"); + symbol(","); + symbol(";"); + symbol(":"); + symbol("*/"); + symbol("await"); + symbol("case"); + symbol("catch"); + symbol("class"); + symbol("default"); + symbol("else"); + symbol("enum"); + symbol("finally"); + symbol("implements"); + symbol("interface"); + symbol("package"); + symbol("private"); + symbol("protected"); + symbol("public"); + symbol("static"); + symbol("super"); + symbol("void"); + symbol("yield"); + + constant("(number)", "number"); + constant("(regexp)", "regexp"); + constant("(string)", "string"); + constant("arguments", "object", function () { + if (option.es6) { + warn("unexpected_a", token); + } return token; }); - constant('eval', 'function', function () { + constant("eval", "function", function () { if (!option.eval) { - warn('unexpected_a', token); - } else if (next_token.id !== '(') { - warn('expected_a_before_b', next_token, '(', artifact()); + warn("unexpected_a", token); + } else if (next_token.id !== "(") { + warn("expected_a_before_b", next_token, "(", artifact()); } return token; }); - constant('false', 'boolean', false); - constant('ignore', 'undefined', function () { - warn('unexpected_a', token); + constant("false", "boolean", false); + constant("Function", "function", function () { + if (!option.eval) { + warn("unexpected_a", token); + } else if (next_token.id !== "(") { + warn("expected_a_before_b", next_token, "(", artifact()); + } + return token; + }); + constant("ignore", "undefined", function () { + warn("unexpected_a", token); + return token; + }); + constant("Infinity", "number", Infinity); + constant("isNaN", "function", function () { + if (option.es6) { + warn("expected_a_b", token, "Number.isNaN", "isNaN"); + } return token; }); - constant('Infinity', 'number', Infinity); - constant('NaN', 'number', NaN); - constant('null', 'null', null); - constant('this', 'object', function () { + constant("NaN", "number", NaN); + constant("null", "null", null); + constant("this", "object", function () { if (!option.this) { - warn('unexpected_a', token); + warn("unexpected_a", token); } return token; }); - constant('true', 'boolean', true); - constant('undefined', 'undefined'); - - assignment('='); - assignment('+='); - assignment('-='); - assignment('*='); - assignment('/='); - assignment('%='); - assignment('&='); - assignment('|='); - assignment('^='); - assignment('<<='); - assignment('>>='); - assignment('>>>='); - - infix('||', 40); - infix('&&', 50); - infix('|', 70); - infix('^', 80); - infix('&', 90); - infix('==', 100); - infix('===', 100); - infix('!=', 100); - infix('!==', 100); - infix('<', 110); - infix('>', 110); - infix('<=', 110); - infix('>=', 110); - infix('in', 110); - infix('instanceof', 110); - infix('<<', 120); - infix('>>', 120); - infix('>>>', 120); - infix('+', 130); - infix('-', 130); - infix('*', 140); - infix('/', 140); - infix('%', 140); - infix('(', 160, function (left) { - var the_paren = token, - the_argument; - if (left.id !== 'function') { + constant("true", "boolean", true); + constant("undefined", "undefined"); + + assignment("="); + assignment("+="); + assignment("-="); + assignment("*="); + assignment("/="); + assignment("%="); + assignment("&="); + assignment("|="); + assignment("^="); + assignment("<<="); + assignment(">>="); + assignment(">>>="); + + infix("||", 40); + infix("&&", 50); + infix("|", 70); + infix("^", 80); + infix("&", 90); + infix("==", 100); + infix("===", 100); + infix("!=", 100); + infix("!==", 100); + infix("<", 110); + infix(">", 110); + infix("<=", 110); + infix(">=", 110); + infix("in", 110); + infix("instanceof", 110); + infix("<<", 120); + infix(">>", 120); + infix(">>>", 120); + infix("+", 130); + infix("-", 130); + infix("*", 140); + infix("/", 140); + infix("%", 140); + infix("(", 160, function (left) { + var the_paren = token; + var the_argument; + if (left.id !== "function") { left_check(left, the_paren); } - the_paren.expression = [left]; - if (left.identifier) { - if (left.new) { - if ( - left.id.charAt(0) > 'Z' || - left.id === 'Boolean' || - left.id === 'Number' || - left.id === 'String' || - (left.id === 'Symbol' && option.es6) - ) { - warn('unexpected_a', left, 'new'); - } else if (left.id === 'Function') { - if (!option.eval) { - warn('unexpected_a', left, 'new Function'); - } - } else if (left.id === 'Array') { - warn('expected_a_b', left, '[]', 'new Array'); - } else if (left.id === 'Object') { - warn( - 'expected_a_b', - left, - 'Object.create(null)', - 'new Object' - ); - } - } else { - if ( - left.id.charAt(0) >= 'A' && - left.id.charAt(0) <= 'Z' && - left.id !== 'Boolean' && - left.id !== 'Number' && - left.id !== 'String' && - left.id !== 'Symbol' - ) { - warn( - 'expected_a_before_b', - left, - 'new', - artifact(left) - ); - } - if (functionage.arity === 'statement') { - functionage.name.calls[left.id] = left; - } - } + if (functionage.arity === "statement" && left.identifier) { + functionage.name.calls[left.id] = left; } - if (next_token.id !== ')') { + the_paren.expression = [left]; + if (next_token.id !== ")") { (function next() { var ellipsis; - if (next_token.id === '...') { + if (next_token.id === "...") { if (!option.es6) { - warn('es6'); + warn("es6"); } ellipsis = true; - advance('...'); + advance("..."); } the_argument = expression(10); if (ellipsis) { the_argument.ellipsis = true; } the_paren.expression.push(the_argument); - if (next_token.id === ',') { - advance(','); + if (next_token.id === ",") { + advance(","); return next(); } }()); } - advance(')', the_paren); + advance(")", the_paren); if (the_paren.expression.length === 2) { the_paren.free = true; if (the_argument.wrapped === true) { - warn('unexpected_a', the_paren); + warn("unexpected_a", the_paren); } - if (the_argument.id === '(') { + if (the_argument.id === "(") { the_argument.wrapped = true; } } else { @@ -2440,23 +2551,23 @@ var jslint = (function JSLint() { } return the_paren; }); - infix('.', 170, function (left) { - var the_token = token, - name = next_token; + infix(".", 170, function (left) { + var the_token = token; + var name = next_token; if ( - (left.id !== '(string)' || name.id !== 'indexOf') && - (left.id !== '[' || ( - name.id !== 'concat' && name.id !== 'forEach' + (left.id !== "(string)" || name.id !== "indexOf") && + (left.id !== "[" || ( + name.id !== "concat" && name.id !== "forEach" )) && - (left.id !== '+' || name.id !== 'slice') && - (left.id !== '(regexp)' || ( - name.id !== 'exec' && name.id !== 'test' + (left.id !== "+" || name.id !== "slice") && + (left.id !== "(regexp)" || ( + name.id !== "exec" && name.id !== "test" )) ) { left_check(left, the_token); } if (!name.identifier) { - stop('expected_identifier_a'); + stop("expected_identifier_a"); } advance(); survey(name); @@ -2467,231 +2578,232 @@ var jslint = (function JSLint() { the_token.expression = left; return the_token; }); - infix('[', 170, function (left) { - var the_token = token, - the_subscript = expression(0); - if ( - the_subscript.id === '(string)' && - rx_identifier.test(the_subscript.value) - ) { - warn('subscript_a', the_subscript); - survey(the_subscript); - } else if (the_subscript.id === '`') { - warn('unexpected_a', the_subscript); + infix("[", 170, function (left) { + var the_token = token; + var the_subscript = expression(0); + if (the_subscript.id === "(string)" || the_subscript.id === "`") { + var name = survey(the_subscript); + if (rx_identifier.test(name)) { + warn("subscript_a", the_subscript, name); + } } left_check(left, the_token); the_token.expression = [left, the_subscript]; - advance(']'); + advance("]"); return the_token; }); - infix('=>', 170, function (left) { - return stop('expected_a_before_b', left, '(', artifact(left)); + infix("=>", 170, function (left) { + return stop("wrap_parameter", left); }); function do_tick() { var the_tick = token; if (!option.es6) { - warn('es6', the_tick); + warn("es6", the_tick); } the_tick.value = []; the_tick.expression = []; - if (next_token.id !== '`') { + if (next_token.id !== "`") { (function part() { - advance('(string)'); + advance("(string)"); the_tick.value.push(token); - if (next_token.id === '${') { - advance('${'); + if (next_token.id === "${") { + advance("${"); the_tick.expression.push(expression(0)); - advance('}'); + advance("}"); return part(); } }()); } - advance('`'); + advance("`"); return the_tick; } - infix('`', 160, function (left) { + infix("`", 160, function (left) { var the_tick = do_tick(); left_check(left, the_tick); the_tick.expression = [left].concat(the_tick.expression); return the_tick; }); - post('++'); - post('--'); - pre('++'); - pre('--'); - - prefix('+'); - prefix('-'); - prefix('~'); - prefix('!'); - prefix('!!'); - prefix('[', function () { + post("++"); + post("--"); + pre("++"); + pre("--"); + + prefix("+"); + prefix("-"); + prefix("~"); + prefix("!"); + prefix("!!"); + prefix("[", function () { var the_token = token; the_token.expression = []; - if (next_token.id !== ']') { + if (next_token.id !== "]") { (function next() { - var element, - ellipsis = false; - if (next_token.id === '...') { + var element; + var ellipsis = false; + if (next_token.id === "...") { ellipsis = true; if (!option.es6) { - warn('es6'); + warn("es6"); } - advance('...'); + advance("..."); } element = expression(10); if (ellipsis) { element.ellipsis = true; } the_token.expression.push(element); - if (next_token.id === ',') { - advance(','); + if (next_token.id === ",") { + advance(","); return next(); } }()); } - advance(']'); + advance("]"); return the_token; }); - prefix('/=', function () { - stop('expected_a_b', token, '/\\=', '/='); + prefix("/=", function () { + stop("expected_a_b", token, "/\\=", "/="); }); - prefix('=>', function () { - return stop('expected_a_before_b', token, '()', '=>'); + prefix("=>", function () { + return stop("expected_a_before_b", token, "()", "=>"); }); - prefix('new', function () { + prefix("new", function () { var the_new = token; - next_token.new = true; - the_new.expression = expression(150); - if (the_new.expression.id !== '(') { - warn('expected_a_before_b', next_token, '()', artifact(next_token)); + var right = expression(160); + if (next_token.id !== "(") { + warn("expected_a_before_b", next_token, "()", artifact(next_token)); } + the_new.expression = right; return the_new; }); - prefix('typeof'); - prefix('void', function () { + prefix("typeof"); + prefix("void", function () { var the_void = token; - warn('unexpected_a', the_void); + warn("unexpected_a", the_void); the_void.expression = expression(0); return the_void; }); - function parameter(list, signature) { - var ellipsis = false, - param; - if (next_token.id === '{') { - if (!option.es6) { - warn('es6'); - } - param = next_token; - param.names = []; - advance('{'); - signature.push('{'); - (function subparameter() { - var subparam = next_token; - if (!subparam.identifier) { - return stop('expected_identifier_a'); - } - survey(subparam); - advance(); - signature.push(subparam.id); - if (next_token.id === ':') { - advance(':'); - advance(); - token.label = subparam; - subparam = token; - if (!subparam.identifier) { - return stop('expected_identifier_a'); + function parameter_list() { + var complex = false; + var list = []; + var signature = ["("]; + if (next_token.id !== ")" && next_token.id !== "(end)") { + (function parameter() { + var ellipsis = false; + var param; + if (next_token.id === "{") { + complex = true; + if (!option.es6) { + warn("es6"); } - } - param.names.push(subparam); - if (next_token.id === ',') { - advance(','); - signature.push(", "); - return subparameter(); - } - }()); - list.push(param); - advance('}'); - signature.push('}'); - if (next_token.id === ',') { - advance(','); - signature.push(", "); - return parameter(list, signature); - } - } else if (next_token.id === '[') { - if (!option.es6) { - warn('es6'); - } - param = next_token; - param.names = []; - advance('['); - signature.push("[]"); - (function subparameter() { - var subparam = next_token; - if (!subparam.identifier) { - return stop('expected_identifier_a'); - } - advance(); - param.names.push(subparam); - if (next_token.id === ',') { - advance(','); - return subparameter(); - } - }()); - list.push(param); - advance(']'); - if (next_token.id === ',') { - advance(','); - signature.push(", "); - return parameter(list, signature); - } - } else { - if (next_token.id === '...') { - if (!option.es6) { - warn('es6'); - } - ellipsis = true; - signature.push("..."); - advance('...'); - } - if (!next_token.identifier) { - return stop('expected_identifier_a'); - } - param = next_token; - list.push(param); - advance(); - signature.push(param.id); - if (ellipsis) { - param.ellipsis = true; - } else { - if (next_token.id === '=') { + param = next_token; + param.names = []; + advance("{"); + signature.push("{"); + (function subparameter() { + var subparam = next_token; + if (!subparam.identifier) { + return stop("expected_identifier_a"); + } + survey(subparam); + advance(); + signature.push(subparam.id); + if (next_token.id === ":") { + advance(":"); + advance(); + token.label = subparam; + subparam = token; + if (!subparam.identifier) { + return stop("expected_identifier_a"); + } + } + param.names.push(subparam); + if (next_token.id === ",") { + advance(","); + signature.push(", "); + return subparameter(); + } + }()); + list.push(param); + advance("}"); + signature.push("}"); + if (next_token.id === ",") { + advance(","); + signature.push(", "); + return parameter(); + } + } else if (next_token.id === "[") { + complex = true; if (!option.es6) { - warn('es6'); + warn("es6"); + } + param = next_token; + param.names = []; + advance("["); + signature.push("[]"); + (function subparameter() { + var subparam = next_token; + if (!subparam.identifier) { + return stop("expected_identifier_a"); + } + advance(); + param.names.push(subparam); + if (next_token.id === ",") { + advance(","); + return subparameter(); + } + }()); + list.push(param); + advance("]"); + if (next_token.id === ",") { + advance(","); + signature.push(", "); + return parameter(); + } + } else { + if (next_token.id === "...") { + complex = true; + if (!option.es6) { + warn("es6"); + } + ellipsis = true; + signature.push("..."); + advance("..."); + } + if (!next_token.identifier) { + return stop("expected_identifier_a"); + } + param = next_token; + list.push(param); + advance(); + signature.push(param.id); + if (ellipsis) { + param.ellipsis = true; + } else { + if (next_token.id === "=") { + complex = true; + if (!option.es6) { + stop("unexpected_statement_a"); + } + advance("="); + param.expression = expression(0); + } + if (next_token.id === ",") { + advance(","); + signature.push(", "); + return parameter(); + } } - advance('='); - param.expression = expression(0); - } - if (next_token.id === ',') { - advance(','); - signature.push(", "); - return parameter(list, signature); } - } - } - } - - function parameter_list() { - var list = [], signature = ['(']; - if (next_token.id !== ')' && next_token.id !== '(end)') { - parameter(list, signature); + }()); } - advance(')'); - signature.push(')'); - return [list, signature.join('')]; + advance(")"); + signature.push(")"); + return [list, signature.join(""), complex]; } function do_function(the_function) { @@ -2701,12 +2813,12 @@ var jslint = (function JSLint() { // A function statement must have a name that will be in the parent's scope. - if (the_function.arity === 'statement') { + if (the_function.arity === "statement") { if (!next_token.identifier) { - return stop('expected_identifier_a', next_token); + return stop("expected_identifier_a", next_token); } name = next_token; - enroll(name, 'variable', true); + enroll(name, "variable", true); the_function.name = name; name.init = true; name.calls = empty(); @@ -2728,30 +2840,32 @@ var jslint = (function JSLint() { } the_function.level = functionage.level + 1; if (mega_mode) { - warn('unexpected_a', the_function); + warn("unexpected_a", the_function); } // Don't make functions in loops. It is inefficient, and it can lead to scoping // errors. if (functionage.loop > 0) { - warn('function_in_loop', the_function); + warn("function_in_loop", the_function); } // Give the function properties for storing its names and for observing the // depth of loops and switches. the_function.context = empty(); + the_function.finally = 0; the_function.loop = 0; the_function.switch = 0; + the_function.try = 0; // Push the current function context and establish a new one. stack.push(functionage); functions.push(the_function); functionage = the_function; - if (the_function.arity !== 'statement' && name) { - enroll(name, 'function', true); + if (the_function.arity !== "statement" && typeof name === "object") { + enroll(name, "function", true); name.dead = false; name.init = true; name.used = 1; @@ -2759,15 +2873,16 @@ var jslint = (function JSLint() { // Parse the parameter list. - advance('('); + advance("("); token.free = false; - token.arity = 'function'; + token.arity = "function"; var pl = parameter_list(); functionage.parameters = pl[0]; functionage.signature = pl[1]; + functionage.complex = pl[2]; functionage.parameters.forEach(function enroll_parameter(name) { if (name.identifier) { - enroll(name, 'parameter', false); + enroll(name, "parameter", false); } else { name.names.forEach(enroll_parameter); } @@ -2775,12 +2890,15 @@ var jslint = (function JSLint() { // The function's body is a block. - the_function.block = block('body'); - if (the_function.arity === 'statement' && next_token.line === token.line) { - return stop('unexpected_a', next_token); + the_function.block = block("body"); + if ( + the_function.arity === "statement" && + next_token.line === token.line + ) { + return stop("unexpected_a", next_token); } - if (next_token.id === '.' || next_token.id === '[') { - warn('unexpected_a'); + if (next_token.id === "." || next_token.id === "[") { + warn("unexpected_a"); } // Restore the previous context. @@ -2789,63 +2907,66 @@ var jslint = (function JSLint() { return the_function; } - prefix('function', do_function); + prefix("function", do_function); function fart(pl) { - if (next_token.id === ';') { - stop('wrap_assignment', token); - } - advance('=>'); - var the_arrow = token; - the_arrow.arity = 'binary'; - the_arrow.name = "=>"; - the_arrow.level = functionage.level + 1; - functions.push(the_arrow); + if (next_token.id === ";") { + stop("wrap_assignment", token); + } + advance("=>"); + var the_fart = token; + the_fart.arity = "binary"; + the_fart.name = "=>"; + the_fart.level = functionage.level + 1; + functions.push(the_fart); if (functionage.loop > 0) { - warn('function_in_loop', the_arrow); + warn("function_in_loop", the_fart); } // Give the function properties storing its names and for observing the depth // of loops and switches. - the_arrow.context = empty(); - the_arrow.loop = 0; - the_arrow.switch = 0; + the_fart.context = empty(); + the_fart.finally = 0; + the_fart.loop = 0; + the_fart.switch = 0; + the_fart.try = 0; // Push the current function context and establish a new one. stack.push(functionage); - functionage = the_arrow; - the_arrow.parameters = pl[0]; - the_arrow.signature = pl[1]; - the_arrow.parameters.forEach(function (name) { - enroll(name, 'parameter', true); + functionage = the_fart; + the_fart.parameters = pl[0]; + the_fart.signature = pl[1]; + the_fart.complex = true; + the_fart.parameters.forEach(function (name) { + enroll(name, "parameter", true); }); if (!option.es6) { - warn('es6', the_arrow); + warn("es6", the_fart); } - if (next_token.id === '{') { - warn('expected_a_b', the_arrow, "function", "=>"); - the_arrow.block = block('body'); + if (next_token.id === "{") { + warn("expected_a_b", the_fart, "function", "=>"); + the_fart.block = block("body"); } else { - the_arrow.expression = expression(0); + the_fart.expression = expression(0); } functionage = stack.pop(); - return the_arrow; + return the_fart; } - prefix('(', function () { - var the_paren = token, - the_value, - cadet = lookahead().id; + prefix("(", function () { + var the_paren = token; + var the_value; + var cadet = lookahead().id; // We can distinguish between a parameter list for => and a wrapped expression // with one token of lookahead. if ( - next_token.id === ')' || - next_token.id === '...' || - (next_token.identifier && (cadet === ',' || cadet === '=')) + next_token.id === ")" || + next_token.id === "..." || + (next_token.identifier && (cadet === "," || cadet === "=")) ) { the_paren.free = false; return fart(parameter_list()); @@ -2853,135 +2974,151 @@ var jslint = (function JSLint() { the_paren.free = true; the_value = expression(0); if (the_value.wrapped === true) { - warn('unexpected_a', the_paren); + warn("unexpected_a", the_paren); } the_value.wrapped = true; - advance(')', the_paren); + advance(")", the_paren); if (next_token.id === "=>") { - if (the_value.arity !== 'variable') { - return stop('expected_identifier_a', the_value); + if (the_value.arity !== "variable") { + if (the_value.id === "{" || the_value.id === "[") { + warn("expected_a_before_b", the_paren, "function", "("); + return stop("expected_a_b", next_token, "{", "=>"); + } + return stop("expected_identifier_a", the_value); } the_paren.expression = [the_value]; return fart([the_paren.expression, "(" + the_value.id + ")"]); } return the_value; }); - prefix('`', do_tick); - prefix('{', function () { - var the_brace = token, - seen = empty(); + prefix("`", do_tick); + prefix("{", function () { + var the_brace = token; + var seen = empty(); the_brace.expression = []; - if (next_token.id !== '}') { + if (next_token.id !== "}") { (function member() { - var extra = true, - id, - name = next_token, - value; + var extra; + var id; + var name = next_token; + var value; advance(); if ( - (name.id === 'get' || name.id === 'set') && + (name.id === "get" || name.id === "set") && next_token.identifier ) { - extra = name.id; + extra = name.id + " " + next_token.id; name = next_token; advance(); + id = survey(name); + if (seen[extra] === true || seen[id] === true) { + warn("duplicate_a", name); + } + seen[id] = false; + seen[extra] = true; + } else { + id = survey(name); + if (typeof seen[id] === "boolean") { + warn("duplicate_a", name); + } + seen[id] = true; } - id = survey(name); - if (seen[id] === true) { - warn('duplicate_a', name); - } else if (seen[id] === 'get' && extra !== 'set') { - warn('expected_a_before_b', name, 'set', artifact(name)); - } - seen[id] = (extra === 'get') - ? 'get' - : true; if (name.identifier) { switch (next_token.id) { - case '}': - case ',': + case "}": + case ",": if (!option.es6) { - warn('es6'); - } else if (extra !== true) { - advance(':'); + warn("es6"); + } + if (typeof extra === "string") { + advance("("); } value = expression(Infinity, true); break; - case '(': - if (!option.es6 && typeof extra !== 'string') { - warn('es6'); + case "(": + if (!option.es6 && typeof extra !== "string") { + warn("es6"); } value = do_function({ - arity: 'unary', + arity: "unary", from: name.from, - id: 'function', + id: "function", line: name.line, - name: name, + name: (typeof extra === "string") + ? extra + : id, thru: name.from - }, name); + }); break; default: - advance(':'); + if (typeof extra === "string") { + advance("("); + } + advance(":"); value = expression(0); } value.label = name; - if (typeof extra === 'string') { + if (typeof extra === "string") { value.extra = extra; } the_brace.expression.push(value); } else { - advance(':'); + advance(":"); value = expression(0); value.label = name; the_brace.expression.push(value); } - if (next_token.id === ',') { - advance(','); + if (next_token.id === ",") { + advance(","); return member(); } }()); } - advance('}'); + advance("}"); return the_brace; }); - stmt(';', function () { - warn('unexpected_a', token); + stmt(";", function () { + warn("unexpected_a", token); return token; }); - stmt('{', function () { - warn('naked_block', token); - return block('naked'); + stmt("{", function () { + warn("naked_block", token); + return block("naked"); }); - stmt('break', function () { - var the_break = token, - the_label; - if (functionage.loop < 1 && functionage.switch < 1) { - warn('unexpected_a', the_break); + stmt("break", function () { + var the_break = token; + var the_label; + if ( + (functionage.loop < 1 && functionage.switch < 1) || + functionage.finally > 0 + ) { + warn("unexpected_a", the_break); } the_break.disrupt = true; if (next_token.identifier && token.line === next_token.line) { the_label = functionage.context[next_token.id]; if ( the_label === undefined || - the_label.role !== 'label' || + the_label.role !== "label" || the_label.dead ) { warn((the_label !== undefined && the_label.dead) - ? 'out_of_scope_a' - : 'not_label_a'); + ? "out_of_scope_a" + : "not_label_a"); } else { the_label.used += 1; } the_break.label = next_token; advance(); } - advance(';'); + advance(";"); return the_break; }); function do_var() { - var the_statement = token, - is_const = the_statement.id === 'const'; + var the_statement = token; + var is_const = the_statement.id === "const"; the_statement.names = []; // A program may use var or let, but not both, and let and const require @@ -2989,16 +3126,16 @@ var jslint = (function JSLint() { if (is_const) { if (!option.es6) { - warn('es6', the_statement); + warn("es6", the_statement); } } else if (var_mode === undefined) { var_mode = the_statement.id; - if (!option.es6 && var_mode !== 'var') { - warn('es6', the_statement); + if (!option.es6 && var_mode !== "var") { + warn("es6", the_statement); } } else if (the_statement.id !== var_mode) { warn( - 'expected_a_b', + "expected_a_b", the_statement, var_mode, the_statement.id @@ -3008,91 +3145,94 @@ var jslint = (function JSLint() { // We don't expect to see variables created in switch statements. if (functionage.switch > 0) { - warn('var_switch', the_statement); + warn("var_switch", the_statement); } - if (functionage.loop > 0 && the_statement.id === 'var') { - warn('var_loop', the_statement); + if (functionage.loop > 0 && the_statement.id === "var") { + warn("var_loop", the_statement); } (function next() { - if (next_token.id === '{' && the_statement.id !== 'var') { + if (next_token.id === "{" && the_statement.id !== "var") { var the_brace = next_token; the_brace.names = []; - advance('{'); + advance("{"); (function pair() { if (!next_token.identifier) { - return stop('expected_identifier_a', next_token); + return stop("expected_identifier_a", next_token); } var name = next_token; survey(name); advance(); - if (next_token.id === ':') { - advance(':'); + if (next_token.id === ":") { + advance(":"); if (!next_token.identifier) { - return stop('expected_identifier_a', next_token); + return stop("expected_identifier_a", next_token); } next_token.label = name; the_brace.names.push(next_token); - enroll(next_token, 'variable', is_const); + enroll(next_token, "variable", is_const); advance(); } else { the_brace.names.push(name); - enroll(name, 'variable', is_const); + enroll(name, "variable", is_const); } - if (next_token.id === ',') { - advance(','); + if (next_token.id === ",") { + advance(","); return pair(); } }()); - advance('}'); - advance('='); + advance("}"); + advance("="); the_brace.expression = expression(0); the_statement.names.push(the_brace); - } else if (next_token.id === '[' && the_statement.id !== 'var') { + } else if (next_token.id === "[" && the_statement.id !== "var") { var the_bracket = next_token; the_bracket.names = []; - advance('['); + advance("["); (function element() { var ellipsis; - if (next_token.id === '...') { + if (next_token.id === "...") { ellipsis = true; - advance('...'); + advance("..."); } if (!next_token.identifier) { - return stop('expected_identifier_a', next_token); + return stop("expected_identifier_a", next_token); } var name = next_token; advance(); the_bracket.names.push(name); - enroll(name, 'variable', the_statement.id === 'const'); + enroll(name, "variable", the_statement.id === "const"); if (ellipsis) { name.ellipsis = true; - } else if (next_token.id === ',') { - advance(','); + } else if (next_token.id === ",") { + advance(","); return element(); } }()); - advance(']'); - advance('='); + advance("]"); + advance("="); the_bracket.expression = expression(0); the_statement.names.push(the_bracket); } else if (next_token.identifier) { var name = next_token; advance(); - if (name.id === 'ignore') { - warn('unexpected_a', name); + if (name.id === "ignore") { + warn("unexpected_a", name); } - enroll(name, 'variable', is_const); - if (next_token.id === '=' || is_const) { - advance('='); + enroll(name, "variable", is_const); + if (next_token.id === "=" || is_const) { + advance("="); name.expression = expression(0); name.init = true; } the_statement.names.push(name); } else { - return stop('expected_identifier_a', next_token); + return stop("expected_identifier_a", next_token); } - if (next_token.id === ',') { - advance(','); + if (next_token.id === ",") { + if (!option.multivar) { + warn("expected_a_b", next_token, ";", ","); + } + advance(","); return next(); } }()); @@ -3103,325 +3243,432 @@ var jslint = (function JSLint() { return the_statement; } - stmt('const', do_var); - stmt('continue', function () { + stmt("const", do_var); + stmt("continue", function () { var the_continue = token; - if (functionage.loop < 1) { - warn('unexpected_a', the_continue); + if (functionage.loop < 1 || functionage.finally > 0) { + warn("unexpected_a", the_continue); } not_top_level(the_continue); the_continue.disrupt = true; - warn('unexpected_a', the_continue); - advance(';'); + warn("unexpected_a", the_continue); + advance(";"); return the_continue; }); - stmt('debugger', function () { + stmt("debugger", function () { var the_debug = token; if (!option.devel) { - warn('unexpected_a', the_debug); + warn("unexpected_a", the_debug); } semicolon(); return the_debug; }); - stmt('delete', function () { - var the_token = token, - the_value = expression(0); + stmt("delete", function () { + var the_token = token; + var the_value = expression(0); if ( - (the_value.id !== '.' && the_value.id !== '[') || - the_value.arity !== 'binary' + (the_value.id !== "." && the_value.id !== "[") || + the_value.arity !== "binary" ) { - stop('expected_a_b', the_value, '.', artifact(the_value)); + stop("expected_a_b", the_value, ".", artifact(the_value)); } the_token.expression = the_value; semicolon(); return the_token; }); - stmt('do', function () { + stmt("do", function () { var the_do = token; not_top_level(the_do); functionage.loop += 1; the_do.block = block(); - advance('while'); + advance("while"); the_do.expression = condition(); semicolon(); if (the_do.block.disrupt === true) { - warn('weird_loop', the_do); + warn("weird_loop", the_do); } functionage.loop -= 1; return the_do; }); - stmt('export', function () { + stmt("export", function () { var the_export = token; - if (!option.es6) { - warn('es6', the_export); + var the_id; + var the_name; + var the_thing; + + function export_id() { + if (!next_token.identifier) { + stop("expected_identifier_a"); + } + the_id = next_token.id; + the_name = global.context[the_id]; + if (the_name === undefined) { + warn("unexpected_a"); + } else { + the_name.used += 1; + if (exports[the_id] !== undefined) { + warn("duplicate_a"); + } + exports[the_id] = the_name; + } + advance(); + the_export.expression.push(the_thing); } - if (typeof module_mode === 'object') { - warn('unexpected_directive_a', module_mode, module_mode.directive); + + if (!option.es6) { + warn("es6", the_export); } - advance('default'); - if (export_mode) { - warn('duplicate_a', token); + the_export.expression = []; + if (next_token.id === "default") { + if (exports.default !== undefined) { + warn("duplicate_a"); + } + advance("default"); + the_thing = expression(); + if (the_thing.id !== "function") { + semicolon(); + } + exports.default = the_thing; + the_export.expression.push(the_thing); + } else { + switch (next_token.id) { + case "function": + the_thing = statement(); + the_name = the_thing.name; + the_id = the_name.id; + the_name.used += 1; + if (exports[the_id] !== undefined) { + warn("duplicate_a", the_name); + } + exports[the_id] = the_thing; + the_export.expression.push(the_thing); + the_thing.statement = false; + the_thing.arity = "unary"; + break; + case "var": + case "let": + case "const": + warn("unexpected_a"); + break; + case "{": + advance("{"); + (function loop() { + export_id(); + if (next_token.id === ",") { + advance(","); + return loop(); + } + }()); + advance("}"); + semicolon(); + break; + default: + export_id(); + if (the_name.writable !== true) { + warn("unexpected_a", token); + } + semicolon(); + } } module_mode = true; - export_mode = true; - the_export.expression = expression(0); - semicolon(); return the_export; }); - stmt('for', function () { - var first, - the_for = token; + stmt("for", function () { + var first; + var the_for = token; if (!option.for) { - warn('unexpected_a', the_for); + warn("unexpected_a", the_for); } not_top_level(the_for); functionage.loop += 1; - advance('('); + advance("("); token.free = true; - if (next_token.id === ';') { - return stop('expected_a_b', the_for, 'while (', 'for (;'); + if (next_token.id === ";") { + return stop("expected_a_b", the_for, "while (", "for (;"); } if ( - next_token.id === 'var' || - next_token.id === 'let' || - next_token.id === 'const' + next_token.id === "var" || + next_token.id === "let" || + next_token.id === "const" ) { - return stop('unexpected_a'); + return stop("unexpected_a"); } first = expression(0); - if (first.id === 'in') { - if (first.expression[0].arity !== 'variable') { - warn('bad_assignment_a', first.expression[0]); + if (first.id === "in") { + if (first.expression[0].arity !== "variable") { + warn("bad_assignment_a", first.expression[0]); } the_for.name = first.expression[0]; the_for.expression = first.expression[1]; - warn('expected_a_b', the_for, 'Object.keys', 'for in'); + warn("expected_a_b", the_for, "Object.keys", "for in"); } else { the_for.initial = first; - advance(';'); + advance(";"); the_for.expression = expression(0); - advance(';'); + advance(";"); the_for.inc = expression(0); - if (the_for.inc.id === '++') { - warn('expected_a_b', the_for.inc, '+= 1', '++'); + if (the_for.inc.id === "++") { + warn("expected_a_b", the_for.inc, "+= 1", "++"); } } - advance(')'); + advance(")"); the_for.block = block(); if (the_for.block.disrupt === true) { - warn('weird_loop', the_for); + warn("weird_loop", the_for); } functionage.loop -= 1; return the_for; }); - stmt('function', do_function); - stmt('if', function () { - var the_else, - the_if = token; + stmt("function", do_function); + stmt("if", function () { + var the_else; + var the_if = token; the_if.expression = condition(); the_if.block = block(); - if (next_token.id === 'else') { - advance('else'); + if (next_token.id === "else") { + advance("else"); the_else = token; - the_if.else = (next_token.id === 'if') + the_if.else = (next_token.id === "if") ? statement() : block(); if (the_if.block.disrupt === true) { if (the_if.else.disrupt === true) { the_if.disrupt = true; } else { - warn('unexpected_a', the_else); + warn("unexpected_a", the_else); } } } return the_if; }); - stmt('import', function () { + stmt("import", function () { var the_import = token; + var name; if (!option.es6) { - warn('es6', the_import); - } else if (typeof module_mode === 'object') { - warn('unexpected_directive_a', module_mode, module_mode.directive); + warn("es6", the_import); + } else if (typeof module_mode === "object") { + warn("unexpected_directive_a", module_mode, module_mode.directive); } module_mode = true; - if (!next_token.identifier) { - return stop('expected_identifier_a'); - } - var name = next_token; - advance(); - if (name.id === 'ignore') { - warn('unexpected_a', name); + if (next_token.identifier) { + name = next_token; + advance(); + if (name.id === "ignore") { + warn("unexpected_a", name); + } + enroll(name, "variable", true); + the_import.name = name; + } else { + var names = []; + advance("{"); + if (next_token.id !== "}") { + while (true) { + if (!next_token.identifier) { + stop("expected_identifier_a"); + } + name = next_token; + advance(); + if (name.id === "ignore") { + warn("unexpected_a", name); + } + enroll(name, "variable", true); + names.push(name); + if (next_token.id !== ",") { + break; + } + advance(","); + } + } + advance("}"); + the_import.name = names; } - enroll(name, 'variable', true); - advance('from'); - advance('(string)'); + advance("from"); + advance("(string)"); the_import.import = token; - the_import.name = name; - if (!rx_identifier.test(token.value)) { - warn('bad_module_name_a', token); + if (!rx_module.test(token.value)) { + warn("bad_module_name_a", token); } - imports.push(token.value); + froms.push(token.value); semicolon(); return the_import; }); - stmt('let', do_var); - stmt('return', function () { + stmt("let", do_var); + stmt("return", function () { var the_return = token; not_top_level(the_return); + if (functionage.finally > 0) { + warn("unexpected_a", the_return); + } the_return.disrupt = true; - if (next_token.id !== ';' && the_return.line === next_token.line) { + if (next_token.id !== ";" && the_return.line === next_token.line) { the_return.expression = expression(10); } - advance(';'); + advance(";"); return the_return; }); - stmt('switch', function () { - var dups = [], - last, - stmts, - the_cases = [], - the_disrupt = true, - the_switch = token; + stmt("switch", function () { + var dups = []; + var last; + var stmts; + var the_cases = []; + var the_disrupt = true; + var the_switch = token; not_top_level(the_switch); + if (functionage.finally > 0) { + warn("unexpected_a", the_switch); + } functionage.switch += 1; - advance('('); + advance("("); token.free = true; the_switch.expression = expression(0); the_switch.block = the_cases; - advance(')'); - advance('{'); + advance(")"); + advance("{"); (function major() { var the_case = next_token; - the_case.arity = 'statement'; + the_case.arity = "statement"; the_case.expression = []; (function minor() { - advance('case'); + advance("case"); token.switch = true; var exp = expression(0); if (dups.some(function (thing) { return are_similar(thing, exp); })) { - warn('unexpected_a', exp); + warn("unexpected_a", exp); } dups.push(exp); the_case.expression.push(exp); - advance(':'); - if (next_token.id === 'case') { + advance(":"); + if (next_token.id === "case") { return minor(); } }()); stmts = statements(); if (stmts.length < 1) { - warn('expected_statements_a'); + warn("expected_statements_a"); return; } the_case.block = stmts; the_cases.push(the_case); last = stmts[stmts.length - 1]; if (last.disrupt) { - if (last.id === 'break' && last.label === undefined) { + if (last.id === "break" && last.label === undefined) { the_disrupt = false; } } else { warn( - 'expected_a_before_b', + "expected_a_before_b", next_token, - 'break;', + "break;", artifact(next_token) ); } - if (next_token.id === 'case') { + if (next_token.id === "case") { return major(); } }()); dups = undefined; - if (next_token.id === 'default') { - advance('default'); + if (next_token.id === "default") { + var the_default = next_token; + advance("default"); token.switch = true; - advance(':'); + advance(":"); the_switch.else = statements(); if (the_switch.else.length < 1) { - warn('expected_statements_a'); + warn("unexpected_a", the_default); the_disrupt = false; } else { - the_disrupt = - the_disrupt && - the_switch.else[the_switch.else.length - 1].disrupt; + var the_last = the_switch.else[the_switch.else.length - 1]; + if (the_last.id === "break" && the_last.label === undefined) { + warn("unexpected_a", the_last); + the_last.disrupt = false; + } + the_disrupt = the_disrupt && the_last.disrupt; } } else { the_disrupt = false; } - advance('}', the_switch); + advance("}", the_switch); functionage.switch -= 1; the_switch.disrupt = the_disrupt; return the_switch; }); - stmt('throw', function () { + stmt("throw", function () { var the_throw = token; the_throw.disrupt = true; the_throw.expression = expression(10); semicolon(); return the_throw; }); - stmt('try', function () { - var clause = false, - the_catch, - the_disrupt, - the_try = token; + stmt("try", function () { + var the_catch; + var the_disrupt; + var the_try = token; + if (functionage.try > 0) { + warn("unexpected_a", the_try); + } + functionage.try += 1; the_try.block = block(); the_disrupt = the_try.block.disrupt; - if (next_token.id === 'catch') { - var ignored = 'ignore'; - clause = true; + if (next_token.id === "catch") { + var ignored = "ignore"; the_catch = next_token; the_try.catch = the_catch; - advance('catch'); - advance('('); + advance("catch"); + advance("("); if (!next_token.identifier) { - return stop('expected_identifier_a', next_token); + return stop("expected_identifier_a", next_token); } - if (next_token.id !== 'ignore') { + if (next_token.id !== "ignore") { ignored = undefined; the_catch.name = next_token; - enroll(next_token, 'exception', true); + enroll(next_token, "exception", true); } advance(); - advance(')'); + advance(")"); the_catch.block = block(ignored); if (the_catch.block.disrupt !== true) { the_disrupt = false; } + } else { + warn( + "expected_a_before_b", + next_token, + "catch", + artifact(next_token) + ); + } - if (next_token.id === 'finally') { - clause = true; - advance('finally'); + if (next_token.id === "finally") { + functionage.finally += 1; + advance("finally"); the_try.else = block(); the_disrupt = the_try.else.disrupt; + functionage.finally -= 1; } the_try.disrupt = the_disrupt; - if (!clause) { - warn('expected_a_before_b', next_token, 'catch', artifact(next_token)); - } + functionage.try -= 1; return the_try; }); - stmt('var', do_var); - stmt('while', function () { + stmt("var", do_var); + stmt("while", function () { var the_while = token; not_top_level(the_while); functionage.loop += 1; the_while.expression = condition(); the_while.block = block(); if (the_while.block.disrupt === true) { - warn('weird_loop', the_while); + warn("weird_loop", the_while); } functionage.loop -= 1; return the_while; }); - stmt('with', function () { - stop('unexpected_a', token); + stmt("with", function () { + stop("unexpected_a", token); }); - ternary('?', ':'); + ternary("?", ":"); // Ambulation of the parse tree. @@ -3431,15 +3678,15 @@ var jslint = (function JSLint() { // the tree is traversed. return function (arity, id, task) { - var a_set = when[arity], - i_set; + var a_set = when[arity]; + var i_set; // The id parameter is optional. If excluded, the task will be applied to all // ids. - if (typeof id !== 'string') { + if (typeof id !== "string") { task = id; - id = '(all)'; + id = "(all)"; } // If this arity has no registrations yet, then create a set object to hold @@ -3474,8 +3721,8 @@ var jslint = (function JSLint() { // Given a task set that was built by an action function, run all of the // relevant tasks on the token. - var a_set = when[the_token.arity], - i_set; + var a_set = when[the_token.arity]; + var i_set; // If there are tasks associated with the token's arity... @@ -3492,7 +3739,7 @@ var jslint = (function JSLint() { // If there are tasks for all ids. - i_set = a_set['(all)']; + i_set = a_set["(all)"]; if (i_set !== undefined) { i_set.forEach(function (task) { return task(the_token); @@ -3502,12 +3749,12 @@ var jslint = (function JSLint() { }; } - var posts = empty(), - pres = empty(), - preaction = action(pres), - postaction = action(posts), - preamble = amble(pres), - postamble = amble(posts); + var posts = empty(); + var pres = empty(); + var preaction = action(pres); + var postaction = action(posts); + var preamble = amble(pres); + var postamble = amble(posts); function walk_expression(thing) { if (thing) { @@ -3516,17 +3763,17 @@ var jslint = (function JSLint() { } else { preamble(thing); walk_expression(thing.expression); - if (thing.id === 'function') { + if (thing.id === "function") { walk_statement(thing.block); } switch (thing.arity) { - case 'post': - case 'pre': - warn('unexpected_a', thing); + case "post": + case "pre": + warn("unexpected_a", thing); break; - case 'statement': - case 'assignment': - warn('unexpected_statement_a', thing); + case "statement": + case "assignment": + warn("unexpected_statement_a", thing); break; } postamble(thing); @@ -3542,16 +3789,21 @@ var jslint = (function JSLint() { preamble(thing); walk_expression(thing.expression); switch (thing.arity) { - case 'statement': - case 'assignment': + case "statement": + case "assignment": break; - case 'binary': - if (thing.id !== '(') { - warn('unexpected_expression_a', thing); + case "binary": + if (thing.id !== "(") { + warn("unexpected_expression_a", thing); } break; default: - warn('unexpected_expression_a', thing); + warn(( + thing.id === "(string)" && + thing.value === "use strict" + ) + ? "unexpected_a" + : "unexpected_expression_a", thing); } walk_statement(thing.block); walk_statement(thing.else); @@ -3561,7 +3813,7 @@ var jslint = (function JSLint() { } function lookup(thing) { - if (thing.arity === 'variable') { + if (thing.arity === "variable") { // Look up the variable in the current context. @@ -3575,7 +3827,7 @@ var jslint = (function JSLint() { var a_variable = outer.context[thing.id]; if ( a_variable !== undefined && - a_variable.role !== 'label' + a_variable.role !== "label" ) { the_variable = a_variable; } @@ -3586,7 +3838,7 @@ var jslint = (function JSLint() { if (the_variable === undefined) { if (declared_globals[thing.id] === undefined) { - warn('undeclared_a', thing); + warn("undeclared_a", thing); return; } the_variable = { @@ -3594,7 +3846,7 @@ var jslint = (function JSLint() { function: global, id: thing.id, init: true, - role: 'variable', + role: "variable", used: 0, writable: false }; @@ -3602,11 +3854,11 @@ var jslint = (function JSLint() { } the_variable.closure = true; functionage.context[thing.id] = the_variable; - } else if (the_variable.role === 'label') { - warn('label_a', thing); + } else if (the_variable.role === "label") { + warn("label_a", thing); } if (the_variable.dead) { - warn('out_of_scope_a', thing); + warn("out_of_scope_a", thing); } return the_variable; } @@ -3619,33 +3871,48 @@ var jslint = (function JSLint() { } function preaction_function(thing) { - if (thing.arity === 'statement' && blockage.body !== true) { - warn('unexpected_a', thing); + if (thing.arity === "statement" && blockage.body !== true) { + warn("unexpected_a", thing); + } + if (thing.level === 1) { + if ( + module_mode === true || + global.strict !== undefined || + thing.complex + ) { + if (thing.id !== "=>" && thing.block.strict !== undefined) { + warn("unexpected_a", thing.block.strict); + } + } else { + if (thing.block.strict === undefined) { + warn("use_strict", thing); + } + } } stack.push(functionage); block_stack.push(blockage); functionage = thing; blockage = thing; thing.live = []; - if (typeof thing.name === 'object') { + if (typeof thing.name === "object") { thing.name.dead = false; thing.name.init = true; } switch (thing.extra) { - case 'get': + case "get": if (thing.parameters.length !== 0) { - warn('bad_get', thing); + warn("bad_get", thing); } break; - case 'set': + case "set": if (thing.parameters.length !== 1) { - warn('bad_set', thing); + warn("bad_set", thing); } break; } thing.parameters.forEach(function (name) { walk_expression(name.expression); - if (name.id === '{' || name.id === '[') { + if (name.id === "{" || name.id === "[") { name.names.forEach(subactivate); } else { name.dead = false; @@ -3656,20 +3923,20 @@ var jslint = (function JSLint() { function bitwise_check(thing) { if (!option.bitwise && bitwiseop[thing.id] === true) { - warn('unexpected_a', thing); + warn("unexpected_a", thing); } if ( - thing.id !== '(' && - thing.id !== '&&' && - thing.id !== '||' && - thing.id !== '=' && + thing.id !== "(" && + thing.id !== "&&" && + thing.id !== "||" && + thing.id !== "=" && Array.isArray(thing.expression) && thing.expression.length === 2 && ( relationop[thing.expression[0].id] === true || relationop[thing.expression[1].id] === true ) ) { - warn('unexpected_a', thing); + warn("unexpected_a", thing); } } @@ -3684,7 +3951,7 @@ var jslint = (function JSLint() { function activate(name) { if (name.expression !== undefined) { walk_expression(name.expression); - if (name.id === '{' || name.id === '[') { + if (name.id === "{" || name.id === "[") { name.names.forEach(subactivate); } else { name.init = true; @@ -3698,60 +3965,64 @@ var jslint = (function JSLint() { thing.names.forEach(activate); } - preaction('assignment', bitwise_check); - preaction('binary', bitwise_check); - preaction('binary', function (thing) { + preaction("assignment", bitwise_check); + preaction("binary", bitwise_check); + preaction("binary", function (thing) { if (relationop[thing.id] === true) { - var left = thing.expression[0], - right = thing.expression[1]; - if (left.id === 'NaN' || right.id === 'NaN') { - warn('isNaN', thing); - } else if (left.id === 'typeof') { - if (right.id !== '(string)') { - if (right.id !== 'typeof') { - warn('expected_string_a', right); + var left = thing.expression[0]; + var right = thing.expression[1]; + if (left.id === "NaN" || right.id === "NaN") { + if (option.es6) { + warn("number_isNaN", thing); + } else { + warn("isNaN", thing); + } + } else if (left.id === "typeof") { + if (right.id !== "(string)") { + if (right.id !== "typeof") { + warn("expected_string_a", right); } } else { var value = right.value; - if (value === 'symbol') { + if (value === "symbol") { if (!option.es6) { - warn('es6', right, value); + warn("es6", right, value); } - } else if (value === 'null' || value === 'undefined') { - warn('unexpected_typeof_a', right, value); + } else if (value === "null" || value === "undefined") { + warn("unexpected_typeof_a", right, value); } else if ( - value !== 'boolean' && - value !== 'function' && - value !== 'number' && - value !== 'object' && - value !== 'string' + value !== "boolean" && + value !== "function" && + value !== "number" && + value !== "object" && + value !== "string" ) { - warn('expected_type_string_a', right, value); + warn("expected_type_string_a", right, value); } } } } }); - preaction('binary', '==', function (thing) { - warn('expected_a_b', thing, '===', '=='); + preaction("binary", "==", function (thing) { + warn("expected_a_b", thing, "===", "=="); }); - preaction('binary', '!=', function (thing) { - warn('expected_a_b', thing, '!==', '!='); + preaction("binary", "!=", function (thing) { + warn("expected_a_b", thing, "!==", "!="); }); - preaction('binary', '=>', preaction_function); - preaction('binary', '||', function (thing) { + preaction("binary", "=>", preaction_function); + preaction("binary", "||", function (thing) { thing.expression.forEach(function (thang) { - if (thang.id === '&&' && !thang.wrapped) { - warn('and', thang); + if (thang.id === "&&" && !thang.wrapped) { + warn("and", thang); } }); }); - preaction('binary', '(', function (thing) { + preaction("binary", "(", function (thing) { var left = thing.expression[0]; if ( left.identifier && functionage.context[left.id] === undefined && - typeof functionage.name === 'object' + typeof functionage.name === "object" ) { var parent = functionage.name.function; if (parent) { @@ -3768,30 +4039,38 @@ var jslint = (function JSLint() { } } }); - preaction('binary', 'in', function (thing) { - warn('infix_in', thing); + preaction("binary", "in", function (thing) { + warn("infix_in", thing); + }); + preaction("binary", "instanceof", function (thing) { + warn("unexpected_a", thing); }); - preaction('statement', '{', function (thing) { + preaction("binary", ".", function (thing) { + if (thing.expression.new) { + thing.new = true; + } + }); + preaction("statement", "{", function (thing) { block_stack.push(blockage); blockage = thing; thing.live = []; }); - preaction('statement', 'for', function (thing) { + preaction("statement", "for", function (thing) { if (thing.name !== undefined) { var the_variable = lookup(thing.name); if (the_variable !== undefined) { the_variable.init = true; if (!the_variable.writable) { - warn('bad_assignment_a', thing.name); + warn("bad_assignment_a", thing.name); } } } walk_statement(thing.initial); }); - preaction('statement', 'function', preaction_function); - preaction('unary', '~', bitwise_check); - preaction('unary', 'function', preaction_function); - preaction('variable', function (thing) { + preaction("statement", "function", preaction_function); + preaction("unary", "~", bitwise_check); + preaction("unary", "function", preaction_function); + preaction("variable", function (thing) { var the_variable = lookup(thing); if (the_variable !== undefined) { thing.variable = the_variable; @@ -3807,44 +4086,73 @@ var jslint = (function JSLint() { return; } } - warn('bad_assignment_a', name); + warn("bad_assignment_a", name); } - postaction('assignment', function (thing) { + postaction("assignment", function (thing) { // Assignment using = sets the init property of a variable. No other assignment // operator can do this. A = token keeps that variable (or array of variables // in case of destructuring) in its name property. - if (thing.id === '=') { + var lvalue = thing.expression[0]; + if (thing.id === "=") { if (thing.names !== undefined) { if (Array.isArray(thing.names)) { thing.names.forEach(init_variable); } else { init_variable(thing.names); } + } else { + if ( + lvalue.id === "." && + thing.expression[1].id === "undefined" + ) { + warn( + "expected_a_b", + lvalue.expression, + "delete", + "undefined" + ); + } } } else { - var lvalue = thing.expression[0]; - if (lvalue.arity === 'variable') { + if (lvalue.arity === "variable") { if (!lvalue.variable || lvalue.variable.writable !== true) { - warn('bad_assignment_a', lvalue); + warn("bad_assignment_a", lvalue); } } + var right = syntax[thing.expression[1].id]; + if ( + right !== undefined && + ( + right.id === "function" || + right.id === "=>" || + ( + right.constant && + right.id !== "(number)" && + (right.id !== "(string)" || thing.id !== "+=") + ) + ) + ) { + warn("unexpected_a", thing.expression[1]); + } } }); function postaction_function(thing) { + delete functionage.finally; delete functionage.loop; delete functionage.switch; + delete functionage.try; functionage = stack.pop(); if (thing.wrapped) { - warn('unexpected_parens', thing); + warn("unexpected_parens", thing); } return pop_block(); } - postaction('binary', function (thing) { + postaction("binary", function (thing) { var right; if (relationop[thing.id]) { if ( @@ -3856,27 +4164,27 @@ var jslint = (function JSLint() { thing.expression[1].constant === true ) ) { - warn('weird_relation_a', thing); + warn("weird_relation_a", thing); } } switch (thing.id) { - case '+': - case '-': + case "+": + case "-": right = thing.expression[1]; if ( right.id === thing.id && - right.arity === 'unary' && + right.arity === "unary" && !right.wrapped ) { - warn('wrap_unary', right); + warn("wrap_unary", right); } break; - case '=>': - case '(': + case "=>": + case "(": break; - case '.': - if (thing.expression.id === 'RegExp') { - warn('weird_expression_a', thing); + case ".": + if (thing.expression.id === "RegExp") { + warn("weird_expression_a", thing); } break; default: @@ -3888,55 +4196,146 @@ var jslint = (function JSLint() { } } }); - postaction('binary', '&&', function (thing) { + postaction("binary", "&&", function (thing) { if ( is_weird(thing.expression[0]) || are_similar(thing.expression[0], thing.expression[1]) || thing.expression[0].constant === true || thing.expression[1].constant === true ) { - warn('weird_condition_a', thing); + warn("weird_condition_a", thing); } }); - postaction('binary', '||', function (thing) { + postaction("binary", "||", function (thing) { if ( is_weird(thing.expression[0]) || are_similar(thing.expression[0], thing.expression[1]) || thing.expression[0].constant === true ) { - warn('weird_condition_a', thing); + warn("weird_condition_a", thing); } }); - postaction('binary', '=>', postaction_function); - postaction('binary', '(', function (thing) { - if (!thing.wrapped && thing.expression[0].id === 'function') { - warn('wrap_immediate', thing); + postaction("binary", "=>", postaction_function); + postaction("binary", "(", function (thing) { + var left = thing.expression[0]; + var the_new; + if (left.id === "new") { + the_new = left; + left = left.expression; + } + if (left.id === "function") { + if (!thing.wrapped) { + warn("wrap_immediate", thing); + } + } else if (left.identifier) { + if (the_new !== undefined) { + if ( + left.id.charAt(0) > "Z" || + left.id === "Boolean" || + left.id === "Number" || + left.id === "String" || + (left.id === "Symbol" && option.es6) + ) { + warn("unexpected_a", the_new); + } else if (left.id === "Function") { + if (!option.eval) { + warn("unexpected_a", left, "new Function"); + } + } else if (left.id === "Array") { + warn("expected_a_b", left, "[]", "new Array"); + } else if (left.id === "Object") { + warn( + "expected_a_b", + left, + "Object.create(null)", + "new Object" + ); + } + } else { + if ( + left.id.charAt(0) >= "A" && + left.id.charAt(0) <= "Z" && + left.id !== "Boolean" && + left.id !== "Number" && + left.id !== "String" && + left.id !== "Symbol" + ) { + warn( + "expected_a_before_b", + left, + "new", + artifact(left) + ); + } + } + } else if (left.id === ".") { + var cack = the_new !== undefined; + if (left.expression.id === "Date" && left.name.id === "UTC") { + cack = !cack; + } + if (rx_cap.test(left.name.id) !== cack) { + if (the_new !== undefined) { + warn("unexpected_a", the_new); + } else { + warn( + "expected_a_before_b", + left.expression, + "new", + left.name.id + ); + } + } + if (left.name.id === "getTime") { + var l1 = left.expression; + if (l1.id === "(") { + var l2 = l1.expression; + if (l2.length === 1) { + var l3 = l2[0]; + if (l3.id === "new" && l3.expression.id === "Date") { + warn( + "expected_a_b", + l3, + "Date.now()", + "new Date().getTime()" + ); + } + } + } + } } }); - postaction('binary', '[', function (thing) { - if (thing.expression[0].id === 'RegExp') { - warn('weird_expression_a', thing); + postaction("binary", "[", function (thing) { + if (thing.expression[0].id === "RegExp") { + warn("weird_expression_a", thing); } if (is_weird(thing.expression[1])) { - warn('weird_expression_a', thing.expression[1]); + warn("weird_expression_a", thing.expression[1]); } }); - postaction('statement', '{', pop_block); - postaction('statement', 'const', action_var); - postaction('statement', 'export', top_level_only); - postaction('statement', 'for', function (thing) { + postaction("statement", "{", pop_block); + postaction("statement", "const", action_var); + postaction("statement", "export", top_level_only); + postaction("statement", "for", function (thing) { walk_statement(thing.inc); }); - postaction('statement', 'function', postaction_function); - postaction('statement', 'import', function (the_thing) { + postaction("statement", "function", postaction_function); + postaction("statement", "import", function (the_thing) { var name = the_thing.name; - name.init = true; - name.dead = false; - blockage.live.push(name); + if (Array.isArray(name)) { + name.forEach(function (name) { + name.dead = false; + name.init = true; + blockage.live.push(name); + }); + } else { + name.dead = false; + name.init = true; + blockage.live.push(name); + } return top_level_only(the_thing); }); - postaction('statement', 'let', action_var); - postaction('statement', 'try', function (thing) { + postaction("statement", "let", action_var); + postaction("statement", "try", function (thing) { if (thing.catch !== undefined) { var the_name = thing.catch.name; if (the_name !== undefined) { @@ -3947,66 +4346,74 @@ var jslint = (function JSLint() { walk_statement(thing.catch.block); } }); - postaction('statement', 'var', action_var); - postaction('ternary', function (thing) { + postaction("statement", "var", action_var); + postaction("ternary", function (thing) { if ( is_weird(thing.expression[0]) || thing.expression[0].constant === true || are_similar(thing.expression[1], thing.expression[2]) ) { - warn('unexpected_a', thing); + warn("unexpected_a", thing); } else if (are_similar(thing.expression[0], thing.expression[1])) { - warn('expected_a_b', thing, '||', '?'); + warn("expected_a_b", thing, "||", "?"); } else if (are_similar(thing.expression[0], thing.expression[2])) { - warn('expected_a_b', thing, '&&', '?'); + warn("expected_a_b", thing, "&&", "?"); } else if ( - thing.expression[1].id === 'true' && - thing.expression[2].id === 'false' + thing.expression[1].id === "true" && + thing.expression[2].id === "false" ) { - warn('expected_a_b', thing, '!!', '?'); + warn("expected_a_b", thing, "!!", "?"); } else if ( - thing.expression[1].id === 'false' && - thing.expression[2].id === 'true' + thing.expression[1].id === "false" && + thing.expression[2].id === "true" ) { - warn('expected_a_b', thing, '!', '?'); + warn("expected_a_b", thing, "!", "?"); } else if (thing.expression[0].wrapped !== true && ( - thing.expression[0].id === '||' || - thing.expression[0].id === '&&' + thing.expression[0].id === "||" || + thing.expression[0].id === "&&" )) { - warn('wrap_condition', thing.expression[0]); + warn("wrap_condition", thing.expression[0]); } }); - postaction('unary', function (thing) { + postaction("unary", function (thing) { switch (thing.id) { - case '[': - case '{': - case 'function': - case 'new': + case "[": + case "{": + case "function": + case "new": break; - case '`': + case "`": if (thing.expression.every(function (thing) { return thing.constant; })) { thing.constant = true; } break; + case "!": + if (thing.expression.constant === true) { + warn("unexpected_a", thing); + } + break; default: if (thing.expression.constant === true) { thing.constant = true; } } }); - postaction('unary', 'function', postaction_function); + postaction("unary", "function", postaction_function); function delve(the_function) { Object.keys(the_function.context).forEach(function (id) { - if (id !== 'ignore') { + if (id !== "ignore") { var name = the_function.context[id]; if (name.function === the_function) { - if (name.used === 0) { - warn('unused_a', name); + if (name.used === 0 && ( + name.role !== "function" || + name.function.arity !== "unary" + )) { + warn("unused_a", name); } else if (!name.init) { - warn('uninitialized_a', name); + warn("uninitialized_a", name); } } } @@ -4028,19 +4435,19 @@ var jslint = (function JSLint() { // Go through the token list, looking at usage of whitespace. function whitage() { - var closer = '(end)', - free = false, - left = global, - margin = 0, - nr_comments_skipped = 0, - open = true, - qmark = '', - result, - right; + var closer = "(end)"; + var free = false; + var left = global; + var margin = 0; + var nr_comments_skipped = 0; + var open = true; + var qmark = ""; + var result; + var right; function expected_at(at) { warn( - 'expected_a_at_b_c', + "expected_a_at_b_c", right, artifact(right), fudge + at, @@ -4056,9 +4463,15 @@ var jslint = (function JSLint() { } function no_space_only() { - if (left.line !== right.line || left.thru !== right.from) { + if ( + left.id !== "(global)" && + left.nr + 1 === right.nr && ( + left.line !== right.line || + left.thru !== right.from + ) + ) { warn( - 'unexpected_space_a_b', + "unexpected_space_a_b", right, artifact(left), artifact(right) @@ -4070,7 +4483,7 @@ var jslint = (function JSLint() { if (left.line === right.line) { if (left.thru !== right.from && nr_comments_skipped === 0) { warn( - 'unexpected_space_a_b', + "unexpected_space_a_b", right, artifact(left), artifact(right) @@ -4095,7 +4508,7 @@ var jslint = (function JSLint() { function one_space_only() { if (left.line !== right.line || left.thru + 1 !== right.from) { warn( - 'expected_space_a_b', + "expected_space_a_b", right, artifact(left), artifact(right) @@ -4107,7 +4520,7 @@ var jslint = (function JSLint() { if (left.line === right.line) { if (left.thru + 1 !== right.from && nr_comments_skipped === 0) { warn( - 'expected_space_a_b', + "expected_space_a_b", right, artifact(left), artifact(right) @@ -4134,25 +4547,25 @@ var jslint = (function JSLint() { if (level > 0) { margin -= level * 4; } - qmark = ''; + qmark = ""; } stack = []; tokens.forEach(function (the_token) { right = the_token; - if (right.id === '(comment)' || right.id === '(end)') { + if (right.id === "(comment)" || right.id === "(end)") { nr_comments_skipped += 1; } else { // If left is an opener and right is not the closer, then push the previous // state. If the token following the opener is on the next line, then this is -// an open form. If the tokens are on different lines, then it is a closed for. +// an open form. If the tokens are on the same line, then it is a closed form. // Open form is more readable, with each item (statement, argument, parameter, // etc) starting on its own line. Closed form is more compact. Statement blocks // are always in open form. var new_closer = opener[left.id]; - if (typeof new_closer === 'string') { + if (typeof new_closer === "string") { if (new_closer !== right.id) { stack.push({ closer: closer, @@ -4161,13 +4574,13 @@ var jslint = (function JSLint() { open: open, qmark: qmark }); - qmark = ''; + qmark = ""; closer = new_closer; if (left.line !== right.line) { - free = closer === ')' && left.free; + free = closer === ")" && left.free; open = true; margin += 4; - if (right.role === 'label') { + if (right.role === "label") { if (right.from !== 0) { expected_at(0); } @@ -4178,9 +4591,9 @@ var jslint = (function JSLint() { at_margin(0); } } else { - if (right.statement || right.role === 'label') { + if (right.statement || right.role === "label") { warn( - 'expected_line_break_a_b', + "expected_line_break_a_b", right, artifact(left), artifact(right) @@ -4203,12 +4616,12 @@ var jslint = (function JSLint() { } } else { -// If right is a closer, then pop the previous state, +// If right is a closer, then pop the previous state. if (right.id === closer) { var previous = stack.pop(); margin = previous.margin; - if (open && right.id !== ';') { + if (open && right.id !== ";") { at_margin(0); } else { no_space_only(); @@ -4223,20 +4636,20 @@ var jslint = (function JSLint() { // right will determine the space between them. // If left is , or ; or right is a statement then if open, right must go at the -// margin, or if closed, a space before. +// margin, or if closed, a space between. if (right.switch) { unqmark(); at_margin(-4); - } else if (right.role === 'label') { + } else if (right.role === "label") { if (right.from !== 0) { expected_at(0); } - } else if (left.id === ',') { + } else if (left.id === ",") { unqmark(); if (!open || ( - (free || closer === ']') && + (free || closer === "]") && left.line === right.line )) { one_space(); @@ -4247,42 +4660,49 @@ var jslint = (function JSLint() { // If right is a ternary operator, line it up on the margin. Use qmark to // deal with nested ternary operators. - } else if (right.arity === 'ternary') { - if (right.id === '?') { + } else if (right.arity === "ternary") { + if (right.id === "?") { margin += 4; - qmark += '?'; + qmark += "?"; } else { result = qmark.match(rx_colons); - qmark = result[1] + ':'; + qmark = result[1] + ":"; margin -= 4 * result[2].length; } at_margin(0); - } else if (right.arity === 'binary' && right.id === '(' && free) { + } else if ( + right.arity === "binary" && + right.id === "(" && + free + ) { no_space(); } else if ( - left.id === '.' || - left.id === '...' || - right.id === ',' || - right.id === ';' || - right.id === ':' || - (right.arity === 'binary' && ( - right.id === '(' || - right.id === '[' + left.id === "." || + left.id === "..." || + right.id === "," || + right.id === ";" || + right.id === ":" || + (right.arity === "binary" && ( + right.id === "(" || + right.id === "[" )) || - (right.arity === 'function' && left.id !== 'function') + ( + right.arity === "function" && + left.id !== "function" + ) ) { no_space_only(); - } else if (right.id === '.') { + } else if (right.id === ".") { if (left.line === right.line) { no_space(); } else { if (!rx_dot.test(qmark)) { - qmark += '.'; + qmark += "."; margin += 4; } at_margin(0); } - } else if (left.id === ';') { + } else if (left.id === ";") { unqmark(); if (open) { at_margin(0); @@ -4290,17 +4710,17 @@ var jslint = (function JSLint() { one_space(); } } else if ( - left.arity === 'ternary' || - left.id === 'case' || - left.id === 'catch' || - left.id === 'else' || - left.id === 'finally' || - left.id === 'while' || - right.id === 'catch' || - right.id === 'else' || - right.id === 'finally' || - (right.id === 'while' && !right.statement) || - (left.id === ')' && right.id === '{') + left.arity === "ternary" || + left.id === "case" || + left.id === "catch" || + left.id === "else" || + left.id === "finally" || + left.id === "while" || + right.id === "catch" || + right.id === "else" || + right.id === "finally" || + (right.id === "while" && !right.statement) || + (left.id === ")" && right.id === "{") ) { one_space_only(); } else if (right.statement === true) { @@ -4310,9 +4730,9 @@ var jslint = (function JSLint() { one_space(); } } else if ( - left.id === 'var' || - left.id === 'const' || - left.id === 'let' + left.id === "var" || + left.id === "const" || + left.id === "let" ) { stack.push({ closer: closer, @@ -4321,10 +4741,10 @@ var jslint = (function JSLint() { open: open, qmark: qmark }); - closer = ';'; + closer = ";"; free = false; open = left.open; - qmark = ''; + qmark = ""; if (open) { margin = margin + 4; at_margin(0); @@ -4338,31 +4758,31 @@ var jslint = (function JSLint() { spaceop[left.id] === true || spaceop[right.id] === true || ( - left.arity === 'binary' && - (left.id === '+' || left.id === '-') + left.arity === "binary" && + (left.id === "+" || left.id === "-") ) || ( - right.arity === 'binary' && - (right.id === '+' || right.id === '-') + right.arity === "binary" && + (right.id === "+" || right.id === "-") ) || - left.id === 'function' || - left.id === ':' || + left.id === "function" || + left.id === ":" || ( ( left.identifier || - left.id === '(string)' || - left.id === '(number)' + left.id === "(string)" || + left.id === "(number)" ) && ( right.identifier || - right.id === '(string)' || - right.id === '(number)' + right.id === "(string)" || + right.id === "(number)" ) ) || - (left.arity === 'statement' && right.id !== ';') + (left.arity === "statement" && right.id !== ";") ) { one_space(); - } else if (left.arity === 'unary') { + } else if (left.arity === "unary" && left.id !== "`") { no_space_only(); } } @@ -4384,19 +4804,21 @@ var jslint = (function JSLint() { return function (source, option_object, global_array) { try { warnings = []; - option = option_object || empty(); + option = Object.assign(empty(), option_object); anon = "anonymous"; block_stack = []; declared_globals = empty(); directive_mode = true; + directives = []; early_stop = true; - export_mode = false; + exports = empty(); + froms = []; fudge = (option.fudge) ? 1 : 0; functions = []; global = { - id: '(global)', + id: "(global)", body: true, context: empty(), from: 0, @@ -4409,7 +4831,6 @@ var jslint = (function JSLint() { }; blockage = global; functionage = global; - imports = []; json_mode = false; mega_mode = false; module_mode = false; @@ -4434,53 +4855,63 @@ var jslint = (function JSLint() { }); tokenize(source); advance(); - if (tokens[0].id === '{' || tokens[0].id === '[') { - json_mode = true; + if (json_mode) { tree = json_value(); - advance('(end)'); + advance("(end)"); } else { // Because browsers encourage combining of script files, the first token might // be a semicolon to defend against a missing semicolon in the preceding file. if (option.browser) { - if (next_token.id === ';') { - advance(';'); + if (next_token.id === ";") { + advance(";"); } } else { // If we are not in a browser, then the file form of strict pragma may be used. if ( - next_token.id === '(string)' && - next_token.value === 'use strict' + next_token.value === "use strict" ) { - advance('(string)'); - advance(';'); - global.strict = true; + global.strict = next_token; + advance("(string)"); + advance(";"); } } tree = statements(); - advance('(end)'); + advance("(end)"); functionage = global; walk_statement(tree); + if (module_mode && global.strict !== undefined) { + warn("unexpected_a", global.strict); + } uninitialized_and_unused(); if (!option.white) { whitage(); } } + if (!option.browser) { + directives.forEach(function (comment) { + if (comment.directive === "global") { + warn("missing_browser", comment); + } + }); + } early_stop = false; } catch (e) { - if (e.name !== 'JSLintError') { + if (e.name !== "JSLintError") { warnings.push(e); } } return { - edition: "2015-10-29", + directives: directives, + edition: "2017-02-07", + exports: exports, + froms: froms, functions: functions, global: global, id: "(JSLint)", - imports: imports, json: json_mode, lines: lines, module: module_mode === true, From 5d0890faa25374edb823360bd846a38f73cce611 Mon Sep 17 00:00:00 2001 From: mnater Date: Sun, 5 Mar 2017 00:08:06 +0100 Subject: [PATCH 73/86] clean up --- compressor.html | 2 +- mergeAndPack.html | 1 + patterns/cu.js | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/compressor.html b/compressor.html index dcd7659..055e326 100644 --- a/compressor.html +++ b/compressor.html @@ -96,7 +96,7 @@ function output2String(meta) { 'use strict'; var tmp, len; - tmp = 'Hyphenator.languages[\'' + document.getElementsByName('language')[0].value + '\'] = {\n'; + tmp = 'Hyphenator.languages["' + document.getElementsByName('language')[0].value + '"] = {\n'; tmp += '\tleftmin : ' + document.getElementsByName('leftmin')[0].value + ',\n'; tmp += '\trightmin : ' + document.getElementsByName('rightmin')[0].value + ',\n'; tmp += '\tspecialChars : "' + specialChars + '",\n'; diff --git a/mergeAndPack.html b/mergeAndPack.html index ea9a93b..a6719aa 100644 --- a/mergeAndPack.html +++ b/mergeAndPack.html @@ -982,6 +982,7 @@

      mergeAndPack বাংলা (Bengali)
    • +
    • diff --git a/patterns/cu.js b/patterns/cu.js index d5bef9e..e925fe8 100644 --- a/patterns/cu.js +++ b/patterns/cu.js @@ -1,10 +1,10 @@ -// Created by Aleksandr Andreev and Mike Kroutikov (aleksandr.andreev (at) gmail.com) +// Created by Aleksandr Andreev and Mike Kroutikov (aleksandr.andreev (at) gmail.com) // // Based on the file: hyph_cu.tex // See: https://github.com/slavonic/cu-tex/ // Copyright (c) 2016 Aleksandr Andreev and Mike Kroutikov // License: MIT -Hyphenator.languages['cu'] = { +Hyphenator.languages["cu"] = { leftmin : 1, rightmin : 1, specialChars : "а̀́̑҆̈веслѡмктꙋріднїѷѷⷠ҇ⷡⷢⷣⷤⷥⷦⷧⷨⷩⷪⷫⷬⷭⷮⷯⷰⷱⷲⷳⷴⷵⷶⷷⷸⷹⷺⷻⷼⷽⷾⷿꙴꙵꙶꙷꙸꙹꙺꙻ꙼꙽бишоѧхпѣчєгыжзю̆йьщцѝуфэѐёѕѯѳѹѻѽѿӓӥӧӭӱӹᲂꙍꙗ̇̾ъ҃ѱᲆⸯ꙾ꙿ︦︮︯", From 1926bc8ddd73294b26093c10b40736abed929fb8 Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 6 Mar 2017 08:17:57 +0100 Subject: [PATCH 74/86] fix typo and language --- mergeAndPack.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mergeAndPack.html b/mergeAndPack.html index a6719aa..0aabc48 100644 --- a/mergeAndPack.html +++ b/mergeAndPack.html @@ -982,7 +982,7 @@

      mergeAndPack বাংলা (Bengali)
    • -
    • +
    • From c9d1f78c919fbb060182ee289b759de23c0c219a Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 6 Mar 2017 08:47:34 +0100 Subject: [PATCH 75/86] added test for Church Slavonic --- testsuite/test35.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testsuite/test35.html b/testsuite/test35.html index 7ee2c68..8480aab 100644 --- a/testsuite/test35.html +++ b/testsuite/test35.html @@ -22,7 +22,7 @@ if (parent != window) { Hyphenator.config({ 'onhyphenationdonecallback': function () { - var i, last = 5, t1, t2, r = true, + var i, last = 6, t1, t2, r = true, desc = document.getElementById('desc').firstChild.data, msg = { desc: desc, @@ -65,5 +65,8 @@

      Serbian Cyrillic

      Ukrainian

      Українська мова належить до індоєвропейської мовної родини, слов'янської групи і разом з російською та білоруською до східнослов'янської підгрупи.

      Укра|їн|ська мо|ва на|ле|жить до ін|до|єв|ро|пей|ської мов|ної ро|ди|ни, слов'|ян|ської гру|пи і ра|зом з ро|сій|ською та бі|ло|ру|ською до схі|дно|слов'|ян|ської під|гру|пи.

      +

      Church Slavonic

      +

      Ꙗ҆зы́къ сегѡ̀ са́йта не мо́жетъ ѡ҆предѣле́нъ бы́ти. Прошꙋ́ тѧ ᲂу҆каза́ти ꙗ҆зы́къ

      +

      Ꙗ҆зы́къ се|гѡ̀ са́й|та не мо́|жетъ ѡ҆|пре|дѣ|ле́нъ бы́|ти. Про|шꙋ́ тѧ ᲂу҆|ка|за́|ти ꙗ҆зы́къ

      \ No newline at end of file From 19780a0680888f6510fd34b615b3b8176a7e7c27 Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 20 Mar 2017 22:35:55 +0100 Subject: [PATCH 76/86] fixes #297 --- Hyphenator.js | 38 ++++++++++++++++++++++++-------------- testsuite/test36.html | 4 ++-- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Hyphenator.js b/Hyphenator.js index 764318c..0e8d2f1 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -83,7 +83,7 @@ Hyphenator = (function (window) { o('be', 'be.js', 1, 'Мова гэтага сайта не можа быць вызначаны аўтаматычна. Калі ласка пакажыце мову:'); o('ca', 'ca.js', 0, ''); o('cs', 'cs.js', 0, 'Jazyk této internetové stránky nebyl automaticky rozpoznán. Určete prosím její jazyk:'); - o('cu', 'cu.js', 1, 'Ꙗ҆зы́къ сегѡ̀ са́йта не мо́жетъ ѡ҆предѣле́нъ бы́ти. Прошꙋ́ тѧ ᲂу҆каза́ти ꙗ҆зы́къ:'); + o('cu', 'cu.js', 1, 'Ꙗ҆зы́къ сегѡ̀ са́йта не мо́жетъ ѡ҆предѣле́нъ бы́ти. Прошꙋ́ тѧ ᲂу҆каза́ти ꙗ҆зы́къ:'); o('da', 'da.js', 0, 'Denne websides sprog kunne ikke bestemmes. Angiv venligst sprog:'); o('bn', 'bn.js', 4, ''); o('de', 'de.js', 0, 'Die Sprache dieser Webseite konnte nicht automatisch bestimmt werden. Bitte Sprache angeben:'); @@ -2085,6 +2085,25 @@ Hyphenator = (function (window) { } } + /** + * @method Hyphenator~createWordRegExp + * @desc + * build a regexp string for finding a word of a given languate + * @access private + * @param {string} lang The language + * @return {string} + */ + function createWordRegExp(lang) { + var lo = Hyphenator.languages[lang], + wrd = ""; + if (String.prototype.normalize) { + wrd = '[\\w' + lo.specialChars + lo.specialChars.normalize("NFD") + hyphen + String.fromCharCode(8204) + '-]{' + min + ',}(?!:\\/\\/)'; + } else { + wrd = '[\\w' + lo.specialChars + hyphen + String.fromCharCode(8204) + '-]{' + min + ',}(?!:\\/\\/)'; + } + return wrd; + } + /** * @method Hyphenator~prepareLanguagesObj * @desc @@ -2096,7 +2115,7 @@ Hyphenator = (function (window) { * @param {string} lang The language of the language object */ function prepareLanguagesObj(lang) { - var lo = Hyphenator.languages[lang], wrd; + var lo = Hyphenator.languages[lang]; if (!lo.prepared) { if (enableCache) { @@ -2134,12 +2153,7 @@ Hyphenator = (function (window) { lo.exceptions = {}; } convertPatternsToArray(lo); - if (String.prototype.normalize) { - wrd = '[\\w' + lo.specialChars + lo.specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}(?!:\\/\\/)'; - } else { - wrd = '[\\w' + lo.specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}(?!:\\/\\/)'; - } - lo.genRegExp = new RegExp('(' + wrd + ')|(' + url + ')|(' + mail + ')', 'gi'); + lo.genRegExp = new RegExp('(' + createWordRegExp(lang) + ')|(' + url + ')|(' + mail + ')', 'gi'); lo.prepared = true; } } @@ -2199,12 +2213,7 @@ Hyphenator = (function (window) { delete exceptions[lang]; } //Replace genRegExp since it may have been changed: - if (String.prototype.normalize) { - tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + Hyphenator.languages[lang].specialChars.normalize("NFD") + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}(?!:\\/\\/)'; - } else { - tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}(?!:\\/\\/)'; - } - Hyphenator.languages[lang].genRegExp = new RegExp('(' + tmp1 + ')|(' + url + ')|(' + mail + ')', 'gi'); + Hyphenator.languages[lang].genRegExp = new RegExp('(' + createWordRegExp(lang) + ')|(' + url + ')|(' + mail + ')', 'gi'); if (enableCache) { if (!Hyphenator.languages[lang].cache) { Hyphenator.languages[lang].cache = {}; @@ -2399,6 +2408,7 @@ Hyphenator = (function (window) { hw = lo.cache[word]; } else if (word.indexOf(hyphen) !== -1) { //word already contains shy; -> leave at it is! + console.log(word, -1); hw = word; } else if (lo.exceptions.hasOwnProperty(word)) { //the word is in the exceptions list hw = lo.exceptions[word].replace(/-/g, hyphen); diff --git a/testsuite/test36.html b/testsuite/test36.html index 0d2fb42..729ddab 100644 --- a/testsuite/test36.html +++ b/testsuite/test36.html @@ -47,7 +47,7 @@

      <<- index | <- Prev | Next ->

      Test 36

      Work with exceptions.

      -

      Künstler platzierte farbige Wachstuben in den Staubecken des Ateliers.

      -

      Künst|ler plat|zier|te far|bi|ge Wachs|tu|ben in den Staub|ecken des Ate|liers.

      +

      Künstler platzierte farbige Wachstuben in den Staubecken des Ateliers. Helikop|ter

      +

      Künst|ler plat|zier|te far|bi|ge Wachs|tu|ben in den Staub|ecken des Ate|liers. Helikop|ter

      \ No newline at end of file From cc84a57c44d83d494356c92fa35ed65d1d8b5a17 Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 20 Mar 2017 22:40:57 +0100 Subject: [PATCH 77/86] remove log --- Hyphenator.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Hyphenator.js b/Hyphenator.js index 0e8d2f1..79ce59f 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -2408,7 +2408,6 @@ Hyphenator = (function (window) { hw = lo.cache[word]; } else if (word.indexOf(hyphen) !== -1) { //word already contains shy; -> leave at it is! - console.log(word, -1); hw = word; } else if (lo.exceptions.hasOwnProperty(word)) { //the word is in the exceptions list hw = lo.exceptions[word].replace(/-/g, hyphen); From 19c82189b16ca0be00dc9c0ca0f8caab6ac05cdc Mon Sep 17 00:00:00 2001 From: mnater Date: Tue, 4 Apr 2017 23:07:08 +0200 Subject: [PATCH 78/86] small fixes --- testsuite/test91.html | 73 +++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/testsuite/test91.html b/testsuite/test91.html index a1fa00c..1a59a5e 100644 --- a/testsuite/test91.html +++ b/testsuite/test91.html @@ -1,5 +1,4 @@ - + Hyphenator.js – Test 91 @@ -11,52 +10,58 @@ margin-right:25%; } h2 + p { - background-color: #ffd6d6; + background-color: #ffd6d6; } h2 + p + p { - background-color: #d6ffd6; + background-color: #d6ffd6; + } + .autohyph { + hyphens: auto; + -webkit-hyphens: auto; + -moz-hyphens: auto; + -ms-hyphens: auto; } -

      <<- index | <- Prev | Next ->

      +

      <<- index | <- Prev | Next ->

      Test 91

      Hyphenate one paragraph with CSS3hyphenation.

      -

      en

      +

      en

      A hyphenation algorithm is a set of rules that decides at which points a word can be broken over two lines with a hyphen.

      -

      A hyphenation algorithm is a set of rules that decides at which points a word can be broken over two lines with a hyphen.

      +

      A hyphenation algorithm is a set of rules that decides at which points a word can be broken over two lines with a hyphen.

      -

      de

      +

      de

      Die Worttrennung, auch Silbentrennung genannt, bezeichnet in der Orthographie die Art und Weise, wie die Wörter insbesondere am Zeilenende getrennt werden können.

      -

      Die Worttrennung, auch Silbentrennung genannt, bezeichnet in der Orthographie die Art und Weise, wie die Wörter insbesondere am Zeilenende getrennt werden können.

      +

      Die Worttrennung, auch Silbentrennung genannt, bezeichnet in der Orthographie die Art und Weise, wie die Wörter insbesondere am Zeilenende getrennt werden können.

      \ No newline at end of file From 387e2f65967a633fb3a0adc73f35e1566b2cf1e8 Mon Sep 17 00:00:00 2001 From: Jon Johnson Date: Fri, 7 Apr 2017 00:23:46 -0700 Subject: [PATCH 79/86] Update README.md Attribute the creation of JavaScript to Brendan Eich instead of Douglas Crockford. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9584dc4..b0f3c97 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,6 @@ And please, be patient. Hyphenator.js is a hobby of mine and sometimes other thi (1) Some of my coding wizards are: * Franklin Mark Liang for his beautiful [hyphenation algorithm](http://www.tug.org/docs/liang/) -* [Douglas Crockford](http://www.crockford.com) for making Javascript a programming language +* [Brendan Eich](https://brendaneich.com/) for making JavaScript a programming language (and [Douglas Crockford](http://www.crockford.com) for finding The Good Parts of it) * Vyacheslav Egorov for his [deep insights to V8](http://mrale.ph/) * Bram Stein for his [initiative on web typography](http://stateofwebtype.com) From 3780eedd2b587a74dbede69d8582e737dcc46544 Mon Sep 17 00:00:00 2001 From: mnater Date: Mon, 10 Apr 2017 21:17:57 +0200 Subject: [PATCH 80/86] normalize word-break when feature testing CSS-hyphens --- Hyphenator.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Hyphenator.js b/Hyphenator.js index 79ce59f..86984ef 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -442,6 +442,7 @@ Hyphenator = (function (window) { shadow.style.fontSize = '12px'; shadow.style.lineHeight = '12px'; shadow.style.wordWrap = 'normal'; + shadow.style.wordBreak = 'normal'; shadow.style.visibility = 'hidden'; shadow.lang = lang; shadow.style['-webkit-locale'] = "'" + lang + "'"; From 0d6712cefcfb15b7617b34cd2858ff024c1993ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?b=C3=A9la?= Date: Fri, 12 May 2017 20:48:57 +0200 Subject: [PATCH 81/86] fixing bower name --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index d270b25..cf4515e 100644 --- a/bower.json +++ b/bower.json @@ -1,5 +1,5 @@ { - "name": "Hyphenator", + "name": "hyphenator", "version": "5.1.0", "main": "Hyphenator.js", "ignore": [ From 683b5f8f358b4bfabac6479ba4fbfe10186ef681 Mon Sep 17 00:00:00 2001 From: mnater Date: Sat, 20 May 2017 23:01:28 +0200 Subject: [PATCH 82/86] update german patterns --- patterns/de.js | 40 ++++++++++++++++----------------- testsuite/test13.html | 4 ++-- testsuite/test19.html | 52 ++++++++++++++++++------------------------- 3 files changed, 44 insertions(+), 52 deletions(-) diff --git a/patterns/de.js b/patterns/de.js index d133f4b..f4b667f 100644 --- a/patterns/de.js +++ b/patterns/de.js @@ -1,25 +1,25 @@ -/*global Hyphenator*/ -Hyphenator.languages['de'] = { - leftmin: 2, - rightmin: 2, - specialChars: "äüößſ", - patterns: { - 3: "2aaa1äa1ba1da1ga1j2aoa1öa1p2aqa1ßa2ua1xä1aä1bä1dä1gä1jä1k1äqä1ß1äxä1z1bibl21cacä3c1dc4h1cic1jc4k3co2cp2cs3cu1cy1de1did1ö1due1be1d4eee1fe1ge1ke1m2eoe1pe1qe1ße1te3üe1wey1e1z1fa1fä1fe1fi1fo1fö1fu1fü1fy2gd1geg1n1guh1j2hl2hnh1q2hr4hsh2ü2hwh1zi1a2iä2ici1d2ifi1ji1ßi1üj2u1ka1käkl21ko1kök1q2ks1kü1le1li4ln1lo1lö1ly1ma3mä1me1mi1mo1mö1mu1mü1my1na1nä1ne1nin1j1noo1b2oco1d2oi2ol2omo1qo2uo1vo1xö1bö1dö1e1öf2önöo1ö1ßö1vö1wö1zp2a1päp2e1php1j1puqu42rc1re1ri4rnr1q1ru1rü1ry1sa1sä1sc1se1si1so1sös1t1su1sü1ße1ßiß1j1ßu1ta1tä1tet1h1ti1to2tö2ts1tu2tü2ua2ucu1h2uiu1ju1lun12uou1q2usu1w1üb2üc2üdü1gü1k2ünü1ß2ütü1vü1zve2v2r2vsw2aw2ä2wnw2rw2ux1a1xe1xix1jx1q1xu2xyx1zy1by1ey1gy1hy1jy1ly1py1ry1vy1wy1yzä2zu1zw2", - 4: "_ax4_äm3_ch2_en1_eu1_fs4_gd2_gs4_he2_ia4_in1_ks2_oa3_öd2_pf4_ph4_ps2_st4_th4_ts2_um3_ur1_xe3a1abaa1ca3au2abaab1ä1abd1abf1abg1abh2abi1abkab1l1abnab3r1abs2abu2abü1abw2aby1abz2aca2acc2acu1add2adf2adh5adj2ado2adp2adq2adu2a1eae2bae2cae2da2ekae2pa2eta2ewae2xaf1a2afe2afia2fö2agaag2n2agt2ah_2ahsa1huah1wa1hyaif2a2il2aisaje22ak_2akb2akc2akd4ako2aks1akza1laa1lä2ale2ali2aloa1lu4aly2am_2amä2amf2amk2amla2mö2amu1anb2ane1anf1anh2anj1anl2anna1nö1anra1nü1anwao1ia1opa1or2ap_2apa2apea2pfap2n2apr2ar_a1raa1rä1arb2are2arf2arh2ari2arr2arua2rü2arv2ary4asha2söa2süaße22a1tata1at2cat2eat2h3atmat1ö4atra3tü2au_2aub4auc2aue2aug2auj4aum4aunau1o2auu2auw2aux2auz2a1ü2a1v4avia2vr2a1wax2eays4ay3t2a1zaz2aaz2oaz2uäb2sä1ckä2daä2dräd2s2ä1eäf3läf3räf2säg2näh1aä3hi2ähm2ähsä1huäh1wä1imä1la2äleä1lu2ämläm2s2än_2äne2änsä1onä1paär1äär1c4äreä1röä2rü1ärzä3suä3teät2häu1cä2uf1äug4äul2äumä2un2äur1äuß4ä1v3bah3basb2ärb2äs4b1bb3bebb2sbbu12b1c3be_3bea3beb3bek3bel1bembe1o3bet1bezbge3bib23bilbiz24b1j2bl_b2leb2lo3blü2b1mbni2bo4abo2cboe1b1op2böfb1öl2b1qb2r42br_3brä3brü4b1sb3säb3scb4slb2söbss2bs2t4b3tb5teb4thbt4rbtü1bu2fbü1c2b1v2b1w3by1by3pbys2ca1h3camc4an3carcäs22c1ccch22cec2cefce1i2cek1cen1cer1cetce1u2c1f4ch_2chb2chc2chd2chf2chg2chh2chj2chk2chp4chs2cht4chü2chv4chw1chy2chzci1cci2s4ck_ck1ack1ä2ckb2ckc2ckd1cke2ckf2ckg2ckh1cki2ckk2ckm2ckp4cks2ckt1cku2ckv2ckw1cky2ckzclo1co2ccoi22c1qcre2cry2cs2ac2si4c1tcti22c1z3da_da1ad1afd1agda1sdä2u2d1cd3dhd5dodeg2d1eides1det2dga2d3gl3di_3dicdi2edi1p2d1j4d1ld3ladni2d1obdo2o2d1qd2r4d3rid3rö2d1s4dsb4dsld2södss4dst42d1td2thdto2d3tödt3rd3tüdu2fdu1idu1odur22düb3düf3dün2d1wdwa2dy2s2d1z2e1aea2ceak1eam3e2ase1ä22eba2ebl2ebre3bue1ce2ecle3cr2ected2eed2öee1eeeg2e1eie1en2ef_2efa2efe2efi2eflefs22efu2efüegd4e3gee2gn2egue1hee1hi2ehme1hoehs22ehte1hue1hüeh1we1hy4eibe2idei1ee4ilei1p2eire2it2eiu2e1jek2a1ekdek4nek2oek4r2ektek2ue1la2eli2eln2eloe1lü2elz2ema2emm2emüen3fe4nre4nten1ue1nüe1nye1ofe1ohe4ole1ore1ove1ö2e3pae3puer1ae1räer1cer3h2erie1roer1ö2eru2esbes2c2esf4eshes3l2esmes2ö2esp2esres3we3syes3ze3teet2he3tie3tö2etre3tü2etz2euf1euke1um2euneu1p2eut2eux2e1ve3vo2ewae3wä2eweew2s2ex_3exp2exuey4neys4e3ziez2wfab43facf4ahf2alf2arf3atfä1cf1äu2f1cfe2c3fewf1ex3fez2f1fff2efff4ff3lff2s3fi_fid2fi2ofi2r3fis3fiz2f1jf2l22fl_1fläf3löf4lü2föf2f1qf2r2f3ruf3rü4f1sf3scf3sifs2tf2süf3sy4f1tf2thf3töf3tü3fugf1umf2ur3fut2fübfü2r2f1v2f1w2f1zfz2afz2öfzu33ga_ga1c5gaiga1kgäs5gä4ugbi22g1cg1dag1dog1dögdt4gd1uge1cged4gef4g2el4g1gg3gegg4r2g1h4gh_gh2egh1lg2hugh1w2g1j4gl_2gls3glüg2ly2gn_gn2e2gng2gnp2gns2gnt2gnug2nüg2ny2gnzgo4a2goggo1igo1y2g1qg2r4gse2g4slgso2gsp4g4swg3sy2g1tg3tegt2sg3tügu1cgu2egu2t2gübgür1güs32g1v2g1w3haah1ahh1aph2as2h1c2heahe3x2hi_2hiahi2ehi2n2hio2hiuhlb4hld4hlg4hll2hlm2h2lo2h1mh2moh3möhm2sh2muh2nah2nähn2eh1nu2hodhoe42hoih2on2hoo2hop3hov1h2öhö2ch4örhr1chr3dhrf2hrg2h2rihrr4h3rüh2ryhrz2hss24h1th2thhto2h4tshtt4h3tühu1chu2n2hurhüs32h1vhvi23hyg3hyphz2o2ia_i4aai2ab2iaci2afi2ahi3aii2aji2ak2iali2am2iani2apia1q2iasi3au2iavi1ämiär22i1bib2oi2böice1idt4i2dyie1ci1eii1exif3lif3rif2s2i1gi2gli3go4i1hi3heih3mih3nih3rihs2ih1wi3i2ii4s2i1k4ikei2kni1la6ilbil2cilf22iloilv42im_2ime2imo2imt2imu2inein3f2inoi1nö2inp2inrin1ui1ny2i1oio1cio2dion2i2ori2oui2ovio2xi3ön2ip_i1pai1peiph2ip4li1pr2ips2ipu2i1qi1räir1cir2eir2i2irki1roi1rö2isb2iseis3ti2sü4itäi6tli3töi3tü2itzium12i1v2i1w2i1xi2xai3xi2i1zi2zöja1c2jatje2aje1cje2gje2pje3wji2ajit3ji2vjoa3jo2iju2kjus32j1v3ka_ka1ck2adk2agka2o3kask1ähk1änkär2kby42k3cki1c3kir2kiz2k3j4kl_k2lek1lu2kly2k1mk2n2k3nek3nu3knü3komk2onk2os3kowkö2fk1ölk2r4kst44k1tk2thktt2k3tükt3zku1ckuh12kübkü1c2k1v2k1w3la_1lad2laf1lai3lao1lawlay1lä1c1läd2läf4lät2l1blb2slb2u2l1c4l1dld3rldt43le_2lec3ledle2e3lehl2ek2leple2u3levl2ey2l1flf4u2l1glgd4l3go3li_3liali1cl2ie3ligli3l2limli2o3liu4l1j2l1klk2l4l1lllb4llg4llk4ll5mlln22l1mlm3plm3tlnd2l3nil1nul1nü3loklo2o2lox2löd4lög4löß2l1plp2fl3pu2l1q4l1s4l1tl2thl6tsltt2l3tü1luf4luo2lur3lux2lüb5lüd2l1v2l3wly3c3lynly1oly3u2l1zl2zölz1wm1abmae2ma1f3mas3maßm4aymb4lmby42m3c2m1dmd1ameb43mehme1o2meö3mesmeu13mi_mi1c3mig3mil3mit2m1jm3ka4m1lm3li4m1mmmd2mmm2mm3pmm2smoa33moh3mom3mos3motmo1ymö2c4mökm1öl2m1pm2pfm3pim3pu2m1q4m1sm3säm3scm3sem2süm3sy4m1tm2thm3tömtt2m3tümt3zmu1a3munm4us2müb3mün3müt2m1vmwa2my4s2m1z3na_n1af3nain1ar3nas3natn1au3näe3näs2näunby42n1cn2ck2n1dn2döndy33ne_2nec3nedn1efneg4ne2l3nenne2un2ew3nez2n1fnf2änff4n3finf4lnf2onf4rnf3s4n1gng3mn2gnn3hän3hen3hu3nian1idn4ie3niknin1n2ip2nitni3v3nix2n1k4n1nnn3fnng4n3ni3no_no1cn1of3nov3now3noz2nödn2ör2n1q6n1snsp4n3sy2n1tn3ton3tön4tsn3tun3tü1nu_1nud3nuenuf21nug1nuinu2n1nuo2nup2nur1nut1nuu1nux1nuz3nü_3nüs1nüt4n1w1ny_1nyhn1yo1nyr1nys1nyw2n1znz3so4aco4ado4aho2aro2aso4ato5au2obbob2e1objob1lo3cao1ceo1ck2odrodt4o2ecoen12ofa2ofiof3l2ofo2oft2o1go3ghogs2o1hao1häo1heo1hio1hooh1soh3to1huoh1wo3ieo1imo1inoi2r2o1j2o1kok4n4okrokt4o1lao1läol2io3loo1lu3olyoms2omy12ona2onä2onc2oneono1o1nuon3v1onyon3zoof2o1opo1oro1pao1pi2or_or1ao3räor1c4ore2orf2orh2orm2orq2orro3ru2osh2osio3sk2oso2o1to3tüoub4oug2o3uho3um2our2ouv2o1ü2ovi2ovo2o1wo3wiox2aox2eo2xu1oxyo1yo2o1zoz2eo3ziöb2l2ö1cödi3öf3lög3lög3rö1heö1huö1keök3r3öl_öls2öm2sön2eö3niön2sö1nuö1peör1cöru4ö2saö2spö2stö3su2ö1töt2höts2öze31pa_1paa1pacpag41pak1pap2paß1pat1pau3päd3pär3päs2p1b2p3cpda41pe_pe2a1pedpef4pei13pel1pem1pep3pet4pf_1pfäpff4pf3r2p1g4ph_ph2a2phä2phb4phd2phf4phg4phkph2l2phm2phn2phöph4r2phs2phz3pik1pilpi2o3pip3pispku22pl_3pläp4lo2p1n1p2opo1c3podpo2i3pokpo2wpo3xpö2c2p1ppp3lppt2p2r2p4rä2p1s4ps_p3sep2söp2st2p1tpt1ap3tep2thptt2ptü4pt3zpu1apub42puc2pur3put1püf2pülpün22p1v2p1w3py1pys4py3t2p1z1ra_r1abr2ad1raer2afr2air2alr2apr1arr2as2raß1rat1raür2ax4räf4räg2räh2rämrä2u2r1brbb2rb2orb2srb2ur1ce2r1dr2dördt43re_2reä3reg3rekre2u2reür1ew3rez2r1frf2u4r1gr1h42rh_2rha2rhä2rhö2rhsrid2r2ie3rigr2isr2itrix12r1j2r1krk4n4r1lrl2erl3t4r1mrm2urnd4r3nern3frng2r3nirn1ör1nur1nür1nyro1c2rof3roir2onr1or4roß2rox2röf4rögr1ök4röpr1örrp4erpf4r3porp3tr3pu2r1rrrb2rr1crr2or3ru4r1sr3sirs3lr3sor3sy4r1tr3tör4tsrtt4r3türt3zru1a3ruf4rug2rum3rut4ruz2rüb2r1v2r1w4r1xry2c2r1zrz2ö3sa_3saa3sams1an3sat3säl2sc_s2ci2scj4scl2scos2cr2scs2scusd4r3see3seh3seq3set2s1hsh2as3häsh3ns3hösh4rsib43sio2s1j4sk_4skbsk4lsk4n4skö4skss3läsl3bs3les3li4sna4snö3so_so4aso1c3sog3sol3somso3o3sos3sov3sow3sozsö2csö2fs1ös1sp22sp_s2pä2spls3pn4spy2s1q6s1sss3l6st_s2ta2stb2stdst2e2stf2stg4sth2stj2stk4stl4stm2stns2to1stö2stp2stqs2trst2u1stü2stv2stwsu2n3suv3süc3sün4s3v2s1ws3was3we1s4ysyl12s1zsz2os3zü2ß1c2ß1d2ß1f2ß1h2ß1l2ß1mß1o2ßos2ßst22ß1t2ß1ü2ß1v2ß1w2ß1z3ta_4taatah2t2ai2tam3tas3tav3tax4täbtä1c4täd3täe3täg2täh4tämt1äptä2st2ät2täx4t1ct4ckt3cr3te_2teh3ten3tes4th_th2e1thi2thk2thp2ths2thü2thvt2hy3tig3tik3tio3tip3tis3tiv2t1j4t3ltl4e3to_to1c3tod3tok3ton3too4toß3tow4töftö4l3tön4töß3töttpf42t1q2tr_3tritry14ts_ts1ot2söt3sy4t1tt3tit3tot3töttt4t3tut3tü2tub3tuc2tud3tue4tuf2tuh2tuk4tüb3tüf3tüm4t3v4t3wtwa21ty13typtys44t1ztz1ätz2öu1amu3auu1ayu1ämu1äu2u1bub2lub1ru1ce2u1d2u1eu2edu2eguen1u2ep2uffuf3luf3r2u1gugo3u2göu2gü2uh_uh1wu1ieu3iguk2au1keu1kiuk4nuk2öu1kuulb4ulg4u2lü1umf1umg1umk1uml4umm1umr1umz4un_u3ne2unk1unruns21unt1unw2unzu3ofuos2u1pau3piu1pr2ur_u1raurd22ure2urfu1röur3purt2u3ruurü2u2sü2u1ß2u1tu3teuto1u3töu3tüu1ü22u1xux2eux2oux3tu1ya2u1z2übc2übdübe2üb3lüb3rüd3rüf3lü2gnüg3süh1aü1heüh1iüh1süh3tü1huüh1wül1aül2cül4eü1luün2sünt2ü1nuü1peü1piür1aürr2ür2süs2aü2stva1cva1sv4at2v1b2v1dve3bve3cve3dve3gve3hve4ive3over1ves12veüve3v2v1g2v1hvi2cvig22v1k2v1m2v1n3vol3voyvö2c2v1pv3revs2e2v3t2v1v2v1w2v1z1waa1wag1wah1walwa2p1was1wäh1wäl1wäswbu22w1c2w1dwe2a1weg1wehwe2i1wet2w1g2w3h1widwi2ewik21wil2w1k2w1l2w1mwn3s1wohwot21wöc2w1pw3ro2w1sws2t2w1twti21wucwul2wus21wühwül2wün32w1w1xa_1xae2x1b2x1c4x1d2xekxe2lx1emx2en3xes2x1f2x1g2x1hxib4xi1cxi3gxil12x1l2x1m2x1nx1or4x1p2x1r4x1txt1äxt1uxu1axu2s2x1v2x1w3xy_3xys1yacy1äty1c2y1d4y2efy1f2ygi2yg2lyhr2y1i4y1k2yl3cynt2y1nuy1ofyom2y1osy1ouypa2ype2y2pfy3phypo3y3riyrr2yse1y1t2yu2ry1z2za1c3zahz1anz1as2z3czdä1ze1e2z1h2z1j3zolzo2oz1orz1öl2zön2z1qz3saz3shz3skz3sz2z1tz3töz3tüzu3azub4zud4zu3kzuz22züb2z1v4z1zzz2ö", - 5: "_ab1a_abi4_ab3l_abo2_ack2_ag4n_ag4r_ag2u_ai2s_ang2_an3s_apo1_aps2_as3t_at4h_au3d_ät2s_by4t_dab4_de1i_de1s_dü1b_dys1_ei3k_eke2_enn2_er1e_erf4_er1i_es1p_et2s_eu3t_ext4_fe2i_fi2s_ga4t_ge3u_hi2s_im2a_im5m_in3e_ink4_inu1_ire3_is2a_jor3_ka2i_ki4e_kus2_li2f_ma3d_ma2i_me2e_ne4s_ni4e_nob4_nus2_ob1a_obe2_or2a_ort2_ozo4_pro1_ro4a_ro3m_rü1b_sch4_sha2_te2e_te2f_te2s_ti2a_tid1_ti2s_to2w_umo2_un3d_un3e_un3g_un3s_ur2i_ut2a_ut3r_übe4_vo4r_wa2s_wi4e_wor2_ya4l_za2s_zi2e_zwe2aa2beaa2gr4a2araart2aas5tab2äuab1ebabe1eabei12abela3ber2abet2abew3abfiab1irab1it2ableab3liab4loa2blua2bo_ab2of2abora3braa4brä2abrü2abs_abs2aab5scab3spabst4ab3szab1uraby4ta1cem2ach_ach1a2achba1che4achfa1chiach3lach3mach3na1choach3öach3ra4chta1chuach3ü2achvac1in2ada_ad2agada2m4adav1a2dä2ade_2aden4a3diad2obad3ru2ads2ad3stad3szad2t1ad4tead4tra2elaa2eleae2o3aes5ta2faka2fana3faraf4ata2faua2fexaf2fl2af3lafo1saf3raaf3räaf3reaf3röaf2spag1abag1arag1auag2diag2drag2duage1iag2er2agesag3gl1aggr2a2glag4laa4glöag4nuag4roagsa2ags3pag2th2a1haah4at2a1heahe1sa1h2iahin3ah2löahnt21ahorah1osa2h3öahr1aah3riaht3saian3aid2sai1e2aien3ai3g4a3ik_ai3keai3kuai2loa1indain4ea1ingai2saaiso2a3iv_aive3a3ivla3ivs2akal2akarak4at4a1kea2kefa2keu2a1ki2ak3lak4li2a1kr4akra3akroak3sh2akta2aktb2a1kua2kun4a3kü2ala_al1abal1afala2ga3lalal1ama2larala4s2alatal1aual1ämal2bralb3sal2däal2dral3dualen1ale2pale4talf4r3algi3almba2l1öal3öfal2ös1alphal2ufa2lumal1ural2zw2am2aamab4amad2ama3g2am4e4ame_a2meba3meta2mewa3miea3mis2ammlammu2am3pr2am2sam3sa1amt_am4töam2tu2ana_2anabana3ca3nak2anam2ananan1äs2anbuan3ch2and_2andua3nee2anfi4ang_2angf2anghang1l2angoang1r2a3ni2ank_an3klank1rankt42anmu3annäan1oda3nola3nos2anpr1ansä1ansc2ansk2ant_2anto1antr1antw2a1nuanu3s2anzb2anzg2anzs1anzü2anzwa1os3ao3t2a3ot_a2pefap2faa3pfla3phäa2pht2ap3la2pot3applap3pu2a3pua3ra_ar2ab2arb_4arba2arbiar2bl2arbr2arbt2arbu1ar1ca2reaa4rega2reha4reka3renare3uar2ewarf1rar2glar2gnar2iaar1ima3riuarm2äarn2e2a1roar1oba2rorar2rh2arsaarse32arsiar2st2arto2artsar1ufar1uhar1umarwa2ar2zä2arze1arztas3aua2s1äa2sca4as2ea2seba3ses2asisas1ora2s1pas2phas2pias2poa3spuas2stas3teas3tias3to2astraßen3at1abat2afat4agata3la3tama2tatat1aua2t1ä4ate_a2teb4atena2tep4atesat3ha3athl4a3ti4atorat3räat3reat2saat2seat2siat2soat3taatt3sa3tubatu2nat2zoau2draue2baue2sau2faauff43aufn4au1iau2isau3lüaun2eau1nua4unz2aup22ausc1ausd3ausf1ausg1auslau2so1ausr1ausü1ausz2aut_2aute1autoauz2wa3v4aawi3eax4am2a1yaa1yeuaysi1ä2b3lä1cheä1chiäch3lä2chrä1chuäck2eäf2fläge1iäge3sä2g3lä2g3räg4ra1ä2gy2ä3heähl1aähl2eäh3neäh3riä1is_ä1iskä2k3lä2k3rälbe2äl2bläl2p3ämt2eän5deän2dräne1sän2f52ängeän2glän2gr2ä3niänk2eän2kränk2säp2pläp2präp4stär4afäre2när2grärk2särm2sär1o2ärse2är4siär2stärt4eär2thär2zwä5s4eäse3tä2s1päss2eäs2stäs4träte2nät1obä2t3rät2saät2sääts3lät4trät2zwäu2bräude3äu3eläuf2eäug3läu2maäun2eäu1nuäu3seä3usgä3uskä3usnäu2späu2trba2bl2babs2b1afbais2ba2kabak1lbak1rbal2a2b1amban2ab1ang2banlban3tb1anzbar3bbar3nba2scba2stbau3gbau1sba1yobben3bbe4pbb2lö2b3d4bde1sbe3anbe3arbe3asb2ebe1be1cbedi4be1eh3bef4be3g2beil2b2einbe3li1ben_ben3nbe1ra3be1sbes2abe1ur3b2ew2b1ex2b5f4bfal22b1g2bges42b5h2bhut2bi3akbibe2bie2sbik2abil2abi2lubin2ebi2o1bio3dbi3onbiri1bi3seb1isobi2spb2it_b2itebi2tu2b1k4b3lad3blatb3leb3blemb4letb3leub2lie2bligb4lisb2litb4locb3los2blun3blut4b3n2bnis1bo5asb1ob3bo2blbo2brbo3d22b1ofbo3febo1is3bon_bond1bo2ne3bonsbo4räbor2sb1ortbo2scbo3thbo2xibö2b32b1p2bpa2gb4ra_b4rahbrä4u2bre_3brea2breg3bremb4rer2brigb4riob3rohb4ronb4rucbru4sbs3arbsat2b4särbs2äubs2cabs4cub3se_bse2bbsi4tbs2kubso2rbs2plb3stob3stöb3stübtal3btil4b4ts2bu2e3bu3libung4b2urgbu2sa2b3z22c1abca2chca2e3ca3g4cal3tca2pecar3ncas3tca1y2ceco4ce2drcen3gcere3ce3sh2ceta2chab2chaf1chaoch1äs1chef4chei2chic2chl2ch2lech2lu4ch2m2chn42chobcho2fch1ohch2r44chrech3rh2chuf2chuh2chum1cka_2ckac1ckag2ckalcka4r2ckau2ckeh2ckexck1imck1in3ckis2ck3l2ck3nck1o22ck3rckt2e3c4l2clet4co3chco2d2co3dicoff4co1itco2keco2lecol2oco2peco1racor3dco3recos3tco4te1c4r2cte3ecti4octur6cu2p32d1ab2d1acd2ac_dagi2dah3lda1ho3d4aida1inda1isdal2ada3löd1altdamo3d4ampd2an_d1ang2danw2d1apd2aph4dapp3darlda2rod3arrdar3sd1artda2rudas4tdat2a4datmdau3e2dauk2d1äh2d1äp2därzdä3us2d1b4dbu2cdco4r2d1d2ddar2de2adde3asde3b43de1cde1e4de3gldehe2de3hod2eicde2löd2en_dend2den3gd2enhde2nide1nude1ondepi2d4er_de3rude2sade2spde2sude1unde3us2dexp2d1f42d1g2dga3gd2ge_2d1h2d2hisdi4abdi2addi4amdi1cediet3dik2adin2adi2obdi2spdist2di2tadi2thdit3sdi2tu3di5vdi3z22d1k4d3l2edli2f2d3m24d5n2dnis1d2obadob4ld2obrdole4doll22doped2opp2dorc2dordd2orp2dortd2os_dos3sdost1dot6hdo3undö2l13d2ör2d3p2drag4d3rai2drädd4räh4dre_2dreg4drem2d3rhd4ri_d4ridd4ried4rifd4rikd4rild3robd3rocd4roid3roud5rubdrü1bd2sands1änd3seidse4td3shodso2rd2späds2pods2pud2steds2tids2tud2sundta2dd5teadt3hodt5s2du1ardub3l2d1uh2dumd2dumf2dumg2dumld2ump2dumrd1umsdung42dunrdun2s2duntdus3t2d1v2e3a2beab3lea2drea2g4ea3gaea3gleakt2ea2laeam1oea2nae2anoe3ar_ea2rae3arre3arveas3se3athea5tre3aug2ebedebe2i2ebeleb2en2ebeteb3loeb2lö2eb2oebot2ebö2seb4rueb2s1ebse22e3caech1äe1chiech3lech3mech3ne1chuech1weci6a2eckteco3dec1s4e3d2aed2dre3deiede2re3d2oeds2äed2suedu2se3dy3ee3a2eeb2lee2ceee1chee2ckeede3e1effeef4leef3see1imeel2ee1empeena2e2enäe2encee3nie2enoeen3see1rae1erde1erkee1röeert2e1erzee3s2ees3kee3taee2thee1u2e1e2xef1are2fate2fäue3fe_ef1emef2er2eff_1effief2flefi2s1efkue3fraef4rüef3soef3spe2fumege1ue2gloeg3nieg2thegus32e1ha2e1häeh2eceh2ele3hereh1läehle2eh3loeh3mue3holehr1äeh3rieh3sheh3übei2blei3de2eidn1eifrei3gl2eigt2eigu2eil_2eilbeil3d2eilne1impei4näein3kei3o2eip2fei3ree1irre2is_2eitäei3teei2theitt4e3ke_e3kene3kese3keye3k2lekt2oe3k2wela2cel1afela2h2elaoela4s2e1läel2da2ele_elea2ele2c2eleh2elei1eleke3lepel2ete3leu2elevele2x1elf_el3feelf4l1elfm1elfte3lieel3klel3leelm2ael5nae2lofe2lolelon2elö2selto22e1luel1ure2lyaelz2eema2keme2se2mop3empfem2saem2stem3t21emule2n1a4ena_2enace3nade4naf4enahe4nak4enam4enaten1äu2ene_2enem2enen2enesenf2aenf2uen3geen2gl1engpe3ni_e3nice2nide3niee3nio2enise3nit2enive2nofen1ohe3nolen1one3noteno2w2e1nöen3sp1entd1entn2entü1entw1entz2enut4enwüeo2fee1on_e1onde1onfe1onhe1onle1onre1onse1opee1opfeop4te3or_e3orbe3orse3orweo1s2e3os_eo3ulepa2gep3leep2paep4plep2prept2aepu2se3ra_era2ge1raie2rake1rale1rape2rare1rasera2ße1rawe1razer1äher1ämerb2eer3brer3da1erdber3de4ere_er1ebere2l2erer2ereserf2eerf4rerg3s2erhüe3ribe3rio2erk_erk3te3ro_er3oaer1ofer1ohe3rone3rose3rowerö2d2eröker3p4er3rä2errüers2aer3seers2ier3sker3sner3sper3sz4ertier3uzerü4bes3abes3ake3sceesch2es2eles2hues2ide2siles2ire4skees3kles3kue4skye3sote3spies3sces3se2essoe1stre1stues4tüeße2setab4et1am3etapet4atet1ähet2enete2oet3hüeti2m2e3toeto2bets2pet3suett1aet2thet2zäet2zweu1a2eu2gaeugs4euil4eu1ineu2käe3um_e3umbe3umleun2eeu1o2eur2eeu3speust4eut2heu2zw4everewä2se2we_e3wirewi2se3witex3atex1er1exis2ext_ex2tu2e3xye3z2aezi2sf1abefab5sfa2drfaib4fa2ke2fanb2fanf2fanlf1anp2fanrfan3s2fanw2f1ap3farifa3shf3aug3f4avfa2xa2f1b22f3d4fdie2f2echfe2drfe2eife1emfef4lf4eief1eisfel3tf2em_fem4m2fempfe2näfen3gfe2nof1entf2er_fe1raf2eref2ertf1erwfe2st3fete2fexpff3arff1auffe2eff3eiffe2mff4enf2fexff4laff4läff4lof3fluf3flüff3roff3röffs3t4f3g2fge3s2f1h2fi3atfien3fi3klfi2krfil3dfilg4fi3lif2inafi3nifin2sfi3olfi3rafis2afis2pfi3tu4f1k4f3ladf3lapf3länf4leef3lerflo2wf4luc2f3m2fma2d2f3n2fni2sfob2l2f1offoli3fo2nafon2efo2nu2f1opfo1ra3form2f1ök2f1ölför2s4f1p2f4racf5radfra4mf5rap2fre_f3recf3red2fregf3repf4reufri3dfri2e2frig1frisf3rocfro2sf3rotf2sanfs3arf4scefs4cofse4tf2sphfs1prfs3s4fs3thf4ta_f2tabft1afft1anft1arf3tatft3hoft1opft2s1ftsa2ftse4ft3stf2tumftwa4ft3z23f2uhfung42funt2gabfgab4r2gabz2gadlga1flga2kagal2ag4amo2ganbgan3d2ganh2ganl2ganwga1ny2garb2garc3gardg2arsga3ruga2saga2siga3spgas3sgat2a2gatmgat4rgau1cg2aukg1aus2g1äp2gärz2g1b2gber2gby4tgd1ing1d3rgd3s2ge3a2geb2ageb4rge1e2ge3ecge2esge1imge1irge2isge3lege3lügelz2ge3migem2uge3nagen3ggen3ngeo2rge1ouge3p4ge1ragerm4ge3sigest2ge5trge1ulge1ur2g1ex2g1f4gga4tg2g3lgg4log2g3n3gh2rgie3ggi2elgi2gugi3negi3tugi4us4g3k2g1labg1lac3glad3glätg2l4e2gle_3gleag3lecg3leg2glehg3len2glesg4lia2glib2glif2gligg2lik4gling2lio2glisg2lizglo3gg2lom2g1luglu2t2g1m2g2n2ag4na_2gnacg4nat3g2näg3neh2gneug2nieg2nifg4nin3g2nogno1r2g1of2g1ohgol2a2gord2gorggo2s1go3stgo3th2g1p2g4rebg4remg4rerg3retg3revgri2e3grif2grig2groc2grohgron4g4rosgro4ug4ruf2grut4g2s1gsa2gg3salgs3angs3arg3s2cg4scagsch4g4scogs2ehgsen1gs3ergse4tgsi2dg3silg3spigs3plgsrü2gs5s4gs3tag3stog3stögs3trg3stugs3tügti2mg5t4rgu3amgu1as2guedguet42g1uhgu1is3gummgu4stgut1agut3h2g3z2hab2ahab2eh2absha1kl2haleh1alph1amth2an_h2andh4ann2hanr2hantha2plha2pr2harbh2ardhasi1h1äff2h3b22h3d4hdan2he2adhe3behe2blhe3brhed2ghee4she2fä2heffhe2frhe2fuhe3guh1eieh1eifh1eighe2im4heioh1eiwhe3lihe3lohe2lö3hemdhe3mi3hemmh2en_he2näheng22henihe2nohen3z4he2ohe3onhe3ophe3phherg22hermhe3roh1eröhert2he3thhet2ih2e2uheu3ghe1y22h3f4hfi2s2h3g2hget42h1h2hi2achi1ce2hi3dh2idehi2krh1infh1inhhi3nohi4onhi3or2hip1hi2phhi2pih2i2rhi3rahi3rihirn1hi3rohir2shis2ahi2sehi2sthi1thhi3ti2h1k4h4lachla2nh1lash1lath3lädh1läsh1läuh3lebhle3eh3lerh3lesh3lexh2lieh2lifh2liph2lish2lith3lochl1ofhl1oph4lorh3löch2löshl3t2h3lufh3lukh1lüfh2mabh3magh3manh3marh4mäch4mähh4mälh4mäuh3me_hme1eh3menh4monhm3p4hm3sahms1phn1adh3namhn1anhn3d4h2nelhn3exh2nich2nidh2niehn1imhn1inh2niphn3k4h2norhnts2h2nuch2nulho2blho2efho4fa3hole4holo3holzhom2ehono3ho1rahor3dh1orgho3slho2spho4st2hot_ho3thh1o2xho1y2hö3ckhö2s1h3öst2h3p2hr1achr3adh1raih3räuh2rech3redh3refh3relh3rephre2th3revh3richri4eh3rinh2robh3rohh3rolh4ronh2rorh3rouhrs3khr2suhr4swhr2thh3ruhh4rübh2sanh2sauh2späh2sphh1stah1stoh2s1uh2t1ahta4nht2ash2tärht1ehhte2sh4thohtod1h3töpht4riht3röht2soht2sphtti2ht3z2hu2buhuko3hu2lähu2loh1umsh1unah1up_h1upshurg2hu3sahu2sohu2tihut2th4übsh3übuhvil4hwe1c2hy2thzug4iab4liaf4li3ak_i3akti5al_ia2läial3bial3dialk2i3allia2lui3am_i4amoian2ei3anni2anoi3anti3anzi3ar_ia2rai2ascia3shi2asiias3siast4i3at_i4ate1iatri3atsia3uni1är_i1ärsi1ät_i1ätaib1eiibe4nibi2ki3blai3blei4bräich1aich1äi1chei1chiich3lich3mi1choi1chuich1wi3damid2ani2deiidni3i2dol2i2drie3a2ie2bäie2blie2ckie2drie1e2iel3di1ell2i1eni3en_i3enai3endi2enei3enfi3enhi3enji3enki3enmi3enni3enöi3enpi3enrien2sie1nui3envi3enwi3enzie1o2i2erei4erii1ernie2röie3sui1ettieu2eie1unif1arif4atif1aui2fecife2iif2enif2flif4läi1flüif4rai1freif3seif3spif2taiga3iig1läig4nai4gnäig4noig4raig3säig4seig3soi2harihe1eihe4ni4is_i4i3ti2käri3ki_ik1ini2k3lik3noiko3si2kölik3räik3reik1s2ik3soik3szikt2eikt3ri2kuni3kusi1lä1il2daild1oil2drile2hil1el2ill_2illsil3öfi1lu2i2lumi3lusim4ati2megi2meji2meki2mew1immo1impoimp4s1impuim2stin2afin3ami3napina4sin1äsin3do2indrin3eii3nelin1euine2x2ingain2gl4inhei3nie2inigin2ir2inis2inn_2innlin1odin1orino3tin3suint2hin3zwi2odaio3e4iof4li2o3hio3k4i3ol_i3om_i3omsi3on_ion3di2onyi2o1pio4pfi3opsi3opti3or_i3orci3orpi3orsi3ortio3s2i2osti3ot_i3otsi3oz_i1ö2ki1ös_ipen3i3perip3fa2i1piipi2sip2plip3pui1r2ai3radirat2ir2bli3ree2irekir2glirg4sir2he2irigir4mäir2no1ironiro2sirr2hir3seir3shir2sti3sacis2api2saui2scaise3eisi2ais1opis1pais1peis3sais2stis4töis4tüit1amit1ani3tatit1auit2ärität22itelite4ni2texi5thr1itiii5tocit3rei3truit2sait2soit1uhitut4it2zä2i3u2i2vebive4niwur2ix2emiz1apiz1auize2niz4erizo2bi2z1wja3nejani1ja1stje3najet3tjo2b1job3rjoni1jo1rajord2jo2scjou4lju2blju3nijur2ok3a2aka3ar2kabh2kabska1frka1inka3kak1allkalo5k3amakand4kan2ekank42kanlk1anska3nu2kanw3kara2karbk2ardk2argk2arkk2arskar3tkaru2k2arwka3sekasi1kas3s2kattk1auskäse32k3b4kbo4nkbu2s2k3d2k1effkefi4kege2ke2glk1einkei1skeit2ke2lake2läkel1ek4eltk2en_ke2no2keo2ke2plk2er_k2erck2erlkerz2k6es_ket3ske1up2k3f42k1g22k1h4kho3mki3a4ki3drki2elki3k4ki3liki3lok2imik2in_k2ing2kinhk2inik2innkin3ski3orkio4skis2pkist2ki3zi2k1k44kla_k4lar4kle_4kleh2klic2kligk2link3lipk2lir4klizk4lopklö2sk2lötkluf23knabk4neiko2al2kobjkoff4ko1i2kol4ako3leko4muko3nu2kop_ko1pe2kops2kopzko3riko2spko2stko3ta2k1ouko2wek1o2x2k1p2k4rawk4raz2kre_2kreg2k3rh2krib2krip3kris2krufkrü1bk2sanks3ark2sauks2änksch4ks3hak3sofks1pak3speks2puks3s2k1stak1stek1stok1strk1stuk2s1uk3talkt1amkt1anktä3skte3ekt1eik2texkt3hokt1imk3topkt4rokt3s4kul2a4kulpkung42kuntku2roku2spkus3tku2sukür4s2k3z2kze3lla3ba2labb2labf2labg2labhlab2ol2abrl1abt3labu2labwla1celad2il1adl2ladm3ladul1advla2falaf3slaf3tla2gala2gnlago2l2akk2l1al4lall4lalpl2amil2amp2lanb2lanf2lanll1anp2lanslar3sla2ru4lasdla3se2lash2lasila2so2laspla2stlat2ala3telat2s1lauglawa41länd2läub2läuc2läue1läufl3bacl3blälb3lel2blil3blolb3salb3selb4sklb3splbs6tl3chel3chilch3llch3rlch3ülch1wlda2gld1all3daml3dasl3datld1auld1ärl2deil2dexldo2rld2osld2ö2l2dreld4rüld3sald3stld3thle2adle2bl4leddle3dele3eilef2ale2gäle2glleg4r4lehs4lehtl2eicl2eidl2eitlel3s4lemplem3sl2en_le2näl2enfle3nil2enkle1os3lepa3lepf3leprl2er_lerb4lerk2ler3tl1erzles2ele3shlesi1le3skles2t4lesw2lesy2leto4leud3leut2lexe2lexzl3fahlfe1elf3lolf2trlfur1lga3tlg3rel3gro2l1h23lhi_li3acli3akli3amli3arlia1sli3b4libi34lickli4ds3lie_lig4nli3keli2krlil2a3limol1inv2linzli4om3lis_li2spliss2lit2ali3telit2hli3tu2lixili2zalk3lolk4nelk4ralk2s1lk3sälks3tl3k2ülla2nl3lapll1aullch4ll3d4ll2emll2esl2lexll3l2ll1obl3lowll3shll5t4llu2fll1urll3z2lme2el2möllmpf4lms2tlna4rl3n4e2lobjl2obrlo1fllof4rloi4rlol2a2lopf2loptlo1ralo4rä2lorcl1ordlo3ro3lorq3los_lo4sa3loselo2talot4h2l1ovlo2velö2b3l2ö2fl1öhrlpi4plp3t42l3r2lre1slrut4lrü1bl3sacl2saul3sexl4shalsho2ls2pols3s2lst2al2stels4trls2tuls1uml2sunlsu3sl2tabltag4lt1aklt1ehlt2enlt3hol3thul2toblt1oplto2wlt1öll3törlt1ösl3trält3relt3sclt2solt1uhlu1anluba2lubs2lu2drlu2es2lufflu2golu2gu2l1uhlume22lumf2lumll2umpl1umsl1umw1lu2n2lunt2lunwl1urnl1urt2luselu2splu4stlu2tälüh1lly1ar2lymply3nolzo2flz3t2m2abe2mabk2mabs2mabtma2cima3damal3dmalu4mam3m2manbm2anfm2anh2manlm4ann2manzma2orm2app2marb4marrm1arzmat4cma3unma1yom1ähnmä1i2m1ärg2m1b2mbe2em3b4rm2d1äm2deimds2em2e1cmedi32medyme1efmega1m2eil3meldmell2m2en_m2ens2meou3mer_me1rame2ro3mersmes1ame4sä4mesume3th2m1ex2m1f4mfi4l4m1g22m1h4mi2admi3akmibi1mi3damie3lmi2ermi4etmi2kimi2ku4milzmi3nimi1nu3mir_mi3ra3miri3mirs3mirwmi2samise1mi2tami2th4mitz4m1k4m2mabmm1eimm3simm3spm2mummm2unmmül22m3n22mobj3m2odmo2dr4mog_mo2i32mol_mom2e3m2onmo3ne3mo2o2moptmo1ramork4m1o2xmp2flm3ponmp3ta2m3r2m2sanm4sapms1asm2saumsch2m4scom4sexmso2rm2späms2poms2pums3s2m3stoms4trms4tüms1ummt1abmt1akm3tammt1armt3homti2smt1ösm4ts1mt2samt2semt1um2m3uhmu3la2mulsmu3nim4unkmunt24munzmu3ra3musimu2spmus3tmu2sumuts32m1w2mwa4rmwel42n1abna2bä4nabg4nabhna2bln2abona2br4nabt3n2ac4naddn2ade3n2ag3n2ahn3ahnnai2en1aig2n1akna2ka3nakon2al_na2län4alena2lu2nalyn4am_3name3namon1an_4nanb2nanh2nani4nank2nanl3nannna3non1anp2nanr2nanw5nar_2narcn2ard4narg3narin2ark2narmn2arpn2as_4naspn4ata4natmnats14natt4naufn3aug5naui3n2äcn1ähn2n1ännä2scn2äss2n3b4nbe3nnbes4nbu2snch3mnd2agndat2nd1aun2dein2dobndo1cnd1opnd1orn2drönd3thndt4rn2dü4ne2apne3asne3atne2bl3necane1ckne2de2nee33nehm2n1ein2eid4neifne2ke3nelanel3bne3lin2em_n4en_n2enbn2encn2enhne2nin2enjnen3kne2non2ensn2envn2enwne2obne1os2nepfn2er_ne1ranere2n1erfn1erh3nerin1erkne2ron2erpn2erv3n2esn4es_nes4cnes1one2thneu1cneu3gneur22n1exnf1aknfo1snft2on2f1ung1adng3d4n3gefn3gerng3g4ng3hun2glon2glöng3neng1orngs3cng3tsn2gum2n1h4n3hann3harn3haunhe2rnib4lni2deni3drnie3bni1elnig2anig3rni3klni2kr3n2ilnim2o2ninfni2obni3okni3olni3ra3n2isni2tinit4sni3tunk2amn2kähnke2cnk2lonk2lunk4nan2knenk2öfn2köl2n3l22n1m4n2naunne2snn2exn2nofnn3scnn3senn2thnn1ur3nobl2no2dno3drn3olen2on_3nor_nor2a2norc3norh3norm3norsn1ortno3shno2täno2tr2nö2f2n3p4npa2gnpro1npsy32n3r2n3savns2cans1ebnse2tn3sexn3siln4sphn2sponsrü2ns3s2ns2tins2tunst2ün2styns2umnta3mnt4atnt1ämnte2bnte1ent1ehnt2enn3ternteu3nte3vn3thrnti3cntmo2nt3sants2onts2pnts2tntum4nt3z21nu1anu3arnubi11nu1cnu2esnu2fe2n1uhnu3k4n2um_2numf2numg3numm2numr2nuna2nunt3nu2snu3scnu3senu3slnu2ta2nü4bnür1c2n1v2n3ver2nymun2zadn2zann2zärnz1ecn2zornz2öln2zwö2o3a2o4abioa3deo4a3ioa3ke2obano3bar2obe_2obea2obewobi4t2o3boo3briob3skobs2pob3sz2o3buobu2s2o3bü2oby4och1ao1cheoch3loch3moch1ooch3roch1socht2o1chuoch1wo3ckeo3ckio2ckoo3d2aod2dro3debo3dexo3diro2donodo4so2dre2o3du2o1e2o4e3so2e3to3et_o3etsof1amof1auof2eno3feroffs2of2fuof1laof4läof4löof3raof3räof4rüofs1aof3thoga3dog2loo3g4nog3spohl1aoh3looh2lu3ohngoh2ni1ohnmo2h3öohr1aoh1ro2o1hyo1i2do2isco1ismoiss2oi1thoki2ook1läo2labol2arol4drole3eoler2ole3sol1exol2faol2flolf1rol2glol2grol2klolk3rol2of1olymol2zwo2mabo2mebome3co2melo2mepom2esom3maom3pfomtu3ona2bo2naeo3nalon1apon2auonbe3one2ion3f2ong4rong3s4o3nion3k2onli4o3nodono3sons1aonsi2ons3lons1pont2hont3s2onukoor3foo4skoo2tr2o1ö2opab4o3panopa5so1peco1pei2opf_op2fäo2pfeopf1l4oph2o3pheopin2op3li2o3poop4plop2pr2o1pr1opsiop3szo1rad2orak2oral3oramo1rasor1ätorb2l2orcaor2ce4orda1ordnor2do2ordr2ords2ordwore2hor1eror3gaor2glor2gn4oril2oritork2aork2s2o1ro2o1röorr4aor3rh2ors2or3shor3szor4töor2ufo2r3üo2ryaos3ados4anosa1sos4co2o3seose3eose2no3shoo4skaos3keo4skios2lo2os1pos2peos2saos4säos3to2osu42o3syo2tebote2s4ot2hot4heo2throt2inotli2ot4olot2oroto1so3traot2saot3scots1pot2thou2ceou2geou3glouri4outu4ove3so3wecoy1s4o3z2aozon1ö2bleö2b3röb2s3öch1lö2chröch2söcht4öd2stöf2flöh3riö3ig_ö2ko3öl1a2öl1eiöl1emöl4enöl1imöl1inöl3laöl1o2öl3saöl3szö2l1uölz2wönn2eön3scön3spöpf3lör3a2ör2drör2glör2klör1o2örs2eört2eör2trös2stös3teös2thös3trö2t3aöt2scöt2trözes4pa3dapa2drpa3ghpa1ho3pala1paläpa3li2paltpank42panl2pannpant2panz4papi23para1parc2parg1paro2parppa4stpat4cp3auf3pä2cpä2to2p1d2pea4rpech1pe2en2peicpe1im2pekupel3dpena41pennpe1rapere21perl3pero5perspe3sape2stp2fabp2fadp2fafpf1aip2feipf3lopf3lup2forpf1ra2pfs2pf3slpf3sz2pf3tpgra2p3hopph3t2phu4s2p1hüpi2a3pias4p4id2pi2el3pierpi3lepin2epi3oipi2pepi3ri4pisopi1thpit2s2pitz2p1k2pkur11p2l43p4lap5la_p5lad2ple_ple1cp4legp4lem2pligp4likp4liz2p3lu2p1m2po3b42p3ohpo3id3poin3p4olpo3li2pondpo1pepo2plpo3pt2pornpor3spos2epo3ta3potepö2blp2p1hpp1läp2plep2pripp3sa1prak1prax1präd1präg3präm3präs2pre_2prec1pred1preipri4e2prig1p4ro3prob2proc3prod3prog3proj3prot1prüf2prünps4anp3s2hps1idps2pop3staps2tup3stü3p2syps2zept2abpt3atpte4lp4tospto2wp2t3rpt3s2pt1um3p2typu2dr2p1uh2pundpun2s2puntput2spwa4r1queura2abr3aalra3ar2rabd2rabf2rabgra2br2rabs2rabt1rabyra1cer2ackr4ad_3radf3radlrad5tra2gn4raht2raic1rake3rakür4al_ral3bra3le2ralgr4aliralk2r4alsra2lu3ralyr2ammr2an_4ranc2ranf2ranl2ranr2rapfr2ara2rarbr2arkr2arpr4as_ras2ar4at_r3atlrat4r4rau_4raud2rauf2raug3raum3r2äd3rän_3räni3räns2r1ärr2är_rä3raräu2s4räutr2bakr3blärb2lörb4rirb3serbs1orb3sprby4tr1chirch3lrch3mrch3rrch1wr2ck1r2dafrd2amr4dapr2deir3denrd1itr2dobr3donrd1osrd4rird3tard3thrdwa4re2amre3asreb1rre2bür2ech3red_4reddre1elre1er3refe4reff3refl3refo5reg_rehl4r2ei_r2eie2reigr1einre3larel2ere3lorelu2r4em_r2emi4remur4en_r2enare2näre2nir2enzre3or3repe3repo4reppr1erfr1ergr1erkr1erlrer2nr2eror1erör1ertre2sa3rese3reso2ress3rest3resu2reulre2wi4rezirf2äurf2esrf4lör3flür3forrf4rurf4rürf2sarf2targ2abrg2anr2gnorg3spr2ha_r3herr2hoe2rholrhu2sri3amria1sri3atri1ceri1elri1euri2frrif3s5rig_5rigjrig1l4rigrrik1lr2imb2rimprim2s2rink3rinn2rint4r1irris2ari3so3rissri2strit4r5riturk2amr2kährk4lork2lur3krirk2sprk1strk2tark1uhrk2umrku2nr3l2arle2ar3lecrle2ir3letr3l2irli2sr3l2orm2ärrm3d2r3me_r2meorm2esrmo1srm3sarmt2arna2brna4nr2naurn3drr4nefrn2eirne2nr5nesrn2etr4nexr3nodr1nötrn1ur2robj2robsro3e4roh1lro1irro3lerol3s2roly4rom_4romm4romt3ronnrons2ro1pero3phr2oraro3shro2ßu3routrö2du1r2öh1r2öl3römir2ös_r2öse2r1p2r3p4ar2plirpro1rps3trr2abrr2arrr1ämr3r2er4rewrr2herrik2rro3mrr2strr2thr3r2ürrü1brs3abrs2anrs3arr3shors2klr4skor4skrr4skurs4nor4sobrs2p4rs3s2rs2thrs2tir3stor3störs2tur3swirtal2rt1amrt1ärrten1r2thirto1prt1orr5trirt2sorube2ru2drru2fa3ruinru1is4rumfru2mi4ruml4rumz2rund4runn2runwru3pr4r3urru2ra5ruroru2siru2strut3hru2zwrü1ch4rümmrz2anr2zarr2zasrz1idrz1oprz3terz2thr3zwä2s1absa2besa2blsa2br4sabss1adm3safasa2fe3safi3sagasag4nsa2gr3s2aisail22s1aksa2ka3saki3sakr4sakt3salo5samms1amps2an_s3anbs2and3sani2s1apsa2po3sapr2s1ar3saris3arrs1aspsat2a4satmsa2trsa3tss1a4u3sau_3sauc3saue3saum3saur2s3avsa2vos3ähns1ält2s1äm2s1är3s2ät3säul2säuß4s3b4sba4n2scams2cans2cap2scar2s1ce4sch_s4chä4schb4schc2schd2schf2schg2schh2schks4chls4chö2schp2schq4schss4chu3schü2schv2schz4s3d2sde1sseb4rse1ecse2glseg4rse3heseh1lseh1sseh3ts1ein3s2eks2el_s2elsse2nä3senkse2noseo2rs4er_3seraser3gs1erh3seriseru25ses_se3su2s1exse2xe4sexpsex3t4s3f4sflo44s3g2sha2k1shass3h2e3shi_3shidshi4rs3hoc4shof3shop3showsi2ad2siat5si1cs2ido3s4iesien3sie2ssi1f43s4igsig4nsi2kisik1lsi2krsik3ssi2ku3silosin1ision43s2issi2sasis3s3s2itsit3rsi3tusiv1asive3si2vr2s1k24skams3kar4skasskel1s4keps2kifs2kig4skirski1s3skiz4skom4skor4skow4sk3t2s1l23slal4slans2laws3lo_s3loe2s3m22s3n4snab4so3baso3et3softso3la3s2onsone22sopf3sor_s1orc3sorsso4rus4os_2s1ox2s1ök2spaa4spak4spap3spaß4spaus2paz3späh2spärs3pe_2spel4spet4s3pf2sphas4phäs3phespi2k4spil3spio4spis4spla4splä4sple2spod2spogs2poi2spok4spol4spr_3spru2s3ps2s4pt2spun2spup3spur4sput4s3r4sret3srü2ds5safs3sagss1ajs3sals3s2äs4sces4scoss1ecssoi4ss2poss3s4sst2ass2thss2tis3stü4sta_3staast2ac2stag3stah2stak2stax3s2tä4stäg2st3c2steas2ted4stee2stem4stens2tep2ster4stes2stetst3ev4stexs4thäs4this2thu2stia2stibs2ticsti2e2stig2stiks2til2stio2stis2stiv2sto_s3tob1stof4ston4stoo1stoß4stou2stow2stoz2stöt1stru1stub4stuc2stue3stuf3stuhstu2n3stüt4st3zsu1ansuba24subi3su1c2s1uhsu1issul2asul2isult23summ3sun_su4nes1unf4sunt3s2upsup3psu2ras1urtsu2s1su3sasu3shsu3sisus3s2sü4bsü2d1sweh24swie4swilsy4n34s3zas2zess2zis4s3zu4s3zw2ß1a22ß1b22ß1ec2ß1eißen3gße2niße2noße2roßer3t2ß3g2ßig4s2ß1in2ß1k4ßler32ß1n22ß1p22ß3r22ß1s22ß1um5taan4tab_2tabf2tabg2tabh2tabkta2br4tabsta2bü2tabw2tabz2t1ac3tacut1adatadi33taf_4tafft1afg3t2agt3agotai2ltai4r2takzta2latal3d3talo2talt3tameta2mit1amt3tan_2tanbta3ne4tanf2tang3tanit2ank4tanlt2anot1ansta2nuta3or2tapfta2pl2tarb4tark2taro2tartta2ruta3sata2tht3atlt4atmt1auk3taum4tägyt1ämt3tänzt2är_tä2ru4tätt2täuß4t3b2t3chat3chetch2itch3lt2chutch1w4t3d4tdun2te2a22teakte3alte3an3tebat2ech2teckte1emte2es2teff3teha3tehä3tei_teik43teiltekt25tel_3telatelb43telg3telk5teln3telp5tels3tem_tem3st6en_ten3ate2nät4enbten3gt4enhte2nit4enjt4enmten3n3terct4erit4erot3erötert2teru2t2estte2su3tet2t2et_4teth4tetl3teuf3teumte1unte2vite1xa4texp3text4t1f4tfi2l4t1g2tger22th4at2hagt3hait2hak2t3hä3thea2thebt2hect2hekt2hem1then3theot2hest2heut2hik4th3l4th3m2th3n1t2hot3hoft3horthou24t3hö2thub4thunti2ad3tib4ti1cetieg42tiehti1elti1etti1eu3tif_ti1fr4tift3tilgti2lötil3stilt4ti2lut2imiti3nat1inbt1infti1nuti3orti3plti1rhti2sptium2tive3ti2za4t3k45tlem6t5li4t3m24t5n4tnes2to4asto5at4tobjtob2ltode2toi4rto3la3tole4tolz2tomg3topo2topt3tor_to1ra4torct1ord3toret1orgto2rö3torsto2rut2orwto3sc3toseto4sktos2p4toss3totrtots23t4outo3un3töch4t1ökt1öst4t3p21t2r45tra_3trac3trag3trak3tral4traß5träc3träg4träs4träß4treb4trec3tref4treg2trekt4remt4rert4rett4reut3rev2trez2t3rh4trict4riptri2x3tro_3troe3tront4rop3troyt3röc2tröh3trös3trua4truktrum2t4rübt4rügts1adts1alt2sants1ast2sauts1emts3krtso2rt3sout2spät2spht2spots3s4t1st4ts2tut2s1u1tsubtt1abtt2actt1aktt2altta1st3telttes1tto1st3trott3rutt3rütts1ptt2untu3antuf2etuff3tu2istul2at2um_3tun_3tune3tungt1up_tu2rätur1c3turntu2rotu4rutu2satu2sotu3ta3tüch3tür_tür1c3türe3türg4tütztwi4ety2pat2za2tz1agtz1altz1artz1aut3ze_t2zortz2thtz1wätz1witz1wuu1a2bu1a2cuad4ru1al_u1albu1alfu1alru1alsu1altua2luu1ansu3ar_u1arsua3saua2thuat2iubau1u3b4iu2bopub3räu2bübuch1auch1äu1cheu1chiuch3luch3much3nu1chuuch3üuch1wu2ckiu3d2au2donud3rau3druue2ckue2enu2elaue2leueli4ue2miue2näue2niue2nou2ereu3errue2tau3fahuf1akuf3aru3fasuf1au2ufe_uff4luffs4u2fobufo2ruf3säuf4sou2fumug1afug1akuga4sug1auug3d2ug3huu2g1lug3lou4gluu2g3nug1orug3roug3seug3siuh1lauh1läuh2liuhme4uhr1auh3riuhrt4uh2ruuh4rüui2chui1emu4igeu1in_u1is_u3käuu1k2lu1k4ruk2tauku2sul1abul1amula2sul1ämul2drule4nule2tu2lexul3f4uli2kul3kaul2knull2aull3sulo2iul1orul2sauls3z2ultaul3thult3sul2vrulz2wuma4rum2enum1irumm2aum2suum3t2um2un2una_1unabun3acun4alun3at1unda1undd1undf2undg1undn1undv1undzune2bune2hung5hun2idunik4un2imuni2r2unisunks23unkuunna2uno4run2os2uns_un3se1unsiun3skun3spun3taun3trunt3s2untuu1o2bu3or_u3orsu1os_uote2u1pe2uper1up2faup2plup2prupt1oup4tru2rabu2rar2u1räur1änurch1ur3diure4nurf3turi2cur1imurk2s4u1rou3roluro1sur4swur2zaur2zäur2ziur2zou4safu3sepus3klu4skous3ocu3sohus1ouus1peu2spou2spuus2thus3tru1stuus2uru2tärut1egute2lut2esut2etu4tevutfi4ut2heu2thiu2thuuto3cut4orutos4ut3rüut3teutts2ut2zo2u1u2uufe22u1v4u2ve_uz1weuz3z4übe3cüber3ü1cheüch3lüd3a4üd1o4üd3s2üdsa1üd3t4ü2f1aüfer2üf2flü2f1iüf2toü2g3lüg4stühla2ühl2eüh3moüh3neühn2süh1roühs2püh4thül2laül2loül2löü2n1aün2daün2dründ3sünen3ün2faün2frünn2sün3scün3seün3spün2zaüp2plür2flür2frür3scür3seür3spürt2hüse3hüse3lüse1süss2eüs2stü2t3rüt2s1üt2tr2v1abval2s2vang2varb2v1auve3arveit4ve3lave3leve3live3love3maven2cve3neve3nive3növer3averd2vere2verf4verg4ve3river3kvert2ver3uve3tavete1ve3trve3x22v1f4vi3arvi2elvi2ervima2vi4navin2svi3savise4vi2spvis2u2v1l22v1obvo3gavo2gu2v1opvo2r1vor3avor3dvor3evor3gvo3ri2v3rav4ree2v3rov1stav3s2zvu2et2vumfwa5gewa3gowai2b2walb2walmwa3nawa3sawa3sewa3sh2wängwäs2c2w1b2we2bawe2blweb3swe2e4weed3we2fl2weiewe3niwerd2we2röwer2s1wesewe4stwet2s2w1eywie3lwin2e2wing1wi4rwi2sp1wisswi3th1wo1c1wolfwor3aw3s2kwun2s4wur_wur2s2xa2b1x2adxa1fl1x2agx3a2mx2anz1x2asx1e4gx2er_x2erexers22x3euxich2xide2xie3lxil2axi2loxi2lux2is1xis2cxi2sexis3sxi2su2x1k22x3s2x2t1axt2asx2tänxtfi4xt3s2x3turx1u2n2y1aby1al_y1a2myan2gy1anky2chiych3nyen4ny2erey2es_yes2pye2thygie5yke3nyk3s2y4le_yli4nyl3s2y2l1uyma4tym3p4ympi1y2n1oyno4dyon4iy1ontyp3any4p3sy3r2eyri2ayri1ey3r4oys2any3s2cy3s2hy4s3lysme3ys2poys1prys3t4y3s2zy2te_y2tesy3to1yure3zab3lz1a2dza3de2z1afza3grzale32z1amza2na3zani2zarb2zarcz1arm3zaubz3aug3zaun2z1äc3z2äh2z1ämz1ärgz1ärm4z3b4zbü1b2z3d2zdan2zeik4zelu25zen_zen3nze2no3zentz2er_zerk2z2ernzers2ze2säze3sczes1ezes1ize2spze2tr2z1ex2z1f42z1g2z2henzhir3zi3arzid3rzil2ezin2ezi2o3zi3opzirk22z3k42z1l22z1m2zme2e2z3n42z1ob2z1ofzo2gl2z1oh2zopezo2ri2z3ot2zö2f2z3p42z3r24z1s2zt3hozt3s2zu4chzudi4zu2elzu3f4zu3gl2zumf2zumg2zumlzun2ezung42zuntz1urkzu3s4zu5t2zür1cz1wac4zwahz1war2zwas4zwäl2zweg2zwet4zwirz2wit2z1woz1wörz1wur2z1wüz3z4az3z2o", - 6: "_ab3ol_ab1or_akt2a_al3br_alt3s_ampe4_an3d2_angs4_ans2p_ans2t_an3th_ari1e_ark2a_ar2sc_as4ta_au2f3_au4s3_be3ra_boge2_da2r1_darm1_de2al_de1o2_des2e_de3sk_des2t_do2mo_do1pe_dorf1_ehe1i_ei3e2_ei4na_ei2sp_ei4st_ei4tr_el2bi_elb3s_em3m2_end3s_enns3_en2t3_en4tr_er2da_ere3c_es3ta_est2h_es3to_es5tr_eu3g4_eve4r_flug1_for2t_fu2sc_ge3ne_guss1_he3fe_he3ri_inn2e_kamp2_kle2i_kni4e_kopf1_le4ar_li4tu_ma3la_ma2st_mel2a_mi4t1_näs1c_no4th_oper4_oste2_ost3r_poka2_ram3s_reli1_ri2as_rom2a_rö2s1_se3ck_sen3s_ser2u_se2t1_si4te_ski1e_tal2e_ta2to_te3no_te4st_ti5ta_tite4_to4pl_tro2s_tu3ri_uf2e2_ufer1_un3a2_uni4t_uns4t_uro2p_ur3s2_wah4l4a1a2naa2r1aaar3f4aat4s3ab1aufab1eilabe2laab1erkab1erzab1ins1a2blaab5lag1a2bläab4le_3a2blö1a2bon2absarab3s2i2abst_ab3ste1abteia1chalach3auach1eia3cho_ach1orach3su4ach1wa1ckarack2ena2ckinack2seack3slacon4na3d2abad3amaa2d1an3a4dapade2aladefi4a2deina2deri4ade1sades4sadi3enad4resa2f1eca2fentaf1erlaf4fluaf3s2aaf3s2haf2t1aaf2teiaf2t3raf2tura2f3urag1a2da3gen_age4naage2saage4si3a2gitag4ne_a2g3rea2g3riag4samag4setag4spoag3staag3stea2gundahl3a2ahl3szah4n1aah3r2eahrta2ain3spai3s2e2a3kam1a2kazaken2nak3rauak5tan2aktikak2t3r2aktstal1ageal3amealami5al3ampal1anaal1ansal1anza3lar_a3lareal2armal3arral1asial1assal3augal2b1lalb3lial2bohalb3rualds2ta4l1eha2l1eia2l1ela2lengal1epoal1erl3alermal1etaal1etha2l1eua4leur3a2lexal2glial1insa2linvalk1ar1alkohalk3s2alks4tal2labal2laual3les1allgäal2lobalo2gaal1opeal1orc3alpe_al3sklal3sunal4takal3tamal2treal2trial2troalt2seal1umbame2n1amer2aa2meriame3rua4mesh2a3mirami3taami3ti2ammalam2meiam2minam3stram2t1aam2t1äam4tel2amtemam2t3ram4treanadi3an1algan3dacande2san2dexand2suand1uran3e2can2ei_an3eifan1e4kan1ethanft5san3f2uang1ar3angeb2angiean2gla4angs_an2i3d3a4nima4ninsan2keian4klöank3ra3an3naann2aban3n2ea2n1orans2enan2seuan3skrans1pa1anspran3s2z1antei1anthran2tro2anwet1anzeian2zwiar3abtara3d2a2r3al2a2rara2r1auar2bauar2bec2arbenar2bre2arbs2ar2droar1effar1ehra2reinar2erfa2reria2rerlar1intar2kalar2knear2korar4kriark1s4ark3saark3shar2lesar2nana2r1oparr3hear3s2har3staar3t2ear2thear3t2iartin2art3rear2z1was1alaa3schea3schia2schma3schua3s2hiasin2gaska3sa3skopas3s2aas3s2eas3s2ias2s1pass3tias3stras3stu2as3taas4tauas4tofast3räaswa2s3a2sylat1apfa2tausat3eiga2teliate2ru4athe1atil4sati2st4atmusatra4tat3romat4setat2s1pat4takat4tauat2teiatz1eratz3t2at2z1w2au1a2au2bliau2bloauf1an2aufe_2aufehauf1er2aufs_2auft_4augehaule2sau2malau2m1oaum3p2aum3s6au3n4aau2nio2au3r2au2sauau2spraus3s22auts4ava3t4äche1eäch2späch4stä2d1iaäft4s3äg3str2äh3t4äl2l1aämi3enäne2n1äng3seän2k3län2s1cänse3häp2s1cä2r3a2ä2r1eiär1intär2k3lärt2s3äse3g2äser2iäskop2ä3s2kräs6s1cä4s3t2äß1erkä4t1a2ät2e1iätein2ät2s1iät2s1pät2s3täum4s52ä3us_backs4b1a2drbah2nuba2k1iba2krabal3th3b2andban2drba3n2eban4klban2kr2b1ansbar3deba2reibar2enbar3zwba3s2abau3sp3b2ä1cbbens2bb3lerbbru2cbe2delbe2erkbe1erlbe1etabei1f4bei3k4bei3labe1indbei3scbeis2ebei1stbeit2sbe3lasbe3lecbe3leibe2letbel3label3szbel3t4ben3arbe3nei3ben3gbe3n2iben2sebenst4ben2su2bentbb2entib1ents2bentwben3unben3z2ber3ambe2ranbere4sber3nab1erntbe2robbe3ropbe3rumbe3slobes2pobess4ebes3szbe2tapbe3thabien3sbi2ke_bi2kes2b1inb2b1infbin3gl2b1intbi2solbi2s5tb2it2abla3b4b2lancb2latt2b3law3ble2a2b3legb3lein3ble4nb3leseble3sz2blich3blickbling43blitzbo3ch2bo2e3ibon2debo1r2abo2reibo4rigbo4s3pbot2st2b3radb4ra3k2b3refb3reif2b3repbri2er2b3rolbrust3bru2thb2s1adb3sandb3sel_bse2n1b3s2esb2s1ofb3s2pubst3acbst1akbs3tätbst3erb2stipb4stodbs4trib4stübb2s1unbu2chibul2la2b3umkbu3r4ibus1erbu2sinbu2s1pbu2s1ubzeit1carri1ca3t4hcha2ck2ch1akch2anb3chancch1ang4chanz4char_1characha2sc3chato4chatuch1ärm3chef_3chefi3chefsch1eimcher3ach1ess2cheta1ch1iachi3na4chind2chinf2chinhch1insch1int1chiruch1offch1orcchre3s1chron2chunt2ck3an4ckeffck1ehe4ck1eick1entcke2rack2ereck1erhck2ern2ckero2ck1id2ckunt2ck1upcon2nec1s4trcussi43d2abäda2ben3d2ablda2bredab4rüdach3ada2chodach1sdal3b2d1amma2d1amt2d1ana2dangedan4kldan2kr2d1ans2dantwd2anz_4danzida2r3a2darb2dar2mada3s2hdat4e2da3teidate4n4d3atl4daush2d1ämt2d1änd2d1ängde3a2tde4ca_de2cka2d1eff2d1ehrdein2ddein2sdel1ändel1ec2delek2delem2delfmdelle2de2lopde3lordel5scdel2sodel3t4dem2ar2d1empden3th2dentwdera2bde1radde2rapder2bl2derdbderer33derieder3m2de4ruhde4rumde3sacdesa2gde4samdes2äcde2sebde4sehde2seide4setde2sinde2sordes3s2de2sto2d1etwde1urlde2xisdha1s4di3e2ddi3enidie2thdige4sdil2s52d1imb2d1ind2d1inf2d1inh2d1ins2d1intdion3sdi4re_di2rendi2ris2d1irl2d1isrdi4t3rdle2ra2d1o2fdo2mardo5n4adoni1e2d1opfdor2fädor2fldor2fr2d1orgdo2riedor2tadö2s1c3d4ra_2d3rad2drahm3d4ramd3rand2d3rät2d3räud4rea_d4reas3d4rehd4reiv4d3ren2d3rep4d3rer4dres_d4resc3d4ria2d5ricd5riegd4rin_3d4rit4dritu2d3rod2d3rot2d3rovdrö2s13d4ruc2d3ruh2d5rutd2sau2d2s1efds2eigd2serhds1errd3s2had2s1imds2infd3skuld2s1opds1orids1pasd2sprods3tabd4stagd4stead3steid4stemds4tilds4tipds1umsds2zend4theidtran2du1alvdu2bli2d1ufe2d1umb2d3umkd2ums_2d1umvdund2a2d1unfdun3kedun2kl2d1url2dursadwest3ea3dereadli4e3aleiealti2eat4e2eater1eat3s2e3au2feau1ste3b2akebert4eb3lereb4leue3blieeb3reiebs3paeb3staeb3strebu2t12e3cheech1eie2cho_e2ch3rech3taech1uheck3seede2aledens1edi4aled2s1oed2s1pee2choeed3s2ee2lekee3lenee4nage1e2pie1erbtee3r2eeere2see4reteer2öse1ertree3r2uee4tateewa4re2f1adef1anae2fente3f4lu2e3f2oef3reaef3rolef3romef2tanege2raeg4saleg4stoegung4eh1ache3h2aleh2auseh1eff1e2hepehe1raeh1inteh1lameh2linehl2seehr1a2eh2reiehre3seh1ro2ehr1obehr1ofeh1stee2hunt2ei3a2ei2bareibu4tei2choei2d1aei3danei3dra4eien33eifrüeig2er2eigew2eigrueik2arei3kauei2lareilen1eil3f41eilzuei2moreim2plei2n1aei4nasein3dr2einduei4nelei2neu2einfoein3g2e1initein4szei2sa4eis2peeis4thei1stoei2sumei2tabei2tanei2tarei2troeit3umek1s4tek5triel3abiel2abte2l1akel4amiel4ampel1ansel1anze2l1apel3ariel1asiel1aspel2ast3elbiseld3s22e3lebe2l1el1e2leme3lem_el1empel1erdel1erfel1erkel1erl2eles2el1esse2l1ideli2neel1itael3lanel5le_el3linell3spel1opee2l1orelo2riel2sumelte2kel2t3re2l1umel3useel2zwae2m1ad3emanze3m2ene2m1imemi5naem1intemi3tiemma3uem2meiem3pflem2spren4amee4nanden3angen3areen2ascen3atte3nauee2n1ären4ce_en2dalend3siend3szend2umen1e2ce2neffe4neine2n1elene4lee2nerfe4nerhe4nerk4enerne4nerz1engad3engagen3g2ien3gloeng3see2n1inen3k2üeno2mae2n1openost3en1ö2den3sacen2sauen2sebens2el1ensemensen1en3skaens2po2enstoent4agen2teb1entfa3entgaen2thi3entlaenü1ste1o2b1e3p2f41episo1e2pocep2tale3rad_er3admeraf4aera1frer3aicer3alleran3de3raneer3anfe2ranher3anmer3apfe3rarie2rathe3ratie2ratme1rauber3aueerau2fer3augerb4sper3chl2erdece3recher1effer1eige2reiner1ele2e3reme3renae3renz4erer_e4rerl4ererne3reroer1errer1erse2rerter1erwer1esser1eul4erfür1ergolergs4t1erhabe2riat4e3ric4e3rieer1inber1inker1inter1ita1erklä2erkreern1oser1o2ber3onye4ro2rer3smoert2aker2thoerts2eeruf4ser1u4mer1underung4er1unses2aches3anze3s2ases3cape3schaes3evaes2haresi1eres3intes2kates4loges2ortes2sau4essemessi2aes2sofes2spues3stres3stuest1ake1stare1state3stele1stile2stipes4trie2s1umes3umse4teinet3haleti2tae4t1ofetons4e2treset4riget2tabet2teiet2t3ret4troett3szetwa4retze4seu2esceu4glae3um2seum4sceums1peum3steu4neie3un2geu2nioeun3ka3eu3roeu1staeu1stoeu1stre2velae2vent1e2xeme2x1inex2tinfa2benfa2chof1aderfa3l2afal2klfal3tefalt2sfan2gr2f1ankf1an3zfar2br2f3arcfarr3s3f4art2f3arzfa3s4afa2to32f1auff1ausb2f1ärmfä2ßerfeatu42f1eckfe1inifek2tafe2l1afel2drfe2lesfe2l1ofen3safer2anfe2rauferde3fer2erf1erfaf2erl_f4erpaf2ers_fest1afest3r2f1etafe4tagfeu4ruf2f3efffe1inf3f4räff3shoffs4trfi2kinfik1o2fi2kobfi2lesfi4linfil2ipfin3sp2f1intfi2s5tfit1o2fi2tor3f4läc2f5läd2f3läu2f3leb3f6limfli4ne2f5lon1f4lop1f4lot1f4lug4f3orgfo3rinfor4stfor2thfor3tu2f1o2xf3rand1f4ränfreik2frein42f3ricf4risc1f4ronfro2nafs1allfs4ammf2s1asf2sauff2sausf2sautfs1e2bf2s1emf2s1erf2si2df2s1o2f3spanfs1penf3s2plf2sprefs2prif2sprofs2pruf2stasf3steif2stipf3st4rf2s1unf2t1alft1e2hft1eigft1eisf4theif2t3rof2t3röf3t4ruft4samft3s2cft4sehfts3elfts2tift1url2f1unffun2klfun2ko2f1unmfu4re_fus2safus2stfzu4gaga2b5l2ga2dr2g1amtgan2gagan2grg3anla3g2ano2g1armga3r2og1arti2g1arzgas3eiga2sorga4spega4sprgas4taga4ste2g1auf2g1autg2d1aug2d1erge3g2l2g1eifge2in_gein2sge2intgein2vgei3shgelb1rge5lehgell2age3lorgels2tgel3szge3lumge4namge4nargen1ebge3necgen3szgen3th2gentwge2rabger2erger3noge1r2öge3r2ug1erwag2e1s23ge3scges4pige3steges3thge3t2a2getapge3t4ugge2ne3g2het3g2hiegi3alogi2e1igie1stgi2me_gi4mesgi2met2g1indgin2ga2g1insgi3t2ag2lade2g1lag3glanz2gläuf2g3leb4g5lerg3lese3g2lid3g2lie3g2lit3g2loa3g2lobg3loch3g4lok3g2lop3g2lotgne2tr4g3notgoa3li2gonis2g1ope2g1opfg2o1ragra2bigra2bl2gradl2g3rah2g3rak2g3räu2g5re_2g3recg4re2eg3reit2g3ric2g3röh2g3rui2g3rum3g4rup2g3rüc3g4rüng3s2ahg4saltgs3amags3augg4s3cegs4chig4s3crg3sel_gs3elig3selngs5erkg4setags4pieg4spingsrat4g3stang3starg4s3täg5stämg3stelg1steugst2heg3stirgs3tocg4stolgs3topgst4rig4sturgs4tücgu1an_gu1antgu4d3r2g1u2fgu1ins2g1unfg2ung_gunge2g2un4s2gunt22g1urlgurt3sgu2s3agus2spgus2stha2choha2delha4dinh1adle2h2al_ha2lauhal2bahalb3rhal2lahal2sthand3shan2krh4a3rah1arm_h2armehar2thh1arti2ha3sahat5t2h1aukthau2sahau2sc2hautohau2trhä3usphe1choh1echthe3ckehe2e3lhe2fanhe2f3lhe3friheim3phei4muheine2h1einkhe1ismhe1isthel1eche3lenhe4lof4h1emphend2she2nethenst2hen5trh1entshe2ral2heraphe3rasherb4she2relh1erfüh1erkeher3thher2zwhe1stahe2tapheter2he3t4she1x4ahfell1hi2angh1i4dihi3enshier1ihiers2hil2frh1induhin2enhi3n2ihin3n2hin3s22hi3rehl1anzh1lauth5len_hlen3ghl2ennhle2rahl1erghl1erwh4lerzh4lesihl1indh3listhlo2reh3losihl2sanhl2serhl3skuhl3slohme1inhmen2shme2rahn3eighn3einhne4n1hne4pfh3nerlh3nerzhn3s2khn1unfho2ch3ho2ckahock3tho2f3rhol1au4holdyhol3g4ho4lor3hol3sh1o2lyho2mecho2medho4seihotli42ho2w1h1raneh3rechh4rei_h3reich3r2enhr2erghr2erkhr2ermhr2erzh4rickh4rineh4rinhh4risth4romeh4romihr2sauhr2serhr4sethr2tabhr2tanhr2torhrt3rihr2trohrt2sahrt2sehr1umsh2s1ech3s2exh2s1ofhs2porh2spräh2sprohst2anh1stechst2heh1s2tih2storh1s4trhst3rih1stunhs2ungh3t2alht3aneh3tankh4tasyht3a2tht1e2ch2t1efhte2heh2teifh2temph2t1euh2t1exh4theihthe3uh2t1inh2tolyh2torgh4trefh2t3ruh2t3rühts2tihu2b1ahu2b3lhu4b3rhu2h1ahu2h1ihuk3t4hu2l3ahu2lerhu2lethu3m2ahung4shu3ni1hus4sahus2sphu2tabhu3t2hhühne4h2wallh1weibhy2pe_i4a3g2ia2l1ai3aleiial3laia2lorial3t4ial3z2ia2nali3and2ia3p2fi2a3spi3a4tai3at4hib2blii2beigi2beisibela2iben3aib3renib4stei2bunki2buntibu2s1ich1eii2chini3chloi2ch3ri3ck2eid2ab4i2d1au1i2deeidel2äide3soide3sp1i2dio1idol_i3d2scid2s1pie2breie2choie2fauief3f4ie2f3lie2froie4g5lie3g4nie2g3riegs3cie3lasiel3auiel1ecielo4biel3sziel3taiena2bi3e2näien1ebie3neri3en3gi3e2noien3scien3siiens2kien3szier3a2ie2rapie3resi3ereuierin3ier3k2i3ern_iers2tier3teies2spie1staie2t1aie4t1oie2triiet2seiet3zwifens2if1ergif1erhi1f4lai1frauif4reii1f4rüif2topift3szig2absig1artiga1s4ige4naig1erzi2g1imig3reiig4salig3sprig4stoig4stöig3strig3stüigung4i2h1ami2h1umi4i3a4ik1amtik1anzik1artik3atti2k1aui2k1eiike2l1ik1erfi2kindi3k4läi2k3raik2trei2l3abi2l1acil1a2di2l1akil1ansil1aspi2l1auil3ausild2eril2doril1e2cil1eheil1einil2f3lilf4s3ilie4ni2l1ipi3lip_i3lipsil3l2ail3l2iil2makil2mauil2mini2l1oril3t2hilung4i2manwima2tri2melei2melfi4meshi2metiim2meiim1orgim3pseim3staimt3s2in3a2ci4nacki2n1adin2arain2arsin4arti2n3auin2dalin2dan1indexind4riin3drü1indusin1ehein2erhi4neskine3un1info_1infosing1af1inhab2inhar2inhauin2i3dini3krini3sei3nitzin2nor1inntain3olsino1s4in1ö2dins2aminsch2in2seb2insenin3skr1insta1insufin3s2z1integin3t4rin5trii3n2umin3unzinvil4io2i3dio2naui3ons3ion4stiore4nipi3elipi3en1i2rakir2k3lirli4nir2makir2mauir2mumir2narirpla4irt2stiru2s1isage2is3arei2s1äni2schmi2s3crise3haise3hiise2n1is2endisen3si2serhiser2uis2hasi2s1idi2s1of3i2soti2sparis1picis2pitis2pori2sprois4sauis3stais3stoiss3tris3stuis2sumis4tabis4tamist2anis4teliste4nistes3is4tocis5törist4raist3reisum3piß1ersit1ab_ital1ait1altit2an_it1arti3tauci4t1axi2t1äsi2t1eii4teigit2eili4teinite2lai4tepoi2t1idit2innitmen2i2t1ofit3rafit3rasit3rauit3räuit3ricit3romit4ronit3runit2stoit2tebit4triitt2spi2t1umi2tunsit1urgitzes4it2z1wi2v1akiv1angi2v1eiiv1elti2v1urizei3ci2z1irjahr4sja3l2ajean2sjek2trje4s3tje2t1aje2t3hje2t3rjet3s2jugen2jut2e1kab2blka2ben2kabla2kabläka3b4r2k1abt2k3adaka1f4lkaf3t2kaken42kala_ka2lanka3leikal2kakal2krkal4trkan2alka2nau2kanda2k1angk2ans_k2anz_2k1apfka3r2i2k1armk2arp3kar2pfk2artaka2s3tka3tanka3t4hka4t3r4kaufrkau3t22kautok1ä2mikä2s1ckdamp22k1e1cke2he_kehr2s2k1eic2k1eig2keinhkel1acke3lagkel3b4ke2lenke2lerkell4e2k1empken3au2kenläkens2kken3szk2enteken3thk2entrk2entu2kentwke1radk2erkok1e2rok2ers_ke2selke4t1ake2t3h2k1e2xki1f4lki1f4r2k1intkis4to4k1lack4leidk3lem_2k3lerkle2ra2k3leukle3usk2lisc2klistklit2s2k3locklo2i3klost4klung42k1lüc2k5nerkno4bl2k5norkoh3lukol2k5ko3n2ekon3s4ko1r2a2k1orckot3s22k3radk3rats2kraum2k3rät2k3rec2kred_2k3refk3reick3reih2k3rick3ries3k4ronks1e2bk2s1emk2sentks1erlk2s1idk2s1ink2s1o2ks2pork1s2tik2stork2sträk2stumks2zenk2t1adkt1aktkta4rek2t1auk2tempk2tentkte3ruk2t1idkt1insk2t1ofkt1opekt4rankt3rask4trefktro1skt3runk2tuns2k1uhrku3l2eku3l2i2k3umlkum2s1kun4s4kunst32k1up_kur2blku2reikuri2ekur2spkur2stlab4ralab4ri2l3absla2ce_la2gio2la1hola2kesla2k1ila1k4lla3min1lammf2l1amtlamt4sla4munl1analla2nau3l2andlan2gl2lanhäl2anhe4lanli2l3ann4lansä2lantrlan2zwlap4pll3artila2saulast1ola4tel2l3athl2auf_lau2fol2aufz2lausl2lausr2lauto2l1ähnlä2s1cl4betal2b1idlb2latl4bre_lb3ritlbst3elb4stol2b3uflbzei2l3d2acl2d1akld1amml2da2rld3arild1arml2delel3der_ld1erpl2d1idl2d1iml2dranl3d4rul2d1umle2chile2gau3l2ei_lei2br4l1eigl2ein_l2eindl2eine2leinkl2eintl4eistlei2talekt2a2lektr3l2ela3lemesle4nad2lendul2e2nolen3szl1ents4lentzlen2zil2e1rale2ragle2raul1erfol2erfrl2erfül2erkal2erkol2erlel4ers_lers2klers2tl2ert_l2ertel2erzales2amle3serleste3le1stole2tat2le3thlet4tule3u2f2leurole2xislfang3l2f1ecl4feisl3f4läl3f4lulf3ramlgen2alge3ral2getilian2gli3chili2ckali3d2ali2deo2l1idolid3scli3enelien3slie2stli2grelik2spli3m2ali3n2alin3alli2nefli2nehli2nepli2nes2l1inflings52l1inh2l1injlink2sli2noll2ins_l2insal2insc2linsp2linst2l1intli3os_li2p3ali3s2a2l1islli2tallit1s2lit3szlizei3lk1alpl3k2anl3kar_lken3tl3k4lul2k3rol2k3rulk4ställ1abbl2labtll1affll1aktl3l2alll3amall2anwll1anzll1armll3augl2lausl2l1ämll1echlle3enl2l1efll1eiml3len_llen3gl3ler_lle2ral2lerzll1imbll1impll1insl2lobel2l1ofll1opfl3lor_l3lorel2l1oul2l3öfll3s2kll2sprllti2mllt5s2l2marclm1auslm1indlm1inslm3stelm3s2zln3are3l2ob_lo2berlob4ril1o2felo2gaulo3h2e2l1ohrlo2k3rl1o2lylo2minlo2n1olo3renlo4skelo2speloss2elo4stelo3thalo3thiloti4o2l3öfelpe2n3l2p1holrat4sl3s2all2sannl3sarel2s1ecl2s1emls1erels1ergl2serhls1erlls2logl3s2pil2sprol3s2pulstab6ls4tafl3stecl3steil3stell4stemls2tiel2stitls2zenlt1a2mlt3andlt1angl3tarblt1artl2t1aultbau1lt3elil5ten_lter3alt2erglt4erölte2thl2t1eul4theiltimo4l2t1ofl4t3ötltra3llt3räult4rielt3roclt3rosl2t3röl2t1umltu2ri4lu4b32l1ufelu2g1alu4g3llu2g3rlug3salug3splu1id_2l1una2l1unf2l1unilu2s1ulu2t1alu4teglu2toplu4t3rl2z3acl3z2anlz2erklz1indlz2wecm2ab4rma2d4rma4d2sma2ge_ma2gebma2gefma2gegma2gekma2gepma2getma2gevma2gew2m1aggma3g4n2m1agomai4se2m1aktmal1akma2lanma2lauma3lermali1emal3lo2malltma2nauman3d2ma2net2mansa2mansä2mansc2mantwmar3g2maro3dma3r2uma2tanma2telma5trimat3semat3sp2mausg4m1ändmä3t4rm2d1ummedie4mee2n12m1eif2m1eig3meistme3lamme2laume2lekme2lermelet42melf_mel2semel5t4mena2bme3nalmen3armen3aumen3glme3normen4skmen2somen3ta2mentnmer2er3merinme2sal4meser2me3shmes2stmeste2me1stome3t2amie3drmi2e1imien3smie2romie4timi2karmi3l2amilch1mild4s2m1impmin2enmin2eumin2ga3min2omi2t1rmit3s2mit5sami5tsumi2t1umk5re_m2m1akm2m1almm1angmm1anzm2m1aumme4namme2samm1inbmm1infmm1inhmm1insmm1intmmi3scmm3stamm3strmmüll1m4nesimode3smo2galmo2k1lmon2s3mon3su2m1opemo2rar2m1orcmor2drmo2rermos4tampf3limpf1ormp3strms3andm4s1efms1erwms1inims1orim2spedm2spotm2sprom4stagm3stelm3s2tims5träm3s2tumt3aremt1eltm2t1eum2t1immtmen2m2t3romt2sprmt1urtmu3cke4m3unfmu4s1amu2s1omut1aumut2stmvoll14n3absna2ch1nach3s4na2drna1f4rna2gemna2h1a3n2aldna2letnal3lanalmo2na2lopnal2phn2als_nal3t4n4amenna3m4n2n1amtnamt4sn1and24n1ang2n1ans2nantrnap2sina2r1an2arle4n3artna3r2unasyl2na3t4hnat4sanat4sc3n2aul4nausb4nausgn2auso4nauss4nausw2n1ä2mnär4s53nä1umnbe2inn2d1akn2danlnd1annnde2sendi2a3ndo2ben2d3ren2drobnd3rolnd3rosn2druind2sornd2spr2n1ebnne3ein4n1ehr3neigtnek3t42n1ele5neleb4nelek4nelemne3lennel4la3ne3lu2n1embn1e2mi2n3emp2n1emsnen3a2n1endgnen3einenen14nengb4nengs4nengtnens4enen3skn1entb4nentn5nentrn1ents4nentzne2n3u2n1epone2posne2ranne2rapne2raun1erbine2reb2nerfü3nergrn2erlin1ermän2ern_ne1rösn2ert_n1ertrne2rup2n1erzne3sanne3skane2s1pne1stanes3tine2tadne2tapn1etatne2taunet3han1e2tunet2zi2n1eupnfalt4nf5linnft4s3ng2absn2g1acn2g1akng2anfng1anzn2g1äln3g2enngen2an3gläsn2glicngrab6ng3ratng3rocngs3panich1s3n2id_nie4n3ni3eneni1eronifes3ni2grenig4spni2kalni2karni3ker4n1imp3n2in_n2in4a4n3ind4n1inhni2nor2n1insn2ins_4ninse4n1int2n1invni2s1eni3se_ni2s1pni3spinis3s4ni2s1uni3t4rni3tscnitts1n2k3adn2k1akn3k2aln2kansn2kausn2k1ärnk4ergnk1inhnk3lennk3lesn2klienk3lunn2k3ronks2eink3s2znk2taknk2tannkt1itnk4topnk2trunmen2snna2ben2nadan2n1annnen3gnn2erhnn2erknne2rönner2znnes1enne4stnn1o2rnn3s2pn2n1ufno2blano2leu3n2opano2radno1rakno3ral3n2os_no2s3pn2ostenost1r2nostvno3tabno2telno3t3hno4thano4thi2n1o2x4n1ö4lnräu3snre3sznrö2s1n2sangn2santn2sausn2s1änns1e2dns1entn2s1epns1erfns1ergn2serhns1ersnsfi4lnsho2fn2simpnsi4tensi2trns2kaln2s1opn4spatn3s2pins4piens3ponn4sprän4spronst1akn3starn3statns4tornstü1bn2s1unns2ungns4unrns4unsn4s3zint3absn3t2alnt1angnt2arbnt1arknt2armn2t1äunte3aunt1ebente3g6n2teignt4enent4ernnt4ersnt4ertnt2hern2t3hon3t4hunti3kln2tinfntini1nt2insn3ti1tnt4lemntmen2nto3ment3recn5trepnt4rign5tropn2t3rünt4saunt2sto3n4tu_ntu2ra2n3umb2n1ums2n3umz3nung_n3ungl2n1uninu4t3rn2z1aun2z1ännzdi1snzi2ganzig4snz1inin2zurkn2z1wan2z1wän2z1wuoa3cheoa3chioa4k1lo4a3lao4a3mi3oa3seo3b2al2o3b2äob3ein2o3b2iob3iteo2b3li2o3bloo2b3reob3s2hob2staocha2boche4boch1eioch3ö2och3teochu2fo2ckarock2erock3szodein3ode2n1odene4ode3sp2o3diaof1a2co2f1eiof2f1a1offizof2f5lof2f3r2o1f1rof4samof2speof2sprof2s1uof2teio2g1abog1alaog1ango2g1eiogi2erog1steohen3sohl3auoh3lecohl1eioh3lemoh3lenoh3lepohls2eoh2n1ooho2laoh1o2poh4rinoimmu4oka2laokale43o2kelok2s1po2l1akolars2ol1aufol4damol1eieol1eisol2fraoli3k4ol2kreol2lakol2lelolo3p2ol1ortol2strol2z1aol2zinom2anwom1arto2m1auo2m1eio3men_o2meruom1erzomiet1om1ingom1orgo4munto2narbon3ausone2n3onens2on1erbon1ergon1eröo3netton3g2lon2i3do4nikro4n1imon3ingonlo2con3n2eo2nokeon1orconsa2gon4samon2sebonse2lonst2hon3t2aoo2k3lo2p3adop3aktopa2leo1pe4nop2f3aop3fahopf3laop1flüopi5a4op5lago2p3le1op3t4or3a2bor4altor2ando2ranhor3arbor3attor1ändor2baror2dauor2deuor2ditor2dumore4aso2r1efor1eigo2reino2rerfor1ethor2fleorf3s42orgetor3g2h2orgiaorgi1eor3gle2o3ric4orie_o3rier4orin1or5ne_or3s4aor2täror2tefor2theor2torort3reo4r3un2o3s2ao3scheo2s1eio3s2hi2os2kl2os2koos3peco3s2poos2seios2s3oos4sonos2s3pos2s3tost1auos4teios2t3hos3tilost3räost3reost3ufo3s2zeo2ß1elota2goo5tarko3tarto2t1auot3augotei4not4em3otemp2ot5helo2t3hiot3hosot1opfoto2rao2t3reot3rinot4spaots2peot2sprot2t3rot4triou1f4lou4le_o3undsou3s2ioviso3owe2r11o2xidöbe2laöbe4liöh3l2eöl2k3löl2naröl2ungönizi1öp4s3tö2r3ecö2r1eiör2ergö2rerlör2f3lö2r1imörner2ör3s2kö2schaö2schlö2schwö2s1eiös2s1cöte4n3pa1f4rpa1k4lpak2topala3tpa2narpa3neipa2neu1pa2nopan3slpa5regpa5rek1park_par2klpar2kr1partn1partypar3z2pa3s2ppat4e2pa5t4rpa3unipä3ckepä2t3hpät3s4pekt4spe2letpe2lexpell2apell4epen3dape4nenpe2n1o3pensi1pensupen3z2per2anper4nape2robperwa4pes3s2p2f1akpf1ansp2fa4rpf3arepf3armp2f1au4p3fe_pf1eimpf1einp3fen_p2fentp3fer_pf2erwp3f2esp2f3läpf3leipf3lie2p1heiphen3dphen3sphi2ka2phthepi3as_pi3chlpiela2ping3s3pinsepi3onupi4pel3pirinpi3t2aplan3gpo2laupo4lorpo1o2bpo1ralpo1raupo4stapo4stäpo2stopos6trpo2t1upp3anlppe2n1p2p1f4p3p2hopp5lanp2p3rap2p3repre2e13preis2p3rer3p4res1prinz2prosspro1stp3steap3stelp3s2tipt3albp4t3ecp4t1eip4telept1in1pto3mept1urspul2sppu2s3t2r3aacra2barrab2blr2aber1r4abi2r3abwra2chura2dam2radapraf3arra2ferra3gle3r2ahmrail4l2r3airra2krera2kro2raktira2la2ral3abr3alar3r4aldral3larall2e2rallgr3alp_2ralper3al3trama3srambi2ra2mer1r2ami2r1amtramt4sr4andar4anderand3sr4aner1rangirani1eran2kr2r1anm2r1anpr2ans_r2ansp2rantr2r3anw3rareirar3f42r3arz2rato_rat2st3raub_rau2mi3rausc2rausgrau2spraut5srä2s1c3rätser2b1abrbal3arba3rerb1artrb1aufrb1echr4belärb1entr3b2larbla2dr2ble_rb3lerrb2linrb4seirb3skarb4stärb3strr1che_r1chenrch1s2rch3sprch3tar3d2acr2d1akr2d1alrdani1rd1antrd1anzrd2ei_rden3drde3rerde3sprdi3a2rdia4lrdo2berd3ratre2altre3at_re3atsre2b1are2b1lreb3ra4rechs2reck_2recki2reditre2hacre2h1ire2h1orei4bl4reifrrei3gareim2p4reingr3eink4reinr4re2ke2r1elbre3lei2r1elf2r1elt4rempfrena2bre3nal3rendiren3drren4gl2rengp2rengsr1ense2rentw3r4er_2r1erbr2erbr2r1erdr2erenr2erki2rerlö2r1ermre2robr2erse2rerspr2erte2rertr2r1erzrer5zer2erzy3r4es_ress2ere1stare2thyreu3g2re3uni2r1eurrewa4rrf1ältr2fentrf3licrf3linrf2s1ärf2s3trf3t4rr2g1ahr2g1akrge4anrge2blr2getor2glanr2gleur2g1obr2gregr2gresr2gretrg3rinrgs4tr3r4he_3r4henrho2i3rib2blri1cha2ridolrie2frriene4rien3srie2nuri1er_ri4ereri2f1ari2ferri2f1orim4scr2i3na2r1indri3n4erine1i2r1infrin2foring3lrin2gr2r1inh2rinitr1innu2r1insrin4sorin2sp2r1inv3risikri4s1pri3t2irit2trr3klaur2klisrk5nebr2k5nurk3räurk3rinrk2s1erk3shirk2tinrk2t3rrk3trark4trirk1unirlös3srl2s1prl3ster3m2agrma2larm1ansrm1anzrm1a2pr2maphr2m1efr2mider2m1imrm3starm3umsrn2andrn3anirn2a2rrn3arern3arirn3eifr4nerfr4nerkr4n1inr2n1opr2n1orrn3s2ärn3s2prn3s2zrn3t2ero2bei3rock_r2o3deroh3na3r2ohrro2madro2mer4ro1nyror3alro2ratro2reiro2r1oror3thro3s2iro3smoro3starost1rro4tagrote3iro2thoro4trirots2orot2taro3t2uro3untrö2b3lrpe2rerrer4srre2strr2n3ar2r3obrr3stur4samprs3anprs3antrsch2lr3schur3schwr2seinrse2n1rs2endrse4ners1erers1erörs1ersrs1erzrs1etars2kalrs2kanrs2kiers2kisr4s1opr4sordr2s3phrs2tecr3stier2stinr2stiprs4tobr4stotr3s4trr3s4türtals1rt1angrt1annrt1antrt1anzr2t1arrte1e2rt4eifr2telfr2temort1ersrt3holrt2humr2t1idr2tinfrto2rirt3recrt3rosrtrü2crt2spart2sprru2ckurude2aruf2s32r1uhrru1insru2m3ar2ums_2r1unar2unde2r1unf2runglrun2kr2r1unl2r1unm4r3untru2r1erus4stru3staru4teiru2t3rrü1benrwun3srz1a2cr5zenerz1engr3z2ofrzug2u3sabetsa3blesach3t2s1ada2s3affsa1f4r3s2al_sal2se2s1alt3s2alz4s1amnsam2tos2an2cs4and_3sang_2s3anh2s3anl2s3anssan4sk2s3anw3s4ar_3s2ara4s3arb3s2ard3s2ars4sartisa4ru24s3ath4s3atlsauri1s3ausw2s1änd3sänge2schak2schao3sche_2schefsch2en3sches4schexschi4es4chim3schis2schmö2schn_2schoxschs2e4sch3tscht2ascht4rsch2up3s4cop3sco4rsda3mese3at_s1echtsee3igseein2se1er_se1erö2s1effse2galse4helse2hinseh3rese2hüb2s1ei_2s1eie2s1eig2seinb4seing2seinh4seink2seinl2seinn4seinr2seinw4s1eis3s2eitse2l1ase3ladsela2gse3lamsel1ec4selem2self_s3elixse2l3ösel3szsel3trs4e3ma2s1emp3s2en_se4nagsen3gl3s2enise4nob3s2enss2ent_s2enti2sentw2sentzse2n3use5refser2ers2erfrs3erfüs2ergr2serhöse2robs2ers_2sersas4ert_s2ertase3rum3s4ervse2selse1stase2tatse1u2n3s2ha_4s3hansho4resi2achsi3enesi1errsi3gnusi2g3rsig4stsi2k1äsik3t42s1immsi3n4a2s1ind2s1infsing1asin3ghsin2gr4s1inhsini1e2s1inq2s1ins2s1int4s1invsi2s1esi2s1osi2s1psi2tausi2tra3skala4skanz3s2ki_3s2kik3skulpsla2vesler3s3s4lipsli4tuslo3be4s5not2s1o2bs1o2he4sohng2s1ohr4so2lyson3auson3säso1ral2s3ordso2rei4s1ostso3unt2s1ö2l2spala2spara4sparo3sparuspe3p4s1peri2sperl2speros2perr4spers3s2pez4spi4p3s2plis3p4lu4s3poss2potts2pracs2pran4sprax2spräm4spräs2spred2spres2sprob4sprüfsrat2ssrö2s1ssa3bos2sanos4sansss2antss3attsse3hass1erös3s2essse3tass1offs2s1opss1oris2spros3stelss4tipss2turss1ums2stabb3s4tad3staff2stale2stalkst1almst1alpst1ami4stan_sta4na3stand2stani2stans2stanws4tar_4staris4tarsst1asis3tat_2stauf2staum3staur2staus4stälts4tänd5stätts3täus4s5te_3s2tegste2gr3s4tehs2te2i3steig4steil1s2tel2stel_2steln2stels4stem_s5ten_st4ens4stermste4sts4teti3s2teu1steue4steufs2t3ho2stie_s2tiegs2tiel2stien3s2tif3s4tims4tinfs3tinnst1ins1stitu2sto3d4stod_s4toffs4t3om2stopo2stor_2store2storg2storis3tort2stose4stote2stöch2strad2strag4strai4strak2stral5straß2strua2strug3struk2strup2st3t43s4tud2stumt2stun_4stunn2stuntstu3rest3url2sturn2s3tus2stüch2stür_2stüre2stürg2stürs3s2tyl3su2b3su2cha2s1u2fsu1it_su2marsu2mau3s2umesu2mels3umfesum1o2su2mors3umsas3umst2s1uni2s1urlsüden24s3zeis2zena4szent4s3zet2ß1e2gße2l1aß2ers_2ßerseßge2bl2t1abb3tabel2taben3table2t3abn2t3abtta3d2s3taf2et1af4rta2ga24ta3gltag4sttah3leta3i2kta1insta1ir_t1a2kata2krotak6ta3taktb3t2al_ta3lagta3lakt1alb_t1albk3t4aletal2löta2mert1amplt1a2na4t2andt3ankl2tanwa2tanwät2anz_t1anzat1anzuta2pe_ta2pes2t1armt1artitar2to2t1arz4t1aspta2tanta2tautat3eita2temtat3heta2tom4tatue2t1auf4taufg4taufnt1ausb3tausct2auset1ausk4tausltaxi1s2t1ältt1ängs3t4ebbte3cha3technteck2ete2ckite2en3te1erwteg3ret3eifr2t1ein4teinf4teinnt3eis_t3eisb3te3letel1eb2telemtel1ente4leute2littell2ete2l1ö3telt4tel3tatel3thte2min2temme2tempfte4m1utena2bte4naste4nauten3dat6endit6endote2nefte2nettens2et4entat3entb4tentdt4ente4tentnten3zwt3e2pi3t4er_tera2bte1rafter3am4terbs4terbtte2relt4erfrte3ria3termi2ternct4ers_terst4ter3zatesa2cte2santesä2cte2selte2sprtes3s2te2tat3teur_2t1exz3t4ha_3thal_4t3hau1t2he_2t3heit4heint4henet4heni2therr3these2t3hil2t3himth4mag2t3hoc2t3hoht4hol_2t3hot1th2r2ti3a2mtiden2ti2deo3tief_3ti2erti2kamti2karti2kinti2kräti2larti2leiti2lel4t1imp3t2in_4t1indti3n2eting3lting3s2t1inj2t1int4t1invti2seiti1sta2ti3tuti2vanti2velti2v1oti2v3rtlung4tnes4s3tochtto4d1utom1e2to2mento2nauto2nehto2pakto2patto2rauto4ränto2relt3orga3torint1ort_3tost4to1sta3to3teto2thotouil44tractt3rad_6trahm5t4rai2trand3trankt3rann3transt3raset3rasi3träne4t5re_tre2brt3recht4reck6t3red5t4ree4trefe4trefot4rei_4treic2treift3reigt3reint3reis6treitt3reiz6t3relt4ren_3trendt3rent2trepe2trepot4reprt4res_3treuh5trieb2triegtri4er5triggt3rind4tringtri3ni4trinn4tripttrizi13t4roitro2ke4trom_tro2mi4troml2t3roo3tropf2t3röttrums15t4ruptru2thtrü1betrü1bu2t3rüct4sa4bt3s2act2s1aht4s3art2s1änts4cort3seiltse2n1t2s1erts1init2s1irt1slalt3spalts1parts2pedt3spekt3s2pit4stagts3takts4talt2stipt4stitts3tocts3tort2strits3türtta2bet2t1adtt2anttt1arttt1ebett1eiftt1eistte2lattel1otte2satte2sätt2häut2t3hott4roctt2sentt2sortt2spett2sprtt2stitu1almtu2chitu3fent3u2kr3t2ume2t3umf2t3umg2t3umk2t3umrtum2situm2so2t3umt2t3umz2t1una2t1und2t3unft3unga2tunif2t3unttu2re_tu2reitu2resturin1tück2s3tür3s3tütentze4n1tz2enetz1erltze2rotz2erst3ze2stzgel2tz1indtz1inttz2tinua2lauu3aletual2mau3a2louara2bu2be2cub3licu2b3luub2sanub2s1oub2spau1cha_uch1eiu3chesuch1iluch1inu2ch3ruch2souchst4u2ckemuder2eudert4udi3enuditi4ue2neruenge4uen2zuue2r3aue2r1äu3erehu3ereru3erexuer3g2uer2neue2r3ouer3scuer3t2u3erumue4teku2f1äsu2f1eiu2f1emu3fen_u2fentuf2ernuf2frouf1oriuf4sinuf2spouft3s2u2g1apu2g1eiug3ladu3g2löug4serug3spaug4sprug4spuug5stäug3strug3stüuhe3s6uh2reruh4rinuisi4nui4s5tukle1iuk2t3ruld2seu2l1elul1erful1erhul1erwule2saul1etaul1insul2lesul2p1hul4samuls2thul4trium1allum1anzu2maut1um3d2umer2aum1ins3umsatum4serum2simu2m1uru3n2amu2n3an2un2asun4dabun4deiun2didun2dorun2d3r4unds_und3spund3stun2ei_un3einunen2tun4es41unget1ungew1unglüun2g1rung3raung3riung4saun3ide1u2nifun3islu3n2it3u2nivun2keiun3n2eunvol2u1or3cu2pf2eu2pf1iu3rabaura2beur2anbur2anhu2r1auur3b2aur1effu2releu4r1epur1erhur1erwur2griurg3s4ur1iniur3insur1int1urlauur3sacur2sanur2sauur2serur4sinurst4rur2z1wus4annu2s1ecu2s1eiu3seiduse1rau2serpu2s1opu2spatus1picus2porus4sezus2sofu1stalus3tauust2inu2stunu2sturut1altut3a2mu2t1apu2t1arute4geut1ei_ut1eieutel1eute2n1u2tentu4t1exu2t3hout1opfu2topsut3reaut3s2aut2s1äut2spaut5t4lutu4reutu5ruut2z1wuve3räüb2s3tücht4eü3ckenück1erü3den_üden4güdwes2ü2f1eiü2h1eiühl1acüh3r2eühr3taü2mentün2fliün2g3lün3strü2r1eiü3r2o1ü2schlüs2s1cü2t1alva2teiva2t3hvatik2va2t3rvat3s4va2t1uveits32ve3muve3nalve3radve3rasver3b2ve4rekve4rinver3stver5te2ve3scves3tivi4a3tvie2w1vi2l1avi4leh2v1i2m2v1intvi3s2ovoll1avol2livo5rigv1steuwab2blwa3chewaffe2wa2g3nwah2liwal4dawal2tawal2towang4s1war2eware1iwart4ewass4e4webebwe2g1awe2g3lwe2g3rweg3s4wei4blwei2gawei3k4wei4trwel2t1wel4trwen3a4we2r3awer2bl1werbu1werduwerer2wer2fl1werk_wer2ka1werkewer2klwer2kuwer2tawer2to1wertswe2s1pwest1awes2thwest3rwes4tuwett3swi3ckawien2ewie2stwim2mawin2drwi3s2e1witzlwo2chawoche4woh2lewo2r3iwo4r3uwört2hwul3sewur2fa1wurstwus3te1wu4t1xe3lei3x2em_xen3s2x1i2doxin3s2xi2so2xis4täx1i2tuxtblo4x2t1eix4tentx2t3evy3chisyloni1y2p1iny1s4tyy2s1u22z3a2b2z3a2k2z1all2z3anf2z3anlz1artizar2tr2z1arzza1st42z3at3z1au2fzbübe32zecho2z1eck2z1effzei3lazeile42z1einzei3s4zeist4zei2trze2lenzell2azel3sz2z1empzens2ezent3sze2r3a2zerhöz2erl_2zerlö2z1erq2z1erzze3skuzes2spzes2stze2s3tze3sta2zettszger2azi3alozi1erhziers1zi1es_2z1impzin4er2z1inf2z1inhzin1itzin2sa2z1invzirk6szi3s2zzi1t2hzor4ne2z1oszz2t1auz4tehezt1inszt3reczu3ckezug1un2z1uhr2z1um_zumen22z1umszup2fizu3r2a2z1url2z1urs2z1urtz2wangz2weigz1weis2z1wel2z1wen2z1werz2werg2z1weszzi1s4", - 7: "_al4tei_amt4s3_and4ri_an3gli_angst3_an4si__an4tag_ausch3_be3erb_be3r2e_berg3a_bo4s3k_bu4ser_da4rin_da4te__da4tes_de4in__dien4e_ebe2r1_en2d3r_en4tei_er4dan_er4dar_er4dei_er4der_es5t4e_fer4no_fi3est_fi4le__fi4len_ge5nar_ge3r2a_ge3r2e_ger4in_hau2t1_her3an_ho4met_ima4ge_ka2b5l_li4ve__lo3ver_lus4tr_men3t4_orts3e_pa4r1e_reb3s2_re3cha_rein4t_reli3e_res6tr_sali3e_sim3p4_sto4re_tage4s_ti4me__ti4mes_to4nin_tri3es_ul4mei_urin4s_ur3o2m_ve5n2e_wei4ta_wor4tu_zin4stab1er2raber4ziaber4zoab3essea4cherfa4cherka4cheröach1o2bach2t1oach1u2fa3d2ar3ade1r2aade3s2pade5str2ad3recaf4t5reage4neba4gentuage4ralage4selage2s3pag3esseags4toca2h1erhah4l1eiahner4eahre4s3ahr6tria3isch_ajekt4o1a2k4adak5t4riala5ch2a2l1angalb3einalb3eisal4berh3a2l1efa4l3einal3endsa2l1erfa2l1erha2l1ert3a2lerza2l1eskali4eneali4nalal3lenda2l1o2balt3eigalt3ricalt4stüalzer4zamen4seamp2fa2am4schlana4lin2ana1s4and4artandel4san2d3rüand4sasand3stean2f5laan2g1eian4gerwan2g3raan2k1anan2k3noan2k3rä3antennan3t4heant3rina3ra3lia2r1anga2r1ansa2r1anza2r3appar2b3unaren4seare3r2aa2r1erhar2f3raari3e4nari3erdari3ergarin3itark3amtar2k1arark3aueark3lagark4trear4merkar3m2ora2r1o2dar2r3adarre4n3ar4schla4schecasch3laa2s3e2ma2s1o2fas4s3eia1s4tasas6t3rea2t1aktater3s2ato4mana2t1ortat4schnatt3angat3t4häat2t3räat4zerkat4zerwat2z1inau2b1alauch3taau4ferkaup4terau2s1ahau4schmau4schoaus3erp3aussagaus4se_aus5triau2t1äuä3isch_äl4schlän3n4e2ä2r1eneär4mentäser4eiäse4renäskopf3ät4schlät4schräu4schmäus2s1cba2k1erban2k1aba2r1ambau3s2k2b1eierbei4ge_2b1eimebe1in2hbe2l1enben3dorben4spaben4sprben5t4rber4ei_be4rerkber4in_ber3issbe2s1erb3esst_be3s4ze4b1illubis2s1cb2i3tusbjek4to2b3leidbo2l1anbor2d1ibor2d3rbor2t3rbra1st42b3rat_2b3riemb4schanb6schefb4s1erfb4s1ersbst1a2bb2s3träbs3treubtast3rbu4schlbu4schmbu4schwbügel3eca3s2a3ch3a2bich3anst3chartache4fer4chelemche4ler4chents4chentwche3rei2ch1e4x3chines2ch1invch3leinch4sper2ch1unf4ckense4ckentw4ckerhö4ckerke2ck1err4ckerze2ck1eseck4stro2ck1um3com4te_comtes4cre4mes2d1alar2d1ammädan4ce_dan5kladan2k1odar2m1i2d1au2f2d1aus3delei4gde3leindel4lebdel4leide2l1obdel4sandel2s5edel2s1p4denergden4sende2re2bde4reckder3ediderer4tderin4f4derklä4derneuder3taudert4rades3eltde2sen1de4stredes4tumdeten4tdge4t1edie4nebdi3ens_die2s3cdi2s5tedi4tengd2o3r4ador2f1a2d3rast2d3rauc3d4reck2d3reic3d4riscdrunge3drü5cked4s1amtds3assid4schind2s1e2bd4seinsd2s1engd2s1entd2s1erfd2s1erkd2s1erzd4s1etad3s2kand2s1pard3stell2d1un3ddu4schndu4schrdu4schwe4aler_e3at5t4ebens3eebet2s3eb4scheeb4stätebs3temebs3t2hech1o2bede3n2eeden4seeden4speder3t2ed2s1esed2s3treein4see2f1e2be2f1i2de2f1insege4strehen6t3ehe3strehl3eineh4lenteh5l2erehr1e2cehr3erleienge44eigeno1ei2g3nei3k4laei4leineil3inseim3allei4nengein4fo_ein4fosein4hab3einkomei2n1o23einsate4inverekt4antekt3erfekt3ergela4bene2l3a2me2l1a2re2l1eine3leinee4leing2e3len_e4lensee2l1ente2l1erge2l1errell3ebeell3eiseller4nelt3eng3elternelt3s2kelt3s2pe2m3anfe2m1ansem2d3a2e2m1erw1e2metiem2p3leena3l2ien3d2acend4ortend3romend3s2pene4bene4n1enten4entr4e3ner_e2n1erd1e2nerge2n1erle2n1erre2n1erse2n1erte2n3erue2n1erwe4n3essenge3raeni3er_e2n1i4me2n1o2benob4lee2n1o2ren4terb3entspr4entwetenz3erte4ratemerd3erwer3echser1e2ckere4dite2r1e2h4e3rei_4e3ren_e4rensee4rentne2r3erfe2r1erher3e4tiere4vid3ergebn4ergehäe3ri3k44e3rin_e2r1ini3erlebnermen4serm3erse2r1o2pers4toder4tersert3ins3erweck6erweise4s3atoe2s3einese4lere3s2peke3s2pore3s4praess3erges2s1paestab4be4starb1e2stase1s2tecest3ories3tropeße3r2eeten3d2eter4höeter4tre4traume6t3recetsch3wet2t3auette4n1et4t1umeu3ereieu3g2ereve5r2iewinde3e2z1ennfa4chebfa2ch1ifäh2r1ufeh4lei2f1eing4f1einh2f1einw2fe2lekfe2l1erfel4sohfe4rangfer3erz4ferneufest3eifet2t3afeuer3effel2d1f2f3emifi1er2ffi2l1anfisch3o2f3leinflu4gerfor4teifor2t3r2f5raucf4schanf4scheff4s1ehrf2s1entf4s1etaf3s2kief2s1pasf3s2porf4stechf3s4telf3sternft1a2bef4t1entft4scheft4s3täft4stri2f1u2nifun2k3rfus2s1pfu2ß1er4gangeb2g3ankugas5tangebe4amge4lanzge4lessgel3stegel3t2agen4auggen2d1rgen3eidgen3erngen4samgen4ta_2g1entfge4renggerin4fgerin4tger4satger4stoges3aufges3eltge2s3erges3s2tgien2e12g3isel3g2laub2g1lauf4g3lein4g3lisc2gni2s13g2num_2g3rede2g3reic2g3rein2g3renng3riese2g3ringg4s3a2kg4schefg3s2eilg3s2pekg3s2porgst3entgst3errg4s3torgs4trat4gungew2g1unglguschi5gus4serhaf3f4lhalan4chal4beihal4t3rhar4mes2h1aufmhau4spahäu2s1chba2r3ahe4b1eihe5ch2ehe2f1eihef3ermheiler4heit4s3he2l3auh3e2lekhel3ershel4meihe4n3a2hen3endhen3erg2h3entwher3a2bhe4reck4hereighe4rerwh1er2foherin4fherin4sh3erlauhe2s5trhie4rinhif3f4rhi2l3a4hin4t1ahir4nerhlags4ohle3runhner3eih3nungeho2l1ei2hot3s2hrei4bah4r3eigh3re2s1h2r1etah3rieslhr2s1achr2s3anhr3schlhr2s1enhr4s1inhr4s1ofh2s1achh4schanhse4lerh2s1erlh2s1ingh2s1parhst3alth2s3tauh3steinh5stellhst3ranh3taktsh4t3alth4t3a2mh4t3assh2t1eimh2t1eish4tentfht3erfoht3erfüh2t1erhh4terklht3erscht3ersth2t1erzh4t1eseh4t1esshte3stah4t3rakht3randh2t3rath4t5rinh2t3rolh2t3rosh4t1rösht3spriht4stabhts4tieht4stürh2t1urshu2b3eihu2b1enhu2l3eihu4lenthu2l1inhut4zeni3alenti3alerfi3alerhi3a2leti3a4liai1ät3s4i2b1aufich4speich2t3rieb4stoieb4strie2f1akie2f1anie3g4rai2e2l1aien4erfienge4fien3s2eie3r2erie4rerfi2er5niier4sehier3staier3steies2s3tie2t3hoie4t1ö4i2f3armift3erkif4t3riift3s2pi2g1angi4gefari3g4neuig3steiig4strei2k1a4ki2k1anoi4kanzei2k1erhi2ker2li2k1etaik4leriik2o3p4ikt3erki2l3a2mi4lentsi2l1erfi2l1ergi2l1erril2f3reilig1a2ili4gabi2l1indil3l2eril4mangil2m3atil2z1arilz3erki2m1armimat5scima4turi2m1erfi2m1erzi2m1infi2m1insindes4ii2n1engin3erbei4nerbiiner4löing4sam3inkarninma4leinn4stains3ertin3skanin3stelin4s3umional3aion4spiir2m1eii4s1amtisch3ari3s2chei4schefi4schini2sch1lisch3leisch3obisch3reisch3rui4schwai4schwoisch3wuise3infi4seinti2s1ermi2s1essis4s1aci1s4tati1s4teui1s4tilit3a4reiten3s2iti4kaniti3k2ei2t1in1i2t3ranits1a2git2s1e4its3er1it2s1peit4stafi2v1enei2v1enti2z1enejek4terjektor4je2t1u2jugend3jung3s42k1a2bo2k3a2drka3len_ka4lenskal3eri2k1annakari3es2k1artikau2f1okauf4spke1in2d2k1eiseke4leim2ke2lek2ke3letkel3s2kk3enten2k1ents4kerfahk4erfamk3ergebk3er4hökerin4tker4kenker4neuker4zeu2k1i2dekie2l3o2ki3l2aki3n4o32k1inse4k1lastkle3ari4k3leit2k1o2fekop4fenkot4tak2k3räum2k3redekreier4k4s1amtk2s1ersk2s1erwk3stat4k2t3a2rk2t1erhk2t1ingkti4terk4torgakt3oriek2u3n2akuri4erku4schl4l3aben4l1a2bl2l1a2drla2g1oblan2d3rlang3s4l1a2po2la2r1anla2r1eila4rene3l2ar3glar3ini2l1ar3t3lasserla2t3ralat4tanlat2t3rlau2b3rlaub4se2l1ausslär2m1al2b1edel2b1insld3a2b1ld3a2ckl2d1a2dl2d3a2nld4arm_lecht4ele2g1asleh3r2elein4dulei4ßerleit3s22le2lekle2m1o24lendet4lenerg2l1ennilen4sem2l3entwlent4wäle2r3asler3engle4rers3lergehl3ergen2l1ergilerin4s2l1er2ö3l2erra2l1esellgeräu33lichem3licherliebe4slie2s3clik4ter2l1indulingst4lin2k1ali4schu2l1i4solkor2b1ll1a2bel2l1a2mlle4n3all3endul4lentsl4lerfol4lergoll3erntll3ertrl2l1indl2l1o2rll1ö4sellus5t6l2m3a2blm3einsl2m1e2pl2m1erz2l1o2bllos3t4r2l1ö4l3l2s1a2dl4s1ambl4schinl4schmül2s1e2bl2s1ersl2s1erwl2s1impls3ohnel4t3amel2t3atol2t1eislt4stablt4stocltu4ranluf2t1aluf2t1eluf2t5rlung4sclus4s3alus2s1cluss3erlus2s1olus2s1plus2s3tlus4stälus4t1alust3relut1o2fmach4trma4ges_ma4laktma4l3atma2l3ut2m1analman4ce_man3ers2m1angr4ma3r2oma3s2pa4m1aspemassen3mas4telma1s4trma2ta2b2m1au2fmäu2s1cmbast3emedien3mein4dame1i4so2m1e2miment4spme2r3apme4rensmerin4dmerin4tmerz4en4m1essames2s1omes2s1pme4t3römierer4mil4cheminde4sming3s4mi4schami4schnmi4schwmis2s1cmi2s5tem2m1ansmme4linm4mentwmme2ra2mme4recmmi1s4tmo4n1ermor2d3amoster4mpf3erpmpf3errms5trenm2t1erfm4t1ergm2t1erlm2t1ersm2t1ertm4t1etam2t1insmt3s2kamun2d1amül4lenmütter3na3chenna2l1a2na4lent4n1a2nana4schw4n1a2synauf4frn4austenbe3r2en3ce2n3n2d1anznde4al_nde4lännde4robn2d3ratn4d3runnd4stabnds3taune2e2i22ne2he_2nehen44n3eing4n3eink3ne3l2o4n1endb4n1endd4n1endf4n1endh4n1endk4n1endp4n1endt4n1endwne4nenenen4ge_nen4gen4n1entl4n3entwne2ra2bne3r4alne2r3am4nerbe_4nerben4n5erfonerfor42n3erhö2n1erlöner4mit4n1ernt3n2ers_2n3ersa4n3essine2t1akne2t1annett4scnfi4le_n2g3a2mn2g1andn2g1einnge4ramnge4zänn2g1i2dn3g2locngs5trinie3l2a3n2ing4ni4schwnitt4san4k3algn2k1insn2k1ortnk2s1aln4n1alln4nentsn2n1unfn2o3ble2n1ob2s2n3o2fenor2d5rno4t3eino2t3inno2t1opn2s1a2dn2s1alln2s1äusn6schefn4schronsen4spn2s1erkn2s1erön2s1erwn2s1erzn4s1etan2s1inin4sperin4stat_nst3eifn3stemmns4tentnst4erön4stracn4strien3t2a3cn4tanzan2t1eisn4t1essn2t1inhnton2s1nt3reifnt3riegntu4re_ntu4res1n2ung4n2z1a2gn4zensen4zentwn4zentznz3erwe2o3b4enoben3d4oben3seobe4riso2ch1ecocher4ko3d2e1iof2f1inoge2l1io2h1eiso2h1erto2h1erzoh4lergoh4lerwo3isch_ol2l3auoll1e2col2l1eiol4lerkoma4nero3m2eiso2m1indo2m1into2n1erdon3n2anont3antont3erwon4t3riop4ferdopi3er_o2r3almor2d3amor2d1irord3s2to4rientor2k3aror4mansor4mentor3n2o1oro3n2aor2t1akor4t1anor2t1auort3eigort3erfor2t3evort3insor4trauort3ricor2t1umo4sentsoss3andost1a2bos4t3amost3angos3tarros4ta4soster3eos4t1obost3ranost3roto2ß1enzo2ß1ereo2ß1erfo3t2e1iote2l1aote4leio2t1erwo2t1i2mot4terkoun4ge_our4ne_ozen4taöchs4tuögen2s1öl2f1eiö2r1e2lö3r2erzö2r1uneö2sch3mpa2r3afpar3akt2par2erpar4kampar4kaupe2l1a2pe3li4npe3n2alper2r1a2ph1erspil4zerpingen4pi2z1in3ple5n4po2p3akpo2p3arpor4tinpor4trepor6tripo2s3tepost3eipost3rap2p3a2bppe4lerp4t1entpt3ereip4t1erwp4t1erz2r1acetra4chebra4chinracht3rr3a2d3r3ra1k4l2r3alm_r4alt2hram4manram4m3uram2p3lran4dep4r3aneiran4spara2r1inra4schl2r3asph2r3attarau3e2nrau4man2raus5srbe3r2erchst4rr2d1elbrden4glrder4err2d1innre3alerrech3ar3reigewrei3l2arei3l2irei3necre1in2v2re2lek2r1entl2r1ents4r3entzr4ergen2r1ernä4r3erns4r3ernt3r2ers_2r1ersare2s2tu2r3evid2r3e2x1rfi4le_rfolg4srf4s1idrf2s3prr2g1a2drge4ralrge4taprgi4selr2g3ralrg5s2turi2d3anri3ers_ri3estiri2f1eirif4terri4generin4dexrin4diz4rinnta3r4ins_r4inspirin4tegrin4t5rri4schori4schwr3i2talr2k3reark4stecrkt3ersrk2t1o2rl2s3tor2m1aldr2n1anzr4n3eisr4n1enern3enser4n1ergrn4erhir4n1ertrol4lanro4nerbron4tanros2s1crre4aler2s1a2dr4s1amtr2s3angr3sch2er4stantrs4temprs4terbrst3ingrst3ranr2t1almrt3a4rer2t3attrtei3lartei1s4rten3s2rt3ereir4terfar4terfor4t3erhr2t1erkrter4rerte3s2kr2t1imar4t3rakr4treisrt4s1ehr2t1urtru3a2r3ruch3strun2d1arund3er2r1u2ni4r3uniorus2s1pru2t1o2rve4n1er2z1erfr2z1ergr2z1erkr2z1erwrz2t3ror3z2wecsa2cho22s1a2drsa4gentsa3i2k1sa2l1ids3ameri6s1amma2s3a2nasan4dri4s3antr4s3a2sy2s3aufb2s3ausb3s2ausesbe3r2es4ch2al4schanc4schangsch3ei_4schemp4schess4schiru4schle_sch6lit4schre_4schrinsch3rom4schrousch3s2k4schunt4schwetsch4wilsdien4e2s1echo2s1e2ckse2e1i4se2h1a2se4h1eise4herk5s4ein_sein4dusei3n2esein4fos4eins_4seinsp4seinstsel3ers2s1endl4s1entf2s3entg2s1entsser3a2dse2r3als3erbe_s3ereig2s1erfo4serfül4serken2s3ernt4s3eröf4sersehse4r1ufse3rund4se4tap4s1e2thsi3ach_siege4ssi2g1a2si2k1absik3erlsin3g4lsing3sasi4schuska4te_4skategska4tes4s3klassni3er_sni3ersso4l3eisol4lerson2s1o2s1orga5s2orgeso2r1o24s1o2ve4spensi3s2pi4e4spier43s4prec3sprosssrat4scss1a2cks4s1alas4s1albs4s3amts4s3angs4s3anzs3sa1s2s2s1egasse3infss3ersessquet4s3ta3li4s3tann3staus_st3a2ve4stechn3steilhstei4naste4mar6s5ter_3sterncs4t3ese3s4tett1s2ti2rst1i4sosto3s2t1s4trah4strans3s4tras4straum4s5träg4sträne4s5tref4streibst3renn2s4trig2s5trisst3rollstro4ma4st3run2s4t3s42stum2sstum4sc3s4tunds2t3uni2s3tuns2st3urtsuch4st3s4zene2ß1estrßi2g1a2ta2b1anta4bend2t1a2drta2g1eitahl3sk3t2aktuta4lensta2l1optan4gar2t1anme4t1anna3t2ans_4t3ansi4t3anspta4rens3t4a3rita2ta2bta2t3erta2t1um4t3ausg4t3auss4t1auswtbauer4tbe3r2e4teilhet3einget3einlate2l3abte2l1acte2l1autele4bete4l1ecte4l1ehte4leinte4lerd4t3elf_te2l1inte4losttel3s2kte2m1ei3temperte4na2dte4na2g4t3endf4t1endl4t3endpten3d4rten3eidten3ens4tenerg4t1eng_ten4glate4n3in4tensem4t3entw4t3entzte3ran_te2re2bter3endte4rengte4rerkterer4z4terfol4terfül3ter3g2t6ergru4terklä2t1erlöter4mert3erneuter4re_ter4sert4erst_t4erstit4erstute4r1ufter4wäh2t3erzbtes3tantest3eitestes4teu3ereteu3eriteu2r3a2t3e2xe2t1e2xi4thrin_4thrinsti4dendti3e4n3tie4recti4gerzti2ma2gtim2m1atin2g1at1in1ittin2k1l3t2ins_4t1inseti4que_ti4schatisch3w3ti3t2etle2r3atmen6t3tmo4desto2d1ertor3inttra3chatra4demtra4far2t3rams3t4ran_tre4ale3t4reib2t3reih4trenditre2t3r2t3rund3t4runkt3s2chat4schart3sch2et4schefts4chemtsch4lit4schrot2s1e2bt4seindt2s1engt2s1entt2s1i2dts4paret3s2pont3s2port4spreits3tätit2s3tepts3tradt4strants3traut2s3trät4streut4stropt2s3trütte4lebtte4lent3u2fertums5trtung4s5tu2r1ertu4schlt2z1e2ct2z1eiet2z1eistz3entsubal3l2ubi3os_u2b3rituch4spruch4toruch2t3ru4ckentu3ck2eruden3s2ue3reigue4rergue4rerku4erinnuer4neru3erunfu3eruntu2f1ä2ßu2f1erhu4ferleufs3temuf2t1ebu4gabteu2g1erfu2g1erlugge4stu2g3rüsu3isch_u3ischsuk2t1inulm3einu2m3a2ku2m1artu2m1ausument4su2m1ergu2m1erlu2m1erwumpf4lium2p3leum2s1peun2d1umun2k1a2unk4titunk2t3run2n3aduns4t1runte4riunvoll3up4t3a2upt3ergu2r3a2mu2r1anau2r1angurgros4ur3s2zeu2s1eseusi3er_us3partu2s1pasu3s2peku5s4pizust3abeu5strasus6trisute4leiuter4eruto4berut4schlut4schmut4schöutz3engut2z1inüch2s1cück3eriü4ckersück4speü3d2ensü2f1ergü2h1engü2h1erkü2h1erzühr3ei_ül2l1eiün2f1eiü2r1entüste3neva2t3a4va4t1inve4l1auvenen4dve3rand2ve3s2evid3s2tvie2h3avie4recvi2l1invollen4vormen4waffel3wah4lerwalt4stwar3stewa4schawä3schewe3cke_we3ckeswei3strwer4gelwe4r3iowest3eiwest1o2wim4m3uwolf4s3wol4lerwor2t3rxi2d1emx2t1e2dxtra3b4x2t3rany2l3a2myl4antezei2t1aze2l1a2ze2l1erze2l1inzel3t2hze4n3aczen4semzen4zerze2re2b2z1ergäz3erhalzerin4tzer4neb2z1ersazert1a2zert4anzer4tin4zerwei3z2erzazessen4zger4s1zin4ser4zinsufzon4terz3t2herzu2g1arzu4gentzwan2d1", - 8: "_al1e2r1_al5l4en_anden6k_ar4m3ac_ar4t3ei_ber6gab_ber4g3r_de3r4en_einen6g_en4d3er_en5der__er4zen4_ka4t3io_lo4g3in_mode6ra_ost5end_oste6re_par3t4h_richt6e_sucher6_tan4k3la2ch1e2ca4ch3erwacht5ergach6tritack3sta43a2er2o1af4t3erlage4s3tiah4l3erhal4b3erw3a2l1e2bal2l3a4rall5erfaalli5er_al4t3erfam4t3ernand6spas3a4n1erban4g3erfan4g3erlan4g3erzang4s3poani5ers_an2t3a4ran2z1i4nar4t3ramau5ereinau4s3erwauster6mau4ten4gau4t3erhäs4s3erkbach7t4ebal4l3ehbe4r3eiwber6gan_ber3st4abe6steinbe4s3tolbote3n4ebst5einbbu4s3chach3e4ben6chergebcher6zie6ckergeb4d3achse2d1an3d22d1e4ben3d2e1i2mde2l1a2gde4l3augdel5sterde4n3endden4k3li4den4semde4r3eisde3r4erbde3r4erfde4r3ero4d3erhöh4d3ersatdest5altdest5ratdienst5r2d1in1it4d3innerdi4t3erldi4t3ermdi4t3ersd4s3tätid3s4tern2d1u2m1edu4sch3le3a4reneech3t4eiege4n3a2eg4se4r1ehr6erleei4b3uteei4d3errei2m1a2gein6karnein6stalei6schwuei4s3erwek4t3erzeld5erstel4d3erwe4ler4fae4ler4lae4l3ernäe4l3e4taelgi5er_elgi5ersel4l3einemen4t3he6mentspen4d3esse4n3ermoeni5ers_en5sch4eenst5alten4s3täten4t3rolen4z3erfen4z3ergen4z3erke2r3a4sie4r3eis_e4r3entferi3e4n3er6tereier4t3erfess4e3rees4t3enges4t3erhes4t3essestmo6deet4z3enteue6reifeut6schnfacher5ffal6schafal6schmfe4r3anzfrach6trf4s3tätif4s3tresf4s3tütef4t1e4tift4s3tanfzeiten6gas4t3el2g1eise2gel4b3ragel4b3rogel6dersge4l3ers4g3ereigge4ren4sge4r3entge4s3terglei4t5rgrammen6gros6selg3s4tatigs4t3rosgu4t3erhhaft4s3phal6lerfhau3f4lihau5steihau6terkhe4f3inghel4l3auhe2n1e2bhe4r3eishe4r3o4bhfel6lerhich6terho6ckerlhol6zeneh6rerlebh3s4terbh3t4akt_h4teil4zh4t3elith4t3entsht5erkenh6terneuh4t3erreh6terstaht6ersteht6raumeht4s3turhu4l3enghut4z3eria4l3ermie4n3a2gie4n3ergienst5räie4r3erziesen3s4ie4t3erhie4t3ertiker6fahi3l4aufbim4m3enti2n1e2bei4ner4trin2g1a2gin4n3ermin4s3tätir4m3untir4sch3wi4sch3eii5schingi6schwiri4s3etatiso6nendis4s3cheit4z3ergjah4r3eika4n1a4s6kantennkehr4s3o4ken4gagken5steiker6gebnkerin6stk3er4lauk3er4lebk6erlebe2k1er2zikeu6schlkor6dergkre1i2e4k4s3tanzk4t3erfolan2d3a22lat2t1alat4t3inl2d1e2seleben4s3lei6nerble4n3end5lentwet4l3ereigle4r3eim3l4ergew6lerwerbli4g3ers2l1in1itl6lergebl6lergen2l1or3g2l4s3ort_l4s3tätils6ternels6ternsl4te4leml4t1e4skl2t1o2rilu2g1e2blus6serflus6serklus6serslu4t3ergl2z1u4femagi5er_magi5ersmar6schmmar6schrma4t3erdmen6tanz4m3entwi4m3ergänmes6sergmp4f3ergmp4f3erz4m3ungebmu4r1u2fnacht6ra4n3a2mernavi5er_navi5ersn4d3entsnder5stene2n1e2bn4g3erseng4s3e4h2n3i2gelni4k3ingn4k3erfanseh5eren4s3ort_n4s3prien4s3tatens6terbenst5opfenten6te_nt4s3parober3in4ode6rat_ode6rateoh4l3erholl5endsoll5erweol4z3ernonderer5on4t3endopf5erdeopi5ers_or4d3engo2r1e2ckorsch5lior4t3entor4t3ereor4t3offor4t3räuos4s3enzo2ß1en2kö4sch3eipargel6dpä4t1e2hpä4t3entpe4l3inkp2f1in3spos4t3agrach6trärali5er_rali5ersran4d3errau4m3agräu5scher2b1a2der4b3lastrch6terwrderin6sr4d3erntrege4l3äre4h3entreister6re4n3end4r3erken4r3erlaurge4l3errgen4z3w4r3innerrkstati6rk4t3engrk4t3erfrk6terscrk4t3erwr2m1o2rirn3e4benrol3l4enrpe4r3inr6scherlr4s3ort_r6strangr4t3erler4t3ernäru6ckerlrun6derlrun6dersrun6derwr4z3entssa4l3erbsat4z3en6schlein2s1e2bense4l3erl4s1e2pos6sereignse4r3eimse4r3enk2s1i2deoson5ende2s1o2riesrücker6sse3in4tstel4l3äs4t3endss4t3engls4t3entfste6rersstes6se_5st4reif1s4tri2ksun6derhtan6zerhta4r3eretau3f4litau6schrtau6schwtblock5e4t1e2bentein3e4cte2m1o2rte2n1e2bte3n4ei_ten4t3riten6zerh4t3erde_te4r3eif6tergreiter4n3art6erscha6terwerbtes6terkti4v3erlto6ckenttrücker6t4s1amt4t4s3esset3s4terotta6gess2t1u2niotu2r1a2gtu2r1e4tu2ch1e4cu3erin4tuern3s4tu4g3reisun4d3erfund5erhau2r1an5sur3a4renu6schentusch5werusi5ers_u4t3ersaüge6leiswach6stuwach4t4rwahl5entwandels6we5cken_wein4s3aweis4s3pwel6schlwel6schrwel4t3a2wen4k3ri5werdensxpor6terx2t1er2fx2t1il2l2z1e2benzeit5endzei4t3er4z3ergebzer4n3ei4z3erstezer4t3agzer6terezer6trau", - 9: "_char8me__er8stein_he6r5inn_men8schl_men8schw_os5t6alg_rü6cker6_wort5en6_wor8tendach8traumalli7ers_allkon8tral5s6terbausan8ne_äh4l3e4be6b5rechtebs3e4r3inchner8ei_dampf8erfden6s5taue6ch5erziee4r3en4ge6l5eier_erg3el4s3fal6l5erk6fel6ternfor4m3a4gforni7er_fzei8tendgot6t5erggrab8schegren6z5eihä6s5chenhe6rin6nuherin8terh6l3er4näh6t5erspaieler8gebi2k1e2r2eil4d3en4ti4sch3e4hkamp8ferfke6rin6nulan6d5erwlan6d5erzleis6s5erlepositi86mel6ternmorgen5s65n2en3t2aner8schlenich8tersn4n3er4wano6t5entrnsch7werdn5s6ternen5s6ternsos4s3en4kpapieren8ram6m5ersr8blasserres6s5erw6r5innenmris6t5ersr6st5eingrs4t3er4wr4t3er4lasfal6l5erspani7er_sse6r5atts4s3e4strsu6m5ents4t3a4genttblocken8tes6ter6gür4g3en4gvati8ons_vol6l5endwer6t5ermwin4d3e4czes6s5end", - 10: "_er8brecht_os8ten8deder6t5en6deren8z7endgram8m7endhrei6b5e6cos6t5er6werein8s7trewel6t5en6dwin8n7ersczge8rin8nu", - 11: "_er8stritt__spiege8leiach8träume_lei8t7er8scpapie8r7endpiegelei8en", - 12: "ach8träumen_7sprechende_", - 13: "_er8stritten_" +Hyphenator.languages["de"] = { + leftmin : 2, + rightmin : 2, + specialChars : "üäöáßçâéôèàñíêëſ", + patterns : { + 3 : "1ba1be1bi1bo1ca1cu1cy1de1di1do1du1dy1fe1fi1fo1fu1fä1fé1fü1ga1ge1gi1gu1gä1gü1ka1ku1kä1kö1kü1le1li1ly1ma1me1mi1mo1mä1mö1ne1ni1no1ph1pu1py1re1sa1sc1se1si1so1sä1te1ti1tu1ty1wj1xe1ze1zi1zü1äq2bs2dc2ds2dt2ee2fs2ft2gd2hl2hn2hr2hs2ht2if2ks2ls2lx2mc2mp2ms2mt2ng2nk2ns2om2ps2pt2ts2tz2uc2uh2ui2ut2vs2ws3gy3té3zy3ño4cc5gé5sé5äx6cs6fq6hm6ic6lc6ll6oi6vd6vü7gè7hè7là7my7né7rí7sí7tà7tá7xu7ää7ën8cq8ea8gc8jv8ln8lz8ow8rc8rn8vc8vz8wc8wd8wk8xv8ßb8ßf8ßna1ja1va1wa1xa1za1ßa2ua7äa7çbl6br6c2kc2rc7jcd2cm2cä7cô8e1be1de1fe1ge1me1pe1ve1we1ze1ße7üf1jh1jh1qh7pi1bi1di1hi1ji1ki1qi1vi1zi1ßii2j6ukl2l1qo1bo1do1eo1jo1ko1vo1zo7qo7ço7ñqu2r1xr7ßr7çs1zsp2u1bu1ju1qu1wu1zu1ßu1üve2vr8w1bw2äw7pw8ix1fx1zx5bx5qx7jx7ry1by1cy1dy1fy1gy1py1ry1ty1wy1zy5jy7qy7yá7nä1aä1bä1gä1jä1kä1vä1zä1ßç8oé7cé7hé7lé7pé7ré7zê7pê8tö1bö1dö1vö1wö1zö1ßö2lö5eü1gü1ßüe8", + 4 : "1abd1abf1abg1abh1abn1abw1abz1anb1anf1anl1anr1anw1blo1c4o1cke1cki1cku1clu1dar1dat1dru1ekd1exp1glü1gna1hyd1k2o1lai1lui1lun1mun1na_1nui1nut1näl1nös1nöt1nüt1on_1ons1p2o1pak1pap1pau1pe_1pel1pro1päd1que1rul1rät1s6y1spi1spü1stä1stö1stü1suc1sul1süc1sün1tag1tok1tor1tou1umg1umk1uml1umr1umz1unr1unt1unw1wah1was1weg1wuc1wäh1wüh1xim1zu11zw81ähn1äug1äuß1ü2b2ak_2akr2aks2ale2am_2amk2ams2ar_2ati2aub2auc2aue2aui2aum2aun2auz2b1b2b1j2b1m2b1t2b1v2b1w2b1z2b7d2can2ch_2chb2chf2chg2chh2chs2cht2ck_2ckc2cks2ckt2d1d2d1g2d1j2d1l2d1n2d1w2d7k2d7m2ehm2etz2f1c2f1d2f1f2f1p2f1v2f1w2f1z2fjä2g1f2g1g2g1h2g1t2g1v2g1w2g7k2gs12how2k1c2k1d2k1g2k1m2k1p2k1t2k1v2k1w2k5z2l1b2l1v2lal2lec2lep2lex2m1d2m1g2m1h2m1l2m1m2m1v2m1w2m1z2m7n2n1c2n1d2n1f2n1m2n1n2n1t2n1z2nec2nee2nei2nit2nod2nup2nur2o1g2orm2p1b2p1k2p1m2p1n2p1p2p7c2ph_2phg2puc2pur2r1b2r1g2r1k2r1l2r1r2r1t2r1v2r1w2rum2rüb2s1d2s1h2s1j2s1l2s1s2s1w2sco2stb2stg2sth2stk2stm2stv2stw2szu2t1c2t1d2t1j2t1l2t1t2t1w2teh2th_2tub2tud2tuf2tuh2tüb2unk2v1b2v1g2v1k2v1m2v1p2v1t2v1v2vii2w1t2x1t2z1c2z1f2z1h2z1k2z1l2z1t2z1v2z1z2züb3ced3cer3ché3cil3dav3dör3fur3fut3go_3got3kom3lig3lua3mes3mit3mod3män3mär3mäs3mäß3müt3nez3nyl3nys3obj3pil3pol3quo3re_3ruf3saa3se_3see3sic3sör3ta_3tes3tig3tio3tiv3tua3v2o3wid3xad3xen3xie4aga4agt4ais4atz4bex4c1t4chw4däu4ete4g1j4gl_4h1g4hod4l1t4m1j4n1j4p1d4p1v4p1z4phs4r1f4r1m4r1z4s1q4sce4stp4t1q4täh4v7w4x1g4z1j4z1q4zaf4äre5cam5cia5cle5com5cro5daw5fae5gig5gos5hyg5hyp5la_5löw5nov5nue5nüc5pet5pis5rée5sai5söh5tib5to_5tue5tus5tüd5upd5wäs6akf6aup6böl6chc6chp6ckb6d3q6ekt6füb6h1h6hi_6hw86it_6k3j6kex6kiz6l1h6l1k6l1m6l1p6lox6luh6m1q6müb6nox6nöl6o7ß6oby6opo6p3w6phk6phz6pl_6r1p6sk_6std6stf6stn6ths6täb6v5h6w5w6x1h6x3w6xek6zön6ß7s6übd7bev7bew7bez7bil7bis7bot7bäe7bär7bün7bür7châ7ciu7cky7coa7cra7da_7dae7day7dyn7däc7dün7ekz7fa_7fav7fe_7fi_7fuc7ga_7ged7gou7göt7hou7kah7kow7laj7lao7lu_7meh7moh7muk7mé_7més7müh7mül7ney7no_7nu_7nud7näc7näe7näg7näi7nü_7nüs7oog7pa_7pav7peg7pip7put7päc7päs7raç7sa_7sio7soß7sud7sui7suv7sät7tai7taz7toj7tow7try7typ7täa7täe7tön7wa_7waa7xa_7xas7xe_7xes7xy_7xys7ze_7zol7zuc7züc7öl_8aby8aca8acu8agl8ain8akh8ako8akä8akü8ap_8ase8asg8atb8atf8atg8atp8atu8auj8b1c8b1q8b3n8bl_8br_8böf8cec8cef8cek8chd8chj8chv8chz8ckm8cua8d1z8daq8däx8e1j8e7q8ebi8ebo8ect8efo8egl8eir8esw8ex_8fja8fl_8fäq8fäx8g3q8gex8gls8gäp8güb8h1c8h1d8h1v8h1z8hae8hid8hio8hö_8i1w8iga8ilb8inä8ish8itt8k1q8kl_8kly8l1f8l1g8l1j8l1w8läx8lök8mox8mäo8mäp8mäq8n1q8näq8obb8obu8ofo8ohl8okl8opy8orr8ose8otr8p7j8phb8phd8phf8phm8phn8ps_8puk8r1d8r1j8r1q8r1s8rh_8rhs8rhä8räm8räx8rök8sc_8scj8scs8skn8skü8sp_8spy8st_8sza8szw8szä8szü8säp8säq8thb8thf8thk8thp8tht8thv8toß8tr_8trh8tsk8tya8täq8täx8tüh8u1d8u1e8u1x8uhl8ur_8veü8vim8w7l8x1k8x1m8x1p8x7d8x7n8xeu8xex8xun8zök8ß7w8ä1e8äma8äml8äul8äum8übc_ch8_fs8_gs8_he2_ia8_in1_ks8_md6_mm6_pf8_ph8_ps8_st8_ts8_ub8_um1a1bra1bua1göa1haa1hia1loa1läa1mua1naa1nöa1pea1pia1pra1raa1roa1rya1sua1taa1tha1toa1tra1tüa3cia5hua5müa7aqa7aua7böa7eia7epa7exa7föa7pua7ö8a8möab1lab1äac7cad3ladt1ae1rah7wait8al1can1sap5tap8nas1pas5öas7zau1rau7aau7ob1spb1sub7beb7teba6xbb2rbb8obe1obe1sbe3gbo2abs2tbu8ebu8fbub8bö8bbü1cc2l2c4dic5cec6mic7räc8sica7hca7oca7ycae7ci7cck3ocoi8cre2cs8fcu8ed1agd1chd1spd1tad1täd2ond2r2d5apd7did7dädi2edip8dn8jdo7xdst8dt1sdu8fdu8ndur2dus1dwa2e1abe1ace1ahe1ake1ane1are1eie1ene1hae1hee1hie1hoe1hue1häe1höe1hüe1kee1kie1lae1lüe1rüe1spe1sue1süe1tae1the1toe1täe1töe1tüe1xie1ö6e2gne2ole3gee5rye6ode7cie7cle7cre7dye7kue7xye7zae7zie7ä4e8oce8rhe8vlec7sed8eee1see7aee7oeeg8eg7deh1wei1eei1oel1cem7temb8en1aen7meo1sep8ier1ces3feu5oeu7hex5cex5leys8f1trf1täf2lif2onf2r2f2usf4uzf7apf8lyfa8ßfay7fe2cfid8fl8oft7zfä1cfü8rg1nug2leg2nog2ong2sag2sig2säg3teg7däg7psg8ähga7egd7tge1cge1ege1oge3pge5kgh7wgh8aghs8go6ags2cgt8sgu2egy3ngüs7h1nuh1ruh1sph2moh2onh3rüh6igh7guh7köh7yoh8aih8ajha8ßhe7yhi2ehl3dhl7mhl7thlk2hr1chs1uhth8hö8shüs3i1ari1aui1eii1eni1fai1iei1ini1lai1loi1lui1läi1mui1müi1oxi1pai1pei1pii1pri1rai1rii1roi1räi1sui1tai1täi1xii2vli2vri3igi5cai5réi5töi7aii7fyi7röi7xoi7öni8jsia1bia1giah8ic7cie1aie1eie1oif1rig5dih1nih1rih7mii7tik1silv8in1sin1uion2ir1city5iun2iö8kjab8je4aje8pji8vjit7jo4bjo6iju1gju7iju8kjul8k1sük2lek7hüka7eka8okoe8kon1ks7ökss6kst8kt1sku1cku8hkü1cl1däl1lal1lol1lul1läl1löl1lül1nal1nul1spl1zol1öll2onl2thl5näl7cal7cel7hel7nil7pula7eld1sld1tldö8ll1cll1zllb4llm8lm7plo8olp2flp5tlss8lub1lz5tlz7llä1clö1clö6fm1chm1pam1pem1pim1prm1pöm1spm1sum1trm2onm7pum7päm8aym8tsme1cme7omey7mi3amo2omo2umo5ymy7lmöb2n1abn1afn1akn1aun1gon1ken1kin1kln1sun3uhn4ien7ban7bsn7can7cun7kyn7män7äfne2ung5dno1cnt1snt1zntt6nu1anu2nnö1co1a2o1fao1fro1heo1hio1hoo1huo1häo1ido1ino1lao1luo1nao1nuo1näo1opo1oro1pio1pro1päo1rio1ruo1ryo1tao1too1wao1wio2aco2ado2ato3nio3sao5cio5dao5fio5tio6eso6ono7auo7cao7ceo7ieo7léo7uho7umo7woo7wäo7yoo8uro8xuoa8rod7toe2loe8coe8hoe8xoh1soh1woh7tokt8on7kor1cosu8ou7aox7loy1eoz6ep2r4p7pup8pspa7epa7qpa7ypda4pe8bph4lpht6phä7pia1po1cpo2epp8ipss8pt1spu7apy7lpy7tr1arr1cer1cir1h2r1nar1nur1när1nür1ärr1örr2dör2isr2itr2onr3pur3rur7aqr8ckr8ierb2rrff8rg7drgö8rl8ärm7proe8rp2frp8ers2prä4us1k2s2ons2sks2szs3uhs3wes7khs7les8slsh8rsi1fsk6lsk7ssk8rsl8aso1cso7ost2usu2fsu2nsu8ksym3sz8esö6fsö8dt1hut2r2t5net7met7nitad2tcu6thr8tih6tl8eto1xtpf8tt7ztwa2tz1atö8du1abu1amu1auu1hau1heu1häu1ieu1igu1lau1lou1luu1läu1löu1muu1peu1piu1pru1riu1ruu1ryu1röu1tru1u4u1v6u2evu5ciu5föu5hou7clu7cru7deu7hüu7näu7péu7yau8egu8ehu8epu8szua1dua8cua8gub2luc7cud8aue8xuf1luf1ruh3wun1eun1oun1uuns2urü2ux4eux7tuä8suö8dv3l6v5rav7dav7drv7opva7cva7fve3hve5dve5gve7bve7cve7vvoy7w7how7row7äuwa1dwa8pwhi8wi8rwo1cwo7fws8kwti8wus2x1emx3akx5lex6onx7aux7läxda8xi7cxu8sy1i6y1k2y1loy1nay3ouy7hay7hey7hoy7huy7hüy7kly7läy7muy7toy8ply8psya7hya8myb8rygi2yk7syl7cym1pym8aym8eyp1typ8eypo7ypu8yrr6ysu8yt7ryt8hyu8rz2ähz3ohz7wüz7zaz8aizdü7zi1azub2ä1heä1hiä1paä1riä1ruä1toä2blä2unä3niä5laä7ceä7imä7luä7suä8gaä8gräd3räf3läf3räg7dälk7är1cät5aäu1cäur8élu8ö1ckö1heö1huö1keö1muö1riö1ruö1suö7niö7peö7thöf3löl7aör1aör5cöt7aöze7ü1heü1huü1piü1riü2gnü3biü5keü5ruü8bsü8fiü8foü8maüb1rüb3lüd3rüdt8üeb7üf7aüf7lüf7äüg8eügs2üh1wüh5aüh7oür2sür5aüt7h", + 5 : "1ab1s1abla1adap1afri1aggr1anpa1antr1anzü1appa1ar1c1arzt1ausd1ausg1auss1auto1b2le1cent1chef1ckad1einu1elft1entw1entz1euro1extr1fahr1g2r21glas1glei1idee1impu1info1k2n21k2r21land1länd1läuf1löhn1n2at1n2us1n8av1nari1naue1naui1op1t1oper1ordn1oxid1p2l21pack1para1pers1prei1pres1präg1präs1prüf1rami1raum1rinn1riss1spor1spru1staa1stad1steh1stud1stuf1summ1t2on1tafe1tast1tatb1taug1trag1trie1tron1trup1träg1tüch1undd1undn1undz1unfa1unfä1unio1wirt1z6on1ästh1öffn1öle_2a1ke2a1ri2a3ni2agel2annt2arbi2are_2ausc2b1f22b1g22b1h42b1k82b1p22blig2bre_2bäug2ch2m2chei2chl82chn22ck3l2ck3r2d1b22d1f22d1h22d1p22d1v82dre_2e1lo2e1ri2e1ru2eigt2enis2f1h82f1k22f1m22f3g22f7b22f7n62g1b22g1m82g1p42g7z82gre_2grig2h7b22hein2k1h82k1k22k7b22k7f22klig2kop_2krip2kunt2labs2lanl2lans2lick2lint2lunt2lymp2lähn2lübe2m1b22m1f22m1k22m3r82mähn2n1b22n1ex2n1v82n3p22n3r22n5l82n7w82naly2narc2nion2p1lu2peic2ple_2plig2pond2r1ir2r1ur2reig2ress2rins2rund2runf2s1ab2s1ak2s1ap2s1ar2s1f22s1ob2s1äm2s1är2s3b22s3g22s3m62s3n42s3r22s7v62s8tl2sanl2sch_2schb2schf2schg2schh2schk2schp2schs2scht2schv2schz2sexp2siat2spak2spha2spol2sten2stes2stet2stig2stis2stön2sunt2sähn2sü8b2t1ac2t1f22t1g22t1hü2t1k22t1m62t1n42t1p22t1v82t7b22tabh2tabs2tanl2tart2teck2tein2temm2texp2th3l2tieg2trec2tunt2unde2v1f82z1ab2z1b22z1d82z1g82z1m82z1p62z1s22z1wo2z3n82z7r82zeni3abko3agog3ahor3antw3atmo3cett3chae3ckat3daue3deei3deer3dreh3drüs3emul3engp3exam3g4ly3gnif3hemd3hole3i4dy3ladu3leer3lehr3leri3lert3löch3lösu3mark3musi3n2ah3nais3nase3norm3oxyd3p2sy3pati3prak3prog3r4ig3raly3reda3refe3refl3refo3repo3resu3rohr3rout3räde3räni3röhr3römi3s2ie3s4ig3s8up3sakr3sam_3samk3samm3sams3sar_3satz3setz3show3tari3teho3teil3tel_3teln3tels3telt3tem_3teuf3theo3tilg3tisc3tite3toli3trak3trog3trua3träc3trüg3tägi3tänz3töch3ver13wese3wett3xa3g4abil4abis4abot4and_4anog4arg_4blän4chum4darc4dol_4dorg4drig4dunf4eimp4ethe4flig4frig4g3oh4ganl4garc4ginf4hy2t4kre_4labh4ladr4leig4lemp4linh4luni4lämt4läug4meff4muls4nanr4nans4nähn4oph44p7g84prig4raha4ranl4reff4reul4riga4rimp4rinf4runa4runi4sopt4spap4spil4spis4st7z4stia4styp4t1hö4takk4teak4texe4traß4tröm4tuml4täuß4zeff5adju5airb5amph5ankü5arzn5atla5b6y15be1c5chao5crew5dais5daub5empf5erdb5ethn5euph5förm5gh6r5gisc5glut5gon_5heft5hymn5inje5inva5kalk5lesu5lose5läde5lösc5münz5noti5nymp5ohmi5opsi5pale5palä5panz5patr5phän5prax5pred5proj5pulv5repe5räle5sake5skiz5surf5sys35säul5tard5tas_5tin_5tod_5tole5unfr5uni_5unsi5wirk5wiss5wö1c5yach5ä6gy5öls_6abol6abs_6ame_6amml6anf_6ang_6arba6arbl6bemp6blun6bruf6chre6chup6d5uh6duml6dunt6durl6eb2r6eigu6eisc6elei6eniv6enut6fanl6fexp6fimp6fiso6funf6g7of6geff6gimp6gord6groh6gumr6gunk6gunt6h7f26hale6halp6hana6hano6harg6hexp6hire6horg6karc6keff6kinf6kinh6kulp6kübl6labf6labl6lobj6lopt6lufe6luna6m5uh6mepa6mope6mänd6möl_6n1än6nagg6nanl6nano6nanw6nobt6norc6numf6numl6nuni6nü8b6o1lo6o1pa6pf1t6piso6proc6ranf6ranw6rher6rigr6roff6runr6s7cl6sadr6satl6scal6schc6schd6sk3t6splä6ston6stäg6suna6suni6tabk6tabz6tanf6tapf6teff6th7n6tinv6tirn6tobj6toss6tält6v7n86vlic6x1s66zunt6zurl7abkü7ablö7abme7abtr7akku7antá7athl7aufn7ausü7b8äd7b8äl7b8äs7be1a7belg7beng7bib27cels7chov7chör7ci7t7cka_7ckag7co2d7co2u7dan_7deem7doba7drej7drew7dria7drif7druc7dräh7elfm7erdg7exkl7f8ug7fase7fat_7fats7fene7finn7flop7flot7gelt7glet7glät7go7y7gons7gor_7gür57hinw7hotl7itii7kadu7kasc7kirc7kmäo7kund7laba7lad_7lakk7lali7lamu7lanx7laru7latw7lehm7leih7lhi_7lib67lie_7limo7lipf7lipt7lis_7logi7loks7malv7man_7maul7melo7mer_7mige7misp7moni7mu7a7mäul7n8uz7nako7nakä7nam_7nar_7nats7neca7nehm7nelk7nior7nis_7nopa7norö7nuhi7nutz7nähe7nähm7odon7oliv7pa3g7pano7paro7path7peil7penn7pero7perü7phas7pier7prem7priv7prot7präd7präf7präm7präp7präv7prüg7pull7radp7rah_7rakü7redu7repu7ritu7rol_7rond7ruin7s8äg7saft7sahs7saki7salo7salp7salz7sati7shi_7shid7sitz7sol_7sold7sole7somm7sott7spaz7spuk7spur7spän7stoß7stuh7städ7stör7stüh7t8ré7taan7taba7tabu7tacu7tafa7tam_7tams7tanc7teha7tehi7tehä7tehö7teic7telp7tenr7teum7teus7the_7thek7thi_7ticc7tif_7timo7tip_7tips7tof_7toil7told7topo7totr7tria7triu7tro_7troe7troy7trub7trög7tröp7tuch7tume7tumo7tun_7tunn7tägl7tür_7türe7tütc7walz7wann7warn7we8e7weil7wied7wies7wild7z8ah7zaun7zen_7zern7ä4gä8a1he8a1ki8a1nu8a1ru8abat8abec8abet8abin8abir8abrö8achf8achv8ade_8aden8afra8akul8akun8anbu8anbö8andt8anfs8ank_8anto8arac8arak8arb_8arbr8arem8argo8aroc8arr_8arrt8asim8asis8ates8atle8atlo8augl8babf8babs8badm8beff8bimp8binb8blaw8bonk8brah8bred8breo8bräd8bumf8buml8burn8chab8cheh8chra8chuf8ck3n8ckex8ckid8ckuh8d1öl8d7oh8dabs8dada8daff8dall8danb8dapp8datl8datm8deff8dekz8demb8demp8didy8dimb8dinj8dobj8dobm8dopf8dord8drez8drou8druf8dumd8dumg8dumk8duni8dänd8e1lu8e1lä8e1lö8e1tr8e7ly8eidn8eitä8eleb8eleh8enah8enam8ene_8enot8ere_8es3l8esso8f7of8fabb8fabg8fabl8fabw8faka8fanb8feu_8fint8forg8funi8funr8furl8färm8fäug8g7uh8gabf8gabg8gabw8gabz8ganr8ganw8garz8gauf8gek_8gemp8gind8ginv8giok8gnah8gobj8gope8gopt8gosz8grah8grar8gref8groc8gued8gumf8gumg8gumk8gunf8gunr8gurl8h1k88habn8habw8halk8hani8hanr8hanz8hars8hasa8heff8hefr8heio8helt8hima8hini8holy8hope8hot_8hums8hunf8häug8i1to8i1u28ingi8ings8k7ec8k7ox8k7rh8kabd8kabf8kabg8kabh8kabt8kabz8kadr8kage8kanw8katt8keig8kemp8kerd8kide8kidy8kila8kilä8kiso8kla_8kleh8klok8kläd8klöc8klöh8knah8kney8kniv8koas8kobj8komn8krah8kref8kräd8kröh8kumg8kuml8kumz8kunw8kurk8kut_8känd8l3r48labb8labd8labg8labn8labw8labz8ladd8ladj8laff8lagg8lamn8lann8lapf8lash8latl8lekz8lepi8limm8lish8lisl8lixi8loly8lorp8lumd8lumk8lumr8lunf8lunr8luns8lunw8luto8läpf8lübu8mabf8mabk8mabt8mabw8madm8mebo8memp8memu8meou8mepi8midy8mopf8n1h68nabb8nabk8nabn8nabs8nabz8nadm8naho8nakt8namt8nanb8nank8nasp8nemu8nepo8neup8nidy8ninv8nobs8noff8nopt8norg8numb8numg8numr8o1ha8o1rö8o1th8o7zi8obef8obez8oppt8orca8ord_8orda8p7hö8p7hü8p7uh8padr8panl8parb8parp8peff8peis8pfe_8phro8poil8pre_8preg8prer8psys8punt8rabf8rabs8rabt8rabw8rabz8ragm8raht8rakk8ranm8rapf8rapo8rarc8rarz8redd8rekk8relt8remb8repi8rhau8rima8rimm8rink8rinl8rinv8roas8robj8robs8ronk8ropt8rosz8runn8runt8runw8rupd8rätz8rübu8s3ps8s7aq8s7ox8sada8saff8sagg8sanw8scar8schq8sexz8skau8skei8skon8skro8skun8soas8soly8sopf8sosz8spaa8spag8spau8spe_8spet8spok8spr_8spub8spup8späs8sta_8sto_8stue8stus8stäp8subi8surk8szet8szeu8szie8sält8säuß8tab_8tabb8tabd8tabf8tabg8tabn8tabw8tadd8taff8tagl8tep_8tery8teup8texi8texz8th1m8thub8thuh8thut8tieh8timm8tinj8tomg8tomk8treb8trel8triv8truf8truw8träd8tump8tumw8tutz8tä8m8tägy8täll8tätt8täug8töck8türz8u1hi8u1ro8ulta8untu8v7au8vanb8varb8vass8veig8vemu8vind8vint8vumf8vumg8vumk8w7ey8wieb8x1al8x2l28x7ö88xerl8z7ob8z7ou8zanb8zanp8zanr8zanw8zarz8zemp8zeth8zinj8zope8zosz8zumf8zumg8zuml8zumr8zunr8zuns8zurs8zurt8zwag8zwah8zwas8zwäs8zänd8zäus8zäuß8zöl_8zöle8zöls8änge_ab1a_ab1r_ab3l_abs2_ace5_ag8u_ai8s_an1e_ang2_anz6_ap7p_at4h_ata7_aze7_bi6t_da7b_de1s_do7b_dü5b_eg8o_ei7e_el8a_er1e_er1i_es5p_eu3r_eu7g_eu7t_fe8i_fi7d_flu2_ga2s_ga6t_ge7u_gee8_go8s_hi8s_ho2f_ibe3_ig8n_imm6_ind8_ink8_inu7_ire7_is8a_it8h_ivo7_ki6e_ko7b_li8f_mi8f_mo8i_ne8s_ni8e_oa7s_ob3l_obe2_os7s_ot7a_ozo8_pe8c_ro8a_rö8s_rü3b_sch4_se2e_se8t_sha6_ski1_te4e_ti2s_ti8a_tsa7_tse7_ufe8_uma8_ums6_un1a_un1s_un3d_une8_wa2s_wi6e_wor2_ya8l_zi2e_zwe2a1chea1chua1laya1lusa1p8aa2brea2rala2reaa3e4da3el_a3er_a4naba4scaa4xioa5dasa5elsa5iksa5ivla5ivsa5meta5nasa5teca5ya_a6nafa6ropa7acea7akta7cema7deea7e8ba7elba7erga7ersa7fala7flua7ho_a7homa7hopa7ia_a7ik_a7iv_a7lawa7le_a7leka7lupa7na_a7nama7neea7nupa7nura7ot_a7pfaa7plaa7pläa7sola7soma7teta7yeua8buma8fepa8fäna8gaua8gnäa8gria8jata8kefa8keua8mapa8nuha8pefa8reha8seca8tepa8v7raa2graa8beaa8raaa8thaarg8aarz6aas5taata8ab1itab1raab1roab1räab1rüab1urab3ruab8akab8skab8ärach1aach3lad1s2ad7adade7aadt3radte8ae8ckae8o7ae8scaes7taes8aaf1anaf3reaf5leaf5räaf7röafi8tafs8tafür7ag7luag8diag8emah3reah5ösah7muah7riah7toah8läah8noahe1sahin5aht7sai3naai7a8ai7enai7erai7frai7trai8saaid4sail7dak3leak3neak8töakbe8al1aual2blal2zwal4töal7ecal7öram2tuam6anam8möama7damt1aamt3ramun5an1eian3fuan6zäan7feane8cans4zap3leap7liap7suap8pfar2zwar4zäar7mäar8gnar8irar8zöarad8arms8aro2daros7as2stas3teas7ätas8urasa8sase8tasu8sat2saat3taat6täat8euata1sata7fata7gath7rato7sats1patu8nau1h6au1inau1thau7kiau7lüau7paau7ruau8noaue8baue8sauf3lauf3raum1saum3paun2eauts8auve8auße4ava7tavas8awi7eax6amax7abay7ofayma8az8zwaßen7b1arbb1risb1stob2lieb2litb2retb2sunb3ebbb3legb3radb5irrb5spib6on_b6remb6ruzb7abab7lebb8arob8eneb8ensb8onsb8ra_b8rucb8rumb8urgba1laba2stba3saba7nyba7yoba8brba8kabak7lbalk2ban6abar2sbar7nbau1sbbe8pbe1rabe1urbe6skbe7arbe7kebedi6bei3fbei7bbel7dbge1nbger4bi1näbi2tubi7akbi7nabi8arbibe8bie8sblu4ebnis5bo5chbo7asbo7robo8brbo8spboo4lbor2sbpa8gbs8cubsde7bsi8tbu3nabu7kibu7ribu8sabus7pbölk7c3ch8c7intca7g8ca7laca8chcana7ce7inch1ahch2lech2luch2r2ci7esck1auck5aack7abck7ö8clau7clet8cli8pclu4bco3dico7itco7raco8keco8peco8tecola7cros8ctur8cu7rad1artd1ostd1stad1stod1strd3d4hd3refd3regd3rekd3rend5ehrd6ge_d6iscd7anhd7außd7irrd7rerd7revd7rudd7thyd7umfd7ängd8elad8en_d8er_d8es_d8sidd8skrd8sphda5löda7fada8kndagi8dah7ldas4tdate2de2sade2spde3amde7asde7tade7usdea8ddel3ddeob2depi8der7fderö8dha7sdi1gndi1nädi5cedi6tudi7cidi7ptdi8szdin8edio1sdist8dit7rdit7sdla5gdli8fdo5rodo7wedo8ordos8pdrü3bds7evdse8tdta8ddu1radu7ardu7cedu8medus2cdus4edä7usdä8umdüns7e1a2ge1al_e1alse1chee1chie1chue1empe1erde1irre1k2le1nüge1offe1rape1rate1roge1rose2kele2lime2nobe2rare2thie3alge3aufe3d6oe3lepe3nite3os_e3riee3rife3rise3ro_e3roie3rone3um_e4anee4lume5alfe5alle5alpe5alwe5alze5nöre5nöse5orte5ra_e5ulke5umse6amee6at_e6bobe6fäue7albe7alke7alne7alue7alve7auee7bake7blae7enge7enke7enle7k8we7olye7onde7onfe7onhe7onle7onme7onpe7onre7opse7or_e7orbe7orse7orwe7rice7rike7roke7rowe7roze7ruse7unge7wire7wite8amue8atre8fate8febe8fexe8glue8lape8loae8lyae8mebe8mexe8mide8moae8nexe8noae8oree8rooe8scue8sphe8tofe8tyme8uree8vake8xile8xumea8beea8ckea8maea8naea8roeas7seat7seb2speb5ameba8peby7sech3wech5mech7lech7neci8aede2ree3e8ee3reee7ufee8tueen8zeerö8ees4teet8reeun8ef6luef7soeft8reg2lieg7nieg7näeg8eneg8skeh3moeh7läeh7mueh7röeh7trehr1aehs8pehst8ei1a2ei1pfei1trei2saei5ruei7löeie8beil7dein1aein1geir8ceit1hel1alel5uhel7p8els8celst8em8däem8saeme8iemo7sen1eien1spen1umen1unen1uren7gnena2bena6nena8pena8xena8zene8henf8aeni8meni8öenns4eo3roeo7raeo7uleob4eeoch8ep1taep3toep8pfepa8ger1aber1acer1aker1aner1auer1ober7huer7pler7sier7äfer7äsera2gera8ßerb4uerf8eerm2ueruf2erö2derü8bes7axesch2esu8set2tret2zwet8theta1bete8seti8mets8ceu1a8eu5kieu7müeu8ebeu8zoeuf3leugs4euin7eul8eeun2eewi2sex1erex3orey6nef1atmf1auff1spaf1sumf2l8ef2s1of3le_f3raff3ricf3rolf5lebf6jorf7augf7fluf7lapf7li_f7lümf7ra_f7radf7rapf7rekf7ripf7rüsf7sonf7tikf7unmf8eief8en_f8er_f8febf8reuf8ränf8ta_fa6tofa6xafa7ecfa7lafa7nyfa7rifa7shfa8stfave7fe1rafe8räfelb8fem8mff5taffa8dfger8fi3nifi6refi7asfi7olfi8arfi8knfi8krfi8zafilb8fin2sflek7fma8dfo7trfoto3fpi8pfra4mfro2sfs2tifs7s4fs7thfse8tfsi8dft2saft2sift7arft7otfte8cftwa4fu7rafuku7ful7dfä5röföde1g1ausg2limg2se2g2so2g3legg3lehg3lohg3recg3rutg3räug3rücg3sehg5dalg5lacg5notg5silg5sucg6scag7adlg7dadg7eulg7lecg7ledg7levg7lukg7nehg7rakg7revg7solg7song7ö8fg8darg8es_g8g7ng8ning8rerg8sakga1laga2saga3klga7flga7nyga7riga8sigass8gber8gd7akgdei8ge1a4ge1näge1rage1roge1räge1röge1s2ge3imge6esge7mige7wage8otgem6egem6ugen7gges3zgfi8lgga8tgh7scgi1nagi1nägi5asgi7negi8elgi8gugi8usgich8gle7ago7mugo7rogo7trgoe7tgre4egri6egs3s2gs7cegs8aags8ätgsa2bgsa8pgsa8rgsa8vgsch6gti8mgu1isgu1ragu4stgu6sägu7amgu7asguet8gum8egun8eh1amth1arbh1eifh1iath1ladh1lash1loch1läsh1löch1lüfh1nash1näsh1stah1stoh1strh1träh2lieh2lifh2limh2lith2lorh2nelh2nieh2niph2norh2sähh3le_h3lebh3ledh3lehh3manh3mash3nerh3redh3refh3regh3rich3ruth3türh4ronh4rübh5tümh6elfh7eigh7logh7lufh7mexh7moph7nagh7raih7rogh7te_h7toih7tomh7täth7töph7umhh7unmh7äffh8alih8an_h8ardh8at_h8en_h8es_h8nulh8späh8timh8übsha5goha7klha8plha8tahab2ihab8ehai7ehas8hhe2blhe3behe3brhe3lihe3rohe3tehe5lohe7amhe7buhe7dihe7guhe7kehe7pahe7phhe7sphe7thhe7tähe8obhed8ghee8shef7lhen7zhert8hhoh8hi5cehi5obhi6rähi7ashi8onhi8sehi8vohin7nhins8hip7shirn1his8ahle7ahlo8nhm7p8hm8sphme7ehn1anhn5ärhn7f8hna8chnoi8ho2spho7nyho7onho7y8ho8echo8efho8enho8fuhof7lhola8hr2skhr7orhre8thri6ehro8lhrst8hse4chse8eht1atht1auht5hiht5z8ht7axht7obhte4chte8mhto8dhu7suhu8bahu8buhu8hahu8lohu8löhu8sohu8tohuh5lhuh7rhuko7hul7chule8huls8hum8ahuni7hurg8hut7rhvil8hös7ci1al_i1alfi1algi1alki1alsi1alvi1an_i1ansi1anti1anzi1as_i1at_i1atsi1chei1chii1chui1elli1g8oi1i6si1näri1o2di1os_i1ös_i2alii2d3ri2enei2erei2soli2z1öi3aldi3alli3alpi3alri3alti3alwi3en_i3enai3endi3engi3enki3enri3enzi3etti3om_i3ot_i3sati3tati3tisi3tudi3türi5alhi5almi5alni5andi5anni5ar_i5de_i5gnoi5or_i5orci5orpi5ä6mi5är_i5ärsi6anei6fefi6kuhi6kübi6lumi6meki6naui6o1ci6odai6scai6scui6sofi6vexi6zori7ad_i7adni7akti7alci7alji7ampi7anci7asbi7enhi7fari7it_i7neei7ol_i7omsi7onbi7ongi7onni7orsi7orti7otsi7oz_i7r8üi7rigi7sasi7tagi7thri7tici7ärzi7ät_i7ätai7ätbi7ätfi7ätii7ätri8bepi8bimi8bini8bübi8feci8is_i8kebi8kedi8kröi8kupi8köli8luri8megi8meji8mewi8mexi8midi8nuhi8pesi8tofi8v7äi8vebi8vefi8vuni8vuri8zagi8zapi8zänia7unias7sias8pibe8nic7laich1lich1nich1wich3mich7äid2enid8ruida7hidho7ids7pie1chie2blie2drie2glie4ckie7imief3tief5fier1aierk8ieu8eiew7uif3leif7auife8nig3süig7luiga7iigho7igo7bihe7eihen7ii7a8ik7nuike8cike8like8niks8tila7filf8eim1tüim8atim8enim8mäim8umimp8simt8eimtu8in1eiin1äsin3f8indü7ine1ainit8int4rint7sio7flio7spio7suiob6riond8ions1iot8oip7taip8anip8plip8spips7tir2klir2nair7umir8heirg8siri7ais1auis1tris5säis7ölis8apis8euise2nit1auit2sait2seito8pitut8ität2ium5uiun5fiv7adive7siz7akiz7amiza8bize8nja7laja7neje6g5je7naje8taje8tujeri7jet7sjet7tjo3ghjo7rajo8dajob7rjord8jou8lju3raju5taju7tejude8jun8ik1ansk1stak1stok1strk2limk2link2t1hk3lork4er_k6erzk7abbk7advk7impk7legk7lück7nesk7numk7runk7sonk8au_k8eltk8erck8lifk8lirk8os_k8tidk8tofka7flka7frka7hoka7klka7nüka7rika7szkaf7tkal7dkaru8kas1tkat4hkbo8nke6take7nyke7upke8dike8sake8thkefi8kel5dki3oski7frkie8zkka7lkkab8kle4iklo8iklu2bkno6sko1rako3roko7leko7läko7ruko8mukol3ckons2kop7skos7pkot6ikrü7bksa8bkse8ckt7säkto3bku1raku3taku7liku7pakuh7akul8akum8ekus5tl1arbl1chel1ordl1stol1strl2tabl2tuml3tenl4vi_l5ohrl5zähl7adll7albl7altl7blol7blul7blöl7de_l7desl7lagl7lepl7n8el7sufl7surl7susl7söll7uhrl7umjl7urkl8au_l8aurl8bidl8dexl8emel8lofl8mepl8mofl8ninl8pärl8tidl8tobl8zidl8zorla6sola7abla8fula8phla8sälaf5slaft8lar7glat8elawa8lbe7slbu6nlchs8ld7akld7alld7ätld8oslda8dldu7ildys7le7kele7ofle7ufle8gälego7lerk8lfe7eli1nali1thli2tuli3celi5nuli5vrli7aclibi7lik8uliss8lit8alk2s1lkse8ll1d8ll7tallt8elmpf8lms8tlnus8lo1sulo3rolo7fjlo7fllo7lälo8gllo8räloi8rlomä7lru7tlrü7bls8kylsa8blse8tlt3oflt5hilt7öllt7ötlu1ralu8riluba8luf2tlume8ly7nely7thlz7aslzi8mlä1umlä4scm1stom1strm5tötm6meum7abmm7anäm7b8rm7ponm7te_m7örtm8errm8mebm8mumm8sexma1töma3rima5e8ma7f8ma7homa7ruma7sama7yama7yoma8cima8szmad8smal3tmand8mbu7tmde8amder6me1rame3thme7aume7tume8sämega7men7kmi1nami2tami5osmi7drmi7nimi7numi8ammi8etmi8zwmia8bmia8nmibi7mil8imis5amise1mit3rmm7p8mmni8mmu7rmmül8mo1ramo1spmo5rämo7demo7nymo7trmol7dmom8emork8mous8mp1famp7lumphe6ms2pumt7romt8emmti8rmu1namu3nimu7rumwa4rmy6s5my7almä7trmäh5rn1andn1angn1arbn1erzn1gnän1stan1ston1strn2aden2dren2en_n2enhn2er_n2f1un2nann2on_n2spln2spon3damn3deen3dien3nitn4al_n4alin4um_n4zorn5y8on6onsn6or_n6zwön6zärn7abhn7aign7anhn7necn8aldn8ardn8atan8cabn8em_n8emon8enmn8es_n8ettn8gakn8gäln8id_n8kimn8käpn8köln8sakn8sphn8sutn8zadn8zofn8zopna4rana7anna7esna7otna7runa8buna8hana8läna8prnala8nat8unave8nch7mnd1acnd1trnd2agnd4osnd7axnd7tondni6ndu3ine1rane2lane8nuneei6neen8neg8lnek7tnem6enen7kneu5ineu7cnf5tünf7s6nf8arnf8lunfo7sng7tsng8nunhe8rni2tini4suni5okni7enni7flni7nuni7olni8euni8glnibu8nie7bnis1enit7snk1spnk7acnke8cnn3spnn6euno2deno7runo7suno8edno8pinot1sns1anns2tins3s2nso8dnt4sknt8imnta4xnteg8nti1tntmo8ntni8nu6fenu7fanu8esnu8rinubi7nude8nur8znute6nz7atnza6bnä2sco1cheo1isto1peno1ra_o1rato1roso1troo1weno2feno2ramo2steo3osmo3pedo3rado3riso3rito5ismo5peko5raxo5rono5theo6nimo6zeao7deco7dexo7e8bo7et_o7etso7feso7g8no7lalo7me_o7mulo7muso7muto7nodo7nuro7p8no7peco7peio7raao7rafo7rago7rawo7razo7rego7sklo7temo7x8ao8bübo8ckoo8ineo8mebo8nako8pumo8roxo8ryao8taho8tako8tebo8tiloa3deoa3tioa7inoa7keob5szobi8tobs8pobut7och1aoch1woch3loch3moch3rochö8od2drod7akodo8sof7eiof7taof7ärof8foof8fuofa8cofa8dog4huog7acog7laoga7dogin7oh5öloh7muoh8nioh8noohl1aohra8oi8daoi8raok8sooka3ioki8ool2glol2zwol7skol7ätol8däol8zoola8volft8oli5aoloi8olye4om1s8om7pfomet6omm6uomm8eon1glon2auon2ison3f8on5eion7z8on8euon8osona7gone8mong7sonli2onoi8onot6oo8moool7coor7doos5uoos7soot7rop7leop7liopab8opin8opoi8or2door2gnor5sior7ebor7leor7noor7unor7ätor7übor8ceor8töor8uford7torr4hors8cors8kos1pios1tüos2koos2spos8akos8hoos8zeot6obot7ämot7ärou3raou7taou7tuou8geouff8owe8rp2feip2p1hp6fadp7haup7leap7te_p8fafp8farp8fefp8fepp8fexp8fidp8fomp8fäup8ho_p8legp8o7xp8pabp8patp8präp8pump8tospa2stpa5frpa7dapa7fapa7hopa7klpans8par5zpas8ppat8cpe1rape6enpe7impe7pipe8acpe8alpe8läpea8spel7dperu8pet8rpf1lopf3repf7akpf7rapf7sepf7sopf7umpf8espft8rpgra8ph7taphu7tpi2elpi3lepi7cepi7glpi8arpiab8pla8qple4eple5cplen4po2inpo5nypo7lipo7ptpo8plpol7zpoly1pons8pont6por3spot7upot8hpp3lepp3lupp5tapp7frpp7toppe7epps8ppri8eprä5rps8topt3repto8ppu1tapu5tepu8klpun8epus8hpuzi7pwa8rpä8topät5hpät7rpö8blr1ahnr1einr1ergr1ö8fr2en_r2nabr3genr3nitr4larr5aalr5donr5gesr5gewr5krir5r6ür5tehr6bübr7deer7ge_r7gerr7kolr7konr7l8or7l8ur7lecr7lepr7mesr7na_r7nacr7nadr7ne_r7nior7nodr7oxor7unlr7unmr7ölpr8abir8ac_r8arar8as_r8at_r8atsr8bimr8dapr8dexr8dübr8eibr8enar8enzr8gapr8he_r8hoer8ik_r8ikar8meor8nidr8obor8tidr8us_r8wo_r8zadr8zohr8är_ra1gora2brra7arra7höra7orra8drrada8rafe8rala2rat8orch1wrch3lrch3mrch3rrd7trrdt8srdwa4rdär8re1elre1orre2wire4bare4hire7cere7erre7gire7more8büre8hüre8obree8treh7lrelu8reu7frf7ferg7narg7nirg7ödrge8crho8iri1elri4fari6stri8eiri8fori8färif3lrif5rrik7lrim7trin8crit7srk4lurk7ourle8arlou7rm7tarn3f8rn7g8rn7k8rn7särn7terna8nrna8rrns8ernö8dro1chro1skro1spro3flro3tero3wero5dero5nyro7irro7lero7ofroa7troi6dror8üros4arpi8prr8errrü5brs2tirs2turs8ilrt7zörtmo7rty7lru1taru7spru8miru8riru8trrube8ruf3lruf7arute8ry8lerz5asrä3terä8scräu2srü1chs1atms1inds2phäs2puls2teis4pirs6el_s6suhs7accs7ceis7chys7labs7lars7osts7ozes7töts8arvs8chäs8ells8elns8elss8em_s8er_s8kigs8kips8söls8teds8tuks8tärs8zessa1lasa1lusa2brsa3fasa8fesa8grsa8sisa8vesag8esai8rsail8sam7psap7psca6psch2ese1umse2glse2nose5amse7apse8höse8ilsee3useh7lserk8sga8tshi6rsi1assi3rusi7ensi8käsi8sosi8susig2nsis7iskto8sku8ssma7gsmab8smit7so2beso5weso7liso7nyso7rhso8bosone8sop7sspa8mspi8ksrö8sss3s2ss8ärssch6ssoi8sst2ast1hist1host2acst5slst7lesu7ansu7fisu8ebsu8rosuba4sul8asult8supp8sus7esus7it1anht1arbt1ehrt1impt1stot2hust2sext3rekt3rüst3sact4es_t5uhrt6hadt6remt7afgt7reht7sekt7sozt7tikt7zest8at_t8rert8ropt8sadt8seft8sikt8sopt8teot8tidt8zidta2plta5dsta5ikta5orta7tutadi1tai8rtal7dtch7wtch8ite2nite3alte7grte7ofte8actea8stel5ötert8teru8ti1elti3neti3nuti4zati6zwti7acti7ceti7frti7plti8eiti8kntif7ltiv7rtmal8to2asto5nyto8rötoi4rtoi8dtond8tot7stre6utro7bts1thts3s6ts7untsa2btse8ctse8etso2rtt1sttt2actt3rütt7hotto7stto7wtu7antu8sotuf8etur7ctwi8ety8paty8pftz1ortz7omtze8ntür3su1cheu1chuu1k8eu1ralu1suru1tatu1to1u3andu3endu3rieu5alfu5alru5ayiu5nitu5nucu5os_u5ra_u6aliu6bübu6elau6g7nu7albu7aldu7algu7alhu7alnu7alpu7alsu7altu7alwu7alzu7ansu7ay_u7ayeu7aysu7bitu7falu7ge_u7iddu7ismu7me_u7namu7nauu7or_u7orcu7orsu7ortu7orwu7raiu7sepu7te_u8bamu8bobu8bopu8fidu8fumu8fänu8gapu8gläu8gobu8gocu8gomu8gräu8igeu8mexu8muru8nobu8repu8sidu8thyu8tidu8ve_ua7drua7yauan8auant8ub8esub8rüuch1auch1wuch3luch3much3ruch7nue8ckue8enueli8uf1aduf1aruf1stuf1tauf3leuf3reuf3ruuf3räuf3rüuf7feufä6ßuga8suhe1sui7emui8stuit7suko8mul8knul8vrula8sule8tulk8aulo8iult8uum3t4um7akum7irum7ofun1arun1glun1inun2daun2kaun3atun3spun3zeun5teun7taun8osune2bune8dung2suno8ruo7ruup8fuup8pfup8toupt1aupt3rur1auur3neur5laur6skur7baur7kuur7änur8rhur8ziur8zäure7eure7uuro7surr6euruf8us1trus1ufus7ouuse8cut1arut1sput1stut3rüut7hiut7seut8esut8evutfi8utt7sutu8butu8nuz7otußen7v6liev8reeva2tava8tuvab8rve3live3love3nive3teve3tive3tove5nuve7müvere2verg4vert8ves1pvi1ruvi3g4vi5trvi7savi8elvi8lavia7tvie2wving7vis8uvize3vle7xvo2r1vo8guvon7svora4vore8vors2w7go7w7skiw7skyw7u8fwa5gewa7liwa7nawa7sawar7uwe2stwe6gawe7niwe8bawe8brwe8flwe8gowel2twer2swi7nawis1pwns8awor5awor7dwor7uwu2t1wun2swur2swäs8cx1a2mx1andx8emex8emsx8erex8t7hx8täsxa7flxdys7xe7noxe7roxis7exiss8xkal8xt7auxtfi8y1erny3endy3er_y6lesy7al_y7anky7en_y7ersy7laty7ne_y7onty7os_y7spay8le_y8pidy8pumya7laya7raydri8yen6nyes8pygie7yl7acyli8nyloi8yn8euyno8dyno8tyoga7ys8poysme7yst8eyure7z1walz3ärgz5wurz7wälz8henz8zalz8zidz8zorza8scza8tozbü7bze2laze7orzeh8lzelu8zem6ezi1trzme8ezo6glzoo7fzsau8zt7hozu3f4zu5s2zu7tazum8uzut8rzwi8ezz8abzzis8zür3cße8laßen7gä1cheä1chiä2g3lä2s1tä3chuä7is_ä7iskä7n8eä7ontä7usnä8umeäf8fläf8roäfen7äh7eiähl7aäl8laäl8p7änd8eäo7s8är1a8är2glär2stär6skär8afär8zuär8zwäs3teäse7gäsei8ät2saät2trät7obät7raätma7äto7räts1päts7iäude5äuf3läun2eäus3pö1cheö4chrö7chiö7ig_ö8recö8reiöch7lödi5eöf8flöhen7öl7tuölb8röo8taöpf3lös2stös3teözes6ü1cheü2d1oü2g3lü3be_ü5tanü8feiü8fumü8heiüb4e2über1üd1a8üd1s8üde8cüdi8rüfer6üg3saüh5i8üh5moüh7läüh7roüh7trühla8ühn8eühs8pülla8ün2stün5a8ün7spün8daün8frün8zaüpf5lür3spür5siür6zöür7seürom8üror8üs2stüs8soüse7eüse7rüst7a", + 6 : "1abläu1abrec1abtei1adres1affär1allee1analy1angab1angeb1angri1annah1anord1anspr1antei1anzei1anzug1apfel1arbei1artig1attac1auftr1chara1e2lem1e2xem1eifri1eig7n1einri1eintr1emiss1energ1engag1ensem1entfe1entla1entna1entsc1entso1erklä1essay1ethik1g2lie1g2nie1i4sot1impor1index1indus1inhab1integ1inves1isoli1lu8st1n2ann1n2ung1n2unz1n4umm1n6as_1na2ch1offiz1olymp1opfer1orgel1park_1partn1prinz1ring_1s2tel1s2teu1s2tic1s2tif1s2til1s2tim1s2tof1s8tah1skrip1sphär1sprac1star_1stark1start1steck1steig1stein1strah1struk1stund1t8al_1t8rai1tabel1tamen1treff1u2nab1u2niv1umfan1umsat1unglü1urtei1ämter1äpfel1ärzti1ärztl1äusse1ö2ko52a5bel2ach3r2b1los2blich2d1arb2d1auf2d1aus2d1ort2de1e62erem_2erer_2eres_2f1eck2f1emp2g1los2g3ler2g3nac2k3le_2k3ler2k3rec2kala_2kanda2klich2küber2l1amt2l1eff2l1ort2l1ärz2lauss2lektr2lentw2lober2loper2m1arb2m1auf2meise2n1art2n1eff2n1erg2n3atm2nerzi2nunte2pross2r1e2x2r1erf2r1erz2r1eur2rakti2reinf2reing2reinh2reinr2reins2relem2rena_2rentw2rient2rinit2s1ans2s1anz2s1auf2s1aus2s1eck2s1eig2s1eis2s1emp2s1ill2s1inf2s1inh2s1ins2s1int2s1ope2s1ord2s1pf82s1unf2s1änd2s3pla2s3tag2s3te_2s3tik2s3zei2s7tou2sauto2schef2sentw2sorga2sproz2spräs2st1s22stel_2steln2stem_2ster_2strak2t1auf2t1h6a2t1h8ä2t1hei2t1hil2t1hob2t1ind2t1inf2t1und2t3reg2t7re_2teche2teign2telem2tempf2tentw2tidee2tiket2tordn2torga2treic2treif2trige2tunab2z1ein2z1wer3a4nim3ab8on3abbau3ablei3aktue3algor3alkoh3allia3ampli3arabi3atmun3ausfl3auslö3ausrü3auswe3chanc3chef_3chron3draht3dreie3e2hep3e4pit3e4tui3echo_3effiz3einna3embar3enniu3entfa3etapp3f4läc3gungs3hands3i4dio3ideol3idol_3imita3infek3isola3lexik3name_3neigt3neigu3ni1tr3oa7se3omnib3onkel3ordnu3perio3plu8s3r2em_3r2er_3r2es_3r8ahm3raub_3reakt3reser3rettu3risik3rock_3s2ali3s2ame3s2ard3s2hop3s2ki_3s2pli3s4eit3s6low3s8en_3sabot3sanie3sarg_3sche_3sches3serie3slalo3spalt3speic3sperr3stab_3stadt3stars3steak3stirn3stoss3straß3ström3su2b33t4ha_3t6en_3t8er_3t8hea3talen3thani3thema3theme3trahi3traue3treib3trisc3trolo3tuber3u4nif3umfel3umset3utopi3war6e3ärmel4abler4abst_4arber4aren_4aufe_4auste4chech4ck1ei4d3ric4d3rut4d3und4d7amt4danzü4deolo4dopti4f3ler4g3le_4gungl4infon4k1int4k3arm4k3rad4k3reg4kanla4kindu4kland4klust4kroba4l3umf4lausg4lelek4lidee4linfo4lordn4manal4mindu4n5emb4na2na4natom4netui4r1amt4rauto4recki4reinn4rempf4ridee4rinte4s1eff4s3ohr4sanal4sanfä4sanga4santr4sidee4soffi4sprod4spunk4stels4stelt4steuf4stor_4storg4stref4strig4strua4sträg4stöch4t1heb4t5umf4tauge4tausd4tausg4tentl4tentz4thrin4trand4tring4täuss4xelem4z7e8x4za8na4zelek4äh3ne5a4syl5addit5album5an1äs5anheb5ansät5assoz5aufru5ausbi5b8lät5chard5chato5chosl5d6eic5darbi5deimp5entfü5episo5exzes5f8ron5glanz5glöck5immob5imped5indik5inhie5innov5insek5insuf5inven5islam5israe5lack_5land_5laria5lokal5lymph5merin5n6in_5nerfr5nivea5oblig5obman5ochse5orake5oszil5pa1la5passa5pfleg5radar5regel5reim_5rezep5rhein5robot5s6es_5s6hip5s6ist5sare_5shire5skop_5skulp5sprün5spule5stabi5stamm5stapl5streb5sung_5taler5talis5teisc5thal_5therm5these5tropf5trümm5tung_5umbau5umdre5umwit5ungew5weise5x4em_5zenin6a7be_6ach1w6aner_6ange_6arbe_6artei6b3leh6b7int6beläh6bents6bentw6bland6blesu6brigk6cheff6chunt6ck5up6ckemp6d7eig6d7int6d7ö8f6darti6delek6dentf6dentn6dentw6dober6drohr6e3le_6erkol6f5lon6f7ärz6f7ö8f6felem6ferd_6g3ort6g7räd6gland6grese6h8al_6herap6k5orc6k7liz6kentz6kinst6klied6korpi6kähnl6l5öfe6lanal6lanwe6latmu6leuro6lorde6löffn6m5imm6malle6manla6mart_6maust6mauto6melek6melem6midee6n3ort6nausb6nauto6nentw6nentz6nidee6nindu6noper6p7auf6pannu6preiz6rachs6ranst6rathl6rattr6reck_6reckg6reinb6reisb6relit6rentl6repos6rerwa6retat6rindu6rungl6s1asp6s5irr6s5pos6s5ufe6screw6seinl6sentf6sentz6sepoc6sisol6skirc6spack6spala6spalä6spatr6spred6sprog6sproj6st7t86sterh6sterm6stimp6stite6store6stori6stort6strai6strup6stänz6stüch6t1amt6t3rüc6t3unf6t5hov6t7abt6t8ruk6tabla6tafet6taggr6tappa6tarot6techt6tefeu6tentn6texam6timpu6toll_6trig_6trohr6trout6va7lu6z1arb6z3ort6z7imp6zelem6zerhö6zurku7a6kaz7a6kup7a6loe7a6nek7a8bo_7a8zal7aer6o7albat7alenc7alge_7allgä7allii7alpe_7ampul7an5od7angol7anmel7anthr7antib7atomk7b8ä1c7bendr7bietu7blick7blish7chia_7chias7chip_7ci8s77d8enh7dreck7dreiv7dresc7dross7e6pid7e8mir7e8pik7effek7eilfr7eilgu7einfü7einkä7eisho7ellip7embry7engad7entga7enthu7enzep7eritr7f8erö7f8in_7f8luc7fer7k7frau_7g6het7g8amo7g8hie7g8lia7g8lid7g8lio7ghale7heusc7induk7infiz7innta7intel7intol7labil7lala_7lammf7lemes7lemet7linhe7manip7mung_7n8asf7n8aul7n8os_7ne7ce7neleb7nenta7nenti7nentr7nergr7nings7noblo7noblö7nä7um7o8kel7p6arc7parfü7pensi7pensu7perle7perlh7persp7pinse7pirin7porti7puls_7pulse7relai7rers_7rerzy7resol7reson7restr7rätse7s4erv7s4kep7s4oba7s4teg7s6kif7s6pez7s8al_7s8apa7s8apr7s8cop7s8ha_7s8hig7s8hoe7s8itu7s8kik7s8lip7s8oft7s8oss7s8poh7s8tyl7s8zew7sabet7sang_7sau2e7schaf7schni7schul7schur7schut7sinn_7sinnl7slash7span_7spat_7sprüc7staff7stagl7sties7stieß7stopp7stroh7stätt7sulta7sy2n17sü2d57t4hur7t8ra_7t8rio7talia7tanne7tapol7taubh7tausc7techn7tel5d7teur_7tief_7tiefl7tiera7tins_7tipp_7tocht7topf_7tract7trauf7traur7trepp7trid87triko7triti7träne7tsubi7tuns_7unget7unis_7uran_7ursac7werk_7witzl7x4er_7z8er_7zwing8a1chi8ab8as8abbat8abbin8absar8ach3m8achsc8agen_8ageri8alabo8aland8anbas8andu88anern8angie8angs_8arbef8arbek8archl8archr8ascht8atmus8aufeh8auft_8augeh8ause_8ausen8b7amt8b7epi8b7lac8b7rol8b7unh8b7ärz8belek8bemul8bentd8bentf8billu8bleih8blis_8brind8chemp8chimp8chinf8chinh8chint8chinv8chiso8chunf8chunm8ck7al8ck7um8ckeff8ckunt8d3rot8d7aug8d7etw8d7eul8d7imp8d7ind8d7inh8d7osm8d7rad8d7rip8d7ufe8d7umt8d7unz8d7urn8d7ärz8d7ö8d8dalar8dalph8dart_8datta8delem8delfm8dentz8derbs8derdb8didee8dinfo8dinsp8dinst8drahm8dumsc8dungl8dunsi8dursa8e3nie8e7na_8eie8n8einfo8ele1s8ena4c8endel8enorm8erbib8erest8euron8f7roc8f7ätz8feing8feise8felek8fentf8fentw8fentz8fober8fungl8g5arm8g5lin8g7amt8g7int8g7lam8g7ruh8g7u8f8g7ärz8gabsc8gabtr8geinr8gelek8gentw8gerdg8glieb8gläuf8gnanl8gnent8gni2s8graub8grege8gruf_8h1emp8h7emb8h7ärz8h8ats8henga8hentw8herif8ider_8ina8c8k3uhr8k7eic8k7eva8k7lac8k7loc8k7loh8k7lät8k7löf8k7nad8k7neu8k7näp8k7ofe8k7org8k7roh8k7up_8k7ärg8kallt8kandä8kanom8kanor8kansä8kauss8ke7o88keinh8keise8kelek8kentl8kentw8kergu8keros8kersa8kiern8kinse8klist8klösu8knorm8kreak8kredu8kreim8l7adv8l7ell8l7eul8l7inj8l7okk8l7umh8lanfo8lanhä8lanor8lanwä8larm_8larom8laun_8lausr8lauto8lehe_8leink8leinn8lengp8lentn8lentz8letap8limpe8limpo8linsu8linsz8lisol8lisot8m7abb8m7eif8m7obs8m7ö8f8mallt8manat8mar8o8marag8matmo8mausd8memis8meser8minfo8minse8n1emp8n1imp8n1ony8n1ä4m8n1ö6f8n7ahn8n7air8n7an_8n7ebn8n7egg8n7ehr8n7ems8n7ink8n7int8n7irr8n7okk8n7umv8n7umz8n7une8namer8nanta8nassi8nausg8nentd8nentn8nerhö8nernä8nesyn8netap8nideo8niget8nisot8orget8orgia8p7lad8pange8pantr8pentw8pring8prott8r7akz8r7egg8r7elb8r7elf8r7erd8r7eva8r7inq8radap8rallt8ralpe8ralta8ramei8ranna8ransp8rantr8ratta8raufb8rausf8rausg8rauss8rausw8re6id8rechs8redit8reint8reisf8reish8relas8remit8rengp8rentg8repoc8rergo8restu8rheit8ridol8s1inv8s7asc8s7ei_8s7eic8s7eul8s7imm8s7osm8s7out8s7tax8s7töl8s7unm8sanka8schao8schex8schmy8schn_8schox8schäq8schöl8schör8sentd8sentn8seros8setap8setik8sex5a8sidea8spero8sperü8spier8spres8spriv8sprom8sprop8sprüf8stabb8stabl8stadm8stala8stalb8stalk8stann8stanw8statb8sterk8sterz8stie_8stien8stole8storp8stors8strad8stre_8strep8stret8stris8stros8ströp8stun_8stuns8stunt8stür_8stüre8sumfa8sumsa8t3hof8t3red8t3rev8t3ö8f8t5hir8t5hoh8t5röc8t7axt8t7egg8t7eul8t7him8t7ohr8t7ruc8t7rut8t7umg8t7umk8t7umr8t7umt8t7umz8t7unm8t7unv8t7up_8ta8br8tablä8talgo8tanhä8tanna8tanwa8tanwä8tarzt8tausn8tausr8tauss8tausw8tellu8teppu8terbs8terbt8teril8ternc8tetap8themd8thinw8thou88tillu8tinse8tochs8toffi8tradp8trahl8trahm8trefo8treit8trett8tritu8träuc8träus8träuß8tunif8u1k2l8ummel8v7ein8ve7sc8ve7se8velan8ventw8veral8x3e4g8x7oe88z3arm8z7akk8z7arg8z7auf8z7aug8z7eul8z7uhr8z7um_8z7umb8z7urn8z7wap8z7wed8z7wel8z7wen8z7wär8z7ä8c8z7ö8f8zelit8zengp8zerlö8zetap8zetat8zunab8zungl8zunio8zuniv8zweil8zwirt8zwiss8zängs_ab1or_ab5ol_ab7si_alt1h_alt5s_amo4k_ampe8_an1gl_ana3c_and6e_angs2_ani8s_ann8a_anti1_ar6sc_ark8a_as8ta_asbe8_ate2m_au2f1_au2s3_aufs8_ausa2_baus8_be3ne_ber2e_ber2g_ber8a_bi8er_bi8os_bit7a_blau3_bre4a_bu5ta_cas7t_dar4m_dar7u_de5mi_de7o8_de8al_dein2_do7pe_do8mo_dy8s3_ebe8r_echo5_ei4na_ei6tr_eine8_eis5t_ek7li_el8bi_el8fl_elb7s_en8dü_en8ta_ents2_er4dä_er4em_er8bu_es7ta_es7th_fe8st_feri5_flug5_fra8s_fu8sc_gas7s_ge3ne_ge3nu_ge3sa_ge5sc_ge7lu_ge7si_ger6a_ger6s_gla5c_gros2_grun2_gus5t_hafe8_han4f_haup2_he3fe_he3ri_he5le_he5xe_hin7u_hips8_ho8st_ioni7_is7ta_joni7_ka3la_ka7le_ke7ra_klan2_ko3pe_kopf1_kraf8_la7ho_le5th_le8ar_lo8sc_lu1th_ma3ge_man7d_man7t_mat8c_matu3_me1nü_me7ni_me7no_mer8a_mi2t1_mil8z_mu7ra_mu7ta_na7no_nabe8_ne7ro_nich2_no8th_näs7c_ober1_of8fl_oper6_ort8h_ost7r_pe5na_pe7la_peri5_pla5c_po4st_rad5r_rau2m_ri8as_ro5be_ro7tu_ro8ha_ro8st_rom4a_rös7c_sa7br_sami7_sau7c_se6ha_se7re_se7ro_se7ru_sen7s_sexu1_si7gn_si8te_sour8_spor2_ste8i_ta8tu_tar7t_te3le_te5ra_te6st_tehe7_tite4_to6pl_to8pr_tode4_tu7ra_tu7ri_ufer7_ul8b7_un3st_unen8_uni8t_ur5en_ur7ec_ur7s8_ural6_ure7t_ve3ne_ves7t_wah2l_weg3s_wort1_wurf3_ze5ro_zo7fe_zu2pfa1g2n8a1o8s7a2genta2l1eia2n1ora2r1aua4bonna4brisa4kusta4reina5d8aga6kes_a6l7ofa6lorca6merfa6nemoa6potha7b2loa7b8äua7chala7cho_a7ckara7dau_a7lar_a7las_a7nat_a7ralea7ralia7raloa7schia8berda8chepa8ckina8dinfa8f7oca8forda8gunda8l7ela8lessa8mesha8nanga8nisoa8ph7ta8que_a8r7uha8ranra8rerha8reria8s7aaa8s7afa8s7ika8t7räaa6t5raa7reaaat2s1ab5sauab5usuab7eicab7eilab7einab7insab7sanabais8abela8abi7stabtes7ach5auach5ecach7ehacon8nade8aladefi8ades8sadi5enadi8staf7artaf7runaf7staaf8fluaf8rolafi6koafi8eiag3reiag7ratag7rieag7rumag7sahag8d3rag8delag8lanage5scages3hags7puah3ostah7neeah8n5aah8ninah8t7rahme7sahn7eiahr7auai4bliai5n6eai8leiak7eisak7reiak7resaka5b6akt7raakt7real1intal6limal6lumal7appal7arral7artal7damal7exial7immal7ontal7stial7zenal8bäral8eidal8kneal8lamal8lapal8lidal8löfal8mapal8teuala5yaala8scalb3lealbst6alde8sale8aralk7saalk7scalk7sealo4gaalo6graloi8dam4minam6e8name7ruamen7eampf7oan2zauan6dexan6klöan6seuan6zidan7desan7ethan7genan7gesan7saran8andan8au_an8düban8ei_an8ergan8g7nan8kroan8o7ban8skuand2acand7eiang1laantes7anz7wäanze8nanzi8nao7t8sar1allar1odiar5ortar6droar6gliar7abbar7ansar7ehrar7eidar7infar7offar7spear8dauar8knear8korar8lesar8radar8rasar8rorar8skaar8tamara5geara7dsarbi5tare7raareim7ari7enark2taark2toark7loarkt3rarm7egart5seartex8arz1wearz4thas2phaas3tomas5tilas7ampas7atoas7eieas7etaas7innas7o8pas7s8ias7skias7tieas7todas7tosas8penas8pinas8praasalt7asau8fasch3masen7oasi8saass7poast8erat2z1wat7attat7rotat8setata3laatei7fati4vaato8moatra8tatt7adatta7sau3chiau4mabau6mumau7en_au7nerau8beuau8bläau8draau8eruau8feuau8morau8munau8soraub3liauer7aauere8aule8saun8auauss2tauto7fauver7aysi7eaz8zinb2lindb3erntb3reizb5riebb5rundb5s6kub6lissb7leseb7liefb7rat_b7ratgb7reicb7riesb7schub7sel_b7ungnb8erzub8erzüb8lancb8läseb8ra7kb8riscb8stodb8stübba4sebba6rorba7lalba8krebacks8bade7ibahn1sbahr8ebal7akbal7kabalke8ban6drban6klban8dubar7zwbas8sabau3fabau5frbau7flbaus8tbb7lerbdome8be1e8hbe5ckebe6lorbe7lecbe7recbe7thibe8atebe8atsbe8au_be8he_be8lelbe8letbe8serbe8sumbei5scbeli8eben2acben3ecben8euber7zebera8sbern8abers8kbes7sabes8pobeste2bgas3sbger7bbi6o5dbi8ke_bi8kesbi8limbi8nokbi8stübiber7bil4dibil4dobild5rbiri7ebla7b8blaus8ble6mublei5fbläs5cbo6litbo7d6sbo8b7lbo8e7ibo8ruhbol7zabon8daboo6k5boo8tibrast8bri8dabru6tebru7nebru8s2brust7bs7ambbs7erkbs8zepbste4vbu4sinbuche8bur8grburg5aburts5by2te_by6tesbä7us_bühre8ca7t8hca8pe_cal8f7carri7ce7s8hce7ta8cere7uch1eilch1insch3lerch7aktch7edich7eimch7rolch7urscha8scchau7tche6noche7blchi3nachoi8dck1erock5a8cck7a8mck7eheck7spock8ernck8tarcka8r7clip7aco6re_co7derco7l8oco8leucof7f8cti4o6ction3cu8p5rcussi8d1s2tid1steid2sprod5rissd7emotd7rampd7s8cod7schwd8ern_d8geshd8riftd8rohud8salkd8saned8sehed8sersda2r1ada5istda7gobda7ismda7lagda7s8hda7teida8nanda8porda8r7oda8tomdab8radab8rüdafo8ndag8o7dan6zwdan8kadan8krdar6drdar8mudar8thdarf4sdauri7dde7rade2s1ude7adede7alode7chade7istde7rotde7sacde7semde8ca_de8delde8ditde8fa_de8nepde8nosde8ridde8rumde8xerdei8spdein7tdel7scdel7tadel8lädem8arden7deden7thdepo6tder7afder7r8dera8sdes1amdes1pades3s6devil8dho7fedi1n8adi3enidi4tandi7e8ddi7oradi7thedi8o7bdi8taudie8thdien2sdiese4dige8sdil8s7din7itdio8nidis1pedo7chido7rabdo7s8kdo8t7odoll8adoni7edoo7fedor6fldorf7udori7edos8tidre4hadre5asdre5nads5amtds8tilds8turdsau8ddtach7du7al_du7aladu7alvdu8rauduf8trdun3dadun4stdurch3dö8s7ce1inite1o2b1e1ralee1räume2helie2l7are2lente2n1ine2n1ofe2n1ope2nente2tat_e3altye3ausfe3p2f8e3ral_e3saste4herle4magoe4manze4n3ohe4nerze5ertre5lunge5nor_e5rolle5romoe5scene5spine6ckade6ckefe6l5afe6lakte6lanfe6minte6mulae6n1äre6natle6nelie6ostae6rupte6vange7a8sce7aleie7alexe7aline7altae7altre7e8cke7erbte7f8lüe7ing_e7ingte7lemae7lex_e7n8aee7nal_e7rabie7rad_e7radie7ralde7ralse7ras_e7ratie7raube7raupe7reibe7reike7renae7renze7rin_e7rolee7roloe7ropoe7sense7usare8arere8arese8aufoe8bunte8e7näe8fenee8harze8herfe8hunie8hunte8l7ure8lahoe8lanpe8lonke8m7abe8manoe8maspe8merwe8mesue8metie8minfe8n7oce8nelte8nerue8nethe8ostre8r7axe8ratle8remue8retie8risre8s7ade8spele8x7inea6b7rea7g8lea7ga8ea8m7oeadli8ealti8ear7eieasin4eate8reb2s1eeb7lerebese8ebs7paebs7peebs7tiech7reech7uhech7ö8ech8enechi7eecke6nede3ruede7o8eder7tee6benee7nadee8tateed7s8eede7seen6aceen7sheena6geer4eseer7aseewa8ref2flief7ausef7regef7s8cef7staef8fleefe8laeg7sagege6loegse7legus7teh5lereh7acheh7armeh7lameh7rateh7roleh7t8aeh8mabehl7auehre6cehre7sei1sprei2bliei2tarei4darei6mabei6sumei6zanei7gläei7sacei8gniei8humei8lamei8letei8murei8n7äei8nieei8tatei8troei8turei8tärei8zarei8zineich3rein2skeina8deina8seit7z8ek2tanek8tatek8tepek8timel1ansel1errel5lecel6limel6zwael7ankel7damel7eigel7elsel7embel7g8lel7orbel7ornel7te_el7zacela8ckela8riela8sielb8reelt7ekelz7arem8simemi7naemm7eiemma7uemme8len1i2den2klien3f2uen6ce_en7acken7echen7eheen7elben7epeen7evaen7olien7olmen7osten7ästen7ö8den8dexen8tidena6giena6scena8keena8maend4acend7saends6pene4ckene8kleng7seenst8üeo7beneo7s8eep6p5aep6p5lep8peiep8talep8tauepoli7er1agier1erker1erler1esser1inser1under6echer7a8ver7ember7ether7inker7inler7omber7up_er7useer7ä8mer7ätzera7faera7raerch4rerdeu8ere2ckere8taerg1s2erg7operik8lerk4seersch4ert7sperufs1erös7ces2kopes2stees2teces3sches5ehres6kates7a8ves7tomes8ammes8anres8chres8pales8sages8spuesa8raessi8aet2hanet7auket7relet7reset7upset8a8cet8erwet8tadet8taket8timete7keeti7naeti8taetin2getons8ett5reett7raetta8mette8netwa8reu4fereu4z3weu6z5aeu7faseu7p8feu7stoeu7t8oeu8esceu8ni_eu8niseudi8eeug7speulan8eum8soeun7kaeur8ereuren8ew7er_ew7ernew7ersewebe5eyreu7f2f1eif2s1erf3randf3raumf3reicf6ristf7f8räf7latsf7lindf7reinf7restf7s8kyf7s8ohf7stalf8f7eff8femif8lansf8lascf8lussf8spasf8terzf8tetif8tinsfa4chifa7s8afa8benfa8delfall7ifar4rhfar6bufe4rabfe6raufe6ridfe7chefe7romfe8l7ofe8l7äfe8tagfeatu6fef8frfehle6fei8nufel7tufen7scfena8dfer7daferde3fes8tofest7rff3licff7arkff7lagff7linff8sumffe8e7ffin7sffs7tifi1n6afi2lesfi3s4hfi7s8afi8klöfier8ffik7aufik7obfik7opfil2mafil8ipfin7scfin7sefing8sfka8t7fli8nefo3r8ufo6napfo8nabfo8nadfo8ninfol4k7for2stfou8l7fra1stfrei5ffrü8hufs4porfs5tipfs7ampfs7takfs7tasfs8horfschi8ft1ansft2s1oft2se8ft3rauft7abeft7eisft7ortft7resft7rilft7rolft7ruhfu8re_fu8ßerfun4knfun6kofun6kufä6ßerfün6flg5ankeg5lochg5reitg6littg6ruftg7iselg7riemg7rinng7rostg7s8äcg7sel_g7selng7selsg7spekg7stutg8sautg8spasg8spruga6b5lga6stega8mecga8seiga8selga8strgamma3gan7d6gan8gugd7elsge1nagge2s3kge3lecge3runge3tauge4rabge7heige7shage7t8uge8ma_ge8nelge8nimge8ropgeest7gei7shgein7igein8vgel7lagelb7sgeli8mgen7trges3seges7ebgest8eget7spghafe8gheit8gi4e3igi4me_gi4mesgi7alogi7stagi8enogi8kangi8metgien8egif6trgift3sgin8gagiste6gläs7cgne8tagne8trgo3s2lgo7t8hgo8posgoa7ligol8frgolf7sgra6bigra8blgrau7fgre7nogren4agro5begro6bagro8blgräs7cgrö3legrü3begs7eltgs8pitgs8thygsau8rgsfi8lgtei7sgu6tedgu7al_gu7an_gu7antgu7ar_gu7arsgu7in_gu7insgu8d7rgu8s7agummi1gus8stgus8trgut8sph1artih1erzäh1ringh1t4rih2aussh3eiseh3leinh3reich4übe_h5lauth5nadeh6risth6spelh6stafh6teifh7ampfh7arm_h7aufbh7echsh7erörh7impeh7len_h7leuth7liedh7los_h7meinh7meldh7minzh7raneh7raumh7ropah7räumh7stanh7stäth7tankh7tat_h7taumh7tet_h7treph7treth7tromh7uhr_h7wackh7weibh8anbeh8andeh8artsh8lormh8melzh8nunfh8r7ehh8rei_h8reigh8salkh8sanhh8sathh8serhh8serlh8sofeh8soffh8sparh8stolh8säugh8trinh8tursha5latha7fakha7ralha8nanha8nemha8ve_hade2nhaf8tohafts1hal4brhalb3lhalb5shan6dahanf7lhar2thhar4frhar8zahas8sahe3chehe3ckehe3isthe3t4she5ismhe5rakhe5x8ahe7chihe7e8mhe7minhe7razhe8dithe8nidhe8rofhe8rophei6mohei8muheine6hel8orhen3glhena8gher7thher8daher8zwhera8bhers8kheter6hflei8hgin8shhohl7hi2liphi7tachi8k7rhi8mithi8o7phi8p7hhi8tanhier7ihiff8rhil4frhile7nhir4mahisto7hit7zehke7nahl1inthl7urnhla4gihla8grhlaf3lhlo8rehmes8thn3einhn5s8phn7innhn8erghne4rahne8pfhni6klho7ralho7rasho7sprho7staho8b7lho8f5rho8lakho8leiho8lopho8me_ho8mecho8medho8melho8sarhocha6hoche6hochs6hol7g8holz3ahotli6hr1inshr7a8bhr7a8chr7atohr7etahr7inhhr7isohr7spahr8tanhr8tophres7thro8nahs7aurhs8tinhs8unght1a8rht1eckht1einht2s1oht5rosht7a8dht7altht7apoht7ineht7rasht7relht7richt7römhte8thhti8n7htni6shu2l1ahu4b3lhu4b7rhu5tanhu6lumhu8leihu8lelhu8lemhu8lerhu8lethu8linhuk7t8hul7ebhump7lhus6sthus8sahut8zuhy8lorhy8pe_hä7us_hühne8i1al1ai2k3lei2schli2schmi3aleii3chloi3choti3enwii4k3nei4v7obi5a8lui5al7zi5ern_i5p6tyi6bunki6dauti6eindi6neski6rakii7alebi7alefi7aleli7alexi7alini7anebi7cha_i7ergii7frevi7frühi7naldi7ningi7nitai7nitzi7pfani7tal_i7ätemi8barzi8broci8bunti8danli8danwi8demui8garbi8gatti8gausi8gelni8gessi8k7äri8kakti8kanbi8kangi8karzi8l7aci8lembi8linvi8m7imi8manwi8merfi8meshi8metii8minfi8minsi8n7oui8ran_i8ranii8s7cri8t7äsi8tepoi8tisoi8tissi8trefi8tunsi8v7aki8v7ami8z7wei8z7wäi8zausi8zerli8zunaia6rabia8loniala8diampe8ian8zaib4recib7artib7aufib7leuib7lufib7rauib7stuib8seriben7aibus7cich3alich5eiich5leich7liid3armid6ritid8setide2o3ide7saie1strie2f3lie5rohie6briie6fanie6fumie6hapie6rapie7g8nie8choie8danie8farie8fauie8fähie8lidie8lorie8retie8sanie8spuie8tagieb6suief7adief7roieg4stieg7liieh7r8iel7d8ieles8ielo8bien8acier3teies8paies8tuiet7zwif2f3lif3licif7erhif8froif8tedif8telif8tepif8troif8turift7efift7riifte8sig3reiig7lagig7limig7radig7s8äih7um_ik7ebeik7eimik7inhik7ladik7losik7lufike8reikro5til1ansil1ippil3e8cil7artil7ip_il7ipsil8minil8moril8zinil8zwaila6beila8deilda8cilde8siler6gilf8s1iliga8ils8toilz7arim7pfoim7pseim7staima2geiman7dimhau8imm7auimp6faimult6in5triin7attin7eidin7ordin7trüin7unzin7ö8din8ergin8gagin8gatin8gorine7näine7uninoi8dinvil8inze2lio7k8rio7r8eio7r8hio8norions7aip4p7fip8panip8stüipeli6ir8rarir8rauirli8nirm7auirpla8irre4lirä7usis1angis1t8ois1talis5paris6poris7ampis7amtis7ortis7panis7teiis7toris7töris7tümis7umfis8endis8sedis8tocisage8isen7sisena8isi7stisi8deisiko3ising8isse7tist8enit1angit1urgit2triit2z1wit3rauit3räuit5einit7ab_it7artit8anwit8erwital7aitel5aiti6kliti7spitse8hitte2lium3a8iv5orgivat3aiz7artiz7irriz8eigizi8thjahr4sje4s3tje4t3rje8t7hje8timje8torjek6trju6b5ljugen2jun6gajun6gljun8grk2s1exk3leitk5aktik5operk5stubk6ans_k7ast_k7erz_k7indik7laufk7lin_k7redek7reifk7spatk7speck7steik7stälk8aus_k8ers_k8lisck8s7avk8s7ork8sengk8serwk8sofek8stalk8t7amk8telak8tunsk8u7naka3thaka4steka6tebka8loska8stika8t7rkai7s8kar6pfkard8akas3s4kasi7ekau3t4ke2lerke6selke7rodke7stake8benke8he_ke8henke8nimke8p7lkehr5okein8dkel5abken7drken7thkes6saket7haki1staki7d8rki7no3kin7shkle2brkle7usko8nemko8terkoch3tkof5f6kol8k7kop4fukop6fokopfa8kor8blkor8brkor8nokre7asks7elfks7erfks8chiks8eifks8endks8porkstat6kt3einkt5armkt7anskt7arskt7augkt8erekt8rankt8sorkta8rektak7tkte7rakte7rukti8mekti8sektro7sku4r3oku8raukun2s8kun3dakunst3kup8plkä8s7cl1amerl1artil1erfol1s2tul1st4al1steil4glicl4l5url4loril5chigl5dachl5draml5inhal6ein_l6einel6erzul6labtl6sampl6serel6tautl7akt_l7aneml7ansil7ausll7auszl7der_l7dernl7drisl7endpl7erz_l7g8ral7g8rol7itall7len_l7manal7s8äml7sundl7tan_l7tehul7tet_l7thasl8aborl8b7ufl8bantl8boral8d7obl8d7ull8datol8doril8einul8erral8getil8k7rul8kabll8l7oul8labkl8larcl8limbl8m7exl8merzl8muntl8s7adl8sanel8sanfl8sannl8sanrl8serwl8sphäl8spirl8spräl8strül8stucl8tamel8tärzl8z5wula2g7nla3teila7t8ila8busla8giola8kesla8kinla8morla8munla8naula8samla8sanla8seila8sinla8stala8stela8stila8xellab8ralaf7ralami7tlan8zwlangs2lar7eblasma3lat7stlat8thlau8brlau8folau8trlb8renlba8rilbst1eld3recld3reild5ranld5rücld7ab7ld7auslde7saldi8milds8poldwes8le6g7lle7s8hle7stale8gaule8inile8levle8maule8obele8spole8xisleb7relech7aleim7plem8enler2zolers8kles8kolesi7elett7slf5ramlf7ledlf7reglfs7tilga7t8li3s4ali7d8ali7g8nli8dolli8greli8nefli8nehli8nepli8veali8vesli8z7äli8zaulian8glie4brlie4frliena8lig7splikt5rlima5glis7salit7selivi7elizei3lk7erdlk7nerlke7rell7affll7attll7idoll7umsll8säulle7erllen7kllti8mlm7stelmer6llnes8slo6minlo7pfalo7rallo7thalo8geilo8gorlo8k7rlo8mello8ninlob8rilobe8slor8enlos7tolos8suloti8olp7le_lrau8slrö8s7ls2porls7ankls7umvls7unkls8potlsau8mlsau8rlschs8lt1einlt3umslt7ecklt7orglt7strlta2raltbau7ltimo8ltra3lltu6rolu2g3rlu2t3rlu3chelu6toplu7id_lu7is_lu7renlu8ckilu8g3llu8ranlu8s7ulu8torluft7rlug3salus2stlut3a6lut5eily7onnlyri7elz7achlz7auslü8hellücke8m1s2tim2einum7abarm7angsm7anzam7auslm7endlm7umstm8d7eim8d7umm8minsm8nesim8penem8spedma5drima7blima7choma7dacma7g8nma7lagma7lasma8delma8ke_ma8narma8netma8nummab8ramai8semali7eman7drmar7g8mar8krmar8sumaro7dmas8pamas8timat7stmats8pmble7imd7a8smd7atomd7rasme7erzme7stome7stume8gelme8laume8nabme8nimme8salmelet8mer7smmer8zämes6sames8pomet7römfi8lemi6sanmi6tesmi7l8ami7nodmi8di_mi8kummie6tamilch3minik8mino7smioni7miser4mit3s8mm7intmmas8pmmi7scmmi7twmmüll7mni7ermo8galmo8rakmok7lamon2s1mon8domont6amor8drmp6formp7hafmp7strmpa7nempe8lampf3lims4porms7amtms7umsmsau7emsch4lmsen8emt2s1emt7scomu7l8amu8ninmu8nivmuner6mus7tamus7tomwegs3mä7us_mär8klmühl7amün6zwn1ersan1s2tun2d1ein2eiden2t1rün3gläsn4kansn5eingn5endgn5erwän5n4exn5obstn6altyn6ide_n6orakn7albkn7e8gon7einkn7entpn7erz_n7eröfn7glotn7s6kyn7sklen7sticn7tehen7trepn7zenin8artan8arthn8d3rön8d7ofn8danan8dautn8dethn8dorin8einun8eratn8erlin8g7nin8geinn8ingon8ketun8klitn8knisn8knitn8krezn8n7ufn8nadan8nalgn8nalln8nison8nunfn8salln8sanmn8serön8soffn8sputn8stobn8sursn8talln8tathn8thotn8thumn8z7akn8z7asn8zantn8zausn8zinhn8zwetna2gemna7dabna7frana7m8nna8perna8rorna8symna8tatna8temna8thenab6rünai8renal7adnal7aknal7g8nal7tanales8nan4zwnan7eunar8rhnat7aunat7einbais8ncha5lnd7immnd7orbnd8ramnde2sendo5stndo8nane4arene5skane7ar_ne8neune8o7bne8penne8racne8ragne8ranne8raune8tabne8tagne8thone8volner7ecnes7evnet6zinet7hanf4t3rnfalt8nfres7ng7a8vng7anzng7lucng7ricng8anbng8anfng8ausngel7tngrab8nho7feni5el_ni5thoni7aloni7choni7d8rni7elzni7onkni7orani7talni8gabni8korni8kreni8norni8ronni8samni8somnie8sanife8snig8spnik7lonin1itnis5innit6tank7ei_nk7optnk7rosnk7urhnk8lipnk8tannk8topnla5genn5einnn7eisnn8ensnne4ranne6seno1r2ano6topno7ralno8leuno8ligno8livno8radno8tanno8tinnoch6rnord3rnot7einote8nnpa8genpas7tnrebe8nrö6s5ns2torns6pelns7erzns7ontns8alpns8penns8tepns8tännsau8rnsau8snsch7tnseha8nsfi8lnsi4vansi6vonsi8tenspa8gnsta8nnt1artnt3recnt3sannt8alant8errnt8opfnta7nenta8lonta8rantin6unu7in_nu8s7inus1penuss7pnz7achnzel7anä7us_nür7sco1skopo1stato1stroo2m1auo4rigio4tarzo5chuno5ras_o5s6hio6a7lao6heiso6herzo6terwo7b8alo7b8aso7de7io7i8tuo7men_o7p8fäo7s8huo7sphäo8a7mio8bunto8ckino8ginio8mageo8meruo8morgo8nerfo8nerho8ninho8nokeo8raddo8rango8ratmo8s7cao8temio8themo8ve7soa5chioa7cheoar8drob7achob7aufob7ausob7iteob7leiob8risoba6laobe5lioben7doch4asoch7ecoch7ehoch7eiocha8bochu8fock7spodein7oden7kodo7raof2f1aof2f3rof7e8dof7erbof7eunof8angof8teioff7laoff7shofs7enofs7paog7einogel7doh5lepoh7lecoh7neeoh7rieohle7sohler4ohn7acohol5eohr7afohr7amok8ab8okas8tol2g3rol2lauol7chiol8d3rol8d7ool8deuol8dimol8f7lol8farol8femol8zimolch7rolde8sole1r2ole5umoli7zeoll7saolo7peolz7wäolza8com7algom7eisom7erhome1naomi8c5on3n8eon4nabon7e8con7eröon7nanon7umson8gueona7thond8saonen7gonens8oni6klonie7gonlo8conse8tonsi6doo8t7aop2p5lop5fluop7erhop7flüop7lagop8finop8panopa8leopeli8opi5a6opo8laor2glior7adror7akuor7attor7ghior7r8eor7s8aor7te_or7uhror8deior8faror8mamor8mebor8nauor8tauoran8forau8sorer7iori8miorin1iork8anormu8normwa7orna8corno7soro7naorta8rorte8norzel5os2s1tos2titos3penos5tocos7pecos8mogos8potos8tidos8toros8tugoser8koss7ovoss7paost3asost7obot3retot5agoot6t7hot7astot7erbot8harot8satot8timot8treote6laotei8notor7aou7chiou7f8lou7is_ou7s8iou8le_ou8lesou8retourme6oviso7p5fentp7fen_p7fensp7fer_p8p7ohp8p7rap8p7rup8p7ö8p8placp8pletp8s7adpa2rodpa6narpa7strpa7unipa8rofpan7depan7slpap8prpar3tepas6sppe7s8ape8a8rpe8n7ope8rakpech7epeni8tpenty8per2rhpere7spest7hpf7eimpf7einpf7lampf7leipf8erkpfen8ephen7sphi5enphil1aphy1lapi5nalpi5t8api6pelpi7o8ipi7onupi7t8hpi8a7kpi8k7lpie8rapil8zwpitz8eplan5gple3naple5nupo7ralpo8pakpo8stipom8phpor3nepot7inpot8trpp7eitpp7rolpp7rotppel3appels8pre7sapri6l7pri7ceprit7tpro1stpro7bepro7peprot6eps7teipst7aupten8gpu7shepu8k7opuf8frpum8plpä8tepr1erstr2ant_r2flicr2n1inr2stemr2sterr2t1arr2telfr3chenr3erblr3euler3schar4auter4nanzr4stinr4tangr5alm_r5discr5schrr6d5alr6mumsr6n5ösr6turtr7allür7alp_r7asphr7asthr7che_r7chilr7den_r7ernir7f8esr7italr7neidr7nen_r7schir7schur7skrir7steur7stier8aberr8althr8anber8andar8ander8anglr8ans_r8areir8aut_r8barzr8binfr8d7ofr8dartr8darzr8dinsr8drear8erflr8fentr8getor8gligr8ins_r8k7imr8keinr8kerwr8klisr8kromr8krour8marzr8merhr8nattr8naugr8nerzr8stasr8t7aer8t7upr8tabor8tallr8tansr8tanwr8temor8trekr8ums_r8z7amr8z7otr8zantr8zwirra4chura7gesra7sanra7torra8beira8g7nra8grura8krera8l7ura8mazra8nanra8naura8prira8retra8rinra8rorra8tidrab8blrad3t4rad5acrad7riraf2trrafor8rail8lral7akral7b8ral7skrala8sram8murama7sran7nerangs8rani7erap8prrar7zwras8torat7eiraue4nraut7sraxi6srb2linrb7rasrbeid8rbla8drch1eirch1s8rch1trrd7eisrd7ratrd7rocrd7rumrd7s8krdo6strduns3re1stare3nadre6pisre7a8dre7at_re7atsre7ebere7leire7menre8b7lre8meire8thyreb5aurede5rredi7ereil8arelea8rem4darem6drren4zwrer2zärer8fürese8hrese8treu7g8rewa8rrf7artrf7recrg7leurg7nomrg7rüsrg7salrg7senrge6anrge8lirho7feri3n6eri5eurri5nalri5t6rri6elari6ferri7am_ri7angri7nadri8conri8enäri8klari8korri8mauri8me_ri8s7priein7rig7lärim8sprin6grrin7nerin8korin8krris7toris8koris8trrismu6rit6toritt7ark7leurk7nebrk7optrk7renrk7sperk8tinrks7eirkto8brku8sarl8storlös7srm7ankrm7starm8orgrmo8nurmon5srn5ertrn7anirn7arirn7astrn7eifrn7s8arn7s8prn7stirn8andrne2tarne7ufrne8toro6tagro7s8iro8borro8brero8livro8ratro8tanro8tasroch6aroh5l6rolls8rom3eiron8abron8thron8täros7umrosso6rost3rrot4tarot7aurot7sarpe4rarper7err7aufrr7obsrr8henrr8hosrr8naurrad7rrre6parre6verror1ars4torrs4winrs7erhrs8mogrs8tevrs8tewrt7amart7rebrt7rolrt8anbrt8extrt8humrta8ckrteis8rtem8erti5narts7partär7sru7al_ru7in_ru7insru8ckiru8ckuru8g7rru8ni_ru8r7eru8t7oru8tabru8z7wrun4enrund1arund7srunei8rven7ery7sthrysti7rz8tanrzu8glräch2srü8helrüher6s1urtes2porns2spros3saris4s7öfs4sanfs4tücks4zenas5erzis5ofens5talos6hirts6kis_s6kribs6pinns6potss6simps6teues6torys6äuges7echos7entgs7erups7sem_s7telas7tinns7trils7tröss7tröts8anz_s8cheus8ensis8has_s8ins_s8phins8prens8prics8s7crs8salls8sanos8sanps8sumgs8sumks8talts8tasis8tauts8tigms8torcs8treasa2bensa4dersa5f8rsa5ikasa6delsa7b8äsa8giosa8gitsa8larsa8lidsa8mazsa8temsa8tomsaf8trsal7blsalz5asan7spsan8sksar8glsauri5sba8nesbil6asch5tasdaue8se3hense5er_se5raise6migse7at_se7en_se7enpse7ersse7eröse7stase8dikse8helse8hübse8legse8n7use8nelse8pense8selse8those8xensee7raseh7risen5klsen7trsena8dsenst8ser7amsera8dsers6ksho8resi1gnesi2k7lsi4s5esi6g5rsi6k3rsi6kabsi6vansi7am_si7errsi7n8asi8geisi8k7nsi8kaksi8kausi8kelsi8ketsi8na_si8samsi8sissi8tausie8busig7spsik3t4siken8sil8brsings8sini7eska1laske7rasko8prsla8vesler7ssliga5so7l8oso7ralso8nabso8nerso8remson8anson8glsor7ansp7le_spe7p8sro7tusrös7css7takss8abass8arass8phiss8potss8tinss8turssa7bossan4cssau6rsse8ckst3algst5alvst7almst7anmst7eiwst7itast7oblst7ugast7unast7urlstapo7ste4muste4sesti5nasti6ristos8tstro2mstsi8dstu5rastum2sstwor8su6mansu7al_su7it_su8mausze7rasüden8t1a2nat1ansct1artit1herrt1s2tut1strot2auset2s1ant2s1aut2s1ert3akkot3helft3ort_t3rannt3recht3reist3reißt3russt3untet4riggt5arm_t5hennt5hesst5holtt5hotet5rindt5untat5ärztt6han_t6res_t7abitt7anont7ansit7ortht7raupt7reigt7reizt7reprt7rosat7rot_t7rumät7rösst7s8ost7semet7sexit7spedt7spekt7tackt7u8not7zwiet7ängst8areit8artat8ens_t8ern_t8halit8reckt8s7ept8sallt8setht8setit8tanwt8temut8wistt8zunita3chota4leuta4temta4tomta6pe_ta7glata7ir_ta7lagta7latta8banta8greta8letta8mazta8pesta8steta8tanta8tauta8tretaf8fltai6l7tak4tatak6trtal7autand3rtand6atar7aptar8totas1tatau8brtauf5atch5upte2chute3erzte3xante4nehte6delte6ditte6nolte7ränte7unite8hacte8himte8litte8mapte8mimte8nette8nevte8rapte8rette8sakte8tatteg8o7tei2lateind6tempo3ten7drten7ecten7imten7ähter7adtera8ctera8stes7sites8tutesa8ctex6tatga8sutger8ath8magthi7nutho7feti3e4nti6ronti6velti6vorti7aloti7choti7sthti8ganti8gitti8keiti8kluti8kopti8larti8lauti8norti8zirtie4frtik8eltin6kntin8eitin8krtin8umtis7title8ratmen8ttmin8sto3chato3ralto4nanto6munto7rasto7rolto8dunto8nadto8napto8nauto8nehto8pakto8patto8pfeto8ruhtof4fltomen4top7hitor5autos8satouil8tra8sttraf5ltraf5ttral7ltre7astre8tatri5cetri7gltri7nitris7ttrizi3tro5petro7smtro7trtro8hutrü3betrü5buts5takts7etats7ikots7um_ts7umbts7umvts7umwts8corts8pitts8puttsing8tswa8stt1arttt7anmtt7hintt7rudtt8erett8errtta8kettesä8tu5al_tu7almtu7alvtu7ar_tu7arstu7chotu7fentu8eretu8gantu8ridtu8roptu8s7etuba7btun8entund8etur7ebtz7editz7ehrtz8enetz8ernu2f1eiu2f1opu2s1eiu2s1opu3eruru3istiu3rundu4spicu5speku6d5onu6gantu7a6läu7alidu7cha_u7cho_u7choru7chosu7eruhu7erumu7erwiu7fen_u7ges_u7rasiu7ratiu7seidu7specu7stalu7t8etu8b7ozu8chedu8f7exu8ferfu8g7aku8g7lou8g7luu8ganbu8ganiu8gausu8geigu8gerfu8ginsu8glicu8glisu8gregu8grouu8m7otu8matlu8matmu8merwu8n1apu8n3anu8rerwu8rindu8rorcu8s7afu8sallu8serlu8serpu8spräu8topsu8z7ecua8danualer4uara8bub5stuub6reiub7eulub7ricubau7cube8beuben7auben7oubsau4uch7auuchst8ud7ratudi3enuditi8ue8na8ue8retue8ridue8tekuer7amuer7o8uer7tauf7a8tuf8froufa8ckufall4ufen8euft7s8ug7g8tug7ladugels8ugs6piuh6reruhe7a8uho7feui8cheuis7tauisi8nuk8teluk8tinul6phaul7embul8darul8secul8tauuld8seuler8huli6kaull7s8ulst7hum8samum8serum8sumumer8aumes8tump8faun2es8un5genun6gadun6kesun7de_un7desun7eisun7gesun7iroun7n8eun8abrun8ei_un8emiun8keiun8ketunau6sund7obupe8reupe8ruur2z1wur3altur7aktur7angur7apour7impur7ä8mur8nolur8sunur8taiur8trour8zepur8zopura8naurg7s8uri7enuru7flus1penus1tauus6sumus8porus8sepus8sezus8sofusde7suske4lusse8gusse8nut2z1wut5edeut6sinut7altut7ei_ut7eieut7helut7skyut8säuut8zehut8zetut8zinuten6auten7euti8viutli8nuto3s4uts8toutsau8utu6reutu7ruuz5z6lva4t3rva8t7hva8timvat7s6vatik6ve5ritve7lasve7leive7nalve7nedven7stver3never3swver5d6ver5snver7flver7tevera8svern2averst6vi7s8ovi8leivi8linvid7stviele8viers8voge8lvol6livu8enuwa1chowa3renwa4g3nwa5chewa8leswaffe8wal6towald5rwalt7hwan8drwangs7we2g3lwe2g3rwe4s3pwe6b7lwe7chaweg1s2wei5drwei8grweifs8wel7lewelt1awelt3rwelt7iwelt7uwelte6wen8kawer5spwer6gnwer6knwer6kower8grwer8kuwer8towerb2swerer6werg5swerin6west3awest7owest7rweste6wet8tawett1rwi7ckawi7s8ewim4mawim8muwin2nawin4drwin6dawin6nowin8gawin8klwiss8zwo8chawo8r7iwol8lawolfs7wort7swun8grwur4frwur6mawur8fawur8flwus7tewöl8fox7i8tux8t7edx8t7umxan7t8xen7s8xer7s8xi6l5uxi8demxi8larxi8lerxt5einxt7ranxtblo8xti8lay2chiay7s8tyydrid7yl3a4myl5estym8phaympi7eyri7enys7troyste8nyze7r8z3wandz5wachz7e8gaz8eindz8einoz8t7hiz8terzz8weigza7chaza7chäzan8kazanti7zar8trzbübe7ze7in_ze8dikze8notzei2trzeile8zela8dzell7szelt7szen3spzen7auzen7glzen8zwzent7szes8spzes8stzfeue8zger8azi5es_zi6o5dzi7chozi7esszi7nalzi8deizi8ninzi8tanzie8lazif8frzim6t1zin4skzin6sazol8lazon7auzon7s8zspor8ztein7zu3n2ezu8glözu8pfezudi6ezup6fizy7an_ße7reiä3hungä8d7iaäch6stäche6nächs7aächs7oäde3s4äf7t8eäfigs8äft2s1äge8roägs8taäh7leräh7stuäher7täl8b7lämi5enän2k5län6s5cän8s7aäne8n7äng8stäp8s7cär7stoär8sehär8zauären6eären7därme7eärme7särs7erärz7teäs2s1cäs8s7täts7enäu3s8eäu4b3läuder8äum8s7äumpf8äuse7iäß7ersö8b7leö8schiö8schnö8schwödien5öl8feiöl8narönizi7öoti7eör7essör8b7lör8f3lörer6eörer6lörer8fös8s7cü1r6o5ü4herfü7den_ü8ckinü8fentü8hentü8herkü8mentü8r7eiü8schlübe7leück1erüf7strüf8fleüge8läüh5lamüh5r4eüh7t8aühls5eül8leiün7strün8feiün8zunüp2p7lür3s8oür8f7rür8fleür8z7wür8zinüs2s1cüs8s7aüsche6üte6reüter7a", + 7 : "1a2ka7d1a2meri1a6larm1agentu1alltag1ameise1anschl1anstal1antenn1e2poch1eigene1eingan1einsat1einsät1elektr1eltern1erhebu1erhöhu1erlaub1erlebn1erneue1errege1erweit1erwerb1ho2ch11ingeni1initia1insel_1instal1instit1instru1interv1n4amen1o2b8er1or7g6a1orches1rangig1s4prec1s4trik1s6tati1s8tand1skala_1spring1steche1streif1t8rans1tausen1tätigk1umschl1urlaub1änderu1österr2aufen_2b3leit2d1anzu2dentif2e3rei_2e3ren_2g1arti2g3reic2k1arti2k3raum2k3reic2kandin2l1aben2l1ergi2lantei2lauftr2lendet2lerfol2lindex2n1e2le2n1entb2n1erke2narbei2nenerg2nersat2r1ertr2renerg2rensem2rergeb2s1alte2s1ange2s1einb2s1eink2s1ents2s1erhö2s3tele2s5eing2santei2schnas2stocht2strahi2t1inst2t3unga2tantei2tarbei2terben2tiefel3a2noma3a2teli3a4nalo3ablenk3admini3agent_3akroba3aktien3alphab3anerke3ansatz3aristo3armee_3aufent3chlori3chthon3dschan3e4pos_3eidech3einlag3englis3entlee3erlös_3erweck3etiket3imbiss3instin3klinik3leistu3liefer3nauste3orange3orient3pflanz3richtu3roman_3romant3räuber3s2pi8e3s2turz3s4arko3s4ars_3s4zint3s8ache3sinfon3spannu3stellu3streit3stuben3taufe_3therap3umstän3unkund3wage8n3z4werg4b3lenk4barbei4benteu4chinst4denerg4dentit4g3ring4genda_4k1arbe4k3räum4k3ä4mi4keleme4l1indu4lanzei4larbei4lebene4leinsa4lenniu4lensem4lerklä4linsel4merleb4munabh4n3anna4n3ungl4neurop4r3ersa4rangeb4rentfe4rentzü4rerkra4rerlau4ristok4s1einh4s1einr4s3prob4schanc4schanl4schron4schwas4senerg4sprinz4stausg4stechn4strieb4zerleb5a2roma5a4spir5a6lema5a6mid_5ablief5amnest5anstie5applik5arena_5aufbau5austri5b8latt5chemie5chemik5christ5e4pile5einfuh5elimin5entgel5erbse_5f6risc5i2deal5illust5infras5insass5labor_5n6auso5n6ing_5partie5partik5patent5radio15ressou5rinde_5romane5s2zene5s4pons5s6hari5s6hing5s6loga5s6tipe5saren_5saust_5status5strom_5sträuc5sungen5tablet5talbun5tracht5tradit5trockn5u6krai5umform5zange_5öffent6amerin6b5echt6b5late6b5ort_6beleme6chelem6chents6ck5ese6d5ärms6d7inse6deidec6deisen6e5lem_6einsel6el7emp6ergebi6erklän6f3ling6f5lein6fentla6g3lauf6g3lein6g5eise6gabtei6geleme6innen_6kensem6kerfah6l3ofen6l5ausb6lastiz6leleme6lendun6lenerg6lentla6linves6m5akti6marchi6n5arme6n5ernt6n5essi6n5estr6n5etat6n5ofen6n7e8pi6n7entl6nerklä6nerneu6o5ber_6p5lere6ph5the6pokaly6r1er2ö6r7erlö6rabend6rengag6rentsc6s3turn6s5ernt6s5ängs6schang6scharm6schle_6schobj6schunt6sensem6serfül6sindex6sperio6sperso6spreis6stabel6strans6stropf6surtei6t3ausb6t3hemm6t3rad_6t3reih6t3rinn6t3riss6t3rund6t5aram6t5eis_6t5endl6t5hiel6t5holz6t5hose6t5rake6tangeb6tanspr6tanzei6tarabi6tarchi6tauto_6tentfa6tentfe6tentso6tessay6tin3it6tinhab6tinsze6toberg6torgel6trisik6tänder6un2d3r6z5ofen6z7indu6zentwi6zergeb6zerwei6zin5it7a8temg7aldehy7antise7assess7aussag7charta7chauff7eintöp7entgeg7entrah7ergebn7erinnr7eu7tha7g8laub7g8num_7inkarn7intrig7k8lien7k8o2st7leitbe7linie_7linien7m8eist7nachsc7nis7s87pe7d8a7pendel7pes7s87pirate7r8erfe7r8erfr7rechts7reigeh7reigru7rerbib7rinnen7s2klav7s6tett7s8anse7s8ein_7s8eren7s8tagr7s8tase7s8taur7s8teti7sagen_7sauste7skanda7spross7statth7steifi7sterbo7sternc7streuu7t8arth7t8ran_7tartei7treck_7trennu7z8erl_8a7d8ar8an7ken8anfors8arre8n8b5ritt8b7adel8b7edel8b7eier8b7eime8b7entb8b7leid8b7rent8b7riem8ch7e2x8chentw8ckentf8ckentw8d3raum8d3reic8d3roll8d3rund8d5rose8d7a8bo8d7alte8d7ammä8d7anzi8d7einb8d7elf_8d7entd8d7erz_8d7erzv8d7i8co8d7rand8d7rauc8d7raup8d7riff8d7rind8dehyds8derklä8e5ner_8eigeno8entwet8erern_8erers_8ergebü8f7e8he8f7einw8f7lins8fenerg8fereig8g3regi8g3reih8g5lenk8g5raum8g7ernt8g7insf8g7lese8gangeb8generg8gerseh8h7aufm8hereig8hot7s88k1entf8k3ents8k3netz8k7akt_8k7anth8k7area8k7entg8k7nach8k7real8k7red_8k7reih8k7ries8ker8fo8kerneu8l7anha8l7ausw8l7eisf8l7elf_8l7ency8l7entk8l7erbt8l7erzi8lat4ta8leintr8leneuv8linsti8m7elf_8mentwu8n7arm_8n7arms8n7auss8n7ehem8n7entf8n7erbs8nehen88nerwar8näpfel8p7ausz8r7acet8r7eckz8r7eilt8r7elix8r7endg8r7erbs8r7erns8r7ernt8r7evid8r7innr8r7isol8re8rek8reier_8reifel8rerken8s5einw8s5eröf8s5tral8s5täus8s7attr8s7eine8s7einz8s7elf_8s7ohng8s7tote8sagent8schech8schess8schloc8schlöc8schmoh8schneb8schnut8schorc8schrad8schre_8schrep8schrou8schweg8schwid8seinfl8seintr8sentla8serseh8spartn8sperle8st7urt8stabit8stapol8stausc8stiefl8stimma8streib8t1herz8t3ausf8t3elf_8t3rein8t5ausz8t7atti8t7erzb8t7eunu8t7inka8t7inku8t7reim8t7rent8tempfi8tenerg8tensem8terbos8terinw8trendi8z7angs8z7arti8z7echo8z7ergu8z7ergä8z7erzi8z7unem8zensem8zerfül8zerlau8zinsuf8zunget_abend3_al4tan_al7len_al8tri_all8ei_alle2r_an1alp_an3s8p_an7alg_an8si__angst7_ar8mun_ar8t7r_ar8tan_arter8_as3tro_as7tra_ato2me_be7erb_be7sab_ber8tr_berg1a_berg3r_berg5l_bi8ens_bo8s7k_bur4ga_bürge2_che2f1_chi4p3_chi7er_da8te__da8tes_dach7s_de1ins_de5spe_de7int_de7ran_den6kr_den8ka_den8ko_donau3_doppe2_dor2f1_eisen5_el8fei_en2d7a_en2t3r_en6d7r_ender8_enn6st_er2dum_er4ban_er8bei_er8dei_er8dep_er8zel_ere5ch_erzen4_es7tra_essig5_est5ri_fan4ga_fern3a_fi7est_fi8le__fi8len_fil4mu_film3a_flugs2_fus6st_ga8me__ge7n8o_ge7nar_ge7nas_ge7r6u_gebe8a_gel2d1_glas5s_grabe6_gross1_haf8tr_han6dr_han6gr_hau2t1_haupt1_he7rat_he7rer_he8bei_heima2_her4za_ho8met_hu5s6a_höch2s_immen6_in7n8e_insel5_ka8b7l_kal8o7_ker2na_kraft5_lang3l_lau6fi_le3n2i_lei6ha_ler6na_li6n5o_li8ve__los3s8_losch7_lus8tr_mar4kl_na5t8h_nor2d1_ost5al_ost7an_ost7el_pa8r7e_par6ka_par6kl_pes6te_phi2la_re7cha_reli5e_ro8t7r_roher4_ru7the_ruh8r7_sali7e_schi8e_schut2_seein8_sen6f3_seri7e_silbe4_sprun2_sto8re_ta6tor_ta7lar_ta8t7h_tan6ka_te3n4o_teil1a_test7r_ti8me__ti8mes_to6der_to6nin_to8nat_todes3_tri7es_tur6mu_tur8ma_umwel8_ur7a8d_ur7o8m_ur7o8p_wei8ta_welt7s_wer8tr_zeit1s_zeit5r_zie8lu_zin8ka_zu8gra_zucht3a2deriga3schena4bitura5isch_a6dels_a7charia7chen_a7l8eica7n8atma7schuna7t8heba7tzerea8cheröa8krotea8l7eska8l7inqa8n7insa8nerz_a8r7anza8r7appa8r7inwa8s7auga8t7raua8th7ina8x7ansab1er2kab1er2zab3esseab7er8rabe8lanabe8linabel7adaben2daabo5ranach5einach7eicach7erlach7u8facken7sade3strade5ramade7s8padi6o5daf8t7reaf8tentaf8terlafi8k7laganda3age8ralagemen6ah8l1a8ah8l7eiah8lerhah8t7exahner6nahr8ergahr8ersahr8ertahr8troahr8tunain7s8pais8se_ais8semaka8tanal2l7aral6t5roal7erlaal7erläal8dernal8t7akal8temualb7insald7ackald7au_alende8aler8klali8nalall6ernals7einalsch7salt7algalt7ricalt7räualt8stüam4mantam8m7auam8schlama8staame7r4aament4sami6kanan2t1aran3dreaan5thanan7i8onan8dentan8gerfan8k7eiana5cheana8derana8t7ranal2phanal7inand7armaner8faanf7rauang7artani7elsano8ideans1paranta8reanz7elfanz7etaaph5ersaps8terar3schear4mausar4meinar6mentar7s8haar8beinar8k7ilar8z7auari3er_ari7erdari7ergarin7itarin7s8ark6treark7aueark7lagark7shearmo6raarn7einarren7ears8katart7renart7riearz6t7ras5s6abas7tattas7trenasch7eiasen7thasen8erasi7er_assau7easser3aast7rauat2z1erat2z1inat6t3eiat7t8elat8s7inat8t7ecate8r7uaten8gaates8saati6kabativer4ato8manatt5ranatt7rasatt7rocatu4reratz7elaau6s5inau8b7auau8ferkau8s7ahau8s7ehau8serkau8serwau8trauauenge2auf7erfauf7indauf7skiaul7eseaul8lesaum7erzaus7erpauten6gavener8b7esst_b8er7krb8s7amtb8st7obb8stracba8k7erba8k7raba8r7amban2k3rban2k5aban4danban4k3nban7g8lban8darbar7a8tbar7astbar7insbauch3tbauer4nbbauer6be3s4aube6nerwbe6stembe7nabebe8l7enbe8l7ombe8ratobe8stabbe8sturbei1s8tbei8ge_bein6hibeit8sobeits1ebel7antben7endben8ergber7eiwber7issber8ei_ber8ergber8galber8habber8in_bere7ckbes7tosbes8abbbet6tanbge7l8ebho6l7abi8k7rebieres8bil8debbis8s7cblech5tblei7scblin6kabo8l7aubon8d7ebor8d7rbor8terbrater8breit3rbrie4fabrie6frbro8t5rbst7ernbtast7rbu8schabu8schlbu8schrbucher8bul8l7abundes1bur8ginbügel7eca7s8a7cam8p7lce8t7amch1a2ckch3echtch7auf_ch7es8sch8stalcha8b7iche8r3achi7stachne4e3cht7ruhcom8te_comtes8cre8mesd3rechtd4spreid7a8bakd7a8bend7ammand7arme_d7armemd7e8vidd7s8hakd8e7ismd8erland8s7embd8s7etad8s7pecd8steilda8del_da8delsdan6ce_dani7erdar4d7edar7inndar7um_dar8m7adar8t7rdauer5ede1in2dde4s5inde7insede7rabbde7randde7rassde7reiede7rerfde8l7obde8r7apde8r7eudel7e8cdelei8gdeler6rdell7audement6den4serden6zindend8ü7der7asider7eckder7ediderer7nderin7tderin8fdes4pordes7e8hdes7e8tdes7eildes8tandeten8tdgas7trdge8t7edi1s6tadi5elekdi6s5tedi7ens_di8s7a8dor6t5hdor8t7adost7andre6h5odrö8s7cdrü7ckeds4ternds7taufds8eigndseein6du6b5lidu7s8tadu8schndu8schrdufter4duk8terdun4k3ldunst5rdwer7tee2l1eine2missie2n1erfe2n1erhe2n1erle2n1erre2n1o2re2n3atte2nachse2nensee2nidene2r1e2he2r1inde2r1inte2tappee4l1erze4lefane4n3erde4nernee4r1o2re4r3uhre5lein_e5leinee5statue6b5le_e6l5eröe6lausfe6lerlae6motioe6r3erme6r5iate6rangre6ransce6reckee7alerbe7at7t8e7neiene7nobele7rand_e8hensee8l7anme8lerkee8lernäe8r7emae8r7erhe8r7icoe8rentne8rernee8rerspe8sta8se8starbe8staufe8stause8z7ennean7a8rearen8eeb7straebe8rasebet6s3ech7einech7takech8erweden2speden8seeder7inederer2editen8ee5i6scee7r8unef7aktiefehl6sefeuil8efühl4segen7eceges3tregse7heeh8mantehen8treher4leeher8anehl8erfehr5eckehr7schehr8ernei2n1inei2n1o8ei2t1alei2t7anei4t7abei6t5umei7ereuei7s8kyei8buteei8lantei8n7atei8nerfei8serhei8traueiche6neid7eiseienge4eig7rateilen7eein8dukein8fizein8ingein8nenein8toleinen8eeis5ermeis8tolek8to8bekor6daekt7aktekt7ankekt7erkektur5ael7auflel7aufwel7echtel7ehe_el7inkael7lendel8seinela6benelbst3aele7r8aelei8meelen6kaelen8seeler6zäeli1ef_eli7efseli8nalelk7s8cell7armelt7ethem6p3leen3ertren6erfren7e8scen7o8bren7sabben7t8elen8kerken8nerfen8nerlen8t7osen8tanmen8zerkenau8f7enchar8end7arrend7s8lends8auene5rösenger8aeni7er_eni7erpenk7ausenk7ergens8telenzlan8er1u8m7er3s2auer7echser7skaner8t7hoera2benerau4f3erd7erwere8ditere8videren6zaerer2sterer8rieres7skeri7er_erien7sermen2sern7erferri7erert7a8dert7strerter8geruch4ses3tantes6s5ofes6tinaes7tat_es8parkesam2t1eschi8eese8lerese8neuesen8aceserve3esi3er_esi7ersess7altessali7essau7eessau8sest7ascest8erkesta7geestab8bet5a6mieta8t7reter4treter8höetstür8ett7ruhetze2s3eu6genteu7ch8aeu7s8treu7thereuerer2eufels5eugen7eeuland7eum4s7peur7asteusch8oeve7r8iewer7teewinde7f5e6benf7sternf8s7etaf8t7ricfa8chebfa8chelfal2l1afal4l5ofan6grafar2b3afar4b5rfar4berfar6b5lfar8binfar8r7afaus8trfe6l5erfe8l7elfe8l7esfe8r7alfe8ranzfe8reisfel6sanfel8dinfeld7a8feld7rifen7s8afer2antfer7eckfer7ellferer8gfest5akfest7eifet6t5afetti7sffe6l7affe7in_ffen7thffs7tanfi2schrfil8medfin7stifisch5mfisch7lfkaken8flauma8fo8n7anfo8n7aufor2t3rfor4t7hfor8masfor8meifor8morfor8tanfort7s8fras7tafro8n7afs7tüteft7e8heftware5fun6k5rfusser8fässer6g1strecg3s4eilg5stangg7erlasg7rand_g7s8ackg7s8ateg7s8eisg7stellg7strumg8stürmgan4g7agandab6gang6spgarten5gas7erzgast7räge7rinnge8l7evge8lantge8tanggeb2lingeist3rgel8deigelder2gen5t8hgener8fgener8zger7altger7ampger8satgeren8sgerin8fges3s8tget4aufgge2stigge6raugister5gla6s3tglan8zaglerei8glings7gmen8tugold3a6gra4b3agra8s7agrati4sgren4zagrenz3wgril8lagro8b7rgs5chefgs7checgs8ki7egst7ritgunge6wgur8t7rgus6sergus8s7ogzeu8gih2l1erzh3re2s1h4ü3benh6nersah7eintrh7erzeuh7lächeh7n8au_h7r8erzh7rieslh7romanh7rö8s7h7s8choh7s8exth7sterbh7t8ateh7treckh7trendh8reinlh8romath8s7amth8s7audh8s7eieh8t7eimh8t7ekeh8t7emih8t7essha8t7rehaft8sphal2b1ohal2t3rhal6binhal8lanhal8seihal8talhalan8chand7rühasser6hau2enehau8merhau8t5rhaus5pahe8l7anhe8n7ethe8reinhe8ro8bheb7eishei8marhei8meihei8n5ahein7echeit2s1hek4t3ahel7e8chel7enthelsau8hen8gagher7eckher8kläheraus1herin8fhi7n8enhie8rinhied4s3hil2f3lhin4t5ahir8nerhl7einghl7einkhle7runhlei6fahlor3a6hluss5thme8reihmeer8shner8dehnflei8hnhof2shni8kanhnsuch8ho7bernho8f5a8ho8l7arhof5f6ahoh8leihor8terhossen8hr8einihrei4bahrei4brhres5s8hs7treuhse6l5ahse8linhst7altht3raucht6s5ahht7herbht7randht7raubht7reifht7reitht7rieght7shakhte7chahte8berhten8gahts7turhts7türhu8b7eihu8lenghul7stehun7d8ehunde3shunde7ihungsa8hus8s7ohutz5enhutz7erhäu2s1chühner7i1al7b8i2k1insi2t1a2mi2taliei4k5ausi5a6leti6b5eisi6b7eigi6dantei6gefari6k7eini6kone_i6schari7a8liai7a8nali7a8naui7alengi7alenti7alerbi7e8thyi7erbuni7g8neui7k8leti7t8o7ci7ät7s8i8f7armi8g7roli8k7eroi8k7etai8k7offi8k7resi8ke7rui8laufri8lentsi8ler8hi8liniti8m7elfi8m7erli8m7erzi8nenzyi8s7pici8schnai8schübi8t7eski8zentzia7n8erial7impian7altib5leinich7ortich8tinide8n7oie2g3reie4reinie6t5riie8b7rüie8fonkie8l7acie8lengie8tentieg8s7ciel5e6ciel7e8biel7intieler6öieler8eien8tarier3eckier7steier8ersier8re_iers7ehiesens8iet7herif7angeif7reifif8f7arif8t7eiifes7taift7erlig3sau4ig5s6agig7s8origenen8iger6zeika8t7aild7ebeiler4foiler8eiill6antimp7le_in6d7anin7ehenin7stanin8achtin8d7alin8elenin8gerwinaler6inden6eindes8iinen5s6ing8spring8stüinma8leinzipi3ir8ch7oir8keneir8m7eiir8muntis7tangis8au8gisch5maisch5miisch7ruise7strisonen8ist7a8citi8kaniti8v7aitt7rolitt8sorittel1eituran8izeit7sjah8reijani7t8jek6tinjek8takjek8terjektor8jugend1jung3s4k4ü3belk6s5ankk6t5rauk7s8pelk7s8telk7s8tepk7s8tewk8s7amtk8s7entk8s7tütk8seindk8steilk8t7erök8t7rask8terfoka4schmka8l7ehka8l7opka8lerikabe6lakal6kankala7b8kampf5skari7eskau4f7okau8ferkaufs7ake8l7acke8l7amke8l7auke8l7enke8l7o8kehr2s1kei8l7ikel7eisken5endken7engkener8nker6lauker6zeuker8eigkern5eiketing3kie8l7okie8leikind6stking7s8klang3rkle7ar_kle7arikno8b7lkoffe5ikop8fenkor6barkor8n7äkor8nackreier6ks7tat_kstatt5kt7austkturen8kul8t7rkur4serkur6s5pkur6stel2lentsl3aktiol3theral3u4ferl4cherzl4l3o4vl4linstl4s3erhl4steill4zer4zl5aufgal5interl5t6ergl6b5unel6m7ästl6meinsl6p5horl6s5anml7armatl7e8voll7k8menl7lans_l7stempl7tartal7tartul8b7ledl8beinkl8chentl8d7elfl8d7emsl8dentll8derfal8derhel8des8sl8f7eisl8fereil8k7alpl8l7infl8l7invl8l7orbl8lermil8m5artl8m7a8bl8m7erfl8messal8p7hirl8s7ambl8schinl8t7arml8t7atol8t7eskl8t7insl8zenthl8zer8hla2g1a4la8f7eila8g7lela8r7eila8s7ella8t7ralab6brilag7stolags4talan8zellang3salang7selanzen5laren8elast7anlat8tralate3ralatzer4ld7ein_lde7strlde8benlden7sele7re7cle7s8kile7s8tile8m7eile8n7atle8r7aple8rerkle8rerslei6brelei8feilei8strlein8duleit5selen7a8dlen7t8ilen8gaglent8wäler5engler7a8sler8riclerei8mlerin6slet8taulet8toplfe8relli7schmlie8s7clier8erlier8splik8tauliko5p6lin5itilink2s1lite3ralkor8b7ll7aufllla4benllen7drller6folli6ganllus7t8lme8ditlo8chello8s5trlop8p7als7e8lils8terklse7rumlstahl7lt6s7aslt7art_lt7reiflt7s8phltampe8lte7stalten4salter2sklter6salts7tütlts8porltu6rerlturan6luf8teilum6p5hlus2s5plus8s7alus8s7clus8s7oluss7trlusser4lut7s8aluter8slände5slär8marlücker7m5e6benm6m7ansm6m7einm6mentwm7achsem7ergänm8mentlm8p7lenm8p7lesm8s7e8dma7chanma7da8mma7lademacht5rmack6seman7ersman8ce_marine5mas6telmat5t6hmat7ortmat7rinmau8lesmaus8trmbi7er_me7nageme8n7evmedi3e6medien3mein7demein8damel7inkmen7endment7akmer6zermer7eckmera7ummerin8dmes6s5omi8e7nomi8k7armi8nerimi8s7temi8schamierer8min7e8cminde6smini7klmis2s1amis2s1tmis7sarmit7t8emma8ge_mme2r7amme8linmmi7s4tmon3s2umon7s8emon8dacmon8delmor2d1ampe8linmt7sendmu8ckelmuck7spmul8laumär8zermäu6s5cn2d3ratn2s1erhn2t1eisn3schenn5emanzn5erfasn5glockn5s8pekn5statin5stemmn6d7aktn6erzein6s5tasn6serfan7erbien7s8argn7s8tewn7t8a7cn7t8lemn7t8reen7tartan8acht_n8d7eden8d7ottn8dentsn8derosn8g7a8cn8g7rain8g7ratn8g7roln8k3rotn8k7lenn8k7leun8k7ortn8k7roln8kerlen8o7r8en8s7agin8schl_n8sernen8stilgn8strikn8t7emon8t7rean8tantrn8z7a8mn8z7wirn8zentln8zentzna2bendna8b7orna8b7rina8lermna8schmna8schwnade6l5naler8gnan4zinnanzen8nas8s7cnat8s7enauf8frnd3reisnd7elfendar4dande6lernde7altnde8al_ndel2spnders6tne1ck8ane7s8anne8r7afne8s7ofne8s7paneis7s8nel8l7anen8darner3eignergie3nes6signest5rineu6ereneuer6sneuer6wneuer6öneuer8fneuer8kneuer8rnfi8le_nfts7trng7ram_ng8se8hnge8ralngen7ecni3stanni7alimni7den_ni8kingnicht5anis7chank7art_nk7auflnk7ersank8tortnke8leinken8tenkt7ricnn8ergrnn8o7benn8s7amnner2zinns7tatno6b5lano7tartno8t7hono8ter8nor2d1anordi4rnoterb7nrau4mans3ersans7priens7tal_ns7trosns8anatnschi8ense7rasnse8hinnse8lernse8litnst7anent5ringnt7e8tant7reifnt8reprnt8sangnte8linnte8nemntest5rntra3fantral3antu6re_ntu8resnu7a8r7nul8l7anul8leinusser6nz7eremnzer6too2t3auso6b5lieo6lanteo6m7inso7undsoo8a7b8io8b7eino8g7inso8h7o8po8l7eiso8ler7to8m3erzo8m7arso8m7arto8m7into8n7inso8ni8kro8r7almo8r7indo8t7abio8t7armo8t7eibo8t7eico8t7i8mo8ß7enzo8ß7erbobe8risocher8kode7spoode8lagode8manodel4laoder8faof8s7amoff7erzogen7ecogener8oh8la8doh8lerhohl7eisoho6l5aoho8lenohren7sohrer6gol6f7raol8d7edol8d7eiol8t7amolar7s8oleste5oli7turoll7e8coll7eicom7a8syoma8neromar8teon8d7anona8linonaus6toner8faoni5a6koni6g7aonig7s2onra8d7ons5tipons7parons7tieonze7inop6p5reopa7s8topi7er_opie8ruopings6or6m5ador7e8thor8dingor8k7aror8muntor8tofforan6küoran6meoran8zeorden6sorgi7erorm7ordorn7ackors7tunort7an_ort7e8vort7einort7erbort7erkort7erzos6t5iros7sentos7ser_os7tarrosch7arosch7leosein8sossen6kosser6eosser8bosser8fost7a8vost7antost7apoost7ausost7ei_ost7eurost7ranot7straots7tauots7triotte4s3oun8ge_our8ne_ozen8tap6ferdep6p5lanp8fenerp8fin5sp8p7erzp8p7lispa7t6e8pa8n7atpa8nislpal8m7opal8t7apal8t7rpala7t8pan7t8hpar7aktpar8k7rpasser8pe8l7elpel7e8hpel7inkpel7innper7infperwa8rpharma5phi8kanpie2l1apil8zerpin7s8ppingen8pings8tplet6tapo8p7arpoi8de_poi8denpol8o7ppor8trepos3telpos5tilpos8tempost7rapp8e4n3pra5l6epreis7cpren6gaprings8priter8pä8d7erpä8tentpät7e8hque8te_r1eigenr1initir3ofen_r4danter4z3infr5achser5ch6lor5t6hagr6a5k6lr6b5le_r6d5umsr6m5erpr6mentwr6n7allr6strunr6terlar6zentsr7d8ensr7gung_r7s8havr7s8horr7statir7stinkr7z8wecr8b7lerr8b7leur8d7elfr8d7infr8ergehr8ergesr8ergewr8ergrur8flandr8g7a8dr8g7lagr8l7augr8m7aphr8mantrr8meinhr8mentfr8n5arer8nentsr8s7amtr8s7umfr8staler8stansr8stantr8t7erör8t7helr8ternär8ventzr8z7erdr8zentwr8zentzr8zes8sra6f5erra6pherra7l8exra7lampra8b7lora8chebra8chinra8lenzra8lingra8nerzrab7erdrabdru8ral7endral7erbrali5enram4mabram6manran2sparan4danran7aderan8deprand7serand7skrans5porast3rerat3z4erau2ererau8m5irau8magrau8trorb7steurb8steirba8delrbe7rumrbs3tätrch8i7drd7anzarde1r2orde7onorder6erre1im2pre7altere8henere8infore8lendre8s7amre8schwre8t7akrech7arreein8srege4larei4brarei7necrei7storei8feirein6szreinen7reises8reit7s8ren6zinren7ermren8sanren8zanrer2lanrer7strrest7rarfall6srfi8le_rgast7argi7er_rgi8selri7alimri7s8anri8f7eiri8g7lari8schwrib6b7lrie7nadrie8femriere8nrif8ferrif8terrin2g3arin6sekrismus5rit8taurit8trork8terlrk8tradrk8tratrka8b7lrkt7erfrlan8dirli8ne_rlust5rrm7anstrminen8rnen6errob7starol6leiron6tanrone6n5ros7telrote1inrpe8rerrr6einirri5er_rs8terbrschi8ersuch4srt3einsrt4s3orrt7anzart7illurt7ramsrt7randrt7ratirt8s7ehrtels8trten7s8rter6rerter8fortext7rru3a8r7ru8nis_rum8plerun8deprund1errvenen8rzell6arzeu6girü8ckels2portls3eindrs4selems5a6ries6and5ss7chargs7s8teps7skalas7tranks8s7amts8t7isls8t7unis8teinss8terits8to8nesa8r7u8sal8le_samten6san4dansan6dabsan8darsat8zelsau3n6asch3ordsch7stuse6rerbse7rungse7s8tuse8e7mise8herkse8n7ause8reinsech2stsee7i8gsee7lensee7n8eseher8esei4l3asei7neisein6fosein8disein8dusel7e8csel7erdsen7ecksen8sidsen8zerser7adlser7ecksest5risi6kanssi7ach_si8g7a8si8k7arsi8keresi8kin7sicht4ssin8g7rsing7sasing7sosinner4ska8te_ska8tessme7n8asni7er_sni7ersso6l5eiso6n5auso8n7ehson8s7osoun8d7spier8rspu8rersrau8masre7chass2portss5tritss8entesser8öfsses8sassquet8st5rosest7a8mist7a8vest7altast7anstst7armesta6siesta7lakstar6taste8g7rste8merste8minste8tagstei6grstei8nastenz5ästes5ersti6kanstraf5astur6masu8m7eisument8sunder8t1a2mert1ereigt2s1amtt2s1entt2t1eift3ordent3rangit4schrot5angeht5strect5u6fert6zentwt7a8dolt7einlit7elbist7hero7t7immatt7stratt8sachst8schamt8t7igit8z7eiet8z7eist8z7indt8zentgt8zentlt8zentst8zentzta2g1a2ta6lerhta8g7eita8l7opta8nerftadion3tage2s3tahls8ttak8tumtall5s6tan6dritan6z5wtan8gartan8gratand6satar7instar8tretarer6etas8temtat5orttau4b7atau8b5ltauchs8tauf7sptbauer8tchar8mtdar8m7te4nerste4reinte4rentte6m5eite6rerkte8m7aute8n7aute8r7ufte8remite8rengte8tablteinen8tel5osttel7e8ctel7ehrtel7eimtel7inntem7erhten7a8dten7emiten7engter5eckter7algter7altter7ascter7ikoter8an_tes7to7test7akthe7ranthi7er_tho7chrti6gerzti6l5eiti6verlti7s8trti8k7amti8k7auti8que_ti8schnti8schrti8schuti8veneti8ventti8verhti8verktie7s8ttie8reutig7strtimmer8tin8k7ltin8spatin8sumtings6ttisch5wtlan8g7tmo8desto5randtod5erntof4fintoff3s6tomar8btor7inttor8fantra7chatra7chltra8demtran6drtre8b7rtrei6bltrei6katri4enatri8ke_tri8kestro8kestrol4latromer4ts5tanzts7ort_ts7tat_tsch8litse8he_tseein8tt7achstte2l1atte8rikttele8btthä5ustuh8lertum8b7ltur5erbtur7anstur7eisty4p5intü7ber_u2f1entu5ischsu6b5lusu6ck7inu6g7anzu6m5armu6r5algu6topieu7alerzu7erintu7erunfu7eruntu7isch_u7o8retu7s8e7bu7s8pizu8b7eheu8beinsu8ckentu8f7e8tu8f7erhu8ferlau8ferneu8g7a8du8g7einu8g7rolu8g7rüsu8m7artu8m7erfu8meinru8meinsu8nerz_u8p7rasu8r7erhu8rentnu8s7ambu8s7eseu8schabu8sentlu8t7rouuar8tanuch8seluch8spruch8tebuch8toruck7elfuden7s8ue3reigue8reinue8remiue8reskuel8lauuen8gaguer7erruer8nanuerer6muf7straufel8saufs7ticug7s8tougend3rugge8stugs8tanuh8lentuhl7erbuhrei8sui8ckeruil8lesukle5inukt7ersul8d7eiull7eicum8s7anump7le_ump7lerump8finumpf8liun4d5umun8g7riun8k7round7a8bunder7gunk8titunk8triunmen2sunste8cunte8riuperer6ur2s1anur2z3a8ur6f5liur7a8beur8m7abur8mantur8mentur8mernur8z7ecural8tauren8erurg7innurgros8urin7iturt7einus6s5ecus8sespuse7ranusi7er_usland2usrich7usser6zut2schlut3t4leut4schout8schmut8schöute7rasute8leiuve3r2äva8tordve7randve7raneven8ergver5b6lver8ei_ver8sepvete3r4vie6l3avie6recvie8h7aview5envogel7evol4l3avollen2wa7la7cwach8trwaffel7wahlen8wal2t3awal6da8wal8dinwal8tinwal8turwan8durwan8zerwarein6wasch3rwe7cke_we7ckeswe7rinswe8g7eiwe8r7iowei2t3rwei7nelwelt1erwen8klawendes8wer2k5awer2k7lwer4t7awer6g5ower8krewer8t7hwer8trewerbe5ewerf3liwes2t1iwes8texwest5ecwest7eiwicht8swie7n8ewieder1wil8d7awin8g7rwisch7lwoch8e2woh8leiwohn6erwor6t3rwor8telwur8f7owä7schex8t7e8vx8til8lxi8d7eixtra7b8y5lantey7lant_y7lantiy8l7e8tyloni7eyri7er_yri7ersyste6moz3a4derzahner8ze7stauzei6tinzer8le_zer8lenzerten8zes8seizessen8zeu2g5azeu6g5rzger8s7zi3the8zie8lerzin8seizirk8s1zol8leizoller6zon8terzte7strzu6ganszu8gentzuchts6zug7rauzwei7scßi8g7a8ä1isch_äg5s6träge6r7aäl6schlämoni7eän3n4e8änge4raär8mentärm7armärme6laärz7erfäse7r8iäse7refät8schräu8schmäus8s7cö4sch7lö6sch7aö7isch_ö7r8erzö8r7uneö8sch7möchst3rögen8saögen8seögen8suöl8k7leöl8k7liörner8vöscher7ü2ckersü3cke8nü7d8ensü8h7erzü8hen8gü8r7entüch8s7cück6erlüge8lecügen7s8ühr7ei_ül8l7adül8l7auün6f5akün8f7acürte8l7", + 8 : "1assiste1eigensc1einheit1entsteh1ereigni1erfahru1erfolg_1erfüllt1erkennu1ersparn1erwartu1erzeugn1identif1offensi1partei51stiefel1älteste2l1ergeb2l1or7g82l5erzeu2m1orien2n1ebene2nerkran2r1e2lek2r1er2bi2r1er2nä2r1ereig2r1inner2r7antei2re6bene2s1ergeb2s1o2rie2stätigk2t1elekt2t1inter2tereign2tergebn2terlebn2torient3a2mateu3agenten3angeleg3d4schun3e2lite_3e2xiste3e4rosio3eigentu3eisenba3erinner3i4mage_3identit3inhalt_3inhalts3inszeni3intensi3interes3pflicht3ressort3s4kelet3s8ti2el3u4tensi4derlebn4fergebn4l3inspe4lantrie4postel_4rerlebn4s1e2ben4s1erfol4s1in1it4s3einsc4schmitt4seinsat4selektr4serweit4t1aktio4t1eisen4t3e4ben4t7umsat4tantenn4teigens4tengage4terhöhu4textrak4trichtu5anatomi5aspekt_5aspekte5aus7tau5editor_5eigentü5einflus5einhalb5einkünf5elastiz5enthalp5enthalt5enzyklo5erfindu5ernähru5ersehnt5erzählu5innere_5inspekt5instanz5k6leid_5spenden5tiegese5tun3d4r5umfahru5umschal5ungenau6b5lein_6chergeb6ckergeb6ckerzeu6d3ring_6d5ärmer6dertrag6erregel6fer6leb6gensemb6hindust6l5erbe_6l5erde_6l5ersat6lerlebn6lerweit6linstru6n5e6dit6n5erde_6n5i6gel6nerosio6r5e6dik6s3einfa6s3trend6schemie6schemik6schraum6serkran6singeni6spartei6t5erde_6t5ofen_6tagentu6teigent6teltern6tentste6terklär6turlaub7a8l7err7ergene_7ergenen7g8asse_7lentwet7r8erbil7r8erfor7rergebü7s6tereo7s6ternb7sterinw7t8artis8ch7e8ta8cker8hö8d7achse8den8sem8g7endmo8gassess8ger8klä8hergebn8k5a6ben8k7aster8k7er8zi8kantenn8ken8gag8l5e8tat8l7erhol8m7ungeb8men8gag8mensemb8n7e8he_8n7ersts8r7e8pen8r7i8gel8s3chara8s7e8gal8s7einsp8s7ermit8s7erset8s7tapot8sch7ei_8schlein8sungena8t1aktiv8t7a8der8t7engla8t7i8gel8z7e8ben8z7enge_8z7er8sa_adel6se_alb8rec_alt5ang_anden6k_app8le__ar6t7ei_ar8m7ac_ar8terh_bah8ner_be7s8an_cha6t5r_da8r7in_de7r8en_den8k7l_einzel1_en4t1ei_en7trop_en8derf_en8t7io_er8d7er_erden8k_erster2_essigs6_fer6n5o_feuer5e_gege4n5_gel6b5r_gol8der_hal2b3a_hau6s5a_heide5r_ka8t7io_kal6k5l_kupfer5_lage4ra_lan2g1a_lan4d3a_lan6d5r_langer6_ler6ner_lo8g7in_luster8_mutter7_nicht1e_ort8s7e_ra7ch8e_re5s6ti_reiner4_renner6_riesen3_runder4_sau7er__sonnen5_sport5a_ster6na_stim6ma_stra6fu_sucher6_tan8k7l_tex8t7r_umwelt5_uran8fa_vol2len_wehrer6_welter2_wer8k7r_wer8ker_worten8_zin8s7c_är8schla4l3endsa4l3ertra6h5er6ha7scher_a8l7endra8s7erkeab6b5le_aben2d1rach2t1umach7entrach8tritachba6raack7sta8adie8s7cag7s8eidagen8ergages8senahner8leahrten8gai8l7aufal8b7erhal8d7eseal8m7astal8scheial8t7ratalen6semalli7er_almo8de_amp2f1a8an6k5lasan6k5opfan6z5artan8g7erwan8g7erzan8k7rasand7erobanden8gaani7ers_ar5n6e5lar8t7ramar8t7rauar8z7erlare7aleraren8semari5ers_arter8laas8t7eseast7rollat8z7e8dateien8datenban4ater7s8tati8kerwau4s3türau6schweau8s7erbau8s7erfau8schmiaum7entsb7rechteba8l7erkba8t7entbach7t8ebal8l7ehballer6eban6d5abban8d7alban8dengbar7schlbauch6arbe1inhalbe4steinbee8r7eibelle6n7ber2einiber7e8scberin6spbran4d3rbri8kansbst7einbbstand4sbti8schobu6sch5wbu6sch7mbu8ch7ecbu8scheibun8d7erch7austrch7e8benchal8leichei4nercher8ziecke5reigcker6lebde7sternde8mentgde8n7e8dde8n7endde8r7endde8rei8sdel8s7poden8zersdes8tempdi3s4perdienst5rdo8m7ingdost7e8cdre6schmdres6sumdresser6du8l7artdu8sch7ldu8sch7we4delstee4e5insee5aler6te5raner_e6l5augee6l5essee6l7ersce6mittere6n5ermie6r5eimee6rerweie7a8lente7a8lenze7aler8ge7stricke8h7entee8l7andae8l7e8tae8l7erfie8ler8fae8r7entse8t7raumebe8r7elech5t6eieck8s7taede7n8erefe8l7eiefor6munege7stalege8l5auegriffs5ehalt8s7ehr6erstehrer8laei6nentsei8l7einei8s7erlei8schineich3takein8derkein8karnein8terveisser8sek7tanteel6d5erpel7d7erlel8d7erfel8l7artel8t7escelb8steielder8saelen4k5lelgi7er_elgi7ersell7einselt1er2femen8gelen2t1erben3ersteen3s2poren5t6arben7d8orten8des8sen8s7etaen8t7rolen8z7ermene2beneeni7ers_enni8gerens7umstenst7altepas8serer1e2bener2t1erser4ter4her8d7inner8n7alter8n7erker8t7erfer8t7erkerg7elsteri7ers_es8t7erzesbi7er_ese8r7u8eserver6esichts3esse5r6uest3eingester8keestmo8deeto8n7aletsch7wueue8reifeue8reigeue8reiseut8schaeut8schneut8schrf8s7tresfal6schafal6schmfal8schlfaller8sfan4gergfeh8l7eifel6d7emfel8d7eifel8s7ohferie6n7fi2sch1afi4sch3wfi8sch7ofings6trfizier4sfor6schlfor8m7agfor8maldfor8t7erfracht5rfzeiten8fäs8sersg5s6tromg7s8orgeg7s8pantg8sportoga6s7e8mga6s7entgan8gerggang6stügas1tankge3n4au_ge7n8augge8r7entge8s7terge8sche_geis8s7cgel8derhgel8dersgen8s7amgen8z7arger4einigerin6deglan8zerglei8t7rgrafi2kagram6mergrenzer4gs8port_gst7reith6sportah7erkranh7ritterh7s8ternh7tratesh8l7entrh8ler8näh8r7eifrh8t7e8seh8t7elfeh8t7elith8t7entfha8ch7enhal6l7auhau7f8lohaus4se_haussen8he6n1endhe8r7inhhein7erthel8l7auher2z1erherbst5aherin6sthfaller8hicht8sphlan8d7aho6ckerlho7bers_hre2ckerhrer6lebhrer8gebht8s7endhten8erghter8de_hterer8shu8b7en8hus8ser8hweis2sti6n7erlöi7a8lerhi7k8lerii8gebraui8kanteii8l7errii8s7es8si8s7etati8sch5rei8schindider8regie4t3ertie6r7eisie8l7eleie8t7ö8sieler8fiieler8keieler8laiens4teries8s7tiif8t7escik8t7eskil8d7eseilan8zerili3e4n5ili8g7abilitär3sim8menthim8p7lerin5sch6lin7d8eidin8k7entin8s7umsin8samt_inan4z3aindes6tuings8porinkauf2sir4sch3lir8sch7mir8sch7rir8sch7wis8s7umsisch5lamisch7musische5reise8r7eiiso8nendit8strasit8z7e8citen8gagk7en8te_k8s7tanzka8n7a8skas8traske8l7eimken8ten_ker2regekeu8schlkre1i4e4kt7i8terl5erhaltl6l5eimel6l5erntl6l7eisel7anschrl8b7e8tal8b7eisel8derlasl8l7ausfl8l7entfl8l7ergol8s7ort_l8s7tat_l8s7tatel8z7u8felan8derwlat8schmlat8schnlat8t7inlat8t7rolau8schald7armenld7armerle4g3astle8l7erdle8r7eisleben2s1lecht6s5lei4schwlei8scholei8sernleifer6gleis6steleis8serleisch7aleit7s8tlen8k5luler4werblester6iletsche6li8g7ersliebe2s1lini8kaulita3n4ellen6erglt6s5ortlu8g7e8blu8t7e8glus8serflus8serklus8serslut7schllüssel5em6energem8p7lem_magi7er_magi7ersmal8dehymar6schlmar8schmmar8schrmasse4n3mee6r5eimeinde5smeiner8kmel8k7eimi6sch5wmt8s7chimu8r7u8fmun8derfmwelten6n2schlicn6n5entsn6zerhaln8k7laden8k7o8ben8nereign8s7erfon8t7anzan8t7es8sn8t7riegn8zen8sena8l7entna8l7erbnan8zengnavi7er_navi7ersnde5strinder5stends7chinne6bene_ne6n5erbnel6l7einera6lernge7l8eingriff6snit8t7ranitter6gnitter8knk8t7ernnnen8ergnner8gebnner8warnnvol7leno5isch_nor5d6ernrücker8ns8t7entnsch7eulnsinn6s7nte8reisnten8te_nus6serlnz7ersteo8n7endso8r7e8cko8t7entbo8t7er8loberin6goge7n6idogel7steogram4mooh4l3erwoh8l7ergol4lerweol8d7engol8d7eseol8l7essol8z7ernold7ersaoli7e8n7oller8geon8t7ratonaler8eonan8zeionzer6tropf7erdeopi7ers_or6m7ansor8m7erfor8mer8gor8t7ortoraus8waort7ersaorter8faorter8scos8s7a8cot8em7p8ot8t7a8spa8r7affpar8k7ampargel8dpaten6trpe6r5e6lpen7s8o7per8r7anphal8t7eppel7steprei4serprung5scpä8ck7erpä8t7erbr4m3erser6strangr7gungenr7t8u7nar8b7lastr8d7erntr8erstadr8f7raucr8l7a8scr8n7order8s7ort_r8t7albera6d5einrach8trärali7er_rali7ersram8mensram8p5leramm7ersran6d7errang7steras8t7eirau8mentrber8ginrcht5ergrderin6sre8h7entre8t7rolrei7n8alreich2s1rein2starein2vesrein8tegreister8rel6l5eiren7enderen8z7arren8zerfrge8l7errgen8semrgen8z7wri4gen4eri8sch7orin8dizerin8g7lerin8t7rerk7erstark8t7engrk8t7etarkstati8rkt7erscrlaub2s3rmi8nanzrnse2h3aro6h5ertro7isch_ro8n7erbrs6t7erwrs8t7erörse1n6alrt3erhalrt7strasrter8mitru6ckerlrun6derkrun6derlrun6dernrut8schas3ertrags4tenglis5engel_s6ha6ke_s6porthas6s5endls6s5estrs6spartis6t5estnsa8l7erbsat4z7ensau8g7lesbau8mensch5armesch7erfüsch7s8tise3r4um_se7stempse8n7essse8r7enksechst7rselbst3iser8sehnsfal8lersho5fen_si6ker6lsi8v7erfsiege2s3sin4nerfsin5g8leson7endesrücker6sse8rattssen8ergssen8semste8mentstel8länstes8se_steu5eristrie7s8su8mentsswe8gerst5s4ternt5s8traft5s8trict7ergreit7s8terot8erstadt8schartt8t7entbta8l7engtal8entstal8l7actal8l7ö8tal8s7entam8m7ertarter6etau6schatau7f8lite7isch_te7n8ei_te8n7endte8r7endte8r7erptei8lenttei8nenstein7e8ctein8habtel7l8ertel8leinten8sumsten8zerwtent7ricter2statter7alleter7eifeteren7thtes8terhteue2rerti8k7reiti8kliniti8scheitim8mergtlei8dertling8s7to7isch_tof8f7ertof8fentton7steltoner8ketrau6mertrücker8ts4port_ts7traumtu8r7e8ttu8r7e8vtudie8n5tzer6gretzwan8d7u7s8trasu8b7erdeu8f7erleu8g7reisu8gleitbu8sch7euuch8terfuchar8meudiener6ue8r7a8tuenge7spuer6bautugel7steum7engelun8n7a8dund7erfrunderer8unsch7elunsch7wiuran7a8turch4teruren8gagurteil6susch7eicusch7werusch7witusi7ers_uss7ersuute8ringversau3evi8l7e8hvie7r6ervoll1endwa8sch5lwan4d7a8wandels6was5s4e2wasser3ewe7cken_weg7erscweh8r7erwei5s4trweifel8dweinsau8weis8spiwel8schlwel8schrwen8k7riwer8gelswer8t7riwerdein8werter8kwillen4swin8derzwor8terhwunsch7lx8t7er8fxpor8t7rxtblock7yste6manz3erhaltzei6t7erzel8l7aczel8leinzen8z7arzen8z7erzerin8tezert7rauzin6s7erzweiter8ähl7e8beäse7r8eiäss7ersaö8sch7eiö8scherfö8scheriüge8l7a8üterich8", + 9 : "1erkranku1strasse_1urkunde_2m1ar7t8i3a4rithme3anhänger3entsprec3interfac3s4kalen_3s4terbli3umfrage_3umwandlu4der4gebn4l1ereign4l3erfass4lentsche4serkläru4t3a4bend4tentsche4terkennu4zen4ergi5a6lerfah5an2t1ago5apostel_5attentat5entdecku5erstattu5erzeuger5inhalte_5italieni5stangen_6che6cke_6lorienti6nengagem6s3einste6s3eintei6serzählu6t5herste6terfahru6tersparn6triegel_7a8l7erwä7oberungs7s8parten8b7e8cke_8cken8sem8d7en8ge_8fel8tern8g7e8sel_8l7en8tro8l7ergen_8mel8tern8r7innenm8s7tapos88t7en8tro8z7ertrag_alter2s7_bein2hal_berg7e8b_char8me__char8mes_de6ments_dienst1e_en7thalp_er4stauf_er4z3eng_er6staus_erwerbs5_gene7cke_got6t5er_he8r7inn_her8b7ra_konzer2n_mach6ter_mark4ter_men6schw_mindest3_namen6s5_os7t8alg_os8terwe_oste8r7e_rau8schl_rü4cker2_schlags6_schrott3_schwung5_teiler8s_tester6g_tester8h_zweigen8a4cherfolachbar3stahrer8laual3e4beneal8b7er8walli7ers_allkon8tralter2s3panadi5er_aro8ckengas7s8aus_ausan8ne_baller6gebor8t7ratbret8t7enbu8ch7ersde8r7innuden8s7choden8s7tauder6tragederin8tege6länderue6n5essene6nerschee8ch7erziebrauch4sechter4haeden6k5reee8r7en8gei2n1en4gei6n5ertrei8nen8seei8s7erstein2strumein7er8scek8t7er8zer8d7en8gerin4terees6t5es6ses8t7er8öeschen6kaeten8z7aretriebs5tetscher5efah8l7entfi6sch5eifleisch3wfliege6raforni7er_gehei2m5agestein4sgleiter8sgren8z7eigu8t7er8hgus8t7endh2t1erstah3er4folgh8t7eil8zh8t7erfülh8t7erleuhan8g7endhandel2s1hau7f8liehau8s7enthfel6l5erhl7s8ternhnacht4s3hte8l7ei_hter8höhuhter8sparhwein8s7ahä8s7cheni7a8l7ermi8ber8gebi8ner6lebi8sch7e8hi8scher8zi8sel8teriderin8nuieler4gebig8s8trasikanten8nil8d7en8tin8n7er8minderer6tinland6s5is8s7chenit6z5ergrk7en8gel_ken7s8teiker6fahrukop8f7errkte8r7ersl5ermittll8lergenela8n7er8flan8d7erzlan8d7innlan8g7esclauben2s3lei6n5erblei8scheill5e6benell7en8dunlu6t5er6glu8t7ersamen8t7ersmp8f7er8zmpor8ter8n3s4tempen5sterbenn6t5estrin8der8satnadi7ers_ndel5sterno8t7entrns8tagentnsch5werdnschaft6snspor4t3rntini7er_ntini7ersnwander6eo8cker8scochzeits3ol6l5ertroster8weipapieren8parer6gebprei8s7eir8sch7e8br8sch7erlraus6gewäredi6t5erren8z7ersricht8sporif8f7endring7s6trris8t7ersron6t5endrter8löses4portarts5erfassuscherin8sschweine5sein8stitsen8s7e8hsilber3a4sser2gebnsun8d7erhtau6sch5mtau6sch5rtblocken8te6r5eiertest7richtex8t7rauti6k5er6hti7schen_ti8d7en8dto8ck7enttre7isch_tta8g7essu7e8r7entu8g7leituuch6t5erzuch8t7ertucker6gebunderten8urin6stinuslands5pvati8ons_ver8b7artvidu3a6lewer8t7ermwin8d7e8cxpor6t5erzes8s7endäher8gebnörer6gebnüge8lei8sür8g7en8g", + 10 : "1erscheinu4lerkranku4s3erschli_er6brecht_er6st5ein_frequen2z_furchter4_geräusch3_lichter8s_mode8rati_scheiner8_schlüsse4_spani7er__steiner8k_tei8lersc_tisch7endbes6t5er6hdert7ende_druckerin6e2r1erschee8l7ei8ernfzei8t7endgen5s6ternh2t1erhalth8t7er8hälhe8r7in8nuhrecken6s5hrei8b7e8cieler6lebniver8folgekamp2f1er2ke8r7in8numet8t7en8dogerätein8r6b5lasserran8g7e8berein8s7treräu5schen_sen8s7turmunder8tendvoran2schlwan8z7en8dwel8t7en8dwes6t5en8dwin8ner8sczel8l7er8tzgerinnun8", + 11 : "1angestellt4terscheinu5ermächtigu5inbetriebn_dienst7a8d_er8stritt__os8t7en8de_spiege8lei_spra4ch5er_wetterer8s_zwei8g7endach8träume_braucherin4ege8l7ei8ereren8z7en8dgram8m7en8dhschnitt4s5le5s6terinsle7s8terin_papie8r7endzge8r7in8nuzgerinnung7", + 12 : "5erleichteru5erschleichu_schaf8t7endach8träumen_ker8oberung_raus8scheidu", + 13 : "5einstellunge_er8stritten_", + 14 : "_stau8be8cken_" }, charSubstitution: { 'ſ': 's' }, - patternChars: "_abcdefghijklmnopqrstuvwxyzßäöü", - patternArrayLength: 257332, - valueStoreLength: 56157 + patternChars : "_abcdefghijklmnopqrstuvwxyzßàáâäçèéêëíñôöü", + patternArrayLength : 522019, + valueStoreLength : 62025 }; \ No newline at end of file diff --git a/testsuite/test13.html b/testsuite/test13.html index a6e835b..c6824c0 100644 --- a/testsuite/test13.html +++ b/testsuite/test13.html @@ -1,5 +1,5 @@ - + Hyphenator.js – Test 13 @@ -75,7 +75,7 @@

      Test 13

      http://•domain.•tld/
      http://•192.•168.•0.•1/
      www.•example.•com
      - ex|amp|le.com
      + ex|am|ple.com
      http://•192.•168.•0.•1:•80/
      name@•host.•com
      pre.•name@•subdomain2.•host.•com
      diff --git a/testsuite/test19.html b/testsuite/test19.html index 83a2ca3..4bd58f9 100644 --- a/testsuite/test19.html +++ b/testsuite/test19.html @@ -77,7 +77,8 @@

      Test 19

      Manuell -

      Absaugtrichter

      +

      Bürokratiekostenermittlung

      +

      Absaugtrichter

      Aberration

      absaugen

      Absaugesiphon

      @@ -93,6 +94,7 @@

      Test 19

      Angstraum

      Angsttraum

      Anschlagsorte

      +

      Anschlagssorte

      Antiklack

      Antragsteller

      anzugleichen

      @@ -128,7 +130,6 @@

      Test 19

      Billigreise

      Billigersatz

      Blumentopferde

      -

      Bombasteinfluss

      Brautradition

      Bonbonniere

      Briefeinwurf

      @@ -138,7 +139,6 @@

      Test 19

      Dachspoiler

      dampfarm

      Deckeleimer

      -

      Deimetal

      Delikatessen

      dementsprechend

      Dezernenten

      @@ -155,7 +155,6 @@

      Test 19

      Einkaufstempel

      einsalben

      einsaugen

      -

      Einzellernen

      Eischnee

      Elektrodengel

      Erblasser

      @@ -197,7 +196,6 @@

      Test 19

      Gespenstern

      Glücksautomaten

      Gourmetrösterei

      -

      Grabschereien

      Grabbepflanzung

      Grabschändung

      Grundübel

      @@ -236,7 +234,6 @@

      Test 19

      Kellerasseln

      Kirschwein

      Klumpstreu

      -

      Kolumbier

      kombinieren

      Kondensstreifen

      Kontopfändung

      @@ -426,9 +423,9 @@

      Test 19

      Zugangebote

      Zwangsehen

      Zwangsexmatrikulation

      -

      Zweigangliederung

      Zwergelstern

      -

      Ab•saug•trich•ter

      +

      Bü•ro•kra•tie•kos•ten•er•mitt•lung

      +

      Ab•saug•trich•ter

      Ab•erra•ti•on

      ab•sau•gen

      Ab•sau•ge•si•phon

      @@ -437,13 +434,14 @@

      Test 19

      Ak•tio•nen

      al•ler•engs•te

      Al•pen•ost•rand

      -

      Alt•bau•char•me

      +

      Alt•bau•charme

      Alt•bau•erhal•tung

      An•ker•lich•ten

      An•alpha•be•ten

      Angst•raum

      Angst•traum

      -

      An•schlagsor•te

      +

      An•schlags•or•te

      +

      An•schlags•sor•te

      An•tik•lack

      An•trag•stel•ler

      an•zu•glei•chen

      @@ -462,7 +460,7 @@

      Test 19

      Ba•den•den

      Bal•la•de

      Ball•kontrol•le

      -

      Bar•am•bien•te

      +

      Bar•am•bi•en•te

      Bau•man•gel

      Bau•mess•tech•nik

      Be•am•ten•adel

      @@ -472,14 +470,13 @@

      Test 19

      be•inhal•ten

      be•rat•schla•gen

      Be•sam•se•gel

      -

      Bett•rost

      +

      Bettrost

      Be•triebs•auf•fahrt

      -

      Beu•tel•ei•mer

      +

      Beu•tel•eimer

      Bil•dungs•ex•pan•si•on

      Bil•lig•rei•se

      Bil•lig•ersatz

      Blu•men•topf•er•de

      -

      Bom•bast•ein•fluss

      Brau•tra•di•ti•on

      Bon•bon•nie•re

      Brief•ein•wurf

      @@ -488,8 +485,7 @@

      Test 19

      Chef•eta•ge

      Dach•spoi•ler

      dampf•arm

      -

      De•ckel•ei•mer

      -

      Deime•tal

      +

      De•ckel•eimer

      De•li•ka•tes•sen

      dem•entspre•chend

      De•zer•nen•ten

      @@ -506,7 +502,6 @@

      Test 19

      Ein•kaufs•tem•pel

      ein•sal•ben

      ein•sau•gen

      -

      Ein•zel•lernen

      Ei•schnee

      Elek•tro•den•gel

      Erb•las•ser

      @@ -539,7 +534,7 @@

      Test 19

      Gas•tur•bi•ne

      Gau•lei•ter

      Ge•bets•turm

      -

      Ge•bets•tür•me

      +

      Ge•bets•türme

      Gelb•rand

      gelb•rot

      Ge•läch•ter

      @@ -548,7 +543,6 @@

      Test 19

      Ge•spens•tern

      Glücks•au•to•ma•ten

      Gour•met•rös•te•rei

      -

      Grabsche•rei•en

      Grab•bepflan•zung

      Grab•schän•dung

      Grund•übel

      @@ -587,7 +581,6 @@

      Test 19

      Kel•ler•as•seln

      Kirsch•wein

      Klump•streu

      -

      Ko•lum•bier

      kom•bi•nie•ren

      Kon•dens•strei•fen

      Kon•to•pfän•dung

      @@ -621,7 +614,7 @@

      Test 19

      Mu•sik•erzie•hung

      Nacht•auf•nah•me

      Nacht•ru•he

      -

      Nach•bars•ka•ter

      +

      Nach•barska•ter

      nach•ge•holt

      Nach•mit•tags•tal•ker

      nach•tra•gend

      @@ -631,7 +624,7 @@

      Test 19

      Na•gel•fei•le

      Nah•tod•er•leb•nis

      Na•mens•er•be

      -

      Neu•bau•char•me

      +

      Neu•bau•charme

      No•tar•ter•min

      Not•ent•rie•ge•lung

      Not•lauf•ei•gen•schaf•ten

      @@ -653,7 +646,7 @@

      Test 19

      Pu•bli•kums•hit

      Punkt•rich•ter

      punk•tu•ell

      -

      Qualm•aus•tritt

      +

      Qualm•austritt

      Quer•ein•stei•ger

      Quetsch•ver•bin•der

      Ra•dies•chen

      @@ -671,13 +664,13 @@

      Test 19

      Rum•aro•ma

      rund•fun•ken

      Rühr•ei•früh•stück

      -

      Saale•ufer

      +

      Saa•le•ufer

      Sah•ne•he•ring

      Sauf•lie•der

      Sau•grip•pe

      sau•gu•te

      Schaf•fa•mi•lie

      -

      Schiffs•tau

      +

      Schiffstau

      Schiffs•tu•ten

      Schiff•si•re•ne

      Schlaf•shirt

      @@ -692,7 +685,7 @@

      Test 19

      Schul•ter•rain

      Schul•ter•ras•se

      Schwei•ne•le•ber

      -

      Schweins•au•gen

      +

      Schweins•augen

      Schwein•ige•lei

      See•leu•te

      See•tang•ar•ten

      @@ -711,9 +704,9 @@

      Test 19

      Stark•re•gen

      Star•ga•gen

      Star•te•nö•re

      -

      Staub•al•ler•gie

      +

      Staub•all•er•gie

      Staubecken

      -

      staub•sau•gen

      +

      staub•saugen

      Stau•tei•che

      Stief•eltern

      Straf•an•zei•ge

      @@ -745,7 +738,7 @@

      Test 19

      ver•beu•len

      ver•blas•sen

      ver•blüfft

      -

      ver•ein•samt

      +

      ver•einsamt

      ver•ges•sen

      Ver•lust•aver•si•on

      ver•se•hen

      @@ -777,7 +770,6 @@

      Test 19

      Zug•an•ge•bo•te

      Zwangs•ehen

      Zwangs•ex•ma•tri•ku•la•ti•on

      -

      Zweig•an•glie•de•rung

      Zwerg•els•tern

      From 3e2dda4044dcdf15423586d59201855026284b7d Mon Sep 17 00:00:00 2001 From: mnater Date: Tue, 23 May 2017 11:34:56 +0200 Subject: [PATCH 83/86] fix loop --- Hyphenator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hyphenator.js b/Hyphenator.js index 86984ef..7d4ef3c 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -157,7 +157,7 @@ Hyphenator = (function (window) { var num = scripts.length - 1; var currScript; var src; - while (num > 0) { + while (num >= 0) { currScript = scripts[num]; if (currScript.hasAttribute("src") && currScript.src.indexOf("Hyphenator") !== -1) { src = currScript.src; From 2efb7a16122e6c2ddb2e50bcc1a86982c1022ba3 Mon Sep 17 00:00:00 2001 From: mnater Date: Tue, 23 May 2017 11:52:17 +0200 Subject: [PATCH 84/86] Test for issue 302 --- testsuite/test128.html | 67 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 testsuite/test128.html diff --git a/testsuite/test128.html b/testsuite/test128.html new file mode 100644 index 0000000..724b2e2 --- /dev/null +++ b/testsuite/test128.html @@ -0,0 +1,67 @@ + + + + Hyphenator.js – Test 128 + + + + + + +

      <<- index | <- Prev | Next ->

      +

      Test 128

      +

      Test for issue 302

      + +
        +
      • +
        Ver­zend­huis­kre­diet
        +
        Door­lo­pend kre­diet
        +
      • +
      • +
        Ver­zend­huis­kre­diet
        +
      • +
      • +
        Door­lo­pend kre­diet
        +
      • +
      + + + \ No newline at end of file From 3e5e6cb3ebabcc38fd5b8f30f16f125f814c1159 Mon Sep 17 00:00:00 2001 From: Christian Hoffart Date: Fri, 4 Aug 2017 09:58:31 +0200 Subject: [PATCH 85/86] adds "main" field to package.json --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index a6a058f..9ed496c 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ ], "author": "Mathias Nater", "license": "MIT", + "main": "Hyphenator.js", "bugs": { "url": "https://github.com/mnater/Hyphenator/issues" }, From 0521eb0f5f3ba136d7b182cccbd79719588cd1dd Mon Sep 17 00:00:00 2001 From: mnater Date: Sun, 6 Aug 2017 23:41:23 +0200 Subject: [PATCH 86/86] Add Georgian --- Hyphenator.js | 7 +++++-- patterns/ka.js | 17 +++++++++++++++++ testsuite/test35.html | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 patterns/ka.js diff --git a/Hyphenator.js b/Hyphenator.js index 7d4ef3c..adcbd74 100644 --- a/Hyphenator.js +++ b/Hyphenator.js @@ -73,7 +73,7 @@ Hyphenator = (function (window) { * @param {string} code The {@link http://tools.ietf.org/rfc/bcp/bcp47.txt bcp47} code of the language * @param {string} file The name of the pattern file * @param {Number} script A shortcut for a specific script: latin:0, cyrillic: 1, arabic: 2, armenian:3, bengali: 4, devangari: 5, greek: 6 - * gujarati: 7, kannada: 8, lao: 9, malayalam: 10, oriya: 11, persian: 12, punjabi: 13, tamil: 14, telugu: 15 + * gujarati: 7, kannada: 8, lao: 9, malayalam: 10, oriya: 11, persian: 12, punjabi: 13, tamil: 14, telugu: 15, georgian: 16 * @param {string} prompt The sentence prompted to the user, if Hyphenator.js doesn't find a language hint */ o = function (code, file, script, prompt) { @@ -105,6 +105,7 @@ Hyphenator = (function (window) { o('hu', 'hu.js', 0, 'A weboldal nyelvét nem sikerült automatikusan megállapítani. Kérem adja meg a nyelvet:'); o('hy', 'hy.js', 3, 'Չհաջողվեց հայտնաբերել այս կայքի լեզուն։ Խնդրում ենք նշեք հիմնական լեզուն՝'); o('it', 'it.js', 0, 'Lingua del sito sconosciuta. Indicare una lingua, per favore:'); + o('ka', 'ka.js', 16, ''); o('kn', 'kn.js', 8, 'ಜಾಲ ತಾಣದ ಭಾಷೆಯನ್ನು ನಿರ್ಧರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ದಯವಿಟ್ಟು ಮುಖ್ಯ ಭಾಷೆಯನ್ನು ಸೂಚಿಸಿ:'); o('la', 'la.js', 0, ''); o('lt', 'lt.js', 0, 'Nepavyko automatiškai nustatyti šios svetainės kalbos. Prašome įvesti kalbą:'); @@ -418,7 +419,9 @@ Hyphenator = (function (window) { //tamil: 14 'ஃஅஆஇஈஉஊஎஏஐஒஓஔகஙசஜஞடணதநனபமயரறலளழவஷஸஹாிீுூெேைொோௌ்ௗ', //telugu: 15 - 'ఁంఃఅఆఇఈఉఊఋఌఎఏఐఒఓఔకఖగఘఙచఛజఝఞటఠడఢణతథదధనపఫబభమయరఱలళవశషసహాిీుూృౄెేైొోౌ్ౕౖౠౡ' + 'ఁంఃఅఆఇఈఉఊఋఌఎఏఐఒఓఔకఖగఘఙచఛజఝఞటఠడఢణతథదధనపఫబభమయరఱలళవశషసహాిీుూృౄెేైొోౌ్ౕౖౠౡ', + //georgian: 16 + 'აიერთხტუფბლდნვკწსგზმქყშჩცძჭჯოღპჟჰ' ], f = function (lang) { var shadow, diff --git a/patterns/ka.js b/patterns/ka.js new file mode 100644 index 0000000..d73f7e8 --- /dev/null +++ b/patterns/ka.js @@ -0,0 +1,17 @@ +Hyphenator.languages["ka"] = { + leftmin : 1, + rightmin : 2, + specialChars : "ავრწყიეთხტუფბლდნკსგზმქშჩცძჭჯოღპჟჰ", + patterns : { + 3 : "1ბა1ბე1ბი1ბო1ბუ1გუ1დნ1ვუ1კე1ლა1ლუ1მა1მი1ნი1ნუ1ჟი1ჟო1რი1რუ1სა1სე1სი1სო1სუ1ფა1ფე1ფი1ფო1ფუ1ქა1ქე1ქი1ქო1ქუ1შა1შე1ში1შო1შუ1ძი1ძუ1ჭა1ჭე1ჭი1ჭო1ჭუ1ჰა1ჰე1ჰი2კდ2კპ2პს2ჟს2ყს2ჩს2ძთ2ძნ2ძს2ხყა1აა1ბა1გა1და1ეა1ვა1ზა1თა1ია1კა1ლა1მა1ნა1ოა1პა1ჟა1რა1სა1ტა1უა1ფა1ღა1ყა1შა1ჩა1ცა1ძა1წა1ჭა1ხა1ჯგმ2დ2ფდღ2ე1აე1ბე1გე1დე1ეე1ვე1ზე1თე1იე1კე1ლე1მე1ნე1ოე1პე1რე1სე1ტე1უე1ფე1ღე1ყე1შე1ჩე1ცე1ძე1წე1ხე1ჯვჟ2ზღ2თვ2თლ2თხ2ი1აი1ბი1გი1დი1ეი1ვი1ზი1თი1იი1კი1ლი1მი1ნი1ოი1პი1ჟი1რი1ტი1უი1ფი1ღი1ყი1ჩი1ცი1ძი1წი1ჭი1ხი1ჯლო1ო1აო1ბო1გო1დო1ეო1ვო1ზო1თო1იო1კო1ლო1მო1ნო1ოო1პო1რო1სო1ტო1უო1ფო1ღო1შო1ჩო1ცო1ძო1წო1ხო1ჯპ1კპყ2რო1რძ2ს1ქტ2ფტ2შტკ2ტყ2უ1აუ1გუ1დუ1ეუ1ვუ1ზუ1თუ1იუ1კუ1ლუ1მუ1ნუ1ოუ1პუ1ჟუ1რუ1ტუ1უუ1ღუ1ყუ1შუ1ჩუ1ცუ1წუ1ჭუ1ხუ1ჯუ1ჰფხ2ქ1გქ1დქ1ზქ1ჟქ1ქქ1ღქ1შქვ2ღ1გღ1ტღ1ფღ1ჭშ1გშ1ზშ2ფჩო1ჩხ2ცხ2ძ2ჭწმ2წრ2წყ2ჭყ2ხგ2ხმ2ჯ2რჯ2შჯვ2ჰ1მჰ1პჰ1რჰ1სჰ1ფჰ1ქჰ1ღ", + 4 : "1ბღ21კ2ბ1ოღლ1ღატ1ძღ22ბ1გ2ბ1დ2ბ1მ2ბ1ჟ2ბ1ქ2ბ1შ2ბ1ჩ2ბ1ც2ბ1ჭ2ბ1ჯ2გ1ბ2გ1დ2გ1ნ2გ1პ2გ1ჟ2გ1ტ2გ1ღ2გ1ჩ2გ1წ2გ1ჯ2დ1ბ2დ1დ2დ1ვ2დ1კ2დ1პ2დ1ჟ2დ1ქ2დ1ყ2დ1ჩ2დ1წ2დ1ხ2დ1ჯ2ეეტ2ვ1პ2ვ1ღ2ვ1ჩ2ზ1ბ2ზ1გ2ზ1დ2ზ1ზ2ზ1თ2ზ1ნ2ზ1შ2თ1ბ2თ1ზ2თ1თ2თ1ნ2თ1ღ2თ1შ2თ1ჯ2თხ_2თხს2კ1ზ2კ1თ2კ1ნ2კ1ს2კ1ქ2კ1შ2კ1ჰ2ლ1ბ2ლ1ზ2ლ1კ2ლ1ლ2ლ1პ2ლ1ჟ2ლ1რ2ლ1ფ2ლ1ძ2ლ1ჯ2ლეხ2მ1მ2მ1ჟ2ნ1ბ2ნ1ლ2ნ1ნ2ნ1პ2ნ1ჟ2ნ1რ2პ1დ2პ1ვ2პ1ზ2პ1მ2პ1ნ2პ1ტ2პ1შ2პ1ჩ2ჟ1ბ2ჟ1დ2ჟ1ვ2ჟ1ზ2ჟ1თ2ჟ1კ2ჟ1ლ2ჟ1მ2ჟ1შ2რ1ლ2რ1მ2რ1ნ2რ1ჟ2რ1ჭ2როფ2ს1ბ2ს1ზ2ს1ს2ს1ღ2ს1ყ2ს1ჩ2ს1ჯ2ტ1ბ2ტ1დ2ტ1ზ2ტ1თ2ტ1ნ2ტ1პ2ტ1ტ2ტ1ც2ტ1წ2ტ1ჯ2ტვ22ტრ22ფ1ბ2ფ1დ2ფ1ვ2ფ1ზ2ფ1კ2ფ1მ2ფ1ნ2ფ1რ2ფ1ტ2ფ1ქ2ფ1ჩ2ფ1ც2ქლ22ღ1ზ2ღ1ნ2ღ1შ2ღ1წ2ღვ22ყ1ბ2ყ1ზ2ყ1თ2ყ1შ2ყდ22ყლ22ყნ22ყრ22შ1დ2შ1თ2შ1მ2შ1ნ2შ1პ2შ1რ2შ1ს2შ1შ2შ1ჩ2შ1ჯ2ჩ1ბ2ჩ1დ2ჩ1ზ2ჩ1თ2ჩ1მ2ჩ1შ2ც1ბ2ც1დ2ც1ზ2ც1კ2ც1ლ2ც1ნ2ც1რ2ც1ს2ც1ღ2ც1შ2ძ1ზ2ძ1მ2წ1ბ2წ1გ2წ1ნ2ჭ1დ2ჭ1ნ2ჭ1რ2ხ1ბ2ხ1თ2ხ1ნ2ხ1პ2ხ1ქ2ხ1ჩ2ხ1ც2ხ1წ2ხ1ხ2ხვ22ხზ22ხრ22ხჰ22ჯ1დ2ჯ1თ2ჯ1ს2ჯგ2_ფრ2ა2გშა2კბა2ჟღა2ტფა2ტშა2შზა2შფა2წლა2წმა2ჯმაკ1დატ1ვატ1რაქ1ვაღ1ვაყ1დაყ1რახ1ვახ1ზახ1რგ1ლეგ1შრგ2შ2დ1ნადეღ2ე2გლე2გშე2სნე2ტშე2შფე2ცქე2წმე2ჯნეკ1დეტ1რექ1ვეღ1ვეყ1ნეყ1რეხ1ვეხ1ზეხ1ყეხ1ჰეჯ1გთ1ვათ1ვოთ1ვრთ1ლდთ2თხი2გმი2გში2ვჟი2ჟღი2ჩლი2ცქი2წმიკ1დის1ნიტ1ვიტ1რიქ1ვიღ1ვიხ1ვიხ1რკ1დიკ1დომ2დღო1ყაო1ყეო1ყოო1ყუო2გმო2გშო2თვო2ტშო2ცქო2წმო2წრო2ხმოკ1დოტ1როღ1ვოყ1როჭ1ლოხ1ვოხ1რჟ1ღერ1ძლრ2ჩხრმ2თრმ2ყს1ნოს1ოღტ1ვატ1კუტ1როტ1რფუ1ძაუ1ძეუ2ააუ2გმუ2სოუ2ცქუ2წშუ2ჭშუ2ჯლუი2აუტ1რუქ1ვუქ1თუყ1დუხ1ვუხ1რფ1ჯ2ფრ2დფრ2ქქ1ვდქ1ლექ1ლოქ1მ2ქ1ნ2ქ1რ2ქ1ს2ქ1ტ2ქ1ც2ღ1ვიღ1ვშღ1კ2ღ1ქ2ღ1ძ2ღ2ტყღფრ2ყ1ნეყ1ნოყ1რეც1ქდც1ქნც1ქრც2ქ2ძ1ნეწ1ლიწ1მდწ1მეწ1მოწ1მყწ1რთჭ1კ2ჭ1ლოხ1ვეხ1ვიხ1ვრჯ1რაჰ1გ2ჰ1კ2ჰ1ყ2ჰ1ხ2", + 5 : "1ათას2ბ1ვ22ბ1ზ22ბ1თ22ბ1ლ22ბ1ნ22ბ1რ22ბ1ს22გ1გ22გ1ვ22გ1ზ22გ1თ22გ1კ22გ1რ22გ1ს22გ1ყ22გ1ც22გ1ძ22გ1ჭ22გ1ხ22დ1გ22დ1თ22დ1ლ22დ1მ22დ1რ22დ1შ22დ1ჰ22დ2ს22ვ1ბ22ვ1გ22ვ1დ22ვ1ვ22ვ1ზ22ვ1თ22ვ1კ22ვ1ლ22ვ1მ22ვ1ნ22ვ1ოხ2ვ1რ22ვ1ს22ვ1ტ22ვ1ფ22ვ1ქ22ვ1ყ22ვ1შ22ვ1ც22ვ1ძ22ვ1წ22ვ1ჭ22ვ1ხ22ვ1ჯ22ზ1ვ22ზ1ლ22ზ1მ22ზ1რ22ზ1ს22თ1გ22თ1დ22თ1იქ2თ1კ22თ1მ22თ1რ22თ1ს22თ1ფ22თ1ქ22თ1ც22კ1ვ22კ1ლ22კ1მ22კ1რ22ლ1გ22ლ1დ22ლ1ვ22ლ1თ22ლ1მ22ლ1ნ22ლ1ს22ლ1ტ22ლ1ქ22ლ1ღ22ლ1ყ22ლ1შ22ლ1ჩ22ლ1ც22ლ1წ22ლ1ხ22ლ1ჰ22ლეჯვ2მ1ბ22მ1გ22მ1დ22მ1ვ22მ1ზ22მ1თ22მ1კ22მ1ლ22მ1ნ22მ1პ22მ1რ22მ1ს22მ1ტ22მ1ფ22მ1ქ22მ1ღ22მ1ყ22მ1შ22მ1ჩ22მ1ც22მ1ძ22მ1წ22მ1ჭ22მ1ხ22მ1ჯ22ნ1გ22ნ1დ22ნ1ვ22ნ1ზ22ნ1თ22ნ1კ22ნ1მ22ნ1ს22ნ1ტ22ნ1ფ22ნ1ქ22ნ1ღ22ნ1ყ22ნ1შ22ნ1ჩ22ნ1ც22ნ1ძ22ნ1წ22ნ1ჭ22ნ1ხ22ნ1ჯ22პ1ლ22პ1რ22პ1წ22ჟ1რ22რ1ბ22რ1გ22რ1დ22რ1ვ22რ1ზ22რ1თ22რ1კ22რ1პ22რ1ს22რ1ტ22რ1ფ22რ1ქ22რ1ღ22რ1ყ22რ1შ22რ1ჩ22რ1ც22რ1წ22რ1ხ22რ1ჯ22რ1ჰ22ს1გ22ს1დ22ს1ვ22ს1თ22ს1კ22ს1ლ22ს1მ22ს1პ22ს1რ22ს1ტ22ს1ფ22ს1შ22ს1ც22ს1ძ22ს1წ22ს1ჭ22ს1ხ22ტ1გ22ტ1ლ22ტ1მ22ტ1ს22ტ1ჩ22ტ1ხ22ფ1თ22ფ1ლ22ფ1ს22ფ1შ22ღ1ბ22ღ1დ22ღ1თ22ღ1ლ22ღ1მ22ღ1რ22ღ1ს22ყ1ვ22ყ1მ22შ1ვ22შ1კ22შ1ლ22შ1ტ22შ1ქ22შ1ხ22ჩ1ვ22ჩ1ნ22ჩ1რ22ჩ1ქ22ც1ვ22ც1თ22ც1მ22ძ1გ22ძ1ვ22ძ1ლ22ძ1რ22წ1ვ22წ1კ22ჭ1ვ22ჭ1მ22ხ1დ22ხ1ლ22ხ1ს22ხ1ტ22ხ1შ23თხსა_აი2ა_ერ2ტ_ირ2ტ_ურ2ტ_უფრ2ა2გ1ლა2გ1მა2დ1ზა2დ1ნა2თ1ვა2თ1ლა2რ1ძა2ს1ნა2ტ1კა2ც1ქა2წ1რა2ხ1მა2ჯ1ვაბ3ლდაბ3ნვაბ3რკაბ3სკაბ3სტაბრ3წაგ3გვაგ3გზაგ3ვბაგ3ვდაგ3ვთაგ3ვკაგ3ვლაგ3ვმაგ3ვნაგ3ვრაგ3ვსაგ3ვქაგ3ვყაგ3ვშაგ3ვჩაგ3ვცაგ3ვძაგ3ვწაგ3ვჭაგ3ვხაგ3ზლაგ3ზნაგ3მნაგ3რჩაგ3სვაგ3სმაგ3სხაგ3ყვაგ3შიაგ3ცდაგ3ძვაგ3ძრაგ3ჭრაგ3ხვაგ3ხსად3გნად3ლმად3ლფად3მყავ3ბნავ3ბრავ3გზავ3დგავ3ზვავ3ზშავ3თბავ3თმავ3კმავ3კრავ3ლდავ3ლნავ3მდავ3მსავ3მშავ3მჯავ3ნდავ3ნძავ3რბავ3რდავ3რთავ3რკავ3რმავ3რჩავ3რცავ3რწავ3სდავ3სვავ3სთავ3სკავ3სმავ3სტავ3სძავ3სწავ3სხავ3სჯავ3ტვავ3ყვავ3ყრავ3შვავ3შლავ3შნავ3შრავ3შტავ3ცდავ3ცლავ3ცნავ3ძვავ3ძრავ3წვავ3ჭრავ3ხდავ3ხვავ3ხსავ3ხტავ3ჯდაზ3რდაზ3რზაზ3რთაზ3რმაზ3სკათ3გვათ3გრათ3ვლათ3ვრათ3კვათ3მფათ3მყათ3რგაკ3ბეაკ3ვდაკ3ვთაკ3ვლაკ3ვნაკ3ვრაკ3ლდაკ3ლთაკ3რთალ3გვალ3გზალ3დშალ3თმალ3მდალ3მხალ3სკალ3სტალ3ტბალ3ტრალ3ღრალ3ყზალ3შვალ3ცრალ3წვალ3ხზალ3ხთალ3ხსალ3ხშამ3ბლამ3ბნამ3ბრამ3გვამ3გზამ3გრამ3დგამ3დვამ3ვლამ3ზრამ3თრამ3თქამ3კვამ3კლამ3კრამ3ლზამ3ნთამ3პლამ3რგამ3რთამ3რტამ3რღამ3რჩამ3რჯამ3სგამ3სვამ3სტამ3სწამ3სჭამ3სხამ3სჯამ3ტვამ3ტრამ3ფლამ3ფსამ3ღვამ3ღლამ3ყვამ3ყნამ3ყრამ3შვამ3შლამ3შრამ3ჩნამ3ცდამ3ცვამ3ცთამ3ცნამ3ძლამ3წვამ3წკამ3ჭრამ3ხდამ3ხვამ3ხნამ3ხრამ3ხსამ3ჯდან3გვან3გთან3გრან3გჯან3დგან3დვან3დლან3დმან3დრან3დსან3დშან3ვთან3ვლან3ვმან3ვრან3ვსან3ვცან3ზრან3თრან3თქან3კმან3კშან3მგან3მდან3მზან3მრან3მსან3მტან3მხან3მჯან3სვან3სმან3სპან3სშან3სცან3სწან3სხან3სჯან3ტვან3ტთან3ტმან3ღვან3ყრან3შტან3ცდან3ცვან3ცლან3ცმან3ძლან3ძრან3ჭვან3ჭნან3ხვან3ხლან3ხრან3ჯგან3ჯდაჟ3რჟარ3ბდარ3ბშარ3გბარ3გდარ3გვარ3გზარ3გნარ3გსარ3გძარ3დგარ3დვარ3დთარ3დლარ3დმარ3დშარ3ვლარ3ვყარ3ვწარ3ზნარ3თზარ3თთარ3თმარ3თნარ3თქარ3თშარ3კვარ3კლარ3კმარ3მთარ3მყარ3სდარ3სკარ3სტარ3ტვარ3ტმარ3ტრარ3ფლარ3ღვარ3ღნარ3ყვარ3შვარ3შრარ3ჩნარ3ცვარ3ცთარ3ცმარ3ძლარ3ხვარ3ხნას1ექას3გვას3გზას3დგას3დრას3ვთას3ვლას3ვრას3თმას3თრას3თქას3კდას3კვას3კნას3მეას3პშას3რვას3რშას3სთას3ტზას3ტრას3შტას3ცდას3ცლას3ცნას3ძლას3ძრას3წვას3ჭრას3ხდას3ხვას3ხლას3ხრატ3ვრატ3კნატ3კრატ3რლატ3რფატ3რშატ3სკატ3ფოატ3შიაფ3თრაფ3ლწაფ3რდაფ3რქაქ3ვდაქ3ვნაქ3მნაქ3რნაქ3ტზაქ3ტმაღ3გზაღ3დგაღ3ვლაღ3ვნაღ3ვრაღ3ვშაღ3ზრაღ3თქაღ3კვაღ3ლდაღ3ლთაღ3ლმაღ3მგაღ3მდაღ3მზაღ3მკაღ3მრაღ3მძაღ3მწაღ3მხაღ3რმაღ3რღაღ3სდაღ3სრაღ3ფრაღ3ძვაღ3ძრაყ3დრაყ3ვზაყ3ვლაყ3რდაშ3ვრაშ3ლზაშ3ტრაშ3ფააშ3ფოაჩ3ნდაჩ3რდაც3ვლაც3თმაც3მლაც3ქეაც3ქვაძ3ვრაძ3რწაწ3ვდაწ3ვნაწ3ვრაწ3მყაწ3რთაჭ3ვზაჭ3ვრაჭ3მლახ3ვდახ3ვრახ3ლდახ3ლთახ3ლკახ3ლმახ3ლსახ3ლშახ3რჩახ3რწახ3სრახ3ტზახ3ტნახ3ტრახ3შთახ3შმაჰ3კვაჰ3კრაჰ3ყვაჰ3ყრაჰ3ხვაჰ3ხსგ3ვთაგი2მოდ3რსადე3რიდე3ღრე2გ1მე2დ1ზე2დ1ნე2თ1ვე2თ1ლე2რ1ძე2ტ1კე2წ1რე2ხ1მე2ჯ1ვეარა3ებ3სვებ3სთებ3სმეგ3ვკეგ3ვპეგ3ვრეგ3ვშეგ3ვწეგ3ვჭეგ3ვხეგ3მვეგ3რჩეგ3ყვეგ3შიეგ3შრეგ3ცდეგ3ძლეგ3ხვედ3რდედ3რკედ3საევ3ბრევ3დგევ3თმევ3კრევ3ლთევ3ლმევ3ლშევ3ლჩევ3მცევ3რგევ3რდევ3რზევ3რკევ3რმევ3რნევ3რსევ3რჩევ3რცევ3რჯევ3სკევ3სრევ3სწევ3სხევ3ყვევ3ცდევ3ცვევ3ძვევ3ძლევ3ხვევ3ხტევ3ჯდეზ3რბეზ3რდეთ3ვლეთ3ვრეთ3რგეთ3რვეთ3რსეთ3რწეთ3ქლეკ3ვრეკ3რთელ3გველ3დშელ3ვყელ3მყელ3მძელ3მწელ3მხელ3ყველ3წვემ3ბრემ3გზემ3დგემ3დრემ3კვემ3კრემ3ლდემ3ლმემ3პმემ3რჩემ3რცემ3სგემ3სკემ3სრემ3სყემ3სწემ3სჯემ3შვემ3შლემ3ჩნემ3ცბემ3ცდემ3ცვემ3ძვემ3ძლემ3წვემ3ჭმემ3ხვემ3ხრენ3დდენ3დრენ3დსენ3თქენ3სკენ3სმენ3ტთენ3ტმენ3ტრენ3ჩვერ1ოფერ3გზერ3დგერ3დშერ3ვლერ3თბერ3თგერ3თდერ3თზერ3თთერ3თკერ3თმერ3თნერ3თსერ3თფერ3თშერ3კვერ3მკერ3პლერ3სზერ3სმერ3სპერ3სტერ3ტბერ3ტზერ3ტმერ3ფლერ3ფმერ3ღვერ3შლერ3ჩხერ3ცვერ3ძნერ3წვერ3წკერ3ხდერ3ხვერ3ხზერ3ხთერ3ხსეს3დგეს3ვგეს3ვლეს3ვმეს3ვრეს3თქეს3კნეს3კრეს3ლმეს3ტმეს3ტნეს3ძლეს3ძრეს3ხდეს3ხვეს3ხზეტ3გვეტ3ლთეტ3ლმეტ3ლშეტ3რფეტ3შიეტ3ჩვეტ3ხნექ3ვთექ3ვსექ3მნექ3რთექ3სკექ3სპექ3სტექ3სცექ3ტზექ3ტმექ3ცნეყ3ნდეყ3რდეშ3ვნეშ3ტრეშ3ფოეც3ვლეც3ქეეც3ქიეძ3ვრეწ3ვზეწ3კვეჭ3ვდეჭ3ვმეხ3დგეხ3ვდეხ3ვზეხ3მძეხ3ტნეჯ3გვეჰ3კრეჰ3ყვვ3რსავი2რუვს3თხზ3რსათა2სეი2გ1ლი2დ1ზი2დ1ნი2თ1ვი2თ1ლი2ტ1კი2წ1რი2ჭ1ზი2ხ1მი2ჯ1ზი2ჯ1ნიბ3ვლიბ3რზიბ3რტიბ3რჭიბ3რჯიგ3ვრიგ3ვყიგ3რგიგ3შიიდ3გვიდ3გნიდ3მნიდ3მპიდ3რდიდ3რვიდ3რნიდ3საიდ3შვივ3ბრივ3დგივ3თთივ3ლდივ3რბივ3რდივ3რზივ3რშივ3რცივ3სღივ3ფსივ3ყვივ3ძლივ3წვივ3ხვივ3ჯდიზ3ვნიზ3ლდიზ3მზიზ3მთიზ3მმიზ3მრიზ3მშიზ3რდით3ვლით3ვრით3ლდით3მკით3მმით3მპით3რგით3რდით3რმით3ფლით3ცნიკ3ბიიკ3ვდიკ3ვლიკ3ვნილ3მსილ3ტვილ3ღვილ3შვილ3ხვიმ3გზიმ3დგიმ3დრიმ3კვიმ3ნდიმ3რბიმ3რთიმ3სვიმ3სხიმ3სჯიმ3ტვიმ3ყნიმ3ყრიმ3შვიმ3შნიმ3შრიმ3ჩნიმ3ძლიმ3ხდიმ3ხნინ3გრინ3დბინ3დდინ3დვინ3დთინ3დრინ3დშინ3თზინ3თქინ3კვინ3კლინ3კრინ3სკინ3სპინ3სტინ3სცინ3სწინ3ტლინ3ტრინ3ქლინ3ღლინ3ცდინ3ცლინ3ძლინ3ძმინ3ძრინ3წვინ3ხვირ1უნირ3გვირ3თმირ3კვირ3კშირ3მშირ3სთირ3სმირ3სსირ3სშირ3ღვირ3ყვირ3ხშის3დგის3დრის3ვლის3ვმის3ვრის3თქის3კდის3კვის3კზის3კრის3კშის3მგის3მსის3მტის3მქის3მყის3მშის3მცის3მძის3ტდის3ტვის3ტთის3ტმის3ტრის3ფრის3შვის3ცვის3წვის3ხდის3ხვის3ხლიტ3ვლიტ3მშიფ3რდიფ3რქიფ3შვიქ3ვნიქ3მნიქ3ნგიქ3ნმიქ3რდიქ3რთიქ3რმიქ3რსიქ3რშიქ3ცვიქ3ცნიღ3ბლიღ3ვრიღ3ვწიღ3რმიღ3რჭიყ3ვდიყ3ვნიშ3ვლიშ3ვნიშ3კრიშ3ფოიშ3ხლიჩ3ნდიჩ3რდიც3ვლიც3ვნიც3ქეიც3ქნიძ3გნიძ3ვრიძ3ლშიძ3რნიწ3ვდიწ3ვნიწ3ვრიწ3კნიწ3კრიწ3რთიჭ3ვრიხ3ვდიხ3ვნიხ3რჩიხ3რწიჰ3გვიჰ3კრიჰ3ყვლ3დსალბრ3ტლბრ3ჭმახ3ვმუ3სონ3ტსან3ტსტნდე2რო2გ1ლო2დ1ზო2დ1ნო2თ1ლო2რ1ძო2ს1ნო2ტ1კო2ქ1ვობ3თმობ3ლდობ3რდობ3რმობ3რშობ3რჭოგ3ვბოგ3ვგოგ3ვდოგ3ვვოგ3ვკოგ3ვლოგ3ვმოგ3ვნოგ3ვროგ3ვსოგ3ვყოგ3ვშოგ3ვცოგ3ვძოგ3ვწოგ3ვხოგ3კლოგ3კროგ3სვოგ3ყვოგ3შიოგ3წვოგ3ხვოდ3გნოვ3ბროვ3დგოვ3ზსოვ3ზშოვ3თქოვ3კვოვ3კლოვ3ლბოვ3ლზოვ3მცოვ3ნდოვ3რდოვ3რთოვ3რჩოვ3სვოვ3სკოვ3სპოვ3სხოვ3ყვოვ3შვოვ3ჩნოვ3ცდოვ3ცვოვ3ცნოვ3ძვოვ3წვოვ3ჭროვ3ხვოვ3ხტოვ3ჯდოზ3ვროზ3რდოთ3ვლოთ3ვროთ3ლშოკ3ვდოკ3ვლოკ3ვნოკ3ვროკ3ლდოლ3დშოლ3სკოლ3შვომ3ბრომ3გდომ3გვომ3გზომ3გრომ3დგომ3ვლომ3კვომ3კლომ3კრომ3პლომ3პრომ3რთომ3რჩომ3სვომ3სკომ3სპომ3სხომ3ტრომ3ღვომ3ყვომ3შვომ3ცდომ3ცვომ3ძვომ3წვომ3ხდომ3ხვომ3ხრომ3ჯდონ3გრონ3დრონ3კრონ3მდონ3სკონ3სპონ3სტონ3ტრონ3ფლონ3ხლორ3ბლორ3თმორ3თქორ3კვორ3მხორ3სმორ3ტმორ3ტრორ3ტსორ3ჩნორ3ცდორ3ცვორ3ცზორ3ცმორ3ცნორ3ცშოს3დგოს3ვლოს3ვროს3თქოს3კდოს3ტლოს3ტროს3ფროს3ცდოს3ცვოს3ცროს3ძვოს3წვოს3ჭროს3ხდოტ3რდოტ3შიოფ3ლმოქ3მზოქ3მნოქ3მშოქ3რთოქ3სთოქ3ტროღ3ვროყ3ვნოშ3კზოჩ3ნდოც3ვლოც3ქროძ3ვროწ3ვდოწ3ვნოწ3ვროწ3მდოხ3ვდოხ3ვნოხ3რჩოხ3ტნოჰ3გვოჰ3კვოჰ3კლოჰ3კროჰ3ყვოჰ3ხვრ1ეფერ3გსარ3დსარ3თსარ3თხმრ3ჩხერი2ბღრი3მღრუ3სოტა3ჯგუ2დ1ზუ2თ1ვუ2ტ1კუ2ხ1მუბ3ლზუბ3ლშუბ3რკუბ3რყუგ3რნუდ3გნუდ3გრუდ3რტუდ3საუზ3რდუთ3ვლუთ3ვნუთ3სვუკ3ვდუკ3ლდულ3გრულ3დგულ3თბულ3თნულ3მკულ3მხულ3ნდულ3ღვულ3ჩვუმ2ტყუმ3დგუმ3კვუმ3სგუმ3სხუმ3ღვუმ3შვუმ3ჩნუმ3ცრუნ3გდუნ3გრუნ3დგუნ3დმუნ3დრუნ3თქუნ3კლუნ3ტრუნ3ღრუნ3ძზუნ3ძმუნ3ძრუნ3ხრუპ3რშურ3ბლურ3ბნურ3გზურ3დთურ3დსურ3ვლურ3თბურ3თმურ3კვურ3კლურ3კრურ3სზურ3სმურ3სშურ3ტლურ3ფსურ3ღვურ3ჩქურ3ცლურ3ჯდუს3ვლუს3ვმუს3ვრუს3კდუს3კრუს3რვუს3რნუს3ტდუს3ტვუს3ტმუს3ხდუს3ხვუფ3ლდუფ3ჯგუქ3მდუქ3მნუქ3მრუქ3სვუღ3რმუშ3ვრუშ3ტმუშ3ტრუჩ3ნდუც3ვლუც3ქდუც3ქიუც3ქუუძ3ვლუძ3ვრუწ3ვდუწ3ვრუჭ3ვრუჭ3კვუხ3ვდუხ3ლზუხ3ლმუხ3ლშუხ3რჩუხ3ტვუჯ3რაუჯ3რიქ3ვთოქ3ვსმქ3ვსოშა3ხვწა3გლჯო2რ1ჯო3რი", + 6 : "2რ1ამბ2რ1აჩა2რ1ეკო2ს1ორა2ფ1იარ3გლეჯვ_ერ2თხა2რ1ერა3თ2ქოარახ2ვას1ასიბა3თ2ვბო3თ2ქე2რ1არერ2თხათა2სათია3მ2ზკო3მ2სლა3მ2ჭლი3თ2ქმა3ს2მმა3ყ2ლნი3თ2ქნია3შტოგვ3თხსი3რ2ვუ2თ1ექუ2ლ1აფუ2ლ1ეკშ2ტერიშ2ტეროშია3თ2", + 7 : "1იღბალმ1იღბლის2მ1ოთხს3ჟ2ლეტახა2ლ1ახ", + 8 : "2ამბავი_2დიღბალმ2დიღბლის2თ1ოცდაა_ავ4რწყააკარ4გს_ასახ4ლს_აძარ4ცვ_გიერ4თს_ემა4სმეთვკარ4გს_მის4ტრს_ნის4ტრს_რთერ4თს_ტექ4სტს_ძარ4ცვს_", + 9 : "3რამბავი_" + }, + patternChars : "_აბგდევზთიკლმნოპჟრსტუფქღყშჩცძწჭხჯჰ", + patternArrayLength : 34171, + valueStoreLength : 7870 +}; \ No newline at end of file diff --git a/testsuite/test35.html b/testsuite/test35.html index 8480aab..598a519 100644 --- a/testsuite/test35.html +++ b/testsuite/test35.html @@ -68,5 +68,8 @@

      Ukrainian

      Church Slavonic

      Ꙗ҆зы́къ сегѡ̀ са́йта не мо́жетъ ѡ҆предѣле́нъ бы́ти. Прошꙋ́ тѧ ᲂу҆каза́ти ꙗ҆зы́къ

      Ꙗ҆зы́къ се|гѡ̀ са́й|та не мо́|жетъ ѡ҆|пре|дѣ|ле́нъ бы́|ти. Про|шꙋ́ тѧ ᲂу҆|ка|за́|ти ꙗ҆зы́къ

      +

      Georgian

      +

      ქართული ენა — ქართველების მშობლიური ენა, საქართველოს სახელმწიფო ენა. ქართულ ენაზე 5 მილიონზე მეტი ადამიანი ლაპარაკობს.

      +

      ქარ|თუ|ლი ენა — ქარ|თვე|ლე|ბის მ|შობ|ლი|უ|რი ენა, სა|ქარ|თვე|ლოს სა|ხელ|მწი|ფო ენა. ქარ|თულ ე|ნა|ზე 5 მი|ლი|ონ|ზე მე|ტი ა|და|მი|ა|ნი ლა|პა|რა|კობს.

      \ No newline at end of file