Code reformat with Netbeans

This commit is contained in:
mossroy 2013-07-01 15:57:16 +02:00
parent a920c0deb4
commit 8cedce59aa
6 changed files with 1349 additions and 1345 deletions

View File

@ -1,100 +1,100 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<head>
<meta charset="utf-8">
<title>Evopedia</title>
<meta name="description" content="Offline wikipedia reader">
<meta name="viewport" content="width=device-width">
<!--
Port of Evopedia (offline wikipedia reader) in HTML5/Javascript, with Firefox OS as the primary target
The original application is at http://www.evopedia.info/
It uses wikipedia dumps located at http://dumpathome.evopedia.info/dumps/finished
<title>Evopedia</title>
<meta name="description" content="Offline wikipedia reader">
<meta name="viewport" content="width=device-width">
<!--
Port of Evopedia (offline wikipedia reader) in HTML5/Javascript, with Firefox OS as the primary target
The original application is at http://www.evopedia.info/
It uses wikipedia dumps located at http://dumpathome.evopedia.info/dumps/finished
Author : Mossroy - mossroy@free.fr
Math image algorithm contributed by christian@evopedia.info
License:
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, see
<http://www.gnu.org/licenses/>.
-->
Author : Mossroy - mossroy@free.fr
Math image algorithm contributed by christian@evopedia.info
<link rel="stylesheet" href="css/mediawiki-main.css">
</head>
<body>
<h1>Evopedia</h1>
<input type="button" id="showHideAbout" value="About" />
<div id="about" style="display: none;">
This is a preliminary work on the port of Evopedia (offline wikipedia reader) in HTML5/Javascript, with Firefox OS as the primary target
<br />
The original application is at <a href="http://www.evopedia.info/">http://www.evopedia.info/</a>
<br />
<br />
To use it, you have to first download locally a dump from <a href="http://dumpathome.evopedia.info/dumps/finished">http://dumpathome.evopedia.info/dumps/finished</a> (with a Bittorrent client).
<br />
<ul>
<li>On desktops, it works on recent Firefox and Chrome, and maybe on other browsers. In this case, you have to select manually some files from your dump (see below)</li>
<li>On the Firefos OS simulator, you have to put the archive files in a "fake-sdcard" folder of your firefox profile (ex : ~/.mozilla/firefox/xxxx.default/extensions/r2d2b2g@mozilla.org/profile/fake-sdcard). It looks for file titles.idx in it. You need to install the application from the dashboard of the simulator (due to security restrictions in Firefox OS : only certified webapps can access the sdcard)</li>
<li>On a real Firefox OS device, you simply have to put the archive files anywhere in your sdcard, so that it finds titles.idx on it. For now, the application has to be installed manually (use the push feature of the Firefos OS Simulator)</li>
</ul>
<br />
It's still a beta version : there are many many ways this could be enhanced (suggestions and patches are welcome : the source code is on <a href="https://github.com/mossroy/evopedia-html5">github</a>). In particular :
<ul>
<li>The performance has to be optimized when searching titles and reading an article</li>
<li>Some searches (for example with prefix "a" on the French dump) do not give any result even if they should</li>
<li>In some cases, the links inside an article do not work, or do not lead to the right article</li>
<li>It is not easy to use on the Peak device from Geeksphone because the buttons and inputs are too small</li>
<li>Some features of the original application still have to be implemented : in particular geolocation of articles</li>
</ul>
The <a href="https://github.com/mossroy/evopedia-html5/issues">bugtracker</a> is on github too.
</div>
<div id="openLocalFiles" style="display: none;">
<br /> Please select the file titles.idx :<br /> <input type="file"
id="titleFile" /><br /> Please select the files wikipedia_*.dat
from the same dump :<br /> <input type="file" id="dataFiles" multiple />
<br /> Please select the file math.idx from the same dump:<br /> <input type="file"
id="mathIndexFile" /><br /> Please select the file math.dat from the
same dump:<br /> <input type="file" id="mathDataFile" /><br />
</div>
<div id="scanningForArchives" style="display: none;">
<br /> Scanning your sdcard for archives... Please wait <img src="img/spinner.gif" />
</div>
<div id="chooseArchiveFromLocalStorage" style="display: none;">
<br /> Please select the archive you want to use : <select id="archiveList"></select>
</div>
<br /> Find titles starting with :
<input type="text" id="prefix" value="" />&nbsp;
<input type="button" id="searchTitles" value="Search titles" />
<img id="searchingForTitles" src="img/spinner.gif" style="display: none;"/>
<br /> Choose a title from the filtered list :
<select id="titleList"></select>
<br />
<input type="button" id="readData" value="Read article from dump" />
<div id="readingArticle" style="display: none;">
Reading article <span id="articleName"></span> from dump... Please wait <img src="img/spinner.gif" />
</div>
<div id="articleContent">&nbsp;</div>
<hr />
License:
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, see
<http://www.gnu.org/licenses/>.
-->
<link rel="stylesheet" href="css/mediawiki-main.css">
</head>
<body>
<h1>Evopedia</h1>
<input type="button" id="showHideAbout" value="About" />
<div id="about" style="display: none;">
This is a preliminary work on the port of Evopedia (offline wikipedia reader) in HTML5/Javascript, with Firefox OS as the primary target
<br />
The original application is at <a href="http://www.evopedia.info/">http://www.evopedia.info/</a>
<br />
<br />
To use it, you have to first download locally a dump from <a href="http://dumpathome.evopedia.info/dumps/finished">http://dumpathome.evopedia.info/dumps/finished</a> (with a Bittorrent client).
<br />
<ul>
<li>On desktops, it works on recent Firefox and Chrome, and maybe on other browsers. In this case, you have to select manually some files from your dump (see below)</li>
<li>On the Firefos OS simulator, you have to put the archive files in a "fake-sdcard" folder of your firefox profile (ex : ~/.mozilla/firefox/xxxx.default/extensions/r2d2b2g@mozilla.org/profile/fake-sdcard). It looks for file titles.idx in it. You need to install the application from the dashboard of the simulator (due to security restrictions in Firefox OS : only certified webapps can access the sdcard)</li>
<li>On a real Firefox OS device, you simply have to put the archive files anywhere in your sdcard, so that it finds titles.idx on it. For now, the application has to be installed manually (use the push feature of the Firefos OS Simulator)</li>
</ul>
<br />
It's still a beta version : there are many many ways this could be enhanced (suggestions and patches are welcome : the source code is on <a href="https://github.com/mossroy/evopedia-html5">github</a>). In particular :
<ul>
<li>The performance has to be optimized when searching titles and reading an article</li>
<li>Some searches (for example with prefix "a" on the French dump) do not give any result even if they should</li>
<li>In some cases, the links inside an article do not work, or do not lead to the right article</li>
<li>It is not easy to use on the Peak device from Geeksphone because the buttons and inputs are too small</li>
<li>Some features of the original application still have to be implemented : in particular geolocation of articles</li>
</ul>
The <a href="https://github.com/mossroy/evopedia-html5/issues">bugtracker</a> is on github too.
</div>
<div id="openLocalFiles" style="display: none;">
<br /> Please select the file titles.idx :<br /> <input type="file"
id="titleFile" /><br /> Please select the files wikipedia_*.dat
from the same dump :<br /> <input type="file" id="dataFiles" multiple />
<br /> Please select the file math.idx from the same dump:<br /> <input type="file"
id="mathIndexFile" /><br /> Please select the file math.dat from the
same dump:<br /> <input type="file" id="mathDataFile" /><br />
</div>
<div id="scanningForArchives" style="display: none;">
<br /> Scanning your sdcard for archives... Please wait <img src="img/spinner.gif" />
</div>
<div id="chooseArchiveFromLocalStorage" style="display: none;">
<br /> Please select the archive you want to use : <select id="archiveList"></select>
</div>
<br /> Find titles starting with :
<input type="text" id="prefix" value="" />&nbsp;
<input type="button" id="searchTitles" value="Search titles" />
<img id="searchingForTitles" src="img/spinner.gif" style="display: none;"/>
<br /> Choose a title from the filtered list :
<select id="titleList"></select>
<br />
<input type="button" id="readData" value="Read article from dump" />
<div id="readingArticle" style="display: none;">
Reading article <span id="articleName"></span> from dump... Please wait <img src="img/spinner.gif" />
</div>
<div id="articleContent">&nbsp;</div>
<hr />
<!-- Using require.js, a module system for javascript, include the
js files. This loads "main.js", which in turn can load other
files, all handled by require.js:
http://requirejs.org/docs/api.html#jsfiles -->
<script type="text/javascript"
data-main="js/init.js"
src="js/lib/require.js"></script>
</body>
<!-- Using require.js, a module system for javascript, include the
js files. This loads "main.js", which in turn can load other
files, all handled by require.js:
http://requirejs.org/docs/api.html#jsfiles -->
<script type="text/javascript"
data-main="js/init.js"
src="js/lib/require.js"></script>
</body>
</html>

400
js/app.js
View File

@ -17,250 +17,250 @@ define(function(require) {
// Define behavior of HTML elements
$('#about').hide();
$('#showHideAbout').on('click', function(e) {
$('#about').toggle();
$('#about').toggle();
});
$('#searchTitles').on('click', function(e) {
searchTitlesFromPrefix($('#prefix').val());
searchTitlesFromPrefix($('#prefix').val());
});
$('#readData').on('click', function(e) {
var titleId = $('#titleList').val();
findTitleFromTitleIdAndLaunchArticleRead(titleId);
var title = evopedia.Title.parseTitleId(localArchive,titleId);
pushBrowserHistoryState(title.name);
var titleId = $('#titleList').val();
findTitleFromTitleIdAndLaunchArticleRead(titleId);
var title = evopedia.Title.parseTitleId(localArchive, titleId);
pushBrowserHistoryState(title.name);
});
$('#prefix').on('keyup', function(e) {
onKeyUpPrefix(e);
onKeyUpPrefix(e);
});
// Detect if DeviceStorage is available
var storage = null;
if ($.isFunction(navigator.getDeviceStorage)) {
storage = navigator.getDeviceStorage('sdcard');
storage = navigator.getDeviceStorage('sdcard');
}
if (storage != null) {
// If DeviceStorage is available, we look for archives in it
$('#scanningForArchives').show();
evopedia.LocalArchive.scanForArchives(storage,populateDropDownListOfArchives);
// If DeviceStorage is available, we look for archives in it
$('#scanningForArchives').show();
evopedia.LocalArchive.scanForArchives(storage, populateDropDownListOfArchives);
}
else {
// If DeviceStorage is not available, we display the file select components
displayFileSelect();
setLocalArchiveFromFileSelect();
// If DeviceStorage is not available, we display the file select components
displayFileSelect();
setLocalArchiveFromFileSelect();
}
// Display the article when the user goes back in the browser history
window.onpopstate = function(event) {
var titleName = event.state.titleName;
goToArticle(titleName);
var titleName = event.state.titleName;
goToArticle(titleName);
};
/**
* Populate the drop-down list of titles with the given list
*/
function populateDropDownListOfArchives(archiveDirectories) {
$('#scanningForArchives').hide();
$('#chooseArchiveFromLocalStorage').show();
var comboArchiveList = document.getElementById('archiveList');
comboArchiveList.options.length = 0;
for (var i=0; i<archiveDirectories.length; i++) {
var archiveDirectory = archiveDirectories[i];
comboArchiveList.options[i] = new Option (archiveDirectory, archiveDirectory);
}
$('#archiveList').on('change', setLocalArchiveFromArchiveList);
if (archiveDirectories.length>0) {
// Set the localArchive from the first result
setLocalArchiveFromArchiveList();
}
else {
alert("No Evopedia archive found in your sdcard. Please see 'About' for more info");
}
}
/**
* Populate the drop-down list of titles with the given list
*/
function populateDropDownListOfArchives(archiveDirectories) {
$('#scanningForArchives').hide();
$('#chooseArchiveFromLocalStorage').show();
var comboArchiveList = document.getElementById('archiveList');
comboArchiveList.options.length = 0;
for (var i = 0; i < archiveDirectories.length; i++) {
var archiveDirectory = archiveDirectories[i];
comboArchiveList.options[i] = new Option(archiveDirectory, archiveDirectory);
}
$('#archiveList').on('change', setLocalArchiveFromArchiveList);
if (archiveDirectories.length > 0) {
// Set the localArchive from the first result
setLocalArchiveFromArchiveList();
}
else {
alert("No Evopedia archive found in your sdcard. Please see 'About' for more info");
}
}
/**
* Sets the localArchive from the selected archive in the drop-down list
*/
function setLocalArchiveFromArchiveList() {
var archiveDirectory = $('#archiveList').val();
localArchive = new evopedia.LocalArchive();
localArchive.readTitleFile(storage, archiveDirectory);
localArchive.readDataFiles(storage, archiveDirectory, 0);
localArchive.readMathFiles(storage, archiveDirectory);
var archiveDirectory = $('#archiveList').val();
localArchive = new evopedia.LocalArchive();
localArchive.readTitleFile(storage, archiveDirectory);
localArchive.readDataFiles(storage, archiveDirectory, 0);
localArchive.readMathFiles(storage, archiveDirectory);
}
/**
* Displays the zone to select files from the dump
*/
function displayFileSelect() {
$('#openLocalFiles').show();
$('#dataFiles').on('change', setLocalArchiveFromFileSelect);
$('#titleFile').on('change', setLocalArchiveFromFileSelect);
$('#mathIndexFile').on('change', setLocalArchiveFromFileSelect);
$('#mathDataFile').on('change', setLocalArchiveFromFileSelect);
}
* Displays the zone to select files from the dump
*/
function displayFileSelect() {
$('#openLocalFiles').show();
$('#dataFiles').on('change', setLocalArchiveFromFileSelect);
$('#titleFile').on('change', setLocalArchiveFromFileSelect);
$('#mathIndexFile').on('change', setLocalArchiveFromFileSelect);
$('#mathDataFile').on('change', setLocalArchiveFromFileSelect);
}
/**
* Sets the localArchive from the File selects populated by user
*/
function setLocalArchiveFromFileSelect() {
var dataFiles=document.getElementById('dataFiles').files;
var titleFile=document.getElementById('titleFile').files[0];
var mathIndexFile=document.getElementById('mathIndexFile').files[0];
var mathDataFile=document.getElementById('mathDataFile').files[0];
localArchive = new evopedia.LocalArchive();
localArchive.dataFiles = dataFiles;
localArchive.titleFile = titleFile;
localArchive.mathIndexFile = mathIndexFile;
localArchive.mathDataFile = mathDataFile;
}
/**
* Sets the localArchive from the File selects populated by user
*/
function setLocalArchiveFromFileSelect() {
var dataFiles = document.getElementById('dataFiles').files;
var titleFile = document.getElementById('titleFile').files[0];
var mathIndexFile = document.getElementById('mathIndexFile').files[0];
var mathDataFile = document.getElementById('mathDataFile').files[0];
localArchive = new evopedia.LocalArchive();
localArchive.dataFiles = dataFiles;
localArchive.titleFile = titleFile;
localArchive.mathIndexFile = mathIndexFile;
localArchive.mathDataFile = mathDataFile;
}
/**
* Handle Enter key in the prefix input zone
*/
function onKeyUpPrefix(evt) {
if (evt.keyCode == 13) {
document.getElementById("searchTitles").click();
}
}
/**
* Handle Enter key in the prefix input zone
*/
function onKeyUpPrefix(evt) {
if (evt.keyCode == 13) {
document.getElementById("searchTitles").click();
}
}
/**
* Search the index for titles that start with the given prefix (implemented
* with a binary search inside the index file)
*/
function searchTitlesFromPrefix(prefix) {
$('#searchingForTitles').show();
if (localArchive.titleFile) {
localArchive.findTitlesWithPrefix(prefix.trim(), populateDropDownListOfTitles);
} else {
alert("Title file not set");
}
}
/**
* Populate the drop-down list of titles with the given list
*/
function populateDropDownListOfTitles(titleList) {
var comboTitleList = document.getElementById('titleList');
// Remove previous results
comboTitleList.options.length = 0;
for (var i=0; i<titleList.length; i++) {
var title = titleList[i];
comboTitleList.options[i] = new Option (title.name, title.toStringId());
}
$('#searchingForTitles').hide();
}
/**
* Search the index for titles that start with the given prefix (implemented
* with a binary search inside the index file)
*/
function searchTitlesFromPrefix(prefix) {
$('#searchingForTitles').show();
if (localArchive.titleFile) {
localArchive.findTitlesWithPrefix(prefix.trim(), populateDropDownListOfTitles);
} else {
alert("Title file not set");
}
}
/**
* Populate the drop-down list of titles with the given list
*/
function populateDropDownListOfTitles(titleList) {
var comboTitleList = document.getElementById('titleList');
// Remove previous results
comboTitleList.options.length = 0;
for (var i = 0; i < titleList.length; i++) {
var title = titleList[i];
comboTitleList.options[i] = new Option(title.name, title.toStringId());
}
$('#searchingForTitles').hide();
}
/**
* Creates an instance of title from given titleId (including resolving redirects),
* and call the function to read the corresponding article
*/
function findTitleFromTitleIdAndLaunchArticleRead(titleId) {
if (localArchive.dataFiles && localArchive.dataFiles.length>0) {
var title = evopedia.Title.parseTitleId(localArchive,titleId);
$("#articleName").html(title.name);
$("#readingArticle").show();
$("#articleContent").html("");
if (title.fileNr == 255) {
localArchive.resolveRedirect(title, readArticle);
}
else {
readArticle(title);
}
}
else {
alert("Data files not set");
}
}
/**
* Creates an instance of title from given titleId (including resolving redirects),
* and call the function to read the corresponding article
*/
function findTitleFromTitleIdAndLaunchArticleRead(titleId) {
if (localArchive.dataFiles && localArchive.dataFiles.length > 0) {
var title = evopedia.Title.parseTitleId(localArchive, titleId);
$("#articleName").html(title.name);
$("#readingArticle").show();
$("#articleContent").html("");
if (title.fileNr == 255) {
localArchive.resolveRedirect(title, readArticle);
}
else {
readArticle(title);
}
}
else {
alert("Data files not set");
}
}
/**
* Read the article corresponding to the given title
*/
function readArticle(title) {
if ($.isArray(title)) {
title = title[0];
if (title.fileNr == 255) {
localArchive.resolveRedirect(title, readArticle);
return;
}
}
localArchive.readArticle(title, displayArticleInForm);
}
/**
* Read the article corresponding to the given title
*/
function readArticle(title) {
if ($.isArray(title)) {
title = title[0];
if (title.fileNr == 255) {
localArchive.resolveRedirect(title, readArticle);
return;
}
}
localArchive.readArticle(title, displayArticleInForm);
}
/**
* Display the the given HTML article in the web page,
* and convert links to javascript calls
*/
function displayArticleInForm(title, htmlArticle) {
$("#readingArticle").hide();
// Display the article inside the web page.
$('#articleContent').html(htmlArticle);
// Convert links into javascript calls
var regex = /^\.?\/?\.\.\/([^\/]+)\/(.*)/;
$('#articleContent').find('a').each(function(){
// Store current link's url
var url = $(this).attr("href");
if(url.slice(0, 1) == "#") {
// It's an anchor link : do nothing
}
else if (url.substring(0,4) === "http") {
// It's an external link : do nothing
}
else if (url.substring(0,2) === ".." || url.substring(0,4) === "./..") {
// It's a link to another language : change the URL to the online version of wikipedia
// The regular expression extracts $1 as the language, and $2 as the title name
var onlineWikipediaUrl = url.replace(regex, "https://$1.wikipedia.org/wiki/$2");
$(this).attr("href",onlineWikipediaUrl);
}
else {
// It's a link to another article : add an onclick event to go to this article
// instead of following the link
$(this).on('click', function(e) {
var titleName = decodeURIComponent($(this).attr("href"));
pushBrowserHistoryState(titleName);
goToArticle(titleName);
return false;
});
}
});
/**
* Display the the given HTML article in the web page,
* and convert links to javascript calls
*/
function displayArticleInForm(title, htmlArticle) {
$("#readingArticle").hide();
// Load math images
$('#articleContent').find('img').each(function(){
// Display the article inside the web page.
$('#articleContent').html(htmlArticle);
// Convert links into javascript calls
var regex = /^\.?\/?\.\.\/([^\/]+)\/(.*)/;
$('#articleContent').find('a').each(function() {
// Store current link's url
var url = $(this).attr("href");
if (url.slice(0, 1) == "#") {
// It's an anchor link : do nothing
}
else if (url.substring(0, 4) === "http") {
// It's an external link : do nothing
}
else if (url.substring(0, 2) === ".." || url.substring(0, 4) === "./..") {
// It's a link to another language : change the URL to the online version of wikipedia
// The regular expression extracts $1 as the language, and $2 as the title name
var onlineWikipediaUrl = url.replace(regex, "https://$1.wikipedia.org/wiki/$2");
$(this).attr("href", onlineWikipediaUrl);
}
else {
// It's a link to another article : add an onclick event to go to this article
// instead of following the link
$(this).on('click', function(e) {
var titleName = decodeURIComponent($(this).attr("href"));
pushBrowserHistoryState(titleName);
goToArticle(titleName);
return false;
});
}
});
// Load math images
$('#articleContent').find('img').each(function() {
var image = $(this);
var m;
if ((m = image.attr("src").match(/^\/math.*\/([0-9a-f]{32})\.png$/))) {
localArchive.loadMathImage(m[1], function(data) {
image.attr("src", 'data:image/png;base64,' + data);
});
}
});
}
/**
* Changes the URL of the browser page
*/
function pushBrowserHistoryState(titleName) {
if (titleName) {
var stateObj = { titleName: titleName};
window.history.pushState(stateObj,"Wikipedia Article : " + titleName,"#" + titleName);
}
}
}
});
}
/**
* Changes the URL of the browser page
*/
function pushBrowserHistoryState(titleName) {
if (titleName) {
var stateObj = {titleName: titleName};
window.history.pushState(stateObj, "Wikipedia Article : " + titleName, "#" + titleName);
}
}
/**
* Replace article content with the one of the given title
*/
function goToArticle(titleName) {
$("#articleName").html(titleName);
$("#readingArticle").show();
$("#articleContent").html("");
localArchive.getTitleByName(titleName, readArticle);
}
/**
* Replace article content with the one of the given title
*/
function goToArticle(titleName) {
$("#articleName").html(titleName);
$("#readingArticle").show();
$("#articleContent").html("");
localArchive.getTitleByName(titleName, readArticle);
}
});

File diff suppressed because it is too large Load Diff

View File

@ -1,108 +1,108 @@
define(function(require) {
var diacriticsMap = [
{'base':'A', 'letters':/[\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g},
{'base':'AA','letters':/[\uA732]/g},
{'base':'AE','letters':/[\u00C4\u00C6\u01FC\u01E2]/g},
{'base':'AO','letters':/[\uA734]/g},
{'base':'AU','letters':/[\uA736]/g},
{'base':'AV','letters':/[\uA738\uA73A]/g},
{'base':'AY','letters':/[\uA73C]/g},
{'base':'B', 'letters':/[\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g},
{'base':'C', 'letters':/[\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g},
{'base':'D', 'letters':/[\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g},
{'base':'DZ','letters':/[\u01F1\u01C4]/g},
{'base':'Dz','letters':/[\u01F2\u01C5]/g},
{'base':'E', 'letters':/[\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E]/g},
{'base':'F', 'letters':/[\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g},
{'base':'G', 'letters':/[\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g},
{'base':'H', 'letters':/[\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g},
{'base':'I', 'letters':/[\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g},
{'base':'J', 'letters':/[\u004A\u24BF\uFF2A\u0134\u0248]/g},
{'base':'K', 'letters':/[\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g},
{'base':'L', 'letters':/[\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780]/g},
{'base':'LJ','letters':/[\u01C7]/g},
{'base':'Lj','letters':/[\u01C8]/g},
{'base':'M', 'letters':/[\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g},
{'base':'N', 'letters':/[\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g},
{'base':'NJ','letters':/[\u01CA]/g},
{'base':'Nj','letters':/[\u01CB]/g},
{'base':'O', 'letters':/[\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C]/g},
{'base':'OE','letters':/[\u00D6\u0152]/g},
{'base':'OI','letters':/[\u01A2]/g},
{'base':'OO','letters':/[\uA74E]/g},
{'base':'OU','letters':/[\u0222]/g},
{'base':'P', 'letters':/[\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g},
{'base':'Q', 'letters':/[\u0051\u24C6\uFF31\uA756\uA758\u024A]/g},
{'base':'R', 'letters':/[\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g},
{'base':'S', 'letters':/[\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g},
{'base':'T', 'letters':/[\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g},
{'base':'TZ','letters':/[\uA728]/g},
{'base':'U', 'letters':/[\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244]/g},
{'base':'UE','letters':/[\u00DC]/g},
{'base':'V', 'letters':/[\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g},
{'base':'VY','letters':/[\uA760]/g},
{'base':'W', 'letters':/[\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g},
{'base':'X', 'letters':/[\u0058\u24CD\uFF38\u1E8A\u1E8C]/g},
{'base':'Y', 'letters':/[\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g},
{'base':'Z', 'letters':/[\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g},
{'base':'a', 'letters':/[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250]/g},
{'base':'aa','letters':/[\uA733]/g},
{'base':'ae','letters':/[\u00E4\u00E6\u01FD\u01E3]/g},
{'base':'ao','letters':/[\uA735]/g},
{'base':'au','letters':/[\uA737]/g},
{'base':'av','letters':/[\uA739\uA73B]/g},
{'base':'ay','letters':/[\uA73D]/g},
{'base':'b', 'letters':/[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253]/g},
{'base':'c', 'letters':/[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184]/g},
{'base':'d', 'letters':/[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A]/g},
{'base':'dz','letters':/[\u01F3\u01C6]/g},
{'base':'e', 'letters':/[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD]/g},
{'base':'f', 'letters':/[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C]/g},
{'base':'g', 'letters':/[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F]/g},
{'base':'h', 'letters':/[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265]/g},
{'base':'hv','letters':/[\u0195]/g},
{'base':'i', 'letters':/[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131]/g},
{'base':'j', 'letters':/[\u006A\u24D9\uFF4A\u0135\u01F0\u0249]/g},
{'base':'k', 'letters':/[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3]/g},
{'base':'l', 'letters':/[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747]/g},
{'base':'lj','letters':/[\u01C9]/g},
{'base':'m', 'letters':/[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F]/g},
{'base':'n', 'letters':/[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5]/g},
{'base':'nj','letters':/[\u01CC]/g},
{'base':'o', 'letters':/[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275]/g},
{'base':'oe','letters': /[\u00F6\u0153]/g},
{'base':'oi','letters':/[\u01A3]/g},
{'base':'ou','letters':/[\u0223]/g},
{'base':'oo','letters':/[\uA74F]/g},
{'base':'p','letters':/[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755]/g},
{'base':'q','letters':/[\u0071\u24E0\uFF51\u024B\uA757\uA759]/g},
{'base':'r','letters':/[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783]/g},
{'base':'s','letters':/[\u0073\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B]/g},
{'base':'ss','letters':/[\u00DF]/g},
{'base':'t','letters':/[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787]/g},
{'base':'tz','letters':/[\uA729]/g},
{'base':'u','letters':/[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289]/g},
{'base':'ue','letters':/[\u00FC]/g},
{'base':'v','letters':/[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C]/g},
{'base':'vy','letters':/[\uA761]/g},
{'base':'w','letters':/[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73]/g},
{'base':'x','letters':/[\u0078\u24E7\uFF58\u1E8B\u1E8D]/g},
{'base':'y','letters':/[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF]/g},
{'base':'z','letters':/[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763]/g},
{'base':'_','letters':/[\ \-\_]/g}
];
function normalizeString(string) {
var normalizedString=string;
for(var i=0; i<diacriticsMap.length; i++) {
normalizedString = normalizedString.replace(diacriticsMap[i].letters, diacriticsMap[i].base);
}
return normalizedString.toLowerCase();
}
return {
normalizeString: normalizeString
};
});
define(function(require) {
var diacriticsMap = [
{'base': 'A', 'letters': /[\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g},
{'base': 'AA', 'letters': /[\uA732]/g},
{'base': 'AE', 'letters': /[\u00C4\u00C6\u01FC\u01E2]/g},
{'base': 'AO', 'letters': /[\uA734]/g},
{'base': 'AU', 'letters': /[\uA736]/g},
{'base': 'AV', 'letters': /[\uA738\uA73A]/g},
{'base': 'AY', 'letters': /[\uA73C]/g},
{'base': 'B', 'letters': /[\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g},
{'base': 'C', 'letters': /[\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g},
{'base': 'D', 'letters': /[\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g},
{'base': 'DZ', 'letters': /[\u01F1\u01C4]/g},
{'base': 'Dz', 'letters': /[\u01F2\u01C5]/g},
{'base': 'E', 'letters': /[\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E]/g},
{'base': 'F', 'letters': /[\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g},
{'base': 'G', 'letters': /[\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g},
{'base': 'H', 'letters': /[\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g},
{'base': 'I', 'letters': /[\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g},
{'base': 'J', 'letters': /[\u004A\u24BF\uFF2A\u0134\u0248]/g},
{'base': 'K', 'letters': /[\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g},
{'base': 'L', 'letters': /[\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780]/g},
{'base': 'LJ', 'letters': /[\u01C7]/g},
{'base': 'Lj', 'letters': /[\u01C8]/g},
{'base': 'M', 'letters': /[\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g},
{'base': 'N', 'letters': /[\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g},
{'base': 'NJ', 'letters': /[\u01CA]/g},
{'base': 'Nj', 'letters': /[\u01CB]/g},
{'base': 'O', 'letters': /[\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C]/g},
{'base': 'OE', 'letters': /[\u00D6\u0152]/g},
{'base': 'OI', 'letters': /[\u01A2]/g},
{'base': 'OO', 'letters': /[\uA74E]/g},
{'base': 'OU', 'letters': /[\u0222]/g},
{'base': 'P', 'letters': /[\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g},
{'base': 'Q', 'letters': /[\u0051\u24C6\uFF31\uA756\uA758\u024A]/g},
{'base': 'R', 'letters': /[\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g},
{'base': 'S', 'letters': /[\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g},
{'base': 'T', 'letters': /[\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g},
{'base': 'TZ', 'letters': /[\uA728]/g},
{'base': 'U', 'letters': /[\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244]/g},
{'base': 'UE', 'letters': /[\u00DC]/g},
{'base': 'V', 'letters': /[\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g},
{'base': 'VY', 'letters': /[\uA760]/g},
{'base': 'W', 'letters': /[\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g},
{'base': 'X', 'letters': /[\u0058\u24CD\uFF38\u1E8A\u1E8C]/g},
{'base': 'Y', 'letters': /[\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g},
{'base': 'Z', 'letters': /[\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g},
{'base': 'a', 'letters': /[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250]/g},
{'base': 'aa', 'letters': /[\uA733]/g},
{'base': 'ae', 'letters': /[\u00E4\u00E6\u01FD\u01E3]/g},
{'base': 'ao', 'letters': /[\uA735]/g},
{'base': 'au', 'letters': /[\uA737]/g},
{'base': 'av', 'letters': /[\uA739\uA73B]/g},
{'base': 'ay', 'letters': /[\uA73D]/g},
{'base': 'b', 'letters': /[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253]/g},
{'base': 'c', 'letters': /[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184]/g},
{'base': 'd', 'letters': /[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A]/g},
{'base': 'dz', 'letters': /[\u01F3\u01C6]/g},
{'base': 'e', 'letters': /[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD]/g},
{'base': 'f', 'letters': /[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C]/g},
{'base': 'g', 'letters': /[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F]/g},
{'base': 'h', 'letters': /[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265]/g},
{'base': 'hv', 'letters': /[\u0195]/g},
{'base': 'i', 'letters': /[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131]/g},
{'base': 'j', 'letters': /[\u006A\u24D9\uFF4A\u0135\u01F0\u0249]/g},
{'base': 'k', 'letters': /[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3]/g},
{'base': 'l', 'letters': /[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747]/g},
{'base': 'lj', 'letters': /[\u01C9]/g},
{'base': 'm', 'letters': /[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F]/g},
{'base': 'n', 'letters': /[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5]/g},
{'base': 'nj', 'letters': /[\u01CC]/g},
{'base': 'o', 'letters': /[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275]/g},
{'base': 'oe', 'letters': /[\u00F6\u0153]/g},
{'base': 'oi', 'letters': /[\u01A3]/g},
{'base': 'ou', 'letters': /[\u0223]/g},
{'base': 'oo', 'letters': /[\uA74F]/g},
{'base': 'p', 'letters': /[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755]/g},
{'base': 'q', 'letters': /[\u0071\u24E0\uFF51\u024B\uA757\uA759]/g},
{'base': 'r', 'letters': /[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783]/g},
{'base': 's', 'letters': /[\u0073\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B]/g},
{'base': 'ss', 'letters': /[\u00DF]/g},
{'base': 't', 'letters': /[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787]/g},
{'base': 'tz', 'letters': /[\uA729]/g},
{'base': 'u', 'letters': /[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289]/g},
{'base': 'ue', 'letters': /[\u00FC]/g},
{'base': 'v', 'letters': /[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C]/g},
{'base': 'vy', 'letters': /[\uA761]/g},
{'base': 'w', 'letters': /[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73]/g},
{'base': 'x', 'letters': /[\u0078\u24E7\uFF58\u1E8B\u1E8D]/g},
{'base': 'y', 'letters': /[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF]/g},
{'base': 'z', 'letters': /[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763]/g},
{'base': '_', 'letters': /[\ \-\_]/g}
];
function normalizeString(string) {
var normalizedString = string;
for (var i = 0; i < diacriticsMap.length; i++) {
normalizedString = normalizedString.replace(diacriticsMap[i].letters, diacriticsMap[i].base);
}
return normalizedString.toLowerCase();
}
return {
normalizeString: normalizeString
};
});

View File

@ -1,33 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Evopedia HTML5 Unit tests</title>
<link rel="stylesheet" href="qunit-1.11.0.css" />
<script src="qunit-1.11.0.js"></script>
<!-- Using require.js, a module system for javascript, include the
js files. This loads "main.js", which in turn can load other
files, all handled by require.js:
http://requirejs.org/docs/api.html#jsfiles -->
<script type="text/javascript"
data-main="init.js"
src="../js/lib/require.js"></script>
</head>
<body>
Please select the file titles.idx from wikipedia_small_2010-08-14 (included with source code) :<br />
<input type="file" id="titleFile" />
<br />Please select the file wikipedia_00.dat from the same dump :<br />
<input type="file" id="dataFiles" multiple />
<br /> Please select the file math.idx from the same dump:<br />
<input type="file" id="mathIndexFile" />
<br /> Please select the file math.dat from the same dump:<br />
<input type="file" id="mathDataFile" />
<br />
<input type="button" id="runTests" value="Run tests" />
<div id="qunit"></div>
</body>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Evopedia HTML5 Unit tests</title>
<link rel="stylesheet" href="qunit-1.11.0.css" />
<script src="qunit-1.11.0.js"></script>
<!-- Using require.js, a module system for javascript, include the
js files. This loads "main.js", which in turn can load other
files, all handled by require.js:
http://requirejs.org/docs/api.html#jsfiles -->
<script type="text/javascript"
data-main="init.js"
src="../js/lib/require.js"></script>
</head>
<body>
Please select the file titles.idx from wikipedia_small_2010-08-14 (included with source code) :<br />
<input type="file" id="titleFile" />
<br />Please select the file wikipedia_00.dat from the same dump :<br />
<input type="file" id="dataFiles" multiple />
<br /> Please select the file math.idx from the same dump:<br />
<input type="file" id="mathIndexFile" />
<br /> Please select the file math.dat from the same dump:<br />
<input type="file" id="mathDataFile" />
<br />
<input type="button" id="runTests" value="Run tests" />
<div id="qunit"></div>
</body>
</html>

View File

@ -1,162 +1,162 @@
define(function (require) {
var $ = require('zepto');
var evopedia = require('evopedia');
// Due to security restrictions in the browsers,
// we can not read directly the files and run the unit tests
// The user has to select them manually, then launch the tests
$('#runTests').on('click', function(e) {
runTests();
});
var runTests = function() {
module("environment");
test("qunit test", function() {
equal("test", "test", "QUnit is properly configured");
});
test("check title and data files are set", function(){
var titleFile = document.getElementById('titleFile').files[0];
var dataFiles = document.getElementById('dataFiles').files;
ok(titleFile && titleFile.size>0,"Title file set and not empty");
ok(dataFiles && dataFiles[0] && dataFiles[0].size>0,"First data file set and not empty");
var mathIndexFile = document.getElementById('mathIndexFile').files[0];
var mathDataFile = document.getElementById('mathDataFile').files[0];
ok(mathIndexFile && mathIndexFile.size>0,"Math index file set and not empty");
ok(mathDataFile && mathDataFile.size>0,"Math data file set and not empty");
});
// Create a localArchive from selected files, in order to run the following tests
var localArchive = new evopedia.LocalArchive();
localArchive.titleFile = document.getElementById('titleFile').files[0];
localArchive.dataFiles = document.getElementById('dataFiles').files;
localArchive.mathIndexFile = document.getElementById('mathIndexFile').files[0];
localArchive.mathDataFile = document.getElementById('mathDataFile').files[0];
localArchive.language = "small";
localArchive.date = "2010-08-14";
module("evopedia");
asyncTest("check getTitlesStartingAtOffset 0", function(){
var callbackFunction = function(titleList) {
equal(titleList.length, 4, "4 titles found, as requested");
var indexAbraham=-1;
for (var i=0; i<titleList.length; i++) {
if (titleList[i] && titleList[i].name == "Abraham") {
indexAbraham=i;
}
}
ok(indexAbraham>-1,"Title 'Abraham' found");
var firstTitleName = "not found";
var secondTitleName = "not found";
if (titleList.length>=1 && titleList[0]) {
firstTitleName = titleList[0].name;
}
if (titleList.length>=2 && titleList[1]) {
secondTitleName = titleList[1].name;
}
equal(firstTitleName,"Abbasid_Caliphate","First article name is 'Abbasid_Caliphate'");
equal(secondTitleName,"Abortion","Second article name is 'Abortion'");
start();
};
localArchive.getTitlesStartingAtOffset(0, 4, callbackFunction);
});
asyncTest("check findTitlesWithPrefix Am", function() {
var callbackFunction = function(titleList) {
ok(titleList && titleList.length>0,"At least one title is found");
var firstTitleName = "not found";
var secondTitleName = "not found";
if (titleList.length>=1 && titleList[0]) {
firstTitleName = titleList[0].name;
}
if (titleList.length>=2 && titleList[1]) {
secondTitleName = titleList[1].name;
}
equal(firstTitleName,"Amazon_River","First article name is 'Amazon_River'");
equal(secondTitleName,"American_Civil_War","Second article name is 'American_Civil_War'");
equal(titleList.length,4,"4 titles should be found");
start();
};
localArchive.findTitlesWithPrefix("Am", callbackFunction);
});
// Create a title instance for the Article 'Abraham'
var titleAbraham = new evopedia.Title();
titleAbraham.archive = localArchive;
titleAbraham.articleLength = 10071;
titleAbraham.blockOffset = 127640;
titleAbraham.blockStart = 2364940;
titleAbraham.fileNr = 0;
titleAbraham.name = "Abraham";
titleAbraham.titleOffset = 57;
asyncTest("check getTitleByName with accents : Diego Velázquez", function() {
var callbackFunction = function(titleList) {
ok (titleList && titleList.length==1,"One title found");
equal(titleList[0].name,"Diego_Velázquez","Name of the title is correct");
start();
};
localArchive.getTitleByName("Diego Velázquez",callbackFunction);
});
asyncTest("check getTitleByName with quote : Hundred Years' War", function() {
var callbackFunction = function(titleList) {
ok (titleList && titleList.length==1,"One title found");
equal(titleList[0].name,"Hundred_Years'_War","Name of the title is correct");
start();
};
localArchive.getTitleByName("Hundred Years' War",callbackFunction);
});
test("check parseTitleFromId", function() {
var titleId = "small|2010-08-14|0|57|Abraham|2364940|127640|10071";
var title = evopedia.Title.parseTitleId(localArchive,titleId);
ok(title,"Title instance created");
deepEqual(title,titleAbraham,"Parsing from titleId gives Abraham title");
});
asyncTest("check readArticle", function(){
var callbackFunction = function(title, htmlArticle) {
ok(htmlArticle && htmlArticle.length>0,"Article not empty");
// Remove new lines
htmlArticle = htmlArticle.replace(/[\r\n]/g, " ");
ok(htmlArticle.match("^[ \t]*<h1[^>]*>Abraham</h1>"),"'Abraham' title at the beginning");
ok(htmlArticle.match("</div>[ \t]$"),"</div> at the end");
start();
};
localArchive.readArticle(titleAbraham, callbackFunction);
});
asyncTest("check getTitleByName and readArticle with escape bytes", function(){
var callbackArticleRead = function(title, htmlArticle) {
ok(htmlArticle && htmlArticle.length>0,"Article not empty");
// Remove new lines
htmlArticle = htmlArticle.replace(/[\r\n]/g, " ");
ok(htmlArticle.match("^[ \t]*<h1[^>]*>AIDS</h1>"),"'AIDS' title at the beginning");
ok(htmlArticle.match("</div>[ \t]$"),"</div> at the end");
start();
};
var callbackTitleList = function(titleList) {
ok (titleList && titleList.length==1,"One title found");
var title = titleList[0];
equal(title.name,"AIDS","Name of the title is correct");
localArchive.readArticle(title, callbackArticleRead);
};
localArchive.getTitleByName("AIDS",callbackTitleList);
});
asyncTest("check loading a math image", function(){
var callbackFunction = function(data) {
ok(data && data.length>0,"Image not empty");
// edb3069b82c68d270f6642c171cc6293.png should give a "1 1/2" formula (can be found in "Rational_number" article)
equal(data,
"iVBORw0KGgoAAAANSUhEUgAAABUAAAApBAMAAAAogX9zAAAAMFBMVEX///8AAADm5uZAQEDMzMwWFhYiIiIwMDBQUFCenp62trZiYmIMDAwEBASKiop0dHRvDVFEAAAAb0lEQVQY02NggAAmAwY4cE2AM9VNEWwG9oFhcxgKN9HJhYyCQCBApgs5jYMVYCKrGdgOwNgGDCzSMLYwA4MYjH2cgeEawjgWCQSbQwjBdpyAYMch2f4Awd7HwAVj8n1g4Iaxl+7e3Q1jXxQUlGMAAJkfGS29Qu04AAAAAElFTkSuQmCC",
"Math image corresponds to '1 1/2' png");
start();
};
localArchive.loadMathImage("edb3069b82c68d270f6642c171cc6293", callbackFunction);
});
};
});
define(function(require) {
var $ = require('zepto');
var evopedia = require('evopedia');
// Due to security restrictions in the browsers,
// we can not read directly the files and run the unit tests
// The user has to select them manually, then launch the tests
$('#runTests').on('click', function(e) {
runTests();
});
var runTests = function() {
module("environment");
test("qunit test", function() {
equal("test", "test", "QUnit is properly configured");
});
test("check title and data files are set", function() {
var titleFile = document.getElementById('titleFile').files[0];
var dataFiles = document.getElementById('dataFiles').files;
ok(titleFile && titleFile.size > 0, "Title file set and not empty");
ok(dataFiles && dataFiles[0] && dataFiles[0].size > 0, "First data file set and not empty");
var mathIndexFile = document.getElementById('mathIndexFile').files[0];
var mathDataFile = document.getElementById('mathDataFile').files[0];
ok(mathIndexFile && mathIndexFile.size > 0, "Math index file set and not empty");
ok(mathDataFile && mathDataFile.size > 0, "Math data file set and not empty");
});
// Create a localArchive from selected files, in order to run the following tests
var localArchive = new evopedia.LocalArchive();
localArchive.titleFile = document.getElementById('titleFile').files[0];
localArchive.dataFiles = document.getElementById('dataFiles').files;
localArchive.mathIndexFile = document.getElementById('mathIndexFile').files[0];
localArchive.mathDataFile = document.getElementById('mathDataFile').files[0];
localArchive.language = "small";
localArchive.date = "2010-08-14";
module("evopedia");
asyncTest("check getTitlesStartingAtOffset 0", function() {
var callbackFunction = function(titleList) {
equal(titleList.length, 4, "4 titles found, as requested");
var indexAbraham = -1;
for (var i = 0; i < titleList.length; i++) {
if (titleList[i] && titleList[i].name == "Abraham") {
indexAbraham = i;
}
}
ok(indexAbraham > -1, "Title 'Abraham' found");
var firstTitleName = "not found";
var secondTitleName = "not found";
if (titleList.length >= 1 && titleList[0]) {
firstTitleName = titleList[0].name;
}
if (titleList.length >= 2 && titleList[1]) {
secondTitleName = titleList[1].name;
}
equal(firstTitleName, "Abbasid_Caliphate", "First article name is 'Abbasid_Caliphate'");
equal(secondTitleName, "Abortion", "Second article name is 'Abortion'");
start();
};
localArchive.getTitlesStartingAtOffset(0, 4, callbackFunction);
});
asyncTest("check findTitlesWithPrefix Am", function() {
var callbackFunction = function(titleList) {
ok(titleList && titleList.length > 0, "At least one title is found");
var firstTitleName = "not found";
var secondTitleName = "not found";
if (titleList.length >= 1 && titleList[0]) {
firstTitleName = titleList[0].name;
}
if (titleList.length >= 2 && titleList[1]) {
secondTitleName = titleList[1].name;
}
equal(firstTitleName, "Amazon_River", "First article name is 'Amazon_River'");
equal(secondTitleName, "American_Civil_War", "Second article name is 'American_Civil_War'");
equal(titleList.length, 4, "4 titles should be found");
start();
};
localArchive.findTitlesWithPrefix("Am", callbackFunction);
});
// Create a title instance for the Article 'Abraham'
var titleAbraham = new evopedia.Title();
titleAbraham.archive = localArchive;
titleAbraham.articleLength = 10071;
titleAbraham.blockOffset = 127640;
titleAbraham.blockStart = 2364940;
titleAbraham.fileNr = 0;
titleAbraham.name = "Abraham";
titleAbraham.titleOffset = 57;
asyncTest("check getTitleByName with accents : Diego Velázquez", function() {
var callbackFunction = function(titleList) {
ok(titleList && titleList.length == 1, "One title found");
equal(titleList[0].name, "Diego_Velázquez", "Name of the title is correct");
start();
};
localArchive.getTitleByName("Diego Velázquez", callbackFunction);
});
asyncTest("check getTitleByName with quote : Hundred Years' War", function() {
var callbackFunction = function(titleList) {
ok(titleList && titleList.length == 1, "One title found");
equal(titleList[0].name, "Hundred_Years'_War", "Name of the title is correct");
start();
};
localArchive.getTitleByName("Hundred Years' War", callbackFunction);
});
test("check parseTitleFromId", function() {
var titleId = "small|2010-08-14|0|57|Abraham|2364940|127640|10071";
var title = evopedia.Title.parseTitleId(localArchive, titleId);
ok(title, "Title instance created");
deepEqual(title, titleAbraham, "Parsing from titleId gives Abraham title");
});
asyncTest("check readArticle", function() {
var callbackFunction = function(title, htmlArticle) {
ok(htmlArticle && htmlArticle.length > 0, "Article not empty");
// Remove new lines
htmlArticle = htmlArticle.replace(/[\r\n]/g, " ");
ok(htmlArticle.match("^[ \t]*<h1[^>]*>Abraham</h1>"), "'Abraham' title at the beginning");
ok(htmlArticle.match("</div>[ \t]$"), "</div> at the end");
start();
};
localArchive.readArticle(titleAbraham, callbackFunction);
});
asyncTest("check getTitleByName and readArticle with escape bytes", function() {
var callbackArticleRead = function(title, htmlArticle) {
ok(htmlArticle && htmlArticle.length > 0, "Article not empty");
// Remove new lines
htmlArticle = htmlArticle.replace(/[\r\n]/g, " ");
ok(htmlArticle.match("^[ \t]*<h1[^>]*>AIDS</h1>"), "'AIDS' title at the beginning");
ok(htmlArticle.match("</div>[ \t]$"), "</div> at the end");
start();
};
var callbackTitleList = function(titleList) {
ok(titleList && titleList.length == 1, "One title found");
var title = titleList[0];
equal(title.name, "AIDS", "Name of the title is correct");
localArchive.readArticle(title, callbackArticleRead);
};
localArchive.getTitleByName("AIDS", callbackTitleList);
});
asyncTest("check loading a math image", function() {
var callbackFunction = function(data) {
ok(data && data.length > 0, "Image not empty");
// edb3069b82c68d270f6642c171cc6293.png should give a "1 1/2" formula (can be found in "Rational_number" article)
equal(data,
"iVBORw0KGgoAAAANSUhEUgAAABUAAAApBAMAAAAogX9zAAAAMFBMVEX///8AAADm5uZAQEDMzMwWFhYiIiIwMDBQUFCenp62trZiYmIMDAwEBASKiop0dHRvDVFEAAAAb0lEQVQY02NggAAmAwY4cE2AM9VNEWwG9oFhcxgKN9HJhYyCQCBApgs5jYMVYCKrGdgOwNgGDCzSMLYwA4MYjH2cgeEawjgWCQSbQwjBdpyAYMch2f4Awd7HwAVj8n1g4Iaxl+7e3Q1jXxQUlGMAAJkfGS29Qu04AAAAAElFTkSuQmCC",
"Math image corresponds to '1 1/2' png");
start();
};
localArchive.loadMathImage("edb3069b82c68d270f6642c171cc6293", callbackFunction);
});
};
});