mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-12-16 21:40:23 +01:00
Compare commits
93 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9b9f090e4 | ||
|
|
b82a6fa888 | ||
|
|
8ab539b518 | ||
|
|
9078c2a536 | ||
|
|
fd20e4a400 | ||
|
|
1a64e40b21 | ||
|
|
cbfba4b45b | ||
|
|
f21a98f37f | ||
|
|
0edd6985ec | ||
|
|
98a646fa62 | ||
|
|
1d69436b44 | ||
|
|
d6c7551120 | ||
|
|
fb53e89023 | ||
|
|
d28beaa4dc | ||
|
|
ac06567617 | ||
|
|
d0a2c077ff | ||
|
|
ebf07626de | ||
|
|
9ef8bb4cdc | ||
|
|
bc8a53aadd | ||
|
|
03c4a1bc73 | ||
|
|
d93163896f | ||
|
|
08bdbc0bcc | ||
|
|
35d6a99775 | ||
|
|
e45e86fcc1 | ||
|
|
9589d340b9 | ||
|
|
91afbf106e | ||
|
|
aff11359ae | ||
|
|
aff8cef5f3 | ||
|
|
879855744d | ||
|
|
b5ab0c9097 | ||
|
|
2c398f81d2 | ||
|
|
520fcadd3f | ||
|
|
e8eb9f91b9 | ||
|
|
8bfb338eee | ||
|
|
bbb655abdd | ||
|
|
095e5527e3 | ||
|
|
4eb8c34855 | ||
|
|
e3185b9560 | ||
|
|
449adfae59 | ||
|
|
714e61b137 | ||
|
|
d0e4689907 | ||
|
|
1996e64c9b | ||
|
|
e2fb617cc0 | ||
|
|
fd88aff195 | ||
|
|
f7a1cca861 | ||
|
|
e3fb996a80 | ||
|
|
fe53037e53 | ||
|
|
438f90d859 | ||
|
|
742c8fb43c | ||
|
|
d43f3cebc6 | ||
|
|
9d452241ad | ||
|
|
c19a51e1b6 | ||
|
|
1b41a8f467 | ||
|
|
f933fc0167 | ||
|
|
8cfb239aac | ||
|
|
a974c6fa99 | ||
|
|
998f780fd2 | ||
|
|
b022d46d47 | ||
|
|
f7793e54b1 | ||
|
|
1e61033667 | ||
|
|
53caa5e422 | ||
|
|
40d20846d8 | ||
|
|
204913c63d | ||
|
|
6c30437c47 | ||
|
|
dd7fe47dfd | ||
|
|
50323c3d23 | ||
|
|
69e0aa338d | ||
|
|
6dcd06b63c | ||
|
|
42d77080f3 | ||
|
|
fbb4998999 | ||
|
|
14744a854f | ||
|
|
2c6afb4244 | ||
|
|
24907e456d | ||
|
|
2039885d96 | ||
|
|
daacdb50f3 | ||
|
|
21155b1b80 | ||
|
|
5d69167a64 | ||
|
|
5db27a835f | ||
|
|
c8e423e9cf | ||
|
|
be3465c5ca | ||
|
|
637e037e27 | ||
|
|
3e6bcd83cc | ||
|
|
dc4aeca427 | ||
|
|
9eb09f14cb | ||
|
|
a55fc364a0 | ||
|
|
2f90949560 | ||
|
|
a940219321 | ||
|
|
aaf6b11dc9 | ||
|
|
0f0913bfe5 | ||
|
|
5569337c40 | ||
|
|
ba2f47ead6 | ||
|
|
b52782deb8 | ||
|
|
2c6bf93eb5 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -19,3 +19,4 @@ feeds/recent.rss
|
||||
|
||||
# winston?
|
||||
error.log
|
||||
events.log
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
* [Follow on Twitter](http://www.twitter.com/NodeBB/ "NodeBB Twitter")
|
||||
* [Like us on Facebook](http://www.facebook.com/NodeBB/ "NodeBB Facebook")
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
## How can I follow along/contribute?
|
||||
|
||||
|
||||
18
app.js
18
app.js
@@ -27,8 +27,9 @@
|
||||
async = require('async'),
|
||||
semver = require('semver'),
|
||||
winston = require('winston'),
|
||||
pkg = require('./package.json'),
|
||||
path = require('path'),
|
||||
pkg = require('./package.json'),
|
||||
utils = require('./public/src/utils.js'),
|
||||
meta;
|
||||
|
||||
// Runtime environment
|
||||
@@ -69,8 +70,8 @@
|
||||
});
|
||||
meta = require('./src/meta');
|
||||
|
||||
nconf.set('url', nconf.get('base_url') + (nconf.get('use_port') ? ':' + nconf.get('port') : '') + nconf.get('relative_path') + '/');
|
||||
nconf.set('upload_url', nconf.get('url') + 'uploads/');
|
||||
nconf.set('url', nconf.get('base_url') + (nconf.get('use_port') ? ':' + nconf.get('port') : '') + nconf.get('relative_path') + path.sep);
|
||||
nconf.set('upload_url', path.join(path.sep, nconf.get('relative_path'), 'uploads', path.sep));
|
||||
nconf.set('base_dir', __dirname);
|
||||
|
||||
winston.info('Initializing NodeBB v' + pkg.version + ', on port ' + nconf.get('port') + ', using Redis store at ' + nconf.get('redis:host') + ':' + nconf.get('redis:port') + '.');
|
||||
@@ -108,15 +109,10 @@
|
||||
|
||||
var customTemplates = meta.config['theme:templates'] ? path.join(__dirname, 'node_modules', meta.config['theme:id'], meta.config['theme:templates']) : false;
|
||||
|
||||
// todo: replace below with read directory code, derp.
|
||||
templates.init([
|
||||
'header', 'footer', 'logout', 'outgoing', 'admin/header', 'admin/footer', 'admin/index',
|
||||
'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext',
|
||||
'emails/header', 'emails/footer',
|
||||
|
||||
'noscript/header', 'noscript/home', 'noscript/category', 'noscript/topic'
|
||||
], customTemplates);
|
||||
|
||||
utils.walk(path.join(__dirname, 'public/templates'), function (err, tplsToLoad) {
|
||||
templates.init(tplsToLoad, customTemplates);
|
||||
});
|
||||
|
||||
plugins.ready(function() {
|
||||
templates.ready(webserver.init);
|
||||
|
||||
12
package.json
12
package.json
@@ -2,7 +2,7 @@
|
||||
"name": "nodebb",
|
||||
"license": "GPLv3 or later",
|
||||
"description": "NodeBB Forum",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.2",
|
||||
"homepage": "http://www.nodebb.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -38,12 +38,14 @@
|
||||
"prompt": "~0.2.11",
|
||||
"uglify-js": "~2.4.0",
|
||||
"validator": "~1.5.1",
|
||||
"nodebb-plugin-mentions": "~0.1.16",
|
||||
"nodebb-plugin-markdown": "~0.2.1",
|
||||
"nodebb-theme-vanilla": "~0.0.10",
|
||||
"nodebb-plugin-mentions": "~0.1",
|
||||
"nodebb-plugin-markdown": "~0.3",
|
||||
"nodebb-theme-vanilla": "~0.0.12",
|
||||
"nodebb-theme-cerulean": "0.0.10",
|
||||
"cron": "~1.0.1",
|
||||
"semver": "~2.2.1"
|
||||
"semver": "~2.2.1",
|
||||
"string": "~1.7.0",
|
||||
"xregexp": "~2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"redis": "0.8.3",
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"reply": "Reply",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"fork": "Fork",
|
||||
"banned": "banned",
|
||||
"link": "Link",
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"location": "Location",
|
||||
"age": "Age",
|
||||
"joined": "Joined",
|
||||
"lastonline": "Last Online",
|
||||
"profile_views": "Profile views",
|
||||
"reputation": "Reputation",
|
||||
"posts": "Posts",
|
||||
|
||||
@@ -178,17 +178,6 @@ var socket,
|
||||
return text.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
|
||||
};
|
||||
|
||||
// Willingly stolen from: http://phpjs.org/functions/strip_tags/
|
||||
app.strip_tags = function (input, allowed) {
|
||||
allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
|
||||
var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
|
||||
commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
|
||||
|
||||
return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
|
||||
return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
|
||||
});
|
||||
};
|
||||
|
||||
// use unique alert_id to have multiple alerts visible at a time, use the same alert_id to fade out the current instance
|
||||
// type : error, success, info, warning/notify
|
||||
// title = bolded title text
|
||||
|
||||
@@ -95,7 +95,7 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) {
|
||||
$('#uploadPictureBtn').on('click', function() {
|
||||
|
||||
$('#change-picture-modal').modal('hide');
|
||||
uploader.open(RELATIVE_PATH + '/user/uploadpicture', function(imageUrlOnServer) {
|
||||
uploader.open(RELATIVE_PATH + '/user/uploadpicture', {}, function(imageUrlOnServer) {
|
||||
imageUrlOnServer = imageUrlOnServer + '?' + new Date().getTime();
|
||||
|
||||
$('#user-current-picture').attr('src', imageUrlOnServer);
|
||||
|
||||
@@ -183,8 +183,8 @@ define(['uploader'], function(uploader) {
|
||||
|
||||
$('.upload-button').on('click', function() {
|
||||
var inputEl = this;
|
||||
|
||||
uploader.open(RELATIVE_PATH + '/admin/category/uploadpicture', function(imageUrlOnServer) {
|
||||
var cid = $(this).parents('li[data-cid]').attr('data-cid');
|
||||
uploader.open(RELATIVE_PATH + '/admin/category/uploadpicture', {cid:cid}, function(imageUrlOnServer) {
|
||||
inputEl.value = imageUrlOnServer;
|
||||
$(inputEl).parents('li[data-cid]').find('.preview-box').css('background', 'url(' + imageUrlOnServer + '?' + new Date().getTime() + ')');
|
||||
modified(inputEl);
|
||||
@@ -270,7 +270,7 @@ define(['uploader'], function(uploader) {
|
||||
liEl = document.createElement('li');
|
||||
var numResults = results.length,
|
||||
resultObj;
|
||||
|
||||
|
||||
for(var x=0;x<numResults;x++) {
|
||||
resultObj = results[x];
|
||||
liEl.setAttribute('data-gid', resultObj.gid);
|
||||
@@ -281,13 +281,13 @@ define(['uploader'], function(uploader) {
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
' '+resultObj.name;
|
||||
|
||||
|
||||
groupsFrag.appendChild(liEl.cloneNode(true));
|
||||
}
|
||||
|
||||
|
||||
groupsResultsEl.html(groupsFrag);
|
||||
});
|
||||
|
||||
|
||||
groupsResultsEl.off().on('click', '[data-gpriv]', function(e) {
|
||||
var btnEl = $(this),
|
||||
gid = btnEl.parents('li[data-gid]').attr('data-gid'),
|
||||
|
||||
@@ -75,7 +75,7 @@ define(['uploader'], function(uploader) {
|
||||
});
|
||||
|
||||
$('#uploadLogoBtn').on('click', function() {
|
||||
uploader.open(RELATIVE_PATH + '/admin/uploadlogo', function(image) {
|
||||
uploader.open(RELATIVE_PATH + '/admin/uploadlogo', {}, function(image) {
|
||||
$('#logoUrl').val(image);
|
||||
});
|
||||
|
||||
@@ -83,7 +83,7 @@ define(['uploader'], function(uploader) {
|
||||
});
|
||||
|
||||
$('#uploadFaviconBtn').on('click', function() {
|
||||
uploader.open(RELATIVE_PATH + '/admin/uploadfavicon', function(icon) {
|
||||
uploader.open(RELATIVE_PATH + '/admin/uploadfavicon', {}, function(icon) {
|
||||
$('#faviconUrl').val(icon);
|
||||
});
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ define(function() {
|
||||
return parent.attr('data-uid');
|
||||
}
|
||||
|
||||
function updateUserButtons() {
|
||||
function updateUserBanButtons() {
|
||||
jQuery('.ban-btn').each(function(index, element) {
|
||||
var banBtn = $(element);
|
||||
var uid = getUID(banBtn);
|
||||
@@ -27,15 +27,37 @@ define(function() {
|
||||
banBtn.addClass('disabled');
|
||||
else if (isUserBanned(banBtn))
|
||||
banBtn.addClass('btn-warning');
|
||||
else if (!isUserAdmin(banBtn))
|
||||
banBtn.removeClass('disabled');
|
||||
else
|
||||
banBtn.removeClass('btn-warning');
|
||||
updateUserAdminButtons();
|
||||
});
|
||||
}
|
||||
|
||||
function updateUserAdminButtons() {
|
||||
jQuery('.admin-btn').each(function(index, element) {
|
||||
var adminBtn = $(element);
|
||||
var uid = getUID(adminBtn);
|
||||
if (isUserAdmin(adminBtn)) {
|
||||
adminBtn.attr('value', 'UnMake Admin').html('Remove Admin');
|
||||
if (uid === yourid) {
|
||||
adminBtn.addClass('disabled');
|
||||
}
|
||||
}
|
||||
else if (isUserBanned(adminBtn))
|
||||
adminBtn.addClass('disabled');
|
||||
else if (!isUserBanned(adminBtn))
|
||||
adminBtn.removeClass('disabled');
|
||||
else
|
||||
adminBtn.removeClass('btn-warning');
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function initUsers() {
|
||||
|
||||
updateUserButtons();
|
||||
updateUserBanButtons();
|
||||
updateUserAdminButtons();
|
||||
|
||||
$('#users-container').on('click', '.ban-btn', function() {
|
||||
var banBtn = $(this);
|
||||
@@ -49,17 +71,56 @@ define(function() {
|
||||
socket.emit('api:admin.user.unbanUser', uid);
|
||||
banBtn.removeClass('btn-warning');
|
||||
parent.attr('data-banned', 0);
|
||||
updateUserAdminButtons();
|
||||
} else {
|
||||
bootbox.confirm('Do you really want to ban "' + parent.attr('data-username') + '"?', function(confirm) {
|
||||
if (confirm) {
|
||||
socket.emit('api:admin.user.banUser', uid);
|
||||
banBtn.addClass('btn-warning');
|
||||
parent.attr('data-banned', 1);
|
||||
updateUserAdminButtons();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#users-container').on('click', '.admin-btn', function() {
|
||||
var adminBtn = $(this);
|
||||
var isAdmin = isUserAdmin(adminBtn);
|
||||
var parent = adminBtn.parents('.users-box');
|
||||
var isBanned = isUserBanned(adminBtn);
|
||||
var uid = getUID(adminBtn);
|
||||
|
||||
if(uid === yourid){
|
||||
app.alert({
|
||||
title: 'Error',
|
||||
message: 'You can\'t remove yourself as Administrator!',
|
||||
type: 'danger',
|
||||
timeout: 5000
|
||||
});
|
||||
}
|
||||
else if (!isAdmin) {
|
||||
socket.emit('api:admin.user.makeAdmin', uid);
|
||||
adminBtn.attr('value', 'UnMake Admin').html('Remove Admin');
|
||||
parent.attr('data-admin', 1);
|
||||
updateUserBanButtons();
|
||||
|
||||
} else if(uid !== yourid) {
|
||||
bootbox.confirm('Do you really want to remove this user as admin "' + parent.attr('data-username') + '"?', function(confirm) {
|
||||
if (confirm) {
|
||||
socket.emit('api:admin.user.removeAdmin', uid);
|
||||
adminBtn.attr('value', 'Make Admin').html('Make Admin');
|
||||
parent.attr('data-admin', 0);
|
||||
updateUserBanButtons();
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
define(function() {
|
||||
var Login = {};
|
||||
|
||||
Login.init = function() {
|
||||
Login.init = function() {
|
||||
$('#login').on('click', function() {
|
||||
var loginData = {
|
||||
'username': $('#username').val(),
|
||||
@@ -40,8 +40,7 @@ define(function() {
|
||||
$('#login').removeAttr('disabled').html('Login');
|
||||
},
|
||||
dataType: 'json',
|
||||
async: true,
|
||||
timeout: 2000
|
||||
async: true
|
||||
});
|
||||
|
||||
return false;
|
||||
|
||||
@@ -334,13 +334,13 @@ define(['composer'], function(composer) {
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#post-container').delegate('.edit', 'click', function(e) {
|
||||
$('#post-container').on('click', '.edit', function(e) {
|
||||
var pid = $(this).parents('li').attr('data-pid');
|
||||
|
||||
composer.editPost(pid);
|
||||
});
|
||||
|
||||
$('#post-container').delegate('.delete', 'click', function(e) {
|
||||
$('#post-container').on('click', '.delete', function(e) {
|
||||
var pid = $(this).parents('li').attr('data-pid'),
|
||||
postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')),
|
||||
deleteAction = !postEl.hasClass('deleted') ? true : false,
|
||||
@@ -369,11 +369,27 @@ define(['composer'], function(composer) {
|
||||
}
|
||||
});
|
||||
|
||||
$('#post-container').on('click', '.fork-post', function(e) {
|
||||
var post = $(this).parents('li'),
|
||||
pid = post.attr('data-pid');
|
||||
|
||||
socket.emit('api:topic.createTopicFromPost', {pid:pid}, function(err) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
post.fadeOut(500, function() {
|
||||
post.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$('#post-container').on('click', '.chat', function(e) {
|
||||
var username = $(this).parents('li.row').attr('data-username');
|
||||
var touid = $(this).parents('li.row').attr('data-uid');
|
||||
|
||||
app.openChat(username, touid);
|
||||
$(this).parents('.btn-group').find('.dropdown-toggle').click();
|
||||
return false;
|
||||
});
|
||||
|
||||
ajaxify.register_events([
|
||||
|
||||
@@ -71,6 +71,7 @@ define(function() {
|
||||
});
|
||||
|
||||
function onTopicsLoaded(topics) {
|
||||
|
||||
var html = templates.prepare(templates['unread'].blocks['topics']).parse({
|
||||
topics: topics
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(['taskbar'], function(taskbar) {
|
||||
define(['taskbar', 'string'], function(taskbar, S) {
|
||||
|
||||
var module = {};
|
||||
|
||||
@@ -92,7 +92,6 @@ define(['taskbar'], function(taskbar) {
|
||||
|
||||
module.center = function(chatModal) {
|
||||
chatModal.css("position", "fixed");
|
||||
chatModal.css("top", "100px");
|
||||
chatModal.css("left", Math.max(0, (($(window).width() - $(chatModal).outerWidth()) / 2) + $(window).scrollLeft()) + "px");
|
||||
return chatModal;
|
||||
}
|
||||
@@ -103,6 +102,7 @@ define(['taskbar'], function(taskbar) {
|
||||
module.bringModalToTop(chatModal);
|
||||
checkOnlineStatus(chatModal);
|
||||
taskbar.updateActive(uuid);
|
||||
scrollToBottom(chatModal.find('#chat-content'));
|
||||
chatModal.find('#chat-message-input').focus();
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ define(['taskbar'], function(taskbar) {
|
||||
}
|
||||
|
||||
function sendMessage(chatModal) {
|
||||
var msg = app.strip_tags(chatModal.find('#chat-message-input').val());
|
||||
var msg = S(chatModal.find('#chat-message-input').val()).stripTags().s;
|
||||
if(msg.length) {
|
||||
msg = msg +'\n';
|
||||
socket.emit('api:chats.send', { touid:chatModal.touid, message:msg});
|
||||
@@ -153,10 +153,14 @@ define(['taskbar'], function(taskbar) {
|
||||
var date = new Date(parseInt(timestamp, 10));
|
||||
|
||||
chatContent.append('[' + date.toLocaleTimeString() + '] ' + message);
|
||||
scrollToBottom(chatContent);
|
||||
};
|
||||
|
||||
function scrollToBottom(chatContent) {
|
||||
chatContent.scrollTop(
|
||||
chatContent[0].scrollHeight - chatContent.height()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
module.toggleNew = function(uuid, state) {
|
||||
taskbar.toggleNew(uuid, state);
|
||||
|
||||
@@ -48,7 +48,6 @@ define(['taskbar'], function(taskbar) {
|
||||
socket.emit('api:composer.push', {
|
||||
pid: pid
|
||||
}, function(threadData) {
|
||||
console.log(threadData);
|
||||
push({
|
||||
pid: pid,
|
||||
title: threadData.title,
|
||||
@@ -95,9 +94,8 @@ define(['taskbar'], function(taskbar) {
|
||||
|
||||
var postContainer = $(composerTemplate[0]);
|
||||
|
||||
if(config.imgurClientIDSet) {
|
||||
if(config.allowFileUploads || config.imgurClientIDSet)
|
||||
initializeFileReader(post_uuid);
|
||||
}
|
||||
|
||||
var postData = composer.posts[post_uuid],
|
||||
titleEl = postContainer.find('.title'),
|
||||
@@ -202,7 +200,7 @@ define(['taskbar'], function(taskbar) {
|
||||
}
|
||||
});
|
||||
|
||||
postContainer.on('click', '.formatting-bar span .fa-picture-o', function() {
|
||||
postContainer.on('click', '.formatting-bar span .fa-picture-o, .formatting-bar span .fa-upload', function() {
|
||||
$('#files').click();
|
||||
});
|
||||
|
||||
@@ -213,6 +211,7 @@ define(['taskbar'], function(taskbar) {
|
||||
loadFile(post_uuid, files[i]);
|
||||
}
|
||||
}
|
||||
$('#fileForm')[0].reset();
|
||||
});
|
||||
|
||||
|
||||
@@ -317,7 +316,12 @@ define(['taskbar'], function(taskbar) {
|
||||
}
|
||||
|
||||
if(config.imgurClientIDSet) {
|
||||
postContainer.find('.upload-instructions').removeClass('hide')
|
||||
postContainer.find('.upload-instructions').removeClass('hide');
|
||||
postContainer.find('.img-upload-btn').removeClass('hide');
|
||||
}
|
||||
|
||||
if(config.allowFileUploads) {
|
||||
postContainer.find('.file-upload-btn').removeClass('hide');
|
||||
}
|
||||
|
||||
postContainer.css('visibility', 'visible');
|
||||
@@ -340,6 +344,7 @@ define(['taskbar'], function(taskbar) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
composer.post = function(post_uuid) {
|
||||
var postData = composer.posts[post_uuid],
|
||||
postContainer = $('#cmp-uuid-' + post_uuid),
|
||||
@@ -350,33 +355,13 @@ define(['taskbar'], function(taskbar) {
|
||||
bodyEl.val(bodyEl.val().trim());
|
||||
|
||||
if(postData.uploadsInProgress && postData.uploadsInProgress.length) {
|
||||
return app.alert({
|
||||
type: 'warning',
|
||||
timeout: 2000,
|
||||
title: 'Still uploading',
|
||||
message: "Please wait for uploads to complete.",
|
||||
alert_id: 'post_error'
|
||||
});
|
||||
}
|
||||
|
||||
if (titleEl.val().length < config.minimumTitleLength) {
|
||||
return app.alert({
|
||||
type: 'danger',
|
||||
timeout: 2000,
|
||||
title: 'Title too short',
|
||||
message: "Please enter a longer title. At least " + config.minimumTitleLength+ " characters.",
|
||||
alert_id: 'post_error'
|
||||
});
|
||||
}
|
||||
|
||||
if (bodyEl.val().length < config.minimumPostLength) {
|
||||
return app.alert({
|
||||
type: 'danger',
|
||||
timeout: 2000,
|
||||
title: 'Content too short',
|
||||
message: "Please enter a longer post. At least " + config.minimumPostLength + " characters.",
|
||||
alert_id: 'post_error'
|
||||
});
|
||||
return composerAlert('Still uploading', 'Please wait for uploads to complete.');
|
||||
} else if (titleEl.val().length < parseInt(config.minimumTitleLength, 10)) {
|
||||
return composerAlert('Title too short', 'Please enter a longer title. At least ' + config.minimumTitleLength+ ' characters.');
|
||||
} else if (titleEl.val().length > parseInt(config.maximumTitleLength, 10)) {
|
||||
return composerAlert('Title too long', 'Please enter a shorter title. Titles can\'t be longer than ' + config.maximumTitleLength + ' characters.');
|
||||
} else if (bodyEl.val().length < parseInt(config.minimumPostLength, 10)) {
|
||||
return composerAlert('Content too short', 'Please enter a longer post. At least ' + config.minimumPostLength + ' characters.');
|
||||
}
|
||||
|
||||
// Still here? Let's post.
|
||||
@@ -402,6 +387,17 @@ define(['taskbar'], function(taskbar) {
|
||||
composer.discard(post_uuid);
|
||||
}
|
||||
|
||||
function composerAlert(title, message) {
|
||||
app.alert({
|
||||
type: 'danger',
|
||||
timeout: 2000,
|
||||
title: title,
|
||||
message: message,
|
||||
alert_id: 'post_error'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
composer.discard = function(post_uuid) {
|
||||
if (composer.posts[post_uuid]) {
|
||||
$('#cmp-uuid-' + post_uuid).remove();
|
||||
@@ -477,36 +473,40 @@ define(['taskbar'], function(taskbar) {
|
||||
}
|
||||
|
||||
function loadFile(post_uuid, file) {
|
||||
|
||||
if (!file.type.match('image.*')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var reader = new FileReader(),
|
||||
dropDiv = $('#cmp-uuid-' + post_uuid).find('.imagedrop');
|
||||
|
||||
$(reader).on('loadend', function(e) {
|
||||
var bin = this.result.split(',')[1];
|
||||
var regex = /^data:.*;base64,(.*)$/;
|
||||
var matches = this.result.match(regex);
|
||||
|
||||
var img = {
|
||||
var fileData = {
|
||||
name: file.name,
|
||||
data: bin
|
||||
data: matches[1]
|
||||
};
|
||||
|
||||
createImagePlaceholder(post_uuid, img);
|
||||
|
||||
dropDiv.hide();
|
||||
|
||||
if(file.type.match('image.*')) {
|
||||
uploadFile('api:posts.uploadImage', post_uuid, fileData);
|
||||
} else {
|
||||
if(file.size > parseInt(config.maximumFileSize, 10) * 1024) {
|
||||
return composerAlert('File too big', 'Maximum allowed file size is ' + config.maximumFileSize + 'kbs');
|
||||
}
|
||||
uploadFile('api:posts.uploadFile', post_uuid, fileData);
|
||||
}
|
||||
});
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
|
||||
function createImagePlaceholder(post_uuid, img) {
|
||||
var postContainer = $('#cmp-uuid-' + post_uuid),
|
||||
function uploadFile(method, post_uuid, img) {
|
||||
var linkStart = method === 'api:posts.uploadImage' ? '!' : '',
|
||||
postContainer = $('#cmp-uuid-' + post_uuid),
|
||||
textarea = postContainer.find('textarea'),
|
||||
text = textarea.val(),
|
||||
imgText = "";
|
||||
imgText = linkStart + '[' + img.name + '](uploading...)';
|
||||
|
||||
text += imgText;
|
||||
textarea.val(text + " ");
|
||||
@@ -517,18 +517,17 @@ define(['taskbar'], function(taskbar) {
|
||||
|
||||
composer.posts[post_uuid].uploadsInProgress.push(1);
|
||||
|
||||
socket.emit("api:posts.uploadImage", img, function(err, data) {
|
||||
socket.emit(method, img, function(err, data) {
|
||||
|
||||
var currentText = textarea.val();
|
||||
|
||||
if(err) {
|
||||
textarea.val(currentText.replace(imgText, linkStart + '[' + img.name + '](upload error)'));
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
var currentText = textarea.val();
|
||||
imgText = "";
|
||||
|
||||
if(!err) {
|
||||
textarea.val(currentText.replace(imgText, ""));
|
||||
} else {
|
||||
textarea.val(currentText.replace(imgText, ""));
|
||||
}
|
||||
textarea.val(currentText.replace(imgText, linkStart + '[' + data.name + '](' + data.url + ')'));
|
||||
|
||||
composer.posts[post_uuid].uploadsInProgress.pop();
|
||||
});
|
||||
}
|
||||
|
||||
3
public/src/modules/string.js
Normal file
3
public/src/modules/string.js
Normal file
File diff suppressed because one or more lines are too long
@@ -2,12 +2,13 @@ define(function() {
|
||||
|
||||
var module = {};
|
||||
|
||||
module.open = function(route, callback) {
|
||||
module.open = function(route, params, callback) {
|
||||
$('#upload-picture-modal').modal('show').removeClass('hide');
|
||||
module.hideAlerts();
|
||||
|
||||
$('#uploadForm')[0].reset();
|
||||
$('#uploadForm').attr('action', route);
|
||||
$('#uploadForm').find('#params').val(JSON.stringify(params));
|
||||
|
||||
$('#pictureUploadSubmitBtn').off('click').on('click', function() {
|
||||
$('#uploadForm').submit();
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
templates.prepare = function (raw_tpl, data) {
|
||||
templates.prepare = function (raw_tpl) {
|
||||
var template = {};
|
||||
template.html = raw_tpl;
|
||||
template.parse = parse;
|
||||
@@ -78,7 +78,9 @@
|
||||
global.templates[file] = new template;
|
||||
|
||||
loaded--;
|
||||
if (loaded == 0) templates.ready();
|
||||
if (loaded === 0) {
|
||||
templates.ready();
|
||||
}
|
||||
});
|
||||
}(templatesToLoad[t]));
|
||||
}
|
||||
@@ -347,7 +349,9 @@
|
||||
|
||||
if (blockInfo) {
|
||||
checkConditional('@first', blockInfo.iterator === 0);
|
||||
checkConditional('!@first', blockInfo.iterator !== 0);
|
||||
checkConditional('@last', blockInfo.iterator === blockInfo.total);
|
||||
checkConditional('!@last', blockInfo.iterator !== blockInfo.total);
|
||||
}
|
||||
|
||||
template = replace(namespace + d, data[d], template);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
(function(module) {
|
||||
'use strict';
|
||||
|
||||
var utils, fs;
|
||||
var utils, fs, XRegExp;
|
||||
|
||||
if ('undefined' === typeof window) {
|
||||
fs = require('fs');
|
||||
XRegExp = require('xregexp').XRegExp;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,19 +93,13 @@
|
||||
|
||||
//http://dense13.com/blog/2009/05/03/converting-string-to-slug-javascript/
|
||||
slugify: function(str) {
|
||||
var invalidChars = XRegExp('[^\\p{L} 0-9\-]', 'g');
|
||||
|
||||
str = str.replace(/^\s+|\s+$/g, ''); // trim
|
||||
str = str.toLowerCase();
|
||||
|
||||
// remove accents, swap ñ for n, etc
|
||||
var from = "àáäâèéëêìíïîıòóöôùúüûñçşğ·/_,:;";
|
||||
var to = "aaaaeeeeiiiiioooouuuuncsg------";
|
||||
for (var i = 0, l = from.length; i < l; i++) {
|
||||
str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
|
||||
}
|
||||
|
||||
str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
|
||||
.replace(/\s+/g, '-') // collapse whitespace and replace by -
|
||||
.replace(/-+/g, '-'); // collapse dashes
|
||||
str = XRegExp.replace(str, invalidChars, '');
|
||||
str = str.replace(/\s+/g, '-') // collapse whitespace and replace by -
|
||||
str = str.replace(/-+/g, '-'); // collapse dashes
|
||||
|
||||
return str;
|
||||
},
|
||||
@@ -123,18 +118,6 @@
|
||||
isPasswordValid: function(password) {
|
||||
return password && password.indexOf(' ') === -1;
|
||||
},
|
||||
|
||||
// Blatently stolen from: http://phpjs.org/functions/strip_tags/
|
||||
'strip_tags': function(input, allowed) {
|
||||
allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
|
||||
var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
|
||||
commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
|
||||
|
||||
return input.replace(commentsAndPhpTags, '').replace(tags, function($0, $1) {
|
||||
return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
|
||||
});
|
||||
},
|
||||
|
||||
buildMetaTags: function(tagsArr) {
|
||||
var tags = '',
|
||||
tag;
|
||||
|
||||
@@ -70,6 +70,10 @@
|
||||
<span class="timeago" title="{joindate}"></span>
|
||||
<br/>
|
||||
|
||||
<span class="account-bio-label">[[user:lastonline]]</span>
|
||||
<span class="timeago" title="{lastonline}"></span>
|
||||
<br/>
|
||||
|
||||
<span class="account-bio-label">[[user:profile_views]]</span>
|
||||
<span class="formatted-number">{profileviews}</span>
|
||||
<br/>
|
||||
|
||||
@@ -76,6 +76,21 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4 col-xs-12">
|
||||
<div class="form-group">
|
||||
<label for="cid-{categories.cid}-class">Custom Class</label>
|
||||
<input id="cid-{categories.cid}-class" type="text" class="form-control" placeholder="col-md-6 col-xs-6" data-name="class" value="{categories.class}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 col-xs-12">
|
||||
<div class="form-group">
|
||||
<label for="cid-{categories.cid}-numRecentReplies"># of Recent Replies Displayed</label>
|
||||
<input id="cid-{categories.cid}-numRecentReplies" type="text" class="form-control" placeholder="2" data-name="numRecentReplies" value="{categories.numRecentReplies}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<input type="hidden" data-name="order" data-value="{categories.order}"></input>
|
||||
</form>
|
||||
|
||||
5
public/templates/admin/events.tpl
Normal file
5
public/templates/admin/events.tpl
Normal file
@@ -0,0 +1,5 @@
|
||||
<h1>Events</h1>
|
||||
|
||||
<pre>
|
||||
{eventdata}
|
||||
</pre>
|
||||
@@ -17,6 +17,7 @@
|
||||
<p class="help-block">You may only upload PNG, JPG, or GIF files under 256kb.</p>
|
||||
</div>
|
||||
<input id="imageUploadCsrf" type="hidden" name="_csrf" value="" />
|
||||
<input type="hidden" id="params" name="params">
|
||||
</form>
|
||||
|
||||
<div id="upload-progress-box" class="progress progress-striped">
|
||||
|
||||
@@ -95,30 +95,29 @@
|
||||
<div class="well sidebar-nav">
|
||||
<ul class="nav nav-list">
|
||||
<li class="nav-header">NodeBB</li>
|
||||
<li class='active'>
|
||||
<a href='{relative_path}/admin/index'><i class='fa fa-home'></i> Home</a>
|
||||
</li>
|
||||
<li><a href='{relative_path}/admin/categories/active'><i class='fa fa-folder'></i> Categories</a></li>
|
||||
<li><a href='{relative_path}/admin/users/latest'><i class='fa fa-user'></i> Users</a></li>
|
||||
<li><a href="{relative_path}/admin/groups"><i class="fa fa-group"></i> Groups</a></li>
|
||||
<li><a href='{relative_path}/admin/topics'><i class='fa fa-book'></i> Topics</a></li>
|
||||
<li><a href='{relative_path}/admin/themes'><i class='fa fa-th'></i> Themes</a></li>
|
||||
<li><a href='{relative_path}/admin/plugins'><i class='fa fa-code-fork'></i> Plugins</a></li>
|
||||
<li><a href='{relative_path}/admin/settings'><i class='fa fa-cogs'></i> Settings</a></li>
|
||||
<li><a href='{relative_path}/admin/database'><i class='fa fa-hdd-o'></i> Database</a></li>
|
||||
<li><a href='{relative_path}/admin/logger'><i class='fa fa-th'></i> Logger</a></li>
|
||||
<li><a href="{relative_path}/admin/motd"><i class="fa fa-comment"></i> MOTD</a></li>
|
||||
<li class="active"><a href="{relative_path}/admin/index"><i class="fa fa-fw fa-home"></i> Home</a></li>
|
||||
<li><a href="{relative_path}/admin/categories/active"><i class="fa fa-fw fa-folder"></i> Categories</a></li>
|
||||
<li><a href="{relative_path}/admin/users/latest"><i class="fa fa-fw fa-user"></i> Users</a></li>
|
||||
<li><a href="{relative_path}/admin/groups"><i class="fa fa-fw fa-group"></i> Groups</a></li>
|
||||
<li><a href="{relative_path}/admin/topics"><i class="fa fa-fw fa-book"></i> Topics</a></li>
|
||||
<li><a href="{relative_path}/admin/themes"><i class="fa fa-fw fa-th"></i> Themes</a></li>
|
||||
<li><a href="{relative_path}/admin/plugins"><i class="fa fa-fw fa-code-fork"></i> Plugins</a></li>
|
||||
<li><a href="{relative_path}/admin/settings"><i class="fa fa-fw fa-cogs"></i> Settings</a></li>
|
||||
<li><a href="{relative_path}/admin/database"><i class="fa fa-fw fa-hdd-o"></i> Database</a></li>
|
||||
<li><a href="{relative_path}/admin/logger"><i class="fa fa-fw fa-th"></i> Logger</a></li>
|
||||
<li><a href="{relative_path}/admin/motd"><i class="fa fa-fw fa-comment"></i> MOTD</a></li>
|
||||
<li><a href="{relative_path}/admin/events"><i class="fa fa-fw fa-calendar-o"></i> Events</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="well sidebar-nav">
|
||||
<ul class="nav nav-list">
|
||||
<li class="nav-header">Social Authentication</li>
|
||||
<li><a href='{relative_path}/admin/twitter'><i class='fa fa-twitter-square'></i> Twitter</a></li>
|
||||
<li><a href='{relative_path}/admin/facebook'><i class='fa fa-facebook-square'></i> Facebook</a></li>
|
||||
<li><a href='{relative_path}/admin/gplus'><i class='fa fa-google-plus-square'></i> Google+</a></li>
|
||||
<li><a href="{relative_path}/admin/twitter"><i class="fa fa-fw fa-twitter-square"></i> Twitter</a></li>
|
||||
<li><a href="{relative_path}/admin/facebook"><i class="fa fa-fw fa-facebook-square"></i> Facebook</a></li>
|
||||
<li><a href="{relative_path}/admin/gplus"><i class="fa fa-fw fa-google-plus-square"></i> Google+</a></li>
|
||||
<!-- BEGIN authentication -->
|
||||
<li>
|
||||
<a href='{relative_path}/admin{authentication.route}'><i class="fa {authentication.icon}"></i> {authentication.name}</a>
|
||||
<a href="{relative_path}/admin{authentication.route}"><i class="fa fa-fw {authentication.icon}"></i> {authentication.name}</a>
|
||||
</li>
|
||||
<!-- END authentication -->
|
||||
</ul>
|
||||
@@ -128,7 +127,7 @@
|
||||
<li class="nav-header">Plugins</li>
|
||||
<!-- BEGIN plugins -->
|
||||
<li>
|
||||
<a href='{relative_path}/admin{plugins.route}'><i class="fa {plugins.icon}"></i> {plugins.name}</a>
|
||||
<a href="{relative_path}/admin{plugins.route}"><i class="fa fa-fw {plugins.icon}"></i> {plugins.name}</a>
|
||||
</li>
|
||||
<!-- END plugins -->
|
||||
</ul>
|
||||
@@ -137,15 +136,15 @@
|
||||
<ul class="nav nav-list">
|
||||
<li class="nav-header">Unit Tests</li>
|
||||
<ul class="nav nav-list">
|
||||
<li><a href='{relative_path}/admin/testing/categories'>Categories</a></li>
|
||||
<!--<li><a href='{relative_path}/admin/testing/topics'>Topics</a></li>
|
||||
<li><a href='{relative_path}/admin/testing/posts'>Posts</a></li>
|
||||
<li><a href='{relative_path}/admin/testing/accounts'>Accounts</a></li>
|
||||
<li><a href='{relative_path}/admin/testing/chat'>Chat</a></li>
|
||||
<li><a href='{relative_path}/admin/testing/notifications'>Notifications</a></li>
|
||||
<li><a href='{relative_path}/admin/testing/friends'>Friends</a></li>
|
||||
<li><a href='{relative_path}/admin/testing/feed'>RSS Feed</a></li>
|
||||
<li><a href='{relative_path}/admin/testing/emails'>Emails</a></li>-->
|
||||
<li><a href="{relative_path}/admin/testing/categories">Categories</a></li>
|
||||
<!--<li><a href="{relative_path}/admin/testing/topics">Topics</a></li>
|
||||
<li><a href="{relative_path}/admin/testing/posts">Posts</a></li>
|
||||
<li><a href="{relative_path}/admin/testing/accounts">Accounts</a></li>
|
||||
<li><a href="{relative_path}/admin/testing/chat">Chat</a></li>
|
||||
<li><a href="{relative_path}/admin/testing/notifications">Notifications</a></li>
|
||||
<li><a href="{relative_path}/admin/testing/friends">Friends</a></li>
|
||||
<li><a href="{relative_path}/admin/testing/feed">RSS Feed</a></li>
|
||||
<li><a href="{relative_path}/admin/testing/emails">Emails</a></li>-->
|
||||
</ul>
|
||||
</ul>
|
||||
</div><!--/.well -->
|
||||
|
||||
@@ -103,7 +103,9 @@
|
||||
<div class="alert alert-warning">
|
||||
<strong>Post Delay</strong><br /> <input type="text" class="form-control" value="10000" data-field="postDelay"><br />
|
||||
<strong>Minimum Title Length</strong><br /> <input type="text" class="form-control" value="3" data-field="minimumTitleLength"><br />
|
||||
<strong>Maximum Title Length</strong><br /> <input type="text" class="form-control" value="255" data-field="maximumTitleLength"><br />
|
||||
<strong>Minimum Post Length</strong><br /> <input type="text" class="form-control" value="8" data-field="minimumPostLength"><br />
|
||||
<strong>Chat Messages To Display</strong><br /> <input type="text" class="form-control" value="50" data-field="chatMessagesToDisplay"><br />
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" data-field="allowGuestPosting"> <strong>Allow guests to post without logging in</strong>
|
||||
@@ -119,6 +121,17 @@
|
||||
<input type="checkbox" data-field="useOutgoingLinksPage"> <strong>Use Outgoing Links Warning Page</strong>
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" data-field="disableSocialButtons"> <strong>Disable social buttons</strong>
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" data-field="allowFileUploads"> <strong>Allow users to upload regular files</strong>
|
||||
</label>
|
||||
</div>
|
||||
<strong>Maximum File Size</strong><br /> <input type="text" class="form-control" value="2048" data-field="maximumFileSize"><br />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
<i class='fa fa-pencil'></i>
|
||||
<span id='postcount'>{users.postcount}</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#" class="btn btn-default admin-btn">Make Admin</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#" class="btn btn-default ban-btn">Ban</a>
|
||||
</div>
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
|
||||
<div>
|
||||
<button id="new_post" class="btn btn-primary {show_topic_button}">[[category:new_topic_button]]</button>
|
||||
|
||||
<!-- IF !disableSocialButtons -->
|
||||
<div class="inline-block pull-right">
|
||||
<a href="#" id="facebook-share"><i class="fa fa-facebook-square fa-2x"></i></a>
|
||||
<a href="#" id="twitter-intent"><i class="fa fa-twitter-square fa-2x"></i></a>
|
||||
<a href="#" id="google-share"><i class="fa fa-google-plus-square fa-2x"></i></a>
|
||||
</div>
|
||||
<!-- ENDIF !disableSocialButtons -->
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
@@ -7,10 +7,15 @@
|
||||
<span class="btn btn-link" tabindex="-1"><i class="fa fa-italic"></i></span>
|
||||
<span class="btn btn-link" tabindex="-1"><i class="fa fa-list"></i></span>
|
||||
<span class="btn btn-link" tabindex="-1"><i class="fa fa-link"></i></span>
|
||||
<span class="btn btn-link" tabindex="-1">
|
||||
<input type="file" id="files" name="files[]" multiple class="hide"/>
|
||||
<span class="btn btn-link img-upload-btn hide" tabindex="-1">
|
||||
<i class="fa fa-picture-o"></i>
|
||||
</span>
|
||||
<span class="btn btn-link file-upload-btn hide" tabindex="-1">
|
||||
<i class="fa fa-upload"></i>
|
||||
</span>
|
||||
<form id="fileForm">
|
||||
<input type="file" id="files" name="files[]" multiple class="hide"/>
|
||||
</form>
|
||||
</div>
|
||||
<!-- <div class="btn btn-link pull-right">Preview</div> -->
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"^admin/categories.*": "admin/categories",
|
||||
"^admin/users.*": "admin/users",
|
||||
"^admin/database.*": "admin/database",
|
||||
"^admin/events.*": "admin/events",
|
||||
"^admin/index.*": "admin/index",
|
||||
"^admin/themes.*": "admin/themes",
|
||||
"^admin/plugins/?$": "admin/plugins",
|
||||
|
||||
@@ -18,14 +18,15 @@
|
||||
<img title="{posts.username}" class="img-rounded user-img" src="{posts.picture}">
|
||||
</a>
|
||||
|
||||
<a href="../../topic/{posts.tid}/#{posts.pid}">
|
||||
<a href="../../user/{posts.userslug}">
|
||||
<strong><span>{posts.username}</span></strong>
|
||||
<p>{posts.content}</p>
|
||||
</a>
|
||||
<p>{posts.content}</p>
|
||||
|
||||
<div>
|
||||
<span class="pull-right">
|
||||
posted in
|
||||
<a href="../../topic/{posts.tid}/#{posts.pid}">posted</a>
|
||||
in
|
||||
<a href="../../category/{posts.categorySlug}">
|
||||
<i class="fa {posts.categoryIcon}"></i> {posts.categoryName}
|
||||
</a>
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
</div><!--END container -->
|
||||
|
||||
<div id="chat-modal" class="modal chat-modal" tabindex="-1" role="dialog" aria-labelledby="Chat" aria-hidden="true" data-backdrop="none">
|
||||
<div id="chat-modal" class="modal chat-modal col-lg-12 col-md-12" tabindex="-1" role="dialog" aria-labelledby="Chat" aria-hidden="true" data-backdrop="none">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">[[footer:chat.chatting_with]]</h3>
|
||||
<h4 id="myModalLabel">[[footer:chat.chatting_with]]</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<textarea class="form-control" id="chat-content" cols="40" rows="10" readonly></textarea><br/>
|
||||
@@ -36,6 +36,7 @@
|
||||
<p class="help-block">[[user:image_spec]]</p>
|
||||
</div>
|
||||
<input id="imageUploadCsrf" type="hidden" name="_csrf" value="" />
|
||||
<input type="hidden" id="params" name="params">
|
||||
</form>
|
||||
|
||||
<div id="upload-progress-box" class="progress progress-striped">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<div class="row home" itemscope itemtype="http://www.schema.org/ItemList">
|
||||
<!-- BEGIN categories -->
|
||||
<div class="col-md-3 col-xs-6">
|
||||
<div class="{categories.class}">
|
||||
<a href="category/{categories.slug}" itemprop="url">
|
||||
<meta itemprop="name" content="{categories.name}">
|
||||
<h4><span class="badge {categories.badgeclass}">{categories.topic_count} </span> {categories.name}</h4>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/">Home</a></li>
|
||||
<li class="active">Recent <a href="./recent.rss"><i class="fa fa-rss-square"></i></a></li>
|
||||
<li class="active">Recent <a href="/recent.rss"><i class="fa fa-rss-square"></i></a></li>
|
||||
</ol>
|
||||
|
||||
<ul class="nav nav-pills">
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/user/{posts.userslug}"><i class="fa fa-user"></i> [[topic:profile]]</a></li>
|
||||
<li><div class="chat"><i class="fa fa-comment"></i> [[topic:chat]]</div></li>
|
||||
<li><a href="#" class="chat"><i class="fa fa-comment"></i> [[topic:chat]]</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -86,15 +86,20 @@
|
||||
<div class="pull-right">
|
||||
<div class="btn-group post-tools">
|
||||
<button class="btn btn-sm btn-default link" type="button" title="[[topic:link]]"><i class="fa fa-link"></i></button>
|
||||
<!-- IF !disableSocialButtons -->
|
||||
<button class="btn btn-sm btn-default facebook-share" type="button" title=""><i class="fa fa-facebook"></i></button>
|
||||
<button class="btn btn-sm btn-default twitter-share" type="button" title=""><i class="fa fa-twitter"></i></button>
|
||||
<button class="btn btn-sm btn-default google-share" type="button" title=""><i class="fa fa-google-plus"></i></button>
|
||||
<!-- ENDIF !disableSocialButtons -->
|
||||
</div>
|
||||
|
||||
<!-- IF posts.display_moderator_tools -->
|
||||
<div class="btn-group post-tools">
|
||||
<button class="btn btn-sm btn-default edit" type="button" title="[[topic:edit]]"><i class="fa fa-pencil"></i></button>
|
||||
<button class="btn btn-sm btn-default delete" type="button" title="[[topic:delete]]"><i class="fa fa-trash-o"></i></button>
|
||||
<!-- IF !@first -->
|
||||
<button class="btn btn-sm btn-default fork-post" type="button" title="[[topic:fork]]"><i class="fa fa-code-fork"></i></button>
|
||||
<!-- ENDIF !@first -->
|
||||
</div>
|
||||
<!-- ENDIF posts.display_moderator_tools -->
|
||||
</div>
|
||||
|
||||
239
public/vendor/xregexp/unicode/unicode-base.js
vendored
Normal file
239
public/vendor/xregexp/unicode/unicode-base.js
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
/*!
|
||||
* XRegExp Unicode Base 3.0.0-pre
|
||||
* <http://xregexp.com/>
|
||||
* Steven Levithan <20> 2008-2012 MIT License
|
||||
* Uses Unicode 6.2.0 <http://unicode.org/>
|
||||
* Unicode data generated by Mathias Bynens <http://mathiasbynens.be/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds support for the `\p{L}` or `\p{Letter}` Unicode category. Addon packages for other Unicode
|
||||
* categories, scripts, blocks, and properties are available separately. Also adds flag A (astral),
|
||||
* which enables 21-bit Unicode support. All Unicode tokens can be inverted using `\P{..}` or
|
||||
* `\p{^..}`. Token names ignore case, spaces, hyphens, and underscores.
|
||||
* @requires XRegExp
|
||||
*/
|
||||
(function(XRegExp) {
|
||||
'use strict';
|
||||
|
||||
// Storage for Unicode data
|
||||
var unicode = {};
|
||||
|
||||
/* ==============================
|
||||
* Private functions
|
||||
* ============================== */
|
||||
|
||||
// Generates a token lookup name: lowercase, with hyphens, spaces, and underscores removed
|
||||
function normalize(name) {
|
||||
return name.replace(/[- _]+/g, '').toLowerCase();
|
||||
}
|
||||
|
||||
// Adds leading zeros if shorter than four characters
|
||||
function pad4(str) {
|
||||
while (str.length < 4) {
|
||||
str = '0' + str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// Converts a hexadecimal number to decimal
|
||||
function dec(hex) {
|
||||
return parseInt(hex, 16);
|
||||
}
|
||||
|
||||
// Converts a decimal number to hexadecimal
|
||||
function hex(dec) {
|
||||
return parseInt(dec, 10).toString(16);
|
||||
}
|
||||
|
||||
// Gets the decimal code of a literal code unit, \xHH, \uHHHH, or a backslash-escaped literal
|
||||
function charCode(chr) {
|
||||
var esc = /^\\[xu](.+)/.exec(chr);
|
||||
return esc ?
|
||||
dec(esc[1]) :
|
||||
chr.charCodeAt(chr.charAt(0) === '\\' ? 1 : 0);
|
||||
}
|
||||
|
||||
// Inverts a list of ordered BMP characters and ranges
|
||||
function invertBmp(range) {
|
||||
var output = '',
|
||||
lastEnd = -1,
|
||||
start;
|
||||
XRegExp.forEach(range, /(\\x..|\\u....|\\?[\s\S])(?:-(\\x..|\\u....|\\?[\s\S]))?/, function(m) {
|
||||
start = charCode(m[1]);
|
||||
if (start > (lastEnd + 1)) {
|
||||
output += '\\u' + pad4(hex(lastEnd + 1));
|
||||
if (start > (lastEnd + 2)) {
|
||||
output += '-\\u' + pad4(hex(start - 1));
|
||||
}
|
||||
}
|
||||
lastEnd = charCode(m[2] || m[1]);
|
||||
});
|
||||
if (lastEnd < 0xFFFF) {
|
||||
output += '\\u' + pad4(hex(lastEnd + 1));
|
||||
if (lastEnd < 0xFFFE) {
|
||||
output += '-\\uFFFF';
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
// Generates an inverted BMP range on first use
|
||||
function cacheInvertedBmp(slug) {
|
||||
var prop = 'b!';
|
||||
return unicode[slug][prop] || (
|
||||
unicode[slug][prop] = invertBmp(unicode[slug].bmp)
|
||||
);
|
||||
}
|
||||
|
||||
// Combines and optionally negates BMP and astral data
|
||||
function buildAstral(slug, isNegated) {
|
||||
var item = unicode[slug],
|
||||
combined = '';
|
||||
if (item.bmp && !item.isBmpLast) {
|
||||
combined = '[' + item.bmp + ']' + (item.astral ? '|' : '');
|
||||
}
|
||||
if (item.astral) {
|
||||
combined += item.astral;
|
||||
}
|
||||
if (item.isBmpLast && item.bmp) {
|
||||
combined += (item.astral ? '|' : '') + '[' + item.bmp + ']';
|
||||
}
|
||||
// Astral Unicode tokens always match a code point, never a code unit
|
||||
return isNegated ?
|
||||
'(?:(?!' + combined + ')(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[\0-\uFFFF]))' :
|
||||
'(?:' + combined + ')';
|
||||
}
|
||||
|
||||
// Builds a complete astral pattern on first use
|
||||
function cacheAstral(slug, isNegated) {
|
||||
var prop = isNegated ? 'a!' : 'a=';
|
||||
return unicode[slug][prop] || (
|
||||
unicode[slug][prop] = buildAstral(slug, isNegated)
|
||||
);
|
||||
}
|
||||
|
||||
/* ==============================
|
||||
* Core functionality
|
||||
* ============================== */
|
||||
|
||||
/* Add Unicode token syntax: \p{..}, \P{..}, \p{^..}. Also add astral mode (flag A).
|
||||
*/
|
||||
XRegExp.addToken(
|
||||
// Use `*` instead of `+` to avoid capturing `^` as the token name in `\p{^}`
|
||||
/\\([pP])(?:{(\^?)([^}]*)}|([A-Za-z]))/,
|
||||
function(match, scope, flags) {
|
||||
var ERR_DOUBLE_NEG = 'Invalid double negation ',
|
||||
ERR_UNKNOWN_NAME = 'Unknown Unicode token ',
|
||||
ERR_UNKNOWN_REF = 'Unicode token missing data ',
|
||||
ERR_ASTRAL_ONLY = 'Astral mode required for Unicode token ',
|
||||
ERR_ASTRAL_IN_CLASS = 'Astral mode does not support Unicode tokens within character classes',
|
||||
// Negated via \P{..} or \p{^..}
|
||||
isNegated = match[1] === 'P' || !!match[2],
|
||||
// Switch from BMP (U+FFFF) to astral (U+10FFFF) mode via flag A or implicit opt-in
|
||||
isAstralMode = flags.indexOf('A') > -1 || XRegExp.isInstalled('astral'),
|
||||
// Token lookup name. Check `[4]` first to avoid passing `undefined` via `\p{}`
|
||||
slug = normalize(match[4] || match[3]),
|
||||
// Token data object
|
||||
item = unicode[slug];
|
||||
|
||||
if (match[1] === 'P' && match[2]) {
|
||||
throw new SyntaxError(ERR_DOUBLE_NEG + match[0]);
|
||||
}
|
||||
if (!unicode.hasOwnProperty(slug)) {
|
||||
throw new SyntaxError(ERR_UNKNOWN_NAME + match[0]);
|
||||
}
|
||||
|
||||
// Switch to the negated form of the referenced Unicode token
|
||||
if (item.inverseOf) {
|
||||
slug = normalize(item.inverseOf);
|
||||
if (!unicode.hasOwnProperty(slug)) {
|
||||
throw new ReferenceError(ERR_UNKNOWN_REF + match[0] + ' -> ' + item.inverseOf);
|
||||
}
|
||||
item = unicode[slug];
|
||||
isNegated = !isNegated;
|
||||
}
|
||||
|
||||
if (!(item.bmp || isAstralMode)) {
|
||||
throw new SyntaxError(ERR_ASTRAL_ONLY + match[0]);
|
||||
}
|
||||
if (isAstralMode) {
|
||||
if (scope === 'class') {
|
||||
throw new SyntaxError(ERR_ASTRAL_IN_CLASS);
|
||||
}
|
||||
|
||||
return cacheAstral(slug, isNegated);
|
||||
}
|
||||
|
||||
return scope === 'class' ?
|
||||
(isNegated ? cacheInvertedBmp(slug) : item.bmp) :
|
||||
(isNegated ? '[^' : '[') + item.bmp + ']';
|
||||
},
|
||||
{
|
||||
scope: 'all',
|
||||
optionalFlags: 'A'
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds to the list of Unicode tokens that XRegExp regexes can match via `\p` or `\P`.
|
||||
* @memberOf XRegExp
|
||||
* @param {Array} data Objects with named character ranges. Each object may have properties `name`,
|
||||
* `alias`, `isBmpLast`, `inverseOf`, `bmp`, and `astral`. All but `name` are optional, although
|
||||
* one of `bmp` or `astral` is required (unless `inverseOf` is set). If `astral` is absent, the
|
||||
* `bmp` data is used for BMP and astral modes. If `bmp` is absent, the name errors in BMP mode
|
||||
* but works in astral mode. If both `bmp` and `astral` are provided, the `bmp` data only is used
|
||||
* in BMP mode, and the combination of `bmp` and `astral` data is used in astral mode.
|
||||
* `isBmpLast` is needed when a token matches orphan high surrogates *and* uses surrogate pairs
|
||||
* to match astral code points. The `bmp` and `astral` data should be a combination of literal
|
||||
* characters and `\xHH` or `\uHHHH` escape sequences, with hyphens to create ranges. Any regex
|
||||
* metacharacters in the data should be escaped, apart from range-creating hyphens. The `astral`
|
||||
* data can additionally use character classes and alternation, and should use surrogate pairs to
|
||||
* represent astral code points. `inverseOf` can be used to avoid duplicating character data if a
|
||||
* Unicode token is defined as the exact inverse of another token.
|
||||
* @example
|
||||
*
|
||||
* // Basic use
|
||||
* XRegExp.addUnicodeData([{
|
||||
* name: 'XDigit',
|
||||
* alias: 'Hexadecimal',
|
||||
* bmp: '0-9A-Fa-f'
|
||||
* }]);
|
||||
* XRegExp('\\p{XDigit}:\\p{Hexadecimal}+').test('0:3D'); // -> true
|
||||
*/
|
||||
XRegExp.addUnicodeData = function(data) {
|
||||
var ERR_NO_NAME = 'Unicode token requires name',
|
||||
ERR_NO_DATA = 'Unicode token has no character data ',
|
||||
item,
|
||||
i;
|
||||
|
||||
for (i = 0; i < data.length; ++i) {
|
||||
item = data[i];
|
||||
if (!item.name) {
|
||||
throw new Error(ERR_NO_NAME);
|
||||
}
|
||||
if (!(item.inverseOf || item.bmp || item.astral)) {
|
||||
throw new Error(ERR_NO_DATA + item.name);
|
||||
}
|
||||
unicode[normalize(item.name)] = item;
|
||||
if (item.alias) {
|
||||
unicode[normalize(item.alias)] = item;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the pattern cache used by the `XRegExp` constructor, since the same pattern and
|
||||
// flags might now produce different results
|
||||
XRegExp.cache.flush('patterns');
|
||||
};
|
||||
|
||||
/* Add data for the Unicode `L` or `Letter` category. Separate addons are available that add other
|
||||
* categories, scripts, blocks, and properties.
|
||||
*/
|
||||
XRegExp.addUnicodeData([{
|
||||
name: 'L',
|
||||
alias: 'Letter',
|
||||
bmp: 'A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC',
|
||||
astral: '\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72]|\uD801[\uDC00-\uDC9D]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1E\uDF30-\uDF40\uDF42-\uDF49\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD81A[\uDC00-\uDE38]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD83-\uDDB2\uDDC1-\uDDC4]|\uD86E[\uDC00-\uDC1D]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD803[\uDC00-\uDC48]|\uD80D[\uDC00-\uDC2E]|\uD805[\uDE80-\uDEAA]|\uD87E[\uDC00-\uDE1D]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD82C[\uDC00\uDC01]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD808[\uDC00-\uDF6E]'
|
||||
}]);
|
||||
|
||||
}(XRegExp));
|
||||
904
public/vendor/xregexp/unicode/unicode-blocks.js
vendored
Normal file
904
public/vendor/xregexp/unicode/unicode-blocks.js
vendored
Normal file
@@ -0,0 +1,904 @@
|
||||
/*!
|
||||
* XRegExp Unicode Blocks 3.0.0-pre
|
||||
* <http://xregexp.com/>
|
||||
* Steven Levithan <20> 2010-2012 MIT License
|
||||
* Uses Unicode 6.2.0 <http://unicode.org/>
|
||||
* Unicode data generated by Mathias Bynens <http://mathiasbynens.be/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds support for all Unicode blocks. Block names use the prefix 'In'. E.g., `\p{InBasicLatin}`.
|
||||
* Token names are case insensitive, and any spaces, hyphens, and underscores are ignored.
|
||||
* @requires XRegExp, Unicode Base
|
||||
*/
|
||||
(function(XRegExp) {
|
||||
'use strict';
|
||||
|
||||
if (!XRegExp.addUnicodeData) {
|
||||
throw new ReferenceError('Unicode Base must be loaded before Unicode Blocks');
|
||||
}
|
||||
|
||||
XRegExp.addUnicodeData([
|
||||
{
|
||||
name: 'InAegean_Numbers',
|
||||
astral: '\uD800[\uDD00-\uDD3F]'
|
||||
},
|
||||
{
|
||||
name: 'InAlchemical_Symbols',
|
||||
astral: '\uD83D[\uDF00-\uDF7F]'
|
||||
},
|
||||
{
|
||||
name: 'InAlphabetic_Presentation_Forms',
|
||||
bmp: '\uFB00-\uFB4F'
|
||||
},
|
||||
{
|
||||
name: 'InAncient_Greek_Musical_Notation',
|
||||
astral: '\uD834[\uDE00-\uDE4F]'
|
||||
},
|
||||
{
|
||||
name: 'InAncient_Greek_Numbers',
|
||||
astral: '\uD800[\uDD40-\uDD8F]'
|
||||
},
|
||||
{
|
||||
name: 'InAncient_Symbols',
|
||||
astral: '\uD800[\uDD90-\uDDCF]'
|
||||
},
|
||||
{
|
||||
name: 'InArabic',
|
||||
bmp: '\u0600-\u06FF'
|
||||
},
|
||||
{
|
||||
name: 'InArabic_Extended_A',
|
||||
bmp: '\u08A0-\u08FF'
|
||||
},
|
||||
{
|
||||
name: 'InArabic_Mathematical_Alphabetic_Symbols',
|
||||
astral: '\uD83B[\uDE00-\uDEFF]'
|
||||
},
|
||||
{
|
||||
name: 'InArabic_Presentation_Forms_A',
|
||||
bmp: '\uFB50-\uFDFF'
|
||||
},
|
||||
{
|
||||
name: 'InArabic_Presentation_Forms_B',
|
||||
bmp: '\uFE70-\uFEFF'
|
||||
},
|
||||
{
|
||||
name: 'InArabic_Supplement',
|
||||
bmp: '\u0750-\u077F'
|
||||
},
|
||||
{
|
||||
name: 'InArmenian',
|
||||
bmp: '\u0530-\u058F'
|
||||
},
|
||||
{
|
||||
name: 'InArrows',
|
||||
bmp: '\u2190-\u21FF'
|
||||
},
|
||||
{
|
||||
name: 'InAvestan',
|
||||
astral: '\uD802[\uDF00-\uDF3F]'
|
||||
},
|
||||
{
|
||||
name: 'InBalinese',
|
||||
bmp: '\u1B00-\u1B7F'
|
||||
},
|
||||
{
|
||||
name: 'InBamum',
|
||||
bmp: '\uA6A0-\uA6FF'
|
||||
},
|
||||
{
|
||||
name: 'InBamum_Supplement',
|
||||
astral: '\uD81A[\uDC00-\uDE3F]'
|
||||
},
|
||||
{
|
||||
name: 'InBasic_Latin',
|
||||
bmp: '\0-\x7F'
|
||||
},
|
||||
{
|
||||
name: 'InBatak',
|
||||
bmp: '\u1BC0-\u1BFF'
|
||||
},
|
||||
{
|
||||
name: 'InBengali',
|
||||
bmp: '\u0980-\u09FF'
|
||||
},
|
||||
{
|
||||
name: 'InBlock_Elements',
|
||||
bmp: '\u2580-\u259F'
|
||||
},
|
||||
{
|
||||
name: 'InBopomofo',
|
||||
bmp: '\u3100-\u312F'
|
||||
},
|
||||
{
|
||||
name: 'InBopomofo_Extended',
|
||||
bmp: '\u31A0-\u31BF'
|
||||
},
|
||||
{
|
||||
name: 'InBox_Drawing',
|
||||
bmp: '\u2500-\u257F'
|
||||
},
|
||||
{
|
||||
name: 'InBrahmi',
|
||||
astral: '\uD804[\uDC00-\uDC7F]'
|
||||
},
|
||||
{
|
||||
name: 'InBraille_Patterns',
|
||||
bmp: '\u2800-\u28FF'
|
||||
},
|
||||
{
|
||||
name: 'InBuginese',
|
||||
bmp: '\u1A00-\u1A1F'
|
||||
},
|
||||
{
|
||||
name: 'InBuhid',
|
||||
bmp: '\u1740-\u175F'
|
||||
},
|
||||
{
|
||||
name: 'InByzantine_Musical_Symbols',
|
||||
astral: '\uD834[\uDC00-\uDCFF]'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Compatibility',
|
||||
bmp: '\u3300-\u33FF'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Compatibility_Forms',
|
||||
bmp: '\uFE30-\uFE4F'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Compatibility_Ideographs',
|
||||
bmp: '\uF900-\uFAFF'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Compatibility_Ideographs_Supplement',
|
||||
astral: '\uD87E[\uDC00-\uDE1F]'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Radicals_Supplement',
|
||||
bmp: '\u2E80-\u2EFF'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Strokes',
|
||||
bmp: '\u31C0-\u31EF'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Symbols_and_Punctuation',
|
||||
bmp: '\u3000-\u303F'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Unified_Ideographs',
|
||||
bmp: '\u4E00-\u9FFF'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Unified_Ideographs_Extension_A',
|
||||
bmp: '\u3400-\u4DBF'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Unified_Ideographs_Extension_B',
|
||||
astral: '[\uD840-\uD868][\uDC00-\uDFFF]|\uD869[\uDC00-\uDEDF]'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Unified_Ideographs_Extension_C',
|
||||
astral: '\uD86D[\uDC00-\uDF3F]|[\uD86A-\uD86C][\uDC00-\uDFFF]|\uD869[\uDF00-\uDFFF]'
|
||||
},
|
||||
{
|
||||
name: 'InCJK_Unified_Ideographs_Extension_D',
|
||||
astral: '\uD86D[\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1F]'
|
||||
},
|
||||
{
|
||||
name: 'InCarian',
|
||||
astral: '\uD800[\uDEA0-\uDEDF]'
|
||||
},
|
||||
{
|
||||
name: 'InChakma',
|
||||
astral: '\uD804[\uDD00-\uDD4F]'
|
||||
},
|
||||
{
|
||||
name: 'InCham',
|
||||
bmp: '\uAA00-\uAA5F'
|
||||
},
|
||||
{
|
||||
name: 'InCherokee',
|
||||
bmp: '\u13A0-\u13FF'
|
||||
},
|
||||
{
|
||||
name: 'InCombining_Diacritical_Marks',
|
||||
bmp: '\u0300-\u036F'
|
||||
},
|
||||
{
|
||||
name: 'InCombining_Diacritical_Marks_Supplement',
|
||||
bmp: '\u1DC0-\u1DFF'
|
||||
},
|
||||
{
|
||||
name: 'InCombining_Diacritical_Marks_for_Symbols',
|
||||
bmp: '\u20D0-\u20FF'
|
||||
},
|
||||
{
|
||||
name: 'InCombining_Half_Marks',
|
||||
bmp: '\uFE20-\uFE2F'
|
||||
},
|
||||
{
|
||||
name: 'InCommon_Indic_Number_Forms',
|
||||
bmp: '\uA830-\uA83F'
|
||||
},
|
||||
{
|
||||
name: 'InControl_Pictures',
|
||||
bmp: '\u2400-\u243F'
|
||||
},
|
||||
{
|
||||
name: 'InCoptic',
|
||||
bmp: '\u2C80-\u2CFF'
|
||||
},
|
||||
{
|
||||
name: 'InCounting_Rod_Numerals',
|
||||
astral: '\uD834[\uDF60-\uDF7F]'
|
||||
},
|
||||
{
|
||||
name: 'InCuneiform',
|
||||
astral: '\uD808[\uDC00-\uDFFF]'
|
||||
},
|
||||
{
|
||||
name: 'InCuneiform_Numbers_and_Punctuation',
|
||||
astral: '\uD809[\uDC00-\uDC7F]'
|
||||
},
|
||||
{
|
||||
name: 'InCurrency_Symbols',
|
||||
bmp: '\u20A0-\u20CF'
|
||||
},
|
||||
{
|
||||
name: 'InCypriot_Syllabary',
|
||||
astral: '\uD802[\uDC00-\uDC3F]'
|
||||
},
|
||||
{
|
||||
name: 'InCyrillic',
|
||||
bmp: '\u0400-\u04FF'
|
||||
},
|
||||
{
|
||||
name: 'InCyrillic_Extended_A',
|
||||
bmp: '\u2DE0-\u2DFF'
|
||||
},
|
||||
{
|
||||
name: 'InCyrillic_Extended_B',
|
||||
bmp: '\uA640-\uA69F'
|
||||
},
|
||||
{
|
||||
name: 'InCyrillic_Supplement',
|
||||
bmp: '\u0500-\u052F'
|
||||
},
|
||||
{
|
||||
name: 'InDeseret',
|
||||
astral: '\uD801[\uDC00-\uDC4F]'
|
||||
},
|
||||
{
|
||||
name: 'InDevanagari',
|
||||
bmp: '\u0900-\u097F'
|
||||
},
|
||||
{
|
||||
name: 'InDevanagari_Extended',
|
||||
bmp: '\uA8E0-\uA8FF'
|
||||
},
|
||||
{
|
||||
name: 'InDingbats',
|
||||
bmp: '\u2700-\u27BF'
|
||||
},
|
||||
{
|
||||
name: 'InDomino_Tiles',
|
||||
astral: '\uD83C[\uDC30-\uDC9F]'
|
||||
},
|
||||
{
|
||||
name: 'InEgyptian_Hieroglyphs',
|
||||
astral: '\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F]'
|
||||
},
|
||||
{
|
||||
name: 'InEmoticons',
|
||||
astral: '\uD83D[\uDE00-\uDE4F]'
|
||||
},
|
||||
{
|
||||
name: 'InEnclosed_Alphanumeric_Supplement',
|
||||
astral: '\uD83C[\uDD00-\uDDFF]'
|
||||
},
|
||||
{
|
||||
name: 'InEnclosed_Alphanumerics',
|
||||
bmp: '\u2460-\u24FF'
|
||||
},
|
||||
{
|
||||
name: 'InEnclosed_CJK_Letters_and_Months',
|
||||
bmp: '\u3200-\u32FF'
|
||||
},
|
||||
{
|
||||
name: 'InEnclosed_Ideographic_Supplement',
|
||||
astral: '\uD83C[\uDE00-\uDEFF]'
|
||||
},
|
||||
{
|
||||
name: 'InEthiopic',
|
||||
bmp: '\u1200-\u137F'
|
||||
},
|
||||
{
|
||||
name: 'InEthiopic_Extended',
|
||||
bmp: '\u2D80-\u2DDF'
|
||||
},
|
||||
{
|
||||
name: 'InEthiopic_Extended_A',
|
||||
bmp: '\uAB00-\uAB2F'
|
||||
},
|
||||
{
|
||||
name: 'InEthiopic_Supplement',
|
||||
bmp: '\u1380-\u139F'
|
||||
},
|
||||
{
|
||||
name: 'InGeneral_Punctuation',
|
||||
bmp: '\u2000-\u206F'
|
||||
},
|
||||
{
|
||||
name: 'InGeometric_Shapes',
|
||||
bmp: '\u25A0-\u25FF'
|
||||
},
|
||||
{
|
||||
name: 'InGeorgian',
|
||||
bmp: '\u10A0-\u10FF'
|
||||
},
|
||||
{
|
||||
name: 'InGeorgian_Supplement',
|
||||
bmp: '\u2D00-\u2D2F'
|
||||
},
|
||||
{
|
||||
name: 'InGlagolitic',
|
||||
bmp: '\u2C00-\u2C5F'
|
||||
},
|
||||
{
|
||||
name: 'InGothic',
|
||||
astral: '\uD800[\uDF30-\uDF4F]'
|
||||
},
|
||||
{
|
||||
name: 'InGreek_Extended',
|
||||
bmp: '\u1F00-\u1FFF'
|
||||
},
|
||||
{
|
||||
name: 'InGreek_and_Coptic',
|
||||
bmp: '\u0370-\u03FF'
|
||||
},
|
||||
{
|
||||
name: 'InGujarati',
|
||||
bmp: '\u0A80-\u0AFF'
|
||||
},
|
||||
{
|
||||
name: 'InGurmukhi',
|
||||
bmp: '\u0A00-\u0A7F'
|
||||
},
|
||||
{
|
||||
name: 'InHalfwidth_and_Fullwidth_Forms',
|
||||
bmp: '\uFF00-\uFFEF'
|
||||
},
|
||||
{
|
||||
name: 'InHangul_Compatibility_Jamo',
|
||||
bmp: '\u3130-\u318F'
|
||||
},
|
||||
{
|
||||
name: 'InHangul_Jamo',
|
||||
bmp: '\u1100-\u11FF'
|
||||
},
|
||||
{
|
||||
name: 'InHangul_Jamo_Extended_A',
|
||||
bmp: '\uA960-\uA97F'
|
||||
},
|
||||
{
|
||||
name: 'InHangul_Jamo_Extended_B',
|
||||
bmp: '\uD7B0-\uD7FF'
|
||||
},
|
||||
{
|
||||
name: 'InHangul_Syllables',
|
||||
bmp: '\uAC00-\uD7AF'
|
||||
},
|
||||
{
|
||||
name: 'InHanunoo',
|
||||
bmp: '\u1720-\u173F'
|
||||
},
|
||||
{
|
||||
name: 'InHebrew',
|
||||
bmp: '\u0590-\u05FF'
|
||||
},
|
||||
{
|
||||
name: 'InHigh_Private_Use_Surrogates',
|
||||
bmp: '\uDB80-\uDBFF'
|
||||
},
|
||||
{
|
||||
name: 'InHigh_Surrogates',
|
||||
bmp: '\uD800-\uDB7F'
|
||||
},
|
||||
{
|
||||
name: 'InHiragana',
|
||||
bmp: '\u3040-\u309F'
|
||||
},
|
||||
{
|
||||
name: 'InIPA_Extensions',
|
||||
bmp: '\u0250-\u02AF'
|
||||
},
|
||||
{
|
||||
name: 'InIdeographic_Description_Characters',
|
||||
bmp: '\u2FF0-\u2FFF'
|
||||
},
|
||||
{
|
||||
name: 'InImperial_Aramaic',
|
||||
astral: '\uD802[\uDC40-\uDC5F]'
|
||||
},
|
||||
{
|
||||
name: 'InInscriptional_Pahlavi',
|
||||
astral: '\uD802[\uDF60-\uDF7F]'
|
||||
},
|
||||
{
|
||||
name: 'InInscriptional_Parthian',
|
||||
astral: '\uD802[\uDF40-\uDF5F]'
|
||||
},
|
||||
{
|
||||
name: 'InJavanese',
|
||||
bmp: '\uA980-\uA9DF'
|
||||
},
|
||||
{
|
||||
name: 'InKaithi',
|
||||
astral: '\uD804[\uDC80-\uDCCF]'
|
||||
},
|
||||
{
|
||||
name: 'InKana_Supplement',
|
||||
astral: '\uD82C[\uDC00-\uDCFF]'
|
||||
},
|
||||
{
|
||||
name: 'InKanbun',
|
||||
bmp: '\u3190-\u319F'
|
||||
},
|
||||
{
|
||||
name: 'InKangxi_Radicals',
|
||||
bmp: '\u2F00-\u2FDF'
|
||||
},
|
||||
{
|
||||
name: 'InKannada',
|
||||
bmp: '\u0C80-\u0CFF'
|
||||
},
|
||||
{
|
||||
name: 'InKatakana',
|
||||
bmp: '\u30A0-\u30FF'
|
||||
},
|
||||
{
|
||||
name: 'InKatakana_Phonetic_Extensions',
|
||||
bmp: '\u31F0-\u31FF'
|
||||
},
|
||||
{
|
||||
name: 'InKayah_Li',
|
||||
bmp: '\uA900-\uA92F'
|
||||
},
|
||||
{
|
||||
name: 'InKharoshthi',
|
||||
astral: '\uD802[\uDE00-\uDE5F]'
|
||||
},
|
||||
{
|
||||
name: 'InKhmer',
|
||||
bmp: '\u1780-\u17FF'
|
||||
},
|
||||
{
|
||||
name: 'InKhmer_Symbols',
|
||||
bmp: '\u19E0-\u19FF'
|
||||
},
|
||||
{
|
||||
name: 'InLao',
|
||||
bmp: '\u0E80-\u0EFF'
|
||||
},
|
||||
{
|
||||
name: 'InLatin_Extended_Additional',
|
||||
bmp: '\u1E00-\u1EFF'
|
||||
},
|
||||
{
|
||||
name: 'InLatin_Extended_A',
|
||||
bmp: '\u0100-\u017F'
|
||||
},
|
||||
{
|
||||
name: 'InLatin_Extended_B',
|
||||
bmp: '\u0180-\u024F'
|
||||
},
|
||||
{
|
||||
name: 'InLatin_Extended_C',
|
||||
bmp: '\u2C60-\u2C7F'
|
||||
},
|
||||
{
|
||||
name: 'InLatin_Extended_D',
|
||||
bmp: '\uA720-\uA7FF'
|
||||
},
|
||||
{
|
||||
name: 'InLatin_1_Supplement',
|
||||
bmp: '\x80-\xFF'
|
||||
},
|
||||
{
|
||||
name: 'InLepcha',
|
||||
bmp: '\u1C00-\u1C4F'
|
||||
},
|
||||
{
|
||||
name: 'InLetterlike_Symbols',
|
||||
bmp: '\u2100-\u214F'
|
||||
},
|
||||
{
|
||||
name: 'InLimbu',
|
||||
bmp: '\u1900-\u194F'
|
||||
},
|
||||
{
|
||||
name: 'InLinear_B_Ideograms',
|
||||
astral: '\uD800[\uDC80-\uDCFF]'
|
||||
},
|
||||
{
|
||||
name: 'InLinear_B_Syllabary',
|
||||
astral: '\uD800[\uDC00-\uDC7F]'
|
||||
},
|
||||
{
|
||||
name: 'InLisu',
|
||||
bmp: '\uA4D0-\uA4FF'
|
||||
},
|
||||
{
|
||||
name: 'InLow_Surrogates',
|
||||
bmp: '\uDC00-\uDFFF'
|
||||
},
|
||||
{
|
||||
name: 'InLycian',
|
||||
astral: '\uD800[\uDE80-\uDE9F]'
|
||||
},
|
||||
{
|
||||
name: 'InLydian',
|
||||
astral: '\uD802[\uDD20-\uDD3F]'
|
||||
},
|
||||
{
|
||||
name: 'InMahjong_Tiles',
|
||||
astral: '\uD83C[\uDC00-\uDC2F]'
|
||||
},
|
||||
{
|
||||
name: 'InMalayalam',
|
||||
bmp: '\u0D00-\u0D7F'
|
||||
},
|
||||
{
|
||||
name: 'InMandaic',
|
||||
bmp: '\u0840-\u085F'
|
||||
},
|
||||
{
|
||||
name: 'InMathematical_Alphanumeric_Symbols',
|
||||
astral: '\uD835[\uDC00-\uDFFF]'
|
||||
},
|
||||
{
|
||||
name: 'InMathematical_Operators',
|
||||
bmp: '\u2200-\u22FF'
|
||||
},
|
||||
{
|
||||
name: 'InMeetei_Mayek',
|
||||
bmp: '\uABC0-\uABFF'
|
||||
},
|
||||
{
|
||||
name: 'InMeetei_Mayek_Extensions',
|
||||
bmp: '\uAAE0-\uAAFF'
|
||||
},
|
||||
{
|
||||
name: 'InMeroitic_Cursive',
|
||||
astral: '\uD802[\uDDA0-\uDDFF]'
|
||||
},
|
||||
{
|
||||
name: 'InMeroitic_Hieroglyphs',
|
||||
astral: '\uD802[\uDD80-\uDD9F]'
|
||||
},
|
||||
{
|
||||
name: 'InMiao',
|
||||
astral: '\uD81B[\uDF00-\uDF9F]'
|
||||
},
|
||||
{
|
||||
name: 'InMiscellaneous_Mathematical_Symbols_A',
|
||||
bmp: '\u27C0-\u27EF'
|
||||
},
|
||||
{
|
||||
name: 'InMiscellaneous_Mathematical_Symbols_B',
|
||||
bmp: '\u2980-\u29FF'
|
||||
},
|
||||
{
|
||||
name: 'InMiscellaneous_Symbols',
|
||||
bmp: '\u2600-\u26FF'
|
||||
},
|
||||
{
|
||||
name: 'InMiscellaneous_Symbols_And_Pictographs',
|
||||
astral: '\uD83D[\uDC00-\uDDFF]|\uD83C[\uDF00-\uDFFF]'
|
||||
},
|
||||
{
|
||||
name: 'InMiscellaneous_Symbols_and_Arrows',
|
||||
bmp: '\u2B00-\u2BFF'
|
||||
},
|
||||
{
|
||||
name: 'InMiscellaneous_Technical',
|
||||
bmp: '\u2300-\u23FF'
|
||||
},
|
||||
{
|
||||
name: 'InModifier_Tone_Letters',
|
||||
bmp: '\uA700-\uA71F'
|
||||
},
|
||||
{
|
||||
name: 'InMongolian',
|
||||
bmp: '\u1800-\u18AF'
|
||||
},
|
||||
{
|
||||
name: 'InMusical_Symbols',
|
||||
astral: '\uD834[\uDD00-\uDDFF]'
|
||||
},
|
||||
{
|
||||
name: 'InMyanmar',
|
||||
bmp: '\u1000-\u109F'
|
||||
},
|
||||
{
|
||||
name: 'InMyanmar_Extended_A',
|
||||
bmp: '\uAA60-\uAA7F'
|
||||
},
|
||||
{
|
||||
name: 'InNKo',
|
||||
bmp: '\u07C0-\u07FF'
|
||||
},
|
||||
{
|
||||
name: 'InNew_Tai_Lue',
|
||||
bmp: '\u1980-\u19DF'
|
||||
},
|
||||
{
|
||||
name: 'InNumber_Forms',
|
||||
bmp: '\u2150-\u218F'
|
||||
},
|
||||
{
|
||||
name: 'InOgham',
|
||||
bmp: '\u1680-\u169F'
|
||||
},
|
||||
{
|
||||
name: 'InOl_Chiki',
|
||||
bmp: '\u1C50-\u1C7F'
|
||||
},
|
||||
{
|
||||
name: 'InOld_Italic',
|
||||
astral: '\uD800[\uDF00-\uDF2F]'
|
||||
},
|
||||
{
|
||||
name: 'InOld_Persian',
|
||||
astral: '\uD800[\uDFA0-\uDFDF]'
|
||||
},
|
||||
{
|
||||
name: 'InOld_South_Arabian',
|
||||
astral: '\uD802[\uDE60-\uDE7F]'
|
||||
},
|
||||
{
|
||||
name: 'InOld_Turkic',
|
||||
astral: '\uD803[\uDC00-\uDC4F]'
|
||||
},
|
||||
{
|
||||
name: 'InOptical_Character_Recognition',
|
||||
bmp: '\u2440-\u245F'
|
||||
},
|
||||
{
|
||||
name: 'InOriya',
|
||||
bmp: '\u0B00-\u0B7F'
|
||||
},
|
||||
{
|
||||
name: 'InOsmanya',
|
||||
astral: '\uD801[\uDC80-\uDCAF]'
|
||||
},
|
||||
{
|
||||
name: 'InPhags_pa',
|
||||
bmp: '\uA840-\uA87F'
|
||||
},
|
||||
{
|
||||
name: 'InPhaistos_Disc',
|
||||
astral: '\uD800[\uDDD0-\uDDFF]'
|
||||
},
|
||||
{
|
||||
name: 'InPhoenician',
|
||||
astral: '\uD802[\uDD00-\uDD1F]'
|
||||
},
|
||||
{
|
||||
name: 'InPhonetic_Extensions',
|
||||
bmp: '\u1D00-\u1D7F'
|
||||
},
|
||||
{
|
||||
name: 'InPhonetic_Extensions_Supplement',
|
||||
bmp: '\u1D80-\u1DBF'
|
||||
},
|
||||
{
|
||||
name: 'InPlaying_Cards',
|
||||
astral: '\uD83C[\uDCA0-\uDCFF]'
|
||||
},
|
||||
{
|
||||
name: 'InPrivate_Use_Area',
|
||||
bmp: '\uE000-\uF8FF'
|
||||
},
|
||||
{
|
||||
name: 'InRejang',
|
||||
bmp: '\uA930-\uA95F'
|
||||
},
|
||||
{
|
||||
name: 'InRumi_Numeral_Symbols',
|
||||
astral: '\uD803[\uDE60-\uDE7F]'
|
||||
},
|
||||
{
|
||||
name: 'InRunic',
|
||||
bmp: '\u16A0-\u16FF'
|
||||
},
|
||||
{
|
||||
name: 'InSamaritan',
|
||||
bmp: '\u0800-\u083F'
|
||||
},
|
||||
{
|
||||
name: 'InSaurashtra',
|
||||
bmp: '\uA880-\uA8DF'
|
||||
},
|
||||
{
|
||||
name: 'InSharada',
|
||||
astral: '\uD804[\uDD80-\uDDDF]'
|
||||
},
|
||||
{
|
||||
name: 'InShavian',
|
||||
astral: '\uD801[\uDC50-\uDC7F]'
|
||||
},
|
||||
{
|
||||
name: 'InSinhala',
|
||||
bmp: '\u0D80-\u0DFF'
|
||||
},
|
||||
{
|
||||
name: 'InSmall_Form_Variants',
|
||||
bmp: '\uFE50-\uFE6F'
|
||||
},
|
||||
{
|
||||
name: 'InSora_Sompeng',
|
||||
astral: '\uD804[\uDCD0-\uDCFF]'
|
||||
},
|
||||
{
|
||||
name: 'InSpacing_Modifier_Letters',
|
||||
bmp: '\u02B0-\u02FF'
|
||||
},
|
||||
{
|
||||
name: 'InSpecials',
|
||||
bmp: '\uFFF0-\uFFFF'
|
||||
},
|
||||
{
|
||||
name: 'InSundanese',
|
||||
bmp: '\u1B80-\u1BBF'
|
||||
},
|
||||
{
|
||||
name: 'InSundanese_Supplement',
|
||||
bmp: '\u1CC0-\u1CCF'
|
||||
},
|
||||
{
|
||||
name: 'InSuperscripts_and_Subscripts',
|
||||
bmp: '\u2070-\u209F'
|
||||
},
|
||||
{
|
||||
name: 'InSupplemental_Arrows_A',
|
||||
bmp: '\u27F0-\u27FF'
|
||||
},
|
||||
{
|
||||
name: 'InSupplemental_Arrows_B',
|
||||
bmp: '\u2900-\u297F'
|
||||
},
|
||||
{
|
||||
name: 'InSupplemental_Mathematical_Operators',
|
||||
bmp: '\u2A00-\u2AFF'
|
||||
},
|
||||
{
|
||||
name: 'InSupplemental_Punctuation',
|
||||
bmp: '\u2E00-\u2E7F'
|
||||
},
|
||||
{
|
||||
name: 'InSupplementary_Private_Use_Area_A',
|
||||
astral: '[\uDB80-\uDBBF][\uDC00-\uDFFF]'
|
||||
},
|
||||
{
|
||||
name: 'InSupplementary_Private_Use_Area_B',
|
||||
astral: '[\uDBC0-\uDBFF][\uDC00-\uDFFF]'
|
||||
},
|
||||
{
|
||||
name: 'InSyloti_Nagri',
|
||||
bmp: '\uA800-\uA82F'
|
||||
},
|
||||
{
|
||||
name: 'InSyriac',
|
||||
bmp: '\u0700-\u074F'
|
||||
},
|
||||
{
|
||||
name: 'InTagalog',
|
||||
bmp: '\u1700-\u171F'
|
||||
},
|
||||
{
|
||||
name: 'InTagbanwa',
|
||||
bmp: '\u1760-\u177F'
|
||||
},
|
||||
{
|
||||
name: 'InTags',
|
||||
astral: '\uDB40[\uDC00-\uDC7F]'
|
||||
},
|
||||
{
|
||||
name: 'InTai_Le',
|
||||
bmp: '\u1950-\u197F'
|
||||
},
|
||||
{
|
||||
name: 'InTai_Tham',
|
||||
bmp: '\u1A20-\u1AAF'
|
||||
},
|
||||
{
|
||||
name: 'InTai_Viet',
|
||||
bmp: '\uAA80-\uAADF'
|
||||
},
|
||||
{
|
||||
name: 'InTai_Xuan_Jing_Symbols',
|
||||
astral: '\uD834[\uDF00-\uDF5F]'
|
||||
},
|
||||
{
|
||||
name: 'InTakri',
|
||||
astral: '\uD805[\uDE80-\uDECF]'
|
||||
},
|
||||
{
|
||||
name: 'InTamil',
|
||||
bmp: '\u0B80-\u0BFF'
|
||||
},
|
||||
{
|
||||
name: 'InTelugu',
|
||||
bmp: '\u0C00-\u0C7F'
|
||||
},
|
||||
{
|
||||
name: 'InThaana',
|
||||
bmp: '\u0780-\u07BF'
|
||||
},
|
||||
{
|
||||
name: 'InThai',
|
||||
bmp: '\u0E00-\u0E7F'
|
||||
},
|
||||
{
|
||||
name: 'InTibetan',
|
||||
bmp: '\u0F00-\u0FFF'
|
||||
},
|
||||
{
|
||||
name: 'InTifinagh',
|
||||
bmp: '\u2D30-\u2D7F'
|
||||
},
|
||||
{
|
||||
name: 'InTransport_And_Map_Symbols',
|
||||
astral: '\uD83D[\uDE80-\uDEFF]'
|
||||
},
|
||||
{
|
||||
name: 'InUgaritic',
|
||||
astral: '\uD800[\uDF80-\uDF9F]'
|
||||
},
|
||||
{
|
||||
name: 'InUnified_Canadian_Aboriginal_Syllabics',
|
||||
bmp: '\u1400-\u167F'
|
||||
},
|
||||
{
|
||||
name: 'InUnified_Canadian_Aboriginal_Syllabics_Extended',
|
||||
bmp: '\u18B0-\u18FF'
|
||||
},
|
||||
{
|
||||
name: 'InVai',
|
||||
bmp: '\uA500-\uA63F'
|
||||
},
|
||||
{
|
||||
name: 'InVariation_Selectors',
|
||||
bmp: '\uFE00-\uFE0F'
|
||||
},
|
||||
{
|
||||
name: 'InVariation_Selectors_Supplement',
|
||||
astral: '\uDB40[\uDD00-\uDDEF]'
|
||||
},
|
||||
{
|
||||
name: 'InVedic_Extensions',
|
||||
bmp: '\u1CD0-\u1CFF'
|
||||
},
|
||||
{
|
||||
name: 'InVertical_Forms',
|
||||
bmp: '\uFE10-\uFE1F'
|
||||
},
|
||||
{
|
||||
name: 'InYi_Radicals',
|
||||
bmp: '\uA490-\uA4CF'
|
||||
},
|
||||
{
|
||||
name: 'InYi_Syllables',
|
||||
bmp: '\uA000-\uA48F'
|
||||
},
|
||||
{
|
||||
name: 'InYijing_Hexagram_Symbols',
|
||||
bmp: '\u4DC0-\u4DFF'
|
||||
}
|
||||
]);
|
||||
|
||||
}(XRegExp));
|
||||
232
public/vendor/xregexp/unicode/unicode-categories.js
vendored
Normal file
232
public/vendor/xregexp/unicode/unicode-categories.js
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
/*!
|
||||
* XRegExp Unicode Categories 3.0.0-pre
|
||||
* <http://xregexp.com/>
|
||||
* Steven Levithan <20> 2010-2012 MIT License
|
||||
* Uses Unicode 6.2.0 <http://unicode.org/>
|
||||
* Unicode data generated by Mathias Bynens <http://mathiasbynens.be/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds support for all Unicode categories. E.g., `\p{Lu}` or `\p{Uppercase Letter}`. Token names
|
||||
* are case insensitive, and any spaces, hyphens, and underscores are ignored.
|
||||
* @requires XRegExp, Unicode Base
|
||||
*/
|
||||
(function(XRegExp) {
|
||||
'use strict';
|
||||
|
||||
if (!XRegExp.addUnicodeData) {
|
||||
throw new ReferenceError('Unicode Base must be loaded before Unicode Categories');
|
||||
}
|
||||
|
||||
XRegExp.addUnicodeData([
|
||||
{
|
||||
name: 'C',
|
||||
alias: 'Other',
|
||||
isBmpLast: true,
|
||||
bmp: '\0-\x1F\x7F-\x9F\xAD\u0378\u0379\u037F-\u0383\u038B\u038D\u03A2\u0528-\u0530\u0557\u0558\u0560\u0588\u058B-\u058E\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u0605\u061C\u061D\u06DD\u070E\u070F\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08A1\u08AD-\u08E3\u08FF\u0978\u0980\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0C00\u0C04\u0C0D\u0C11\u0C29\u0C34\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5A-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C81\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D01\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5F\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F5-\u13FF\u169D-\u169F\u16F1-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191D-\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7-\u1CFF\u1DE7-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u200B-\u200F\u202A-\u202E\u2060-\u206F\u2072\u2073\u208F\u209D-\u209F\u20BB-\u20CF\u20F1-\u20FF\u218A-\u218F\u23F4-\u23FF\u2427-\u243F\u244B-\u245F\u2700\u2B4D-\u2B4F\u2B5A-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E3C-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FCD-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA698-\uA69E\uA6F8-\uA6FF\uA78F\uA794-\uA79F\uA7AB-\uA7F7\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FC-\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9E0-\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAA7C-\uAA7F\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F-\uABBF\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE27-\uFE2F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD-\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFFB\uFFFE\uFFFF',
|
||||
astral: '\uD808[\uDF6F-\uDFFF]|\uD809[\uDC63-\uDC6F\uDC74-\uDFFF]|\uD804[\uDC4E-\uDC51\uDC70-\uDC7F\uDCBD\uDCC2-\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD44-\uDD7F\uDDC9-\uDDCF\uDDDA-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56\uDC60-\uDCFF\uDD1C-\uDD1E\uDD3A-\uDD3E\uDD40-\uDD7F\uDDB8-\uDDBD\uDDC0-\uDDFF\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE34-\uDE37\uDE3B-\uDE3E\uDE48-\uDE4F\uDE59-\uDE5F\uDE80-\uDEFF\uDF36-\uDF38\uDF56\uDF57\uDF73-\uDF77\uDF80-\uDFFF]|\uD86D[\uDF35-\uDF3F]|\uD81B[\uDC00-\uDEFF\uDF45-\uDF4F\uDF7F-\uDF8E\uDFA0-\uDFFF]|\uD86E[\uDC1E-\uDFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDCFF\uDD03-\uDD06\uDD34-\uDD36\uDD8B-\uDD8F\uDD9C-\uDDCF\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEFF\uDF1F\uDF24-\uDF2F\uDF4B-\uDF7F\uDF9E\uDFC4-\uDFC7\uDFD6-\uDFFF]|\uD869[\uDED7-\uDEFF]|\uD83B[\uDC00-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDEEF\uDEF2-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uDB40[\uDC00-\uDCFF\uDDF0-\uDFFF]|\uD803[\uDC49-\uDE5F\uDE7F-\uDFFF]|\uD80D[\uDC2F-\uDFFF]|[\uD806\uD807\uD80A\uD80B\uD80E-\uD819\uD81C-\uD82B\uD82D-\uD833\uD836-\uD83A\uD83E\uD83F\uD86F-\uD87D\uD87F-\uDB3F\uDB41-\uDBFF][\uDC00-\uDFFF]|\uD83D[\uDC3F\uDC41\uDCF8\uDCFD-\uDCFF\uDD3E\uDD3F\uDD44-\uDD4F\uDD68-\uDDFA\uDE41-\uDE44\uDE50-\uDE7F\uDEC6-\uDEFF\uDF74-\uDFFF]|\uD83C[\uDC2C-\uDC2F\uDC94-\uDC9F\uDCAF\uDCB0\uDCBF\uDCC0\uDCD0\uDCE0-\uDCFF\uDD0B-\uDD0F\uDD2F\uDD6C-\uDD6F\uDD9B-\uDDE5\uDE03-\uDE0F\uDE3B-\uDE3F\uDE49-\uDE4F\uDE52-\uDEFF\uDF21-\uDF2F\uDF36\uDF7D-\uDF7F\uDF94-\uDF9F\uDFC5\uDFCB-\uDFDF\uDFF1-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDFCC\uDFCD]|\uD81A[\uDE39-\uDFFF]|\uD834[\uDCF6-\uDCFF\uDD27\uDD28\uDD73-\uDD7A\uDDDE-\uDDFF\uDE46-\uDEFF\uDF57-\uDF5F\uDF72-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDFFF]|\uD805[\uDC00-\uDE7F\uDEB8-\uDEBF\uDECA-\uDFFF]|\uD82C[\uDC02-\uDFFF]'
|
||||
},
|
||||
{
|
||||
name: 'Cc',
|
||||
alias: 'Control',
|
||||
bmp: '\0-\x1F\x7F-\x9F'
|
||||
},
|
||||
{
|
||||
name: 'Cf',
|
||||
alias: 'Format',
|
||||
bmp: '\xAD\u0600-\u0604\u06DD\u070F\u200B-\u200F\u202A-\u202E\u2060-\u2064\u206A-\u206F\uFEFF\uFFF9-\uFFFB',
|
||||
astral: '\uDB40[\uDC01\uDC20-\uDC7F]|\uD834[\uDD73-\uDD7A]|\uD804\uDCBD'
|
||||
},
|
||||
{
|
||||
name: 'Cn',
|
||||
alias: 'Unassigned',
|
||||
bmp: '\u0378\u0379\u037F-\u0383\u038B\u038D\u03A2\u0528-\u0530\u0557\u0558\u0560\u0588\u058B-\u058E\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u05FF\u0605\u061C\u061D\u070E\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08A1\u08AD-\u08E3\u08FF\u0978\u0980\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0C00\u0C04\u0C0D\u0C11\u0C29\u0C34\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5A-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C81\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D01\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5F\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F5-\u13FF\u169D-\u169F\u16F1-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191D-\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7-\u1CFF\u1DE7-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u2065-\u2069\u2072\u2073\u208F\u209D-\u209F\u20BB-\u20CF\u20F1-\u20FF\u218A-\u218F\u23F4-\u23FF\u2427-\u243F\u244B-\u245F\u2700\u2B4D-\u2B4F\u2B5A-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E3C-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FCD-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA698-\uA69E\uA6F8-\uA6FF\uA78F\uA794-\uA79F\uA7AB-\uA7F7\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FC-\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9E0-\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAA7C-\uAA7F\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F-\uABBF\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE27-\uFE2F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD\uFEFE\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFF8\uFFFE\uFFFF',
|
||||
astral: '\uD808[\uDF6F-\uDFFF]|\uDB40[\uDC00\uDC02-\uDC1F\uDC80-\uDCFF\uDDF0-\uDFFF]|\uD834[\uDCF6-\uDCFF\uDD27\uDD28\uDDDE-\uDDFF\uDE46-\uDEFF\uDF57-\uDF5F\uDF72-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56\uDC60-\uDCFF\uDD1C-\uDD1E\uDD3A-\uDD3E\uDD40-\uDD7F\uDDB8-\uDDBD\uDDC0-\uDDFF\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE34-\uDE37\uDE3B-\uDE3E\uDE48-\uDE4F\uDE59-\uDE5F\uDE80-\uDEFF\uDF36-\uDF38\uDF56\uDF57\uDF73-\uDF77\uDF80-\uDFFF]|\uD86D[\uDF35-\uDF3F]|\uD81B[\uDC00-\uDEFF\uDF45-\uDF4F\uDF7F-\uDF8E\uDFA0-\uDFFF]|\uD809[\uDC63-\uDC6F\uDC74-\uDFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDCFF\uDD03-\uDD06\uDD34-\uDD36\uDD8B-\uDD8F\uDD9C-\uDDCF\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEFF\uDF1F\uDF24-\uDF2F\uDF4B-\uDF7F\uDF9E\uDFC4-\uDFC7\uDFD6-\uDFFF]|\uD869[\uDED7-\uDEFF]|\uD804[\uDC4E-\uDC51\uDC70-\uDC7F\uDCC2-\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD44-\uDD7F\uDDC9-\uDDCF\uDDDA-\uDFFF]|\uD83B[\uDC00-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDEEF\uDEF2-\uDFFF]|[\uDBBF\uDBFF][\uDFFE\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD803[\uDC49-\uDE5F\uDE7F-\uDFFF]|\uD80D[\uDC2F-\uDFFF]|[\uD806\uD807\uD80A\uD80B\uD80E-\uD819\uD81C-\uD82B\uD82D-\uD833\uD836-\uD83A\uD83E\uD83F\uD86F-\uD87D\uD87F-\uDB3F\uDB41-\uDB7F][\uDC00-\uDFFF]|\uD83D[\uDC3F\uDC41\uDCF8\uDCFD-\uDCFF\uDD3E\uDD3F\uDD44-\uDD4F\uDD68-\uDDFA\uDE41-\uDE44\uDE50-\uDE7F\uDEC6-\uDEFF\uDF74-\uDFFF]|\uD86E[\uDC1E-\uDFFF]|\uD83C[\uDC2C-\uDC2F\uDC94-\uDC9F\uDCAF\uDCB0\uDCBF\uDCC0\uDCD0\uDCE0-\uDCFF\uDD0B-\uDD0F\uDD2F\uDD6C-\uDD6F\uDD9B-\uDDE5\uDE03-\uDE0F\uDE3B-\uDE3F\uDE49-\uDE4F\uDE52-\uDEFF\uDF21-\uDF2F\uDF36\uDF7D-\uDF7F\uDF94-\uDF9F\uDFC5\uDFCB-\uDFDF\uDFF1-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDFCC\uDFCD]|\uD81A[\uDE39-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDFFF]|\uD805[\uDC00-\uDE7F\uDEB8-\uDEBF\uDECA-\uDFFF]|\uD82C[\uDC02-\uDFFF]'
|
||||
},
|
||||
{
|
||||
name: 'Co',
|
||||
alias: 'Private_Use',
|
||||
bmp: '\uE000-\uF8FF',
|
||||
astral: '[\uDB80-\uDBBE\uDBC0-\uDBFE][\uDC00-\uDFFF]|[\uDBBF\uDBFF][\uDC00-\uDFFD]'
|
||||
},
|
||||
{
|
||||
name: 'Cs',
|
||||
alias: 'Surrogate',
|
||||
bmp: '\uD800-\uDFFF'
|
||||
},
|
||||
// Included in Unicode Base
|
||||
/*{
|
||||
name: 'L',
|
||||
alias: 'Letter',
|
||||
bmp: '...',
|
||||
astral: '...'
|
||||
},*/
|
||||
{
|
||||
name: 'Ll',
|
||||
alias: 'Lowercase_Letter',
|
||||
bmp: 'a-z\xB5\xDF-\xF6\xF8-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0561-\u0587\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6\u1FC7\u1FD0-\u1FD3\u1FD6\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6\u1FF7\u210A\u210E\u210F\u2113\u212F\u2134\u2139\u213C\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7FA\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A',
|
||||
astral: '\uD835[\uDC1A-\uDC33\uDC4E-\uDC54\uDC56-\uDC67\uDC82-\uDC9B\uDCB6-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDCEA-\uDD03\uDD1E-\uDD37\uDD52-\uDD6B\uDD86-\uDD9F\uDDBA-\uDDD3\uDDEE-\uDE07\uDE22-\uDE3B\uDE56-\uDE6F\uDE8A-\uDEA5\uDEC2-\uDEDA\uDEDC-\uDEE1\uDEFC-\uDF14\uDF16-\uDF1B\uDF36-\uDF4E\uDF50-\uDF55\uDF70-\uDF88\uDF8A-\uDF8F\uDFAA-\uDFC2\uDFC4-\uDFC9\uDFCB]|\uD801[\uDC28-\uDC4F]'
|
||||
},
|
||||
{
|
||||
name: 'Lm',
|
||||
alias: 'Modifier_Letter',
|
||||
bmp: '\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5\u06E6\u07F4\u07F5\u07FA\u081A\u0824\u0828\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1AA7\u1C78-\u1C7D\u1D2C-\u1D6A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C\u2C7D\u2D6F\u2E2F\u3005\u3031-\u3035\u303B\u309D\u309E\u30FC-\u30FE\uA015\uA4F8-\uA4FD\uA60C\uA67F\uA717-\uA71F\uA770\uA788\uA7F8\uA7F9\uA9CF\uAA70\uAADD\uAAF3\uAAF4\uFF70\uFF9E\uFF9F',
|
||||
astral: '\uD81B[\uDF93-\uDF9F]'
|
||||
},
|
||||
{
|
||||
name: 'Lo',
|
||||
alias: 'Other_Letter',
|
||||
bmp: '\xAA\xBA\u01BB\u01C0-\u01C3\u0294\u05D0-\u05EA\u05F0-\u05F2\u0620-\u063F\u0641-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u0800-\u0815\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0972-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E45\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10D0-\u10FA\u10FD-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17DC\u1820-\u1842\u1844-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C77\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u2135-\u2138\u2D30-\u2D67\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3006\u303C\u3041-\u3096\u309F\u30A1-\u30FA\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA014\uA016-\uA48C\uA4D0-\uA4F7\uA500-\uA60B\uA610-\uA61F\uA62A\uA62B\uA66E\uA6A0-\uA6E5\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA6F\uAA71-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB\uAADC\uAAE0-\uAAEA\uAAF2\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF66-\uFF6F\uFF71-\uFF9D\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC',
|
||||
astral: '\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1E\uDF30-\uDF40\uDF42-\uDF49\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD81A[\uDC00-\uDE38]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD83-\uDDB2\uDDC1-\uDDC4]|\uD86E[\uDC00-\uDC1D]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD803[\uDC00-\uDC48]|\uD80D[\uDC00-\uDC2E]|\uD805[\uDE80-\uDEAA]|\uD87E[\uDC00-\uDE1D]|\uD81B[\uDF00-\uDF44\uDF50]|\uD801[\uDC50-\uDC9D]|\uD82C[\uDC00\uDC01]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD808[\uDC00-\uDF6E]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]'
|
||||
},
|
||||
{
|
||||
name: 'Lt',
|
||||
alias: 'Titlecase_Letter',
|
||||
bmp: '\u01C5\u01C8\u01CB\u01F2\u1F88-\u1F8F\u1F98-\u1F9F\u1FA8-\u1FAF\u1FBC\u1FCC\u1FFC'
|
||||
},
|
||||
{
|
||||
name: 'Lu',
|
||||
alias: 'Uppercase_Letter',
|
||||
bmp: 'A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA\uFF21-\uFF3A',
|
||||
astral: '\uD835[\uDC00-\uDC19\uDC34-\uDC4D\uDC68-\uDC81\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB5\uDCD0-\uDCE9\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD38\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD6C-\uDD85\uDDA0-\uDDB9\uDDD4-\uDDED\uDE08-\uDE21\uDE3C-\uDE55\uDE70-\uDE89\uDEA8-\uDEC0\uDEE2-\uDEFA\uDF1C-\uDF34\uDF56-\uDF6E\uDF90-\uDFA8\uDFCA]|\uD801[\uDC00-\uDC27]'
|
||||
},
|
||||
{
|
||||
name: 'M',
|
||||
alias: 'Mark',
|
||||
bmp: '\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u08FE\u0900-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C82\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D02\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1DC0-\u1DE6\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE26',
|
||||
astral: '\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC80-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD80-\uDD82\uDDB3-\uDDC0]|\uD805[\uDEAB-\uDEB7]|\uD800\uDDFD|\uDB40[\uDD00-\uDDEF]'
|
||||
},
|
||||
{
|
||||
name: 'Mc',
|
||||
alias: 'Spacing_Mark',
|
||||
bmp: '\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E\u094F\u0982\u0983\u09BE-\u09C0\u09C7\u09C8\u09CB\u09CC\u09D7\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB\u0ACC\u0B02\u0B03\u0B3E\u0B40\u0B47\u0B48\u0B4B\u0B4C\u0B57\u0BBE\u0BBF\u0BC1\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD7\u0C01-\u0C03\u0C41-\u0C44\u0C82\u0C83\u0CBE\u0CC0-\u0CC4\u0CC7\u0CC8\u0CCA\u0CCB\u0CD5\u0CD6\u0D02\u0D03\u0D3E-\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D57\u0D82\u0D83\u0DCF-\u0DD1\u0DD8-\u0DDF\u0DF2\u0DF3\u0F3E\u0F3F\u0F7F\u102B\u102C\u1031\u1038\u103B\u103C\u1056\u1057\u1062-\u1064\u1067-\u106D\u1083\u1084\u1087-\u108C\u108F\u109A-\u109C\u17B6\u17BE-\u17C5\u17C7\u17C8\u1923-\u1926\u1929-\u192B\u1930\u1931\u1933-\u1938\u19B0-\u19C0\u19C8\u19C9\u1A19-\u1A1B\u1A55\u1A57\u1A61\u1A63\u1A64\u1A6D-\u1A72\u1B04\u1B35\u1B3B\u1B3D-\u1B41\u1B43\u1B44\u1B82\u1BA1\u1BA6\u1BA7\u1BAA\u1BAC\u1BAD\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2\u1BF3\u1C24-\u1C2B\u1C34\u1C35\u1CE1\u1CF2\u1CF3\u302E\u302F\uA823\uA824\uA827\uA880\uA881\uA8B4-\uA8C3\uA952\uA953\uA983\uA9B4\uA9B5\uA9BA\uA9BB\uA9BD-\uA9C0\uAA2F\uAA30\uAA33\uAA34\uAA4D\uAA7B\uAAEB\uAAEE\uAAEF\uAAF5\uABE3\uABE4\uABE6\uABE7\uABE9\uABEA\uABEC',
|
||||
astral: '\uD834[\uDD65\uDD66\uDD6D-\uDD72]|\uD804[\uDC00\uDC02\uDC82\uDCB0-\uDCB2\uDCB7\uDCB8\uDD2C\uDD82\uDDB3-\uDDB5\uDDBF\uDDC0]|\uD805[\uDEAC\uDEAE\uDEAF\uDEB6]|\uD81B[\uDF51-\uDF7E]'
|
||||
},
|
||||
{
|
||||
name: 'Me',
|
||||
alias: 'Enclosing_Mark',
|
||||
bmp: '\u0488\u0489\u20DD-\u20E0\u20E2-\u20E4\uA670-\uA672'
|
||||
},
|
||||
{
|
||||
name: 'Mn',
|
||||
alias: 'Nonspacing_Mark',
|
||||
bmp: '\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u08FE\u0900-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2\u09E3\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B62\u0B63\u0B82\u0BC0\u0BCD\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0CBC\u0CBF\u0CC6\u0CCC\u0CCD\u0CE2\u0CE3\u0D41-\u0D44\u0D4D\u0D62\u0D63\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1A17\u1A18\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1DC0-\u1DE6\u1DFC-\u1DFF\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302D\u3099\u309A\uA66F\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA825\uA826\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE26',
|
||||
astral: '\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F]|\uD834[\uDD67-\uDD69\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD81B[\uDF8F-\uDF92]|\uD805[\uDEAB\uDEAD\uDEB0-\uDEB5\uDEB7]|\uD804[\uDC01\uDC38-\uDC46\uDC80\uDC81\uDCB3-\uDCB6\uDCB9\uDCBA\uDD00-\uDD02\uDD27-\uDD2B\uDD2D-\uDD34\uDD80\uDD81\uDDB6-\uDDBE]|\uD800\uDDFD|\uDB40[\uDD00-\uDDEF]'
|
||||
},
|
||||
{
|
||||
name: 'N',
|
||||
alias: 'Number',
|
||||
bmp: '0-9\xB2\xB3\xB9\xBC-\xBE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19',
|
||||
astral: '\uD802[\uDC58-\uDC5F\uDD16-\uDD1B\uDE40-\uDE47\uDE7D\uDE7E\uDF58-\uDF5F\uDF78-\uDF7F]|\uD801[\uDCA0-\uDCA9]|\uD809[\uDC00-\uDC62]|\uD835[\uDFCE-\uDFFF]|\uD800[\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDF20-\uDF23\uDF41\uDF4A\uDFD1-\uDFD5]|\uD834[\uDF60-\uDF71]|\uD803[\uDE60-\uDE7E]|\uD83C[\uDD00-\uDD0A]|\uD805[\uDEC0-\uDEC9]|\uD804[\uDC52-\uDC6F\uDCF0-\uDCF9\uDD36-\uDD3F\uDDD0-\uDDD9]'
|
||||
},
|
||||
{
|
||||
name: 'Nd',
|
||||
alias: 'Decimal_Number',
|
||||
bmp: '0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19',
|
||||
astral: '\uD804[\uDC66-\uDC6F\uDCF0-\uDCF9\uDD36-\uDD3F\uDDD0-\uDDD9]|\uD805[\uDEC0-\uDEC9]|\uD801[\uDCA0-\uDCA9]|\uD835[\uDFCE-\uDFFF]'
|
||||
},
|
||||
{
|
||||
name: 'Nl',
|
||||
alias: 'Letter_Number',
|
||||
bmp: '\u16EE-\u16F0\u2160-\u2182\u2185-\u2188\u3007\u3021-\u3029\u3038-\u303A\uA6E6-\uA6EF',
|
||||
astral: '\uD800[\uDD40-\uDD74\uDF41\uDF4A\uDFD1-\uDFD5]|\uD809[\uDC00-\uDC62]'
|
||||
},
|
||||
{
|
||||
name: 'No',
|
||||
alias: 'Other_Number',
|
||||
bmp: '\xB2\xB3\xB9\xBC-\xBE\u09F4-\u09F9\u0B72-\u0B77\u0BF0-\u0BF2\u0C78-\u0C7E\u0D70-\u0D75\u0F2A-\u0F33\u1369-\u137C\u17F0-\u17F9\u19DA\u2070\u2074-\u2079\u2080-\u2089\u2150-\u215F\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA830-\uA835',
|
||||
astral: '\uD802[\uDC58-\uDC5F\uDD16-\uDD1B\uDE40-\uDE47\uDE7D\uDE7E\uDF58-\uDF5F\uDF78-\uDF7F]|\uD834[\uDF60-\uDF71]|\uD803[\uDE60-\uDE7E]|\uD800[\uDD07-\uDD33\uDD75-\uDD78\uDD8A\uDF20-\uDF23]|\uD83C[\uDD00-\uDD0A]|\uD804[\uDC52-\uDC65]'
|
||||
},
|
||||
{
|
||||
name: 'P',
|
||||
alias: 'Punctuation',
|
||||
bmp: '\x21-\x23\x25-\\x2A\x2C-\x2F\x3A\x3B\\x3F\x40\\x5B-\\x5D\x5F\\x7B\x7D\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E3B\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65',
|
||||
astral: '\uD809[\uDC70-\uDC73]|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDF39-\uDF3F]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDDC5-\uDDC8]'
|
||||
},
|
||||
{
|
||||
name: 'Pc',
|
||||
alias: 'Connector_Punctuation',
|
||||
bmp: '\x5F\u203F\u2040\u2054\uFE33\uFE34\uFE4D-\uFE4F\uFF3F'
|
||||
},
|
||||
{
|
||||
name: 'Pd',
|
||||
alias: 'Dash_Punctuation',
|
||||
bmp: '\\x2D\u058A\u05BE\u1400\u1806\u2010-\u2015\u2E17\u2E1A\u2E3A\u2E3B\u301C\u3030\u30A0\uFE31\uFE32\uFE58\uFE63\uFF0D'
|
||||
},
|
||||
{
|
||||
name: 'Pe',
|
||||
alias: 'Close_Punctuation',
|
||||
bmp: '\\x29\\x5D\x7D\u0F3B\u0F3D\u169C\u2046\u207E\u208E\u232A\u2769\u276B\u276D\u276F\u2771\u2773\u2775\u27C6\u27E7\u27E9\u27EB\u27ED\u27EF\u2984\u2986\u2988\u298A\u298C\u298E\u2990\u2992\u2994\u2996\u2998\u29D9\u29DB\u29FD\u2E23\u2E25\u2E27\u2E29\u3009\u300B\u300D\u300F\u3011\u3015\u3017\u3019\u301B\u301E\u301F\uFD3F\uFE18\uFE36\uFE38\uFE3A\uFE3C\uFE3E\uFE40\uFE42\uFE44\uFE48\uFE5A\uFE5C\uFE5E\uFF09\uFF3D\uFF5D\uFF60\uFF63'
|
||||
},
|
||||
{
|
||||
name: 'Pf',
|
||||
alias: 'Final_Punctuation',
|
||||
bmp: '\xBB\u2019\u201D\u203A\u2E03\u2E05\u2E0A\u2E0D\u2E1D\u2E21'
|
||||
},
|
||||
{
|
||||
name: 'Pi',
|
||||
alias: 'Initial_Punctuation',
|
||||
bmp: '\xAB\u2018\u201B\u201C\u201F\u2039\u2E02\u2E04\u2E09\u2E0C\u2E1C\u2E20'
|
||||
},
|
||||
{
|
||||
name: 'Po',
|
||||
alias: 'Other_Punctuation',
|
||||
bmp: '\x21-\x23\x25-\x27\\x2A\x2C\\x2E\x2F\x3A\x3B\\x3F\x40\\x5C\xA1\xA7\xB6\xB7\xBF\u037E\u0387\u055A-\u055F\u0589\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u166D\u166E\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u1805\u1807-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2016\u2017\u2020-\u2027\u2030-\u2038\u203B-\u203E\u2041-\u2043\u2047-\u2051\u2053\u2055-\u205E\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00\u2E01\u2E06-\u2E08\u2E0B\u2E0E-\u2E16\u2E18\u2E19\u2E1B\u2E1E\u2E1F\u2E2A-\u2E2E\u2E30-\u2E39\u3001-\u3003\u303D\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFE10-\uFE16\uFE19\uFE30\uFE45\uFE46\uFE49-\uFE4C\uFE50-\uFE52\uFE54-\uFE57\uFE5F-\uFE61\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF07\uFF0A\uFF0C\uFF0E\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3C\uFF61\uFF64\uFF65',
|
||||
astral: '\uD809[\uDC70-\uDC73]|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDF39-\uDF3F]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDDC5-\uDDC8]'
|
||||
},
|
||||
{
|
||||
name: 'Ps',
|
||||
alias: 'Open_Punctuation',
|
||||
bmp: '\\x28\\x5B\\x7B\u0F3A\u0F3C\u169B\u201A\u201E\u2045\u207D\u208D\u2329\u2768\u276A\u276C\u276E\u2770\u2772\u2774\u27C5\u27E6\u27E8\u27EA\u27EC\u27EE\u2983\u2985\u2987\u2989\u298B\u298D\u298F\u2991\u2993\u2995\u2997\u29D8\u29DA\u29FC\u2E22\u2E24\u2E26\u2E28\u3008\u300A\u300C\u300E\u3010\u3014\u3016\u3018\u301A\u301D\uFD3E\uFE17\uFE35\uFE37\uFE39\uFE3B\uFE3D\uFE3F\uFE41\uFE43\uFE47\uFE59\uFE5B\uFE5D\uFF08\uFF3B\uFF5B\uFF5F\uFF62'
|
||||
},
|
||||
{
|
||||
name: 'S',
|
||||
alias: 'Symbol',
|
||||
bmp: '\\x24\\x2B\x3C-\x3E\\x5E\x60\\x7C\x7E\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20BA\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u2190-\u2328\u232B-\u23F3\u2400-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u26FF\u2701-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B4C\u2B50-\u2B59\u2CE5-\u2CEA\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u32FE\u3300-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uFB29\uFBB2-\uFBC1\uFDFC\uFDFD\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD',
|
||||
astral: '\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCF7\uDCF9-\uDCFC\uDD00-\uDD3D\uDD40-\uDD43\uDD50-\uDD67\uDDFB-\uDE40\uDE45-\uDE4F\uDE80-\uDEC5\uDF00-\uDF73]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBE\uDCC1-\uDCCF\uDCD1-\uDCDF\uDD10-\uDD2E\uDD30-\uDD6B\uDD70-\uDD9A\uDDE6-\uDE02\uDE10-\uDE3A\uDE40-\uDE48\uDE50\uDE51\uDF00-\uDF20\uDF30-\uDF35\uDF37-\uDF7C\uDF80-\uDF93\uDFA0-\uDFC4\uDFC6-\uDFCA\uDFE0-\uDFF0]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDDD\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD90-\uDD9B\uDDD0-\uDDFC]|\uD83B[\uDEF0\uDEF1]'
|
||||
},
|
||||
{
|
||||
name: 'Sc',
|
||||
alias: 'Currency_Symbol',
|
||||
bmp: '\\x24\xA2-\xA5\u058F\u060B\u09F2\u09F3\u09FB\u0AF1\u0BF9\u0E3F\u17DB\u20A0-\u20BA\uA838\uFDFC\uFE69\uFF04\uFFE0\uFFE1\uFFE5\uFFE6'
|
||||
},
|
||||
{
|
||||
name: 'Sk',
|
||||
alias: 'Modifier_Symbol',
|
||||
bmp: '\\x5E\x60\xA8\xAF\xB4\xB8\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u309B\u309C\uA700-\uA716\uA720\uA721\uA789\uA78A\uFBB2-\uFBC1\uFF3E\uFF40\uFFE3'
|
||||
},
|
||||
{
|
||||
name: 'Sm',
|
||||
alias: 'Math_Symbol',
|
||||
bmp: '\\x2B\x3C-\x3E\\x7C\x7E\xAC\xB1\xD7\xF7\u03F6\u0606-\u0608\u2044\u2052\u207A-\u207C\u208A-\u208C\u2118\u2140-\u2144\u214B\u2190-\u2194\u219A\u219B\u21A0\u21A3\u21A6\u21AE\u21CE\u21CF\u21D2\u21D4\u21F4-\u22FF\u2308-\u230B\u2320\u2321\u237C\u239B-\u23B3\u23DC-\u23E1\u25B7\u25C1\u25F8-\u25FF\u266F\u27C0-\u27C4\u27C7-\u27E5\u27F0-\u27FF\u2900-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2AFF\u2B30-\u2B44\u2B47-\u2B4C\uFB29\uFE62\uFE64-\uFE66\uFF0B\uFF1C-\uFF1E\uFF5C\uFF5E\uFFE2\uFFE9-\uFFEC',
|
||||
astral: '\uD83B[\uDEF0\uDEF1]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]'
|
||||
},
|
||||
{
|
||||
name: 'So',
|
||||
alias: 'Other_Symbol',
|
||||
bmp: '\xA6\xA9\xAE\xB0\u0482\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u09FA\u0B70\u0BF3-\u0BF8\u0BFA\u0C7F\u0D79\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116\u2117\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u214A\u214C\u214D\u214F\u2195-\u2199\u219C-\u219F\u21A1\u21A2\u21A4\u21A5\u21A7-\u21AD\u21AF-\u21CD\u21D0\u21D1\u21D3\u21D5-\u21F3\u2300-\u2307\u230C-\u231F\u2322-\u2328\u232B-\u237B\u237D-\u239A\u23B4-\u23DB\u23E2-\u23F3\u2400-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u25B6\u25B8-\u25C0\u25C2-\u25F7\u2600-\u266E\u2670-\u26FF\u2701-\u2767\u2794-\u27BF\u2800-\u28FF\u2B00-\u2B2F\u2B45\u2B46\u2B50-\u2B59\u2CE5-\u2CEA\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u32FE\u3300-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA828-\uA82B\uA836\uA837\uA839\uAA77-\uAA79\uFDFD\uFFE4\uFFE8\uFFED\uFFEE\uFFFC\uFFFD',
|
||||
astral: '\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCF7\uDCF9-\uDCFC\uDD00-\uDD3D\uDD40-\uDD43\uDD50-\uDD67\uDDFB-\uDE40\uDE45-\uDE4F\uDE80-\uDEC5\uDF00-\uDF73]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDDD\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBE\uDCC1-\uDCCF\uDCD1-\uDCDF\uDD10-\uDD2E\uDD30-\uDD6B\uDD70-\uDD9A\uDDE6-\uDE02\uDE10-\uDE3A\uDE40-\uDE48\uDE50\uDE51\uDF00-\uDF20\uDF30-\uDF35\uDF37-\uDF7C\uDF80-\uDF93\uDFA0-\uDFC4\uDFC6-\uDFCA\uDFE0-\uDFF0]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD90-\uDD9B\uDDD0-\uDDFC]'
|
||||
},
|
||||
{
|
||||
name: 'Z',
|
||||
alias: 'Separator',
|
||||
bmp: '\x20\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000'
|
||||
},
|
||||
{
|
||||
name: 'Zl',
|
||||
alias: 'Line_Separator',
|
||||
bmp: '\u2028'
|
||||
},
|
||||
{
|
||||
name: 'Zp',
|
||||
alias: 'Paragraph_Separator',
|
||||
bmp: '\u2029'
|
||||
},
|
||||
{
|
||||
name: 'Zs',
|
||||
alias: 'Space_Separator',
|
||||
bmp: '\x20\xA0\u1680\u180E\u2000-\u200A\u202F\u205F\u3000'
|
||||
}
|
||||
]);
|
||||
|
||||
}(XRegExp));
|
||||
69
public/vendor/xregexp/unicode/unicode-properties.js
vendored
Normal file
69
public/vendor/xregexp/unicode/unicode-properties.js
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*!
|
||||
* XRegExp Unicode Properties 3.0.0-pre
|
||||
* <http://xregexp.com/>
|
||||
* Steven Levithan <20> 2012 MIT License
|
||||
* Uses Unicode 6.2.0 <http://unicode.org/>
|
||||
* Unicode data generated by Mathias Bynens <http://mathiasbynens.be/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds Level 1 Unicode properties (detailed in UTS #18 RL1.2). Token names are case insensitive,
|
||||
* and any spaces, hyphens, and underscores are ignored.
|
||||
* @requires XRegExp, Unicode Base
|
||||
*/
|
||||
(function(XRegExp) {
|
||||
'use strict';
|
||||
|
||||
if (!XRegExp.addUnicodeData) {
|
||||
throw new ReferenceError('Unicode Base must be loaded before Unicode Properties');
|
||||
}
|
||||
|
||||
XRegExp.addUnicodeData([
|
||||
{
|
||||
name: 'ASCII',
|
||||
bmp: '\0-\x7F'
|
||||
},
|
||||
{
|
||||
name: 'Alphabetic',
|
||||
bmp: 'A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0345\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05B0-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0657\u0659-\u065F\u066E-\u06D3\u06D5-\u06DC\u06E1-\u06E8\u06ED-\u06EF\u06FA-\u06FC\u06FF\u0710-\u073F\u074D-\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0817\u081A-\u082C\u0840-\u0858\u08A0\u08A2-\u08AC\u08E4-\u08E9\u08F0-\u08FE\u0900-\u093B\u093D-\u094C\u094E-\u0950\u0955-\u0963\u0971-\u0977\u0979-\u097F\u0981-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD-\u09C4\u09C7\u09C8\u09CB\u09CC\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09F0\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3E-\u0A42\u0A47\u0A48\u0A4B\u0A4C\u0A51\u0A59-\u0A5C\u0A5E\u0A70-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD-\u0AC5\u0AC7-\u0AC9\u0ACB\u0ACC\u0AD0\u0AE0-\u0AE3\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D-\u0B44\u0B47\u0B48\u0B4B\u0B4C\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD0\u0BD7\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4C\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C82\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCC\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CF1\u0CF2\u0D02\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4C\u0D4E\u0D57\u0D60-\u0D63\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E46\u0E4D\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0ECD\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F71-\u0F81\u0F88-\u0F97\u0F99-\u0FBC\u1000-\u1036\u1038\u103B-\u103F\u1050-\u1062\u1065-\u1068\u106E-\u1086\u108E\u109C\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1713\u1720-\u1733\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17B3\u17B6-\u17C8\u17D7\u17DC\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191C\u1920-\u192B\u1930-\u1938\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A1B\u1A20-\u1A5E\u1A61-\u1A74\u1AA7\u1B00-\u1B33\u1B35-\u1B43\u1B45-\u1B4B\u1B80-\u1BA9\u1BAC-\u1BAF\u1BBA-\u1BE5\u1BE7-\u1BF1\u1C00-\u1C35\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u24B6-\u24E9\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA674-\uA67B\uA67F-\uA697\uA69F-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA827\uA840-\uA873\uA880-\uA8C3\uA8F2-\uA8F7\uA8FB\uA90A-\uA92A\uA930-\uA952\uA960-\uA97C\uA980-\uA9B2\uA9B4-\uA9BF\uA9CF\uAA00-\uAA36\uAA40-\uAA4D\uAA60-\uAA76\uAA7A\uAA80-\uAABE\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF5\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABEA\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC',
|
||||
astral: '\uD803[\uDC00-\uDC48]|\uD801[\uDC00-\uDC9D]|\uD809[\uDC00-\uDC62]|\uD81A[\uDC00-\uDE38]|\uD804[\uDC00-\uDC45\uDC82-\uDCB8\uDCD0-\uDCE8\uDD00-\uDD32\uDD80-\uDDBF\uDDC1-\uDDC4]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD87E[\uDC00-\uDE1D]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1E\uDF30-\uDF4A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF93-\uDF9F]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD82C[\uDC00\uDC01]|\uD808[\uDC00-\uDF6E]|\uD805[\uDE80-\uDEB5]'
|
||||
},
|
||||
// Assert: In BMP-only mode, `[\P{Any}]` (inverted Any within a character class) compiles to `[]`
|
||||
{
|
||||
name: 'Any',
|
||||
isBmpLast: true,
|
||||
bmp: '\0-\uFFFF',
|
||||
astral: '[\uD800-\uDBFF][\uDC00-\uDFFF]'
|
||||
},
|
||||
// Defined as the inverse of Unicode category Cn (Unassigned)
|
||||
{
|
||||
name: 'Assigned',
|
||||
inverseOf: 'Cn'
|
||||
},
|
||||
{
|
||||
name: 'Default_Ignorable_Code_Point',
|
||||
bmp: '\xAD\u034F\u115F\u1160\u17B4\u17B5\u180B-\u180D\u200B-\u200F\u202A-\u202E\u2060-\u206F\u3164\uFE00-\uFE0F\uFEFF\uFFA0\uFFF0-\uFFF8',
|
||||
astral: '[\uDB40-\uDB43][\uDC00-\uDFFF]|\uD834[\uDD73-\uDD7A]'
|
||||
},
|
||||
{
|
||||
name: 'Lowercase',
|
||||
bmp: 'a-z\xAA\xB5\xBA\xDF-\xF6\xF8-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02B8\u02C0\u02C1\u02E0-\u02E4\u0345\u0371\u0373\u0377\u037A-\u037D\u0390\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0561-\u0587\u1D00-\u1DBF\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6\u1FC7\u1FD0-\u1FD3\u1FD6\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6\u1FF7\u2071\u207F\u2090-\u209C\u210A\u210E\u210F\u2113\u212F\u2134\u2139\u213C\u213D\u2146-\u2149\u214E\u2170-\u217F\u2184\u24D0-\u24E9\u2C30-\u2C5E\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7D\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7F8-\uA7FA\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A',
|
||||
astral: '\uD835[\uDC1A-\uDC33\uDC4E-\uDC54\uDC56-\uDC67\uDC82-\uDC9B\uDCB6-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDCEA-\uDD03\uDD1E-\uDD37\uDD52-\uDD6B\uDD86-\uDD9F\uDDBA-\uDDD3\uDDEE-\uDE07\uDE22-\uDE3B\uDE56-\uDE6F\uDE8A-\uDEA5\uDEC2-\uDEDA\uDEDC-\uDEE1\uDEFC-\uDF14\uDF16-\uDF1B\uDF36-\uDF4E\uDF50-\uDF55\uDF70-\uDF88\uDF8A-\uDF8F\uDFAA-\uDFC2\uDFC4-\uDFC9\uDFCB]|\uD801[\uDC28-\uDC4F]'
|
||||
},
|
||||
{
|
||||
name: 'Noncharacter_Code_Point',
|
||||
bmp: '\uFDD0-\uFDEF\uFFFE\uFFFF',
|
||||
astral: '[\uDB3F\uDB7F\uDBBF\uDBFF\uD83F\uD87F\uD8BF\uDAFF\uD97F\uD9BF\uD9FF\uDA3F\uD8FF\uDABF\uDA7F\uD93F][\uDFFE\uDFFF]'
|
||||
},
|
||||
{
|
||||
name: 'Uppercase',
|
||||
bmp: 'A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2160-\u216F\u2183\u24B6-\u24CF\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA\uFF21-\uFF3A',
|
||||
astral: '\uD835[\uDC00-\uDC19\uDC34-\uDC4D\uDC68-\uDC81\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB5\uDCD0-\uDCE9\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD38\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD6C-\uDD85\uDDA0-\uDDB9\uDDD4-\uDDED\uDE08-\uDE21\uDE3C-\uDE55\uDE70-\uDE89\uDEA8-\uDEC0\uDEE2-\uDEFA\uDF1C-\uDF34\uDF56-\uDF6E\uDF90-\uDFA8\uDFCA]|\uD801[\uDC00-\uDC27]'
|
||||
},
|
||||
{
|
||||
name: 'White_Space',
|
||||
bmp: '\x09-\x0D\x20\x85\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000'
|
||||
}
|
||||
]);
|
||||
|
||||
}(XRegExp));
|
||||
440
public/vendor/xregexp/unicode/unicode-scripts.js
vendored
Normal file
440
public/vendor/xregexp/unicode/unicode-scripts.js
vendored
Normal file
@@ -0,0 +1,440 @@
|
||||
/*!
|
||||
* XRegExp Unicode Scripts 3.0.0-pre
|
||||
* <http://xregexp.com/>
|
||||
* Steven Levithan <20> 2010-2012 MIT License
|
||||
* Uses Unicode 6.2.0 <http://unicode.org/>
|
||||
* Unicode data generated by Mathias Bynens <http://mathiasbynens.be/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds support for all Unicode scripts. E.g., `\p{Latin}`. Token names are case insensitive, and
|
||||
* any spaces, hyphens, and underscores are ignored.
|
||||
* @requires XRegExp, Unicode Base
|
||||
*/
|
||||
(function(XRegExp) {
|
||||
'use strict';
|
||||
|
||||
if (!XRegExp.addUnicodeData) {
|
||||
throw new ReferenceError('Unicode Base must be loaded before Unicode Scripts');
|
||||
}
|
||||
|
||||
XRegExp.addUnicodeData([
|
||||
{
|
||||
name: 'Arabic',
|
||||
bmp: '\u0600-\u0604\u0606-\u060B\u060D-\u061A\u061E\u0620-\u063F\u0641-\u064A\u0656-\u065F\u066A-\u066F\u0671-\u06DC\u06DE-\u06FF\u0750-\u077F\u08A0\u08A2-\u08AC\u08E4-\u08FE\uFB50-\uFBC1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFC\uFE70-\uFE74\uFE76-\uFEFC',
|
||||
astral: '\uD803[\uDE60-\uDE7E]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB\uDEF0\uDEF1]'
|
||||
},
|
||||
{
|
||||
name: 'Armenian',
|
||||
bmp: '\u0531-\u0556\u0559-\u055F\u0561-\u0587\u058A\u058F\uFB13-\uFB17'
|
||||
},
|
||||
{
|
||||
name: 'Avestan',
|
||||
astral: '\uD802[\uDF00-\uDF35\uDF39-\uDF3F]'
|
||||
},
|
||||
{
|
||||
name: 'Balinese',
|
||||
bmp: '\u1B00-\u1B4B\u1B50-\u1B7C'
|
||||
},
|
||||
{
|
||||
name: 'Bamum',
|
||||
bmp: '\uA6A0-\uA6F7',
|
||||
astral: '\uD81A[\uDC00-\uDE38]'
|
||||
},
|
||||
{
|
||||
name: 'Batak',
|
||||
bmp: '\u1BC0-\u1BF3\u1BFC-\u1BFF'
|
||||
},
|
||||
{
|
||||
name: 'Bengali',
|
||||
bmp: '\u0981-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09FB'
|
||||
},
|
||||
{
|
||||
name: 'Bopomofo',
|
||||
bmp: '\u02EA\u02EB\u3105-\u312D\u31A0-\u31BA'
|
||||
},
|
||||
{
|
||||
name: 'Brahmi',
|
||||
astral: '\uD804[\uDC00-\uDC4D\uDC52-\uDC6F]'
|
||||
},
|
||||
{
|
||||
name: 'Braille',
|
||||
bmp: '\u2800-\u28FF'
|
||||
},
|
||||
{
|
||||
name: 'Buginese',
|
||||
bmp: '\u1A00-\u1A1B\u1A1E\u1A1F'
|
||||
},
|
||||
{
|
||||
name: 'Buhid',
|
||||
bmp: '\u1740-\u1753'
|
||||
},
|
||||
{
|
||||
name: 'Canadian_Aboriginal',
|
||||
bmp: '\u1400-\u167F\u18B0-\u18F5'
|
||||
},
|
||||
{
|
||||
name: 'Carian',
|
||||
astral: '\uD800[\uDEA0-\uDED0]'
|
||||
},
|
||||
{
|
||||
name: 'Chakma',
|
||||
astral: '\uD804[\uDD00-\uDD34\uDD36-\uDD43]'
|
||||
},
|
||||
{
|
||||
name: 'Cham',
|
||||
bmp: '\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA5C-\uAA5F'
|
||||
},
|
||||
{
|
||||
name: 'Cherokee',
|
||||
bmp: '\u13A0-\u13F4'
|
||||
},
|
||||
{
|
||||
name: 'Common',
|
||||
bmp: '\0-\x40\\x5B-\x60\\x7B-\xA9\xAB-\xB9\xBB-\xBF\xD7\xF7\u02B9-\u02DF\u02E5-\u02E9\u02EC-\u02FF\u0374\u037E\u0385\u0387\u0589\u060C\u061B\u061F\u0640\u0660-\u0669\u06DD\u0964\u0965\u0E3F\u0FD5-\u0FD8\u10FB\u16EB-\u16ED\u1735\u1736\u1802\u1803\u1805\u1CD3\u1CE1\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u2000-\u200B\u200E-\u2064\u206A-\u2070\u2074-\u207E\u2080-\u208E\u20A0-\u20BA\u2100-\u2125\u2127-\u2129\u212C-\u2131\u2133-\u214D\u214F-\u215F\u2189\u2190-\u23F3\u2400-\u2426\u2440-\u244A\u2460-\u26FF\u2701-\u27FF\u2900-\u2B4C\u2B50-\u2B59\u2E00-\u2E3B\u2FF0-\u2FFB\u3000-\u3004\u3006\u3008-\u3020\u3030-\u3037\u303C-\u303F\u309B\u309C\u30A0\u30FB\u30FC\u3190-\u319F\u31C0-\u31E3\u3220-\u325F\u327F-\u32CF\u3358-\u33FF\u4DC0-\u4DFF\uA700-\uA721\uA788-\uA78A\uA830-\uA839\uFD3E\uFD3F\uFDFD\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFEFF\uFF01-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65\uFF70\uFF9E\uFF9F\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFF9-\uFFFD',
|
||||
astral: '\uD800[\uDD00-\uDD02\uDD07-\uDD33\uDD37-\uDD3F\uDD90-\uDD9B\uDDD0-\uDDFC]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBE\uDCC1-\uDCCF\uDCD1-\uDCDF\uDD00-\uDD0A\uDD10-\uDD2E\uDD30-\uDD6B\uDD70-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE10-\uDE3A\uDE40-\uDE48\uDE50\uDE51\uDF00-\uDF20\uDF30-\uDF35\uDF37-\uDF7C\uDF80-\uDF93\uDFA0-\uDFC4\uDFC6-\uDFCA\uDFE0-\uDFF0]|\uDB40[\uDC01\uDC20-\uDC7F]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDFCB\uDFCE-\uDFFF]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD66\uDD6A-\uDD7A\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDDD\uDF00-\uDF56\uDF60-\uDF71]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCF7\uDCF9-\uDCFC\uDD00-\uDD3D\uDD40-\uDD43\uDD50-\uDD67\uDDFB-\uDE40\uDE45-\uDE4F\uDE80-\uDEC5\uDF00-\uDF73]'
|
||||
},
|
||||
{
|
||||
name: 'Coptic',
|
||||
bmp: '\u03E2-\u03EF\u2C80-\u2CF3\u2CF9-\u2CFF'
|
||||
},
|
||||
{
|
||||
name: 'Cuneiform',
|
||||
astral: '\uD809[\uDC00-\uDC62\uDC70-\uDC73]|\uD808[\uDC00-\uDF6E]'
|
||||
},
|
||||
{
|
||||
name: 'Cypriot',
|
||||
astral: '\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F]'
|
||||
},
|
||||
{
|
||||
name: 'Cyrillic',
|
||||
bmp: '\u0400-\u0484\u0487-\u0527\u1D2B\u1D78\u2DE0-\u2DFF\uA640-\uA697\uA69F'
|
||||
},
|
||||
{
|
||||
name: 'Deseret',
|
||||
astral: '\uD801[\uDC00-\uDC4F]'
|
||||
},
|
||||
{
|
||||
name: 'Devanagari',
|
||||
bmp: '\u0900-\u0950\u0953-\u0963\u0966-\u0977\u0979-\u097F\uA8E0-\uA8FB'
|
||||
},
|
||||
{
|
||||
name: 'Egyptian_Hieroglyphs',
|
||||
astral: '\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]'
|
||||
},
|
||||
{
|
||||
name: 'Ethiopic',
|
||||
bmp: '\u1200-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u137C\u1380-\u1399\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E'
|
||||
},
|
||||
{
|
||||
name: 'Georgian',
|
||||
bmp: '\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u10FF\u2D00-\u2D25\u2D27\u2D2D'
|
||||
},
|
||||
{
|
||||
name: 'Glagolitic',
|
||||
bmp: '\u2C00-\u2C2E\u2C30-\u2C5E'
|
||||
},
|
||||
{
|
||||
name: 'Gothic',
|
||||
astral: '\uD800[\uDF30-\uDF4A]'
|
||||
},
|
||||
{
|
||||
name: 'Greek',
|
||||
bmp: '\u0370-\u0373\u0375-\u0377\u037A-\u037D\u0384\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03E1\u03F0-\u03FF\u1D26-\u1D2A\u1D5D-\u1D61\u1D66-\u1D6A\u1DBF\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FC4\u1FC6-\u1FD3\u1FD6-\u1FDB\u1FDD-\u1FEF\u1FF2-\u1FF4\u1FF6-\u1FFE\u2126',
|
||||
astral: '\uD834[\uDE00-\uDE45]|\uD800[\uDD40-\uDD8A]'
|
||||
},
|
||||
{
|
||||
name: 'Gujarati',
|
||||
bmp: '\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AF1'
|
||||
},
|
||||
{
|
||||
name: 'Gurmukhi',
|
||||
bmp: '\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75'
|
||||
},
|
||||
{
|
||||
name: 'Han',
|
||||
bmp: '\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DB5\u4E00-\u9FCC\uF900-\uFA6D\uFA70-\uFAD9',
|
||||
astral: '[\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD87E[\uDC00-\uDE1D]'
|
||||
},
|
||||
{
|
||||
name: 'Hangul',
|
||||
bmp: '\u1100-\u11FF\u302E\u302F\u3131-\u318E\u3200-\u321E\u3260-\u327E\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC'
|
||||
},
|
||||
{
|
||||
name: 'Hanunoo',
|
||||
bmp: '\u1720-\u1734'
|
||||
},
|
||||
{
|
||||
name: 'Hebrew',
|
||||
bmp: '\u0591-\u05C7\u05D0-\u05EA\u05F0-\u05F4\uFB1D-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFB4F'
|
||||
},
|
||||
{
|
||||
name: 'Hiragana',
|
||||
bmp: '\u3041-\u3096\u309D-\u309F',
|
||||
astral: '\uD82C\uDC01|\uD83C\uDE00'
|
||||
},
|
||||
{
|
||||
name: 'Imperial_Aramaic',
|
||||
astral: '\uD802[\uDC40-\uDC55\uDC57-\uDC5F]'
|
||||
},
|
||||
{
|
||||
name: 'Inherited',
|
||||
bmp: '\u0300-\u036F\u0485\u0486\u064B-\u0655\u0670\u0951\u0952\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1DC0-\u1DE6\u1DFC-\u1DFF\u200C\u200D\u20D0-\u20F0\u302A-\u302D\u3099\u309A\uFE00-\uFE0F\uFE20-\uFE26',
|
||||
astral: '\uD834[\uDD67-\uDD69\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD]|\uD800\uDDFD|\uDB40[\uDD00-\uDDEF]'
|
||||
},
|
||||
{
|
||||
name: 'Inscriptional_Pahlavi',
|
||||
astral: '\uD802[\uDF60-\uDF72\uDF78-\uDF7F]'
|
||||
},
|
||||
{
|
||||
name: 'Inscriptional_Parthian',
|
||||
astral: '\uD802[\uDF40-\uDF55\uDF58-\uDF5F]'
|
||||
},
|
||||
{
|
||||
name: 'Javanese',
|
||||
bmp: '\uA980-\uA9CD\uA9CF-\uA9D9\uA9DE\uA9DF'
|
||||
},
|
||||
{
|
||||
name: 'Kaithi',
|
||||
astral: '\uD804[\uDC80-\uDCC1]'
|
||||
},
|
||||
{
|
||||
name: 'Kannada',
|
||||
bmp: '\u0C82\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2'
|
||||
},
|
||||
{
|
||||
name: 'Katakana',
|
||||
bmp: '\u30A1-\u30FA\u30FD-\u30FF\u31F0-\u31FF\u32D0-\u32FE\u3300-\u3357\uFF66-\uFF6F\uFF71-\uFF9D',
|
||||
astral: '\uD82C\uDC00'
|
||||
},
|
||||
{
|
||||
name: 'Kayah_Li',
|
||||
bmp: '\uA900-\uA92F'
|
||||
},
|
||||
{
|
||||
name: 'Kharoshthi',
|
||||
astral: '\uD802[\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F-\uDE47\uDE50-\uDE58]'
|
||||
},
|
||||
{
|
||||
name: 'Khmer',
|
||||
bmp: '\u1780-\u17DD\u17E0-\u17E9\u17F0-\u17F9\u19E0-\u19FF'
|
||||
},
|
||||
{
|
||||
name: 'Lao',
|
||||
bmp: '\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF'
|
||||
},
|
||||
{
|
||||
name: 'Latin',
|
||||
bmp: 'A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA7FF\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A'
|
||||
},
|
||||
{
|
||||
name: 'Lepcha',
|
||||
bmp: '\u1C00-\u1C37\u1C3B-\u1C49\u1C4D-\u1C4F'
|
||||
},
|
||||
{
|
||||
name: 'Limbu',
|
||||
bmp: '\u1900-\u191C\u1920-\u192B\u1930-\u193B\u1940\u1944-\u194F'
|
||||
},
|
||||
{
|
||||
name: 'Linear_B',
|
||||
astral: '\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA]'
|
||||
},
|
||||
{
|
||||
name: 'Lisu',
|
||||
bmp: '\uA4D0-\uA4FF'
|
||||
},
|
||||
{
|
||||
name: 'Lycian',
|
||||
astral: '\uD800[\uDE80-\uDE9C]'
|
||||
},
|
||||
{
|
||||
name: 'Lydian',
|
||||
astral: '\uD802[\uDD20-\uDD39\uDD3F]'
|
||||
},
|
||||
{
|
||||
name: 'Malayalam',
|
||||
bmp: '\u0D02\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D75\u0D79-\u0D7F'
|
||||
},
|
||||
{
|
||||
name: 'Mandaic',
|
||||
bmp: '\u0840-\u085B\u085E'
|
||||
},
|
||||
{
|
||||
name: 'Meetei_Mayek',
|
||||
bmp: '\uAAE0-\uAAF6\uABC0-\uABED\uABF0-\uABF9'
|
||||
},
|
||||
{
|
||||
name: 'Meroitic_Cursive',
|
||||
astral: '\uD802[\uDDA0-\uDDB7\uDDBE\uDDBF]'
|
||||
},
|
||||
{
|
||||
name: 'Meroitic_Hieroglyphs',
|
||||
astral: '\uD802[\uDD80-\uDD9F]'
|
||||
},
|
||||
{
|
||||
name: 'Miao',
|
||||
astral: '\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]'
|
||||
},
|
||||
{
|
||||
name: 'Mongolian',
|
||||
bmp: '\u1800\u1801\u1804\u1806-\u180E\u1810-\u1819\u1820-\u1877\u1880-\u18AA'
|
||||
},
|
||||
{
|
||||
name: 'Myanmar',
|
||||
bmp: '\u1000-\u109F\uAA60-\uAA7B'
|
||||
},
|
||||
{
|
||||
name: 'New_Tai_Lue',
|
||||
bmp: '\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u19DE\u19DF'
|
||||
},
|
||||
{
|
||||
name: 'Nko',
|
||||
bmp: '\u07C0-\u07FA'
|
||||
},
|
||||
{
|
||||
name: 'Ogham',
|
||||
bmp: '\u1680-\u169C'
|
||||
},
|
||||
{
|
||||
name: 'Ol_Chiki',
|
||||
bmp: '\u1C50-\u1C7F'
|
||||
},
|
||||
{
|
||||
name: 'Old_Italic',
|
||||
astral: '\uD800[\uDF00-\uDF1E\uDF20-\uDF23]'
|
||||
},
|
||||
{
|
||||
name: 'Old_Persian',
|
||||
astral: '\uD800[\uDFA0-\uDFC3\uDFC8-\uDFD5]'
|
||||
},
|
||||
{
|
||||
name: 'Old_South_Arabian',
|
||||
astral: '\uD802[\uDE60-\uDE7F]'
|
||||
},
|
||||
{
|
||||
name: 'Old_Turkic',
|
||||
astral: '\uD803[\uDC00-\uDC48]'
|
||||
},
|
||||
{
|
||||
name: 'Oriya',
|
||||
bmp: '\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B77'
|
||||
},
|
||||
{
|
||||
name: 'Osmanya',
|
||||
astral: '\uD801[\uDC80-\uDC9D\uDCA0-\uDCA9]'
|
||||
},
|
||||
{
|
||||
name: 'Phags_Pa',
|
||||
bmp: '\uA840-\uA877'
|
||||
},
|
||||
{
|
||||
name: 'Phoenician',
|
||||
astral: '\uD802[\uDD00-\uDD1B\uDD1F]'
|
||||
},
|
||||
{
|
||||
name: 'Rejang',
|
||||
bmp: '\uA930-\uA953\uA95F'
|
||||
},
|
||||
{
|
||||
name: 'Runic',
|
||||
bmp: '\u16A0-\u16EA\u16EE-\u16F0'
|
||||
},
|
||||
{
|
||||
name: 'Samaritan',
|
||||
bmp: '\u0800-\u082D\u0830-\u083E'
|
||||
},
|
||||
{
|
||||
name: 'Saurashtra',
|
||||
bmp: '\uA880-\uA8C4\uA8CE-\uA8D9'
|
||||
},
|
||||
{
|
||||
name: 'Sharada',
|
||||
astral: '\uD804[\uDD80-\uDDC8\uDDD0-\uDDD9]'
|
||||
},
|
||||
{
|
||||
name: 'Shavian',
|
||||
astral: '\uD801[\uDC50-\uDC7F]'
|
||||
},
|
||||
{
|
||||
name: 'Sinhala',
|
||||
bmp: '\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2-\u0DF4'
|
||||
},
|
||||
{
|
||||
name: 'Sora_Sompeng',
|
||||
astral: '\uD804[\uDCD0-\uDCE8\uDCF0-\uDCF9]'
|
||||
},
|
||||
{
|
||||
name: 'Sundanese',
|
||||
bmp: '\u1B80-\u1BBF\u1CC0-\u1CC7'
|
||||
},
|
||||
{
|
||||
name: 'Syloti_Nagri',
|
||||
bmp: '\uA800-\uA82B'
|
||||
},
|
||||
{
|
||||
name: 'Syriac',
|
||||
bmp: '\u0700-\u070D\u070F-\u074A\u074D-\u074F'
|
||||
},
|
||||
{
|
||||
name: 'Tagalog',
|
||||
bmp: '\u1700-\u170C\u170E-\u1714'
|
||||
},
|
||||
{
|
||||
name: 'Tagbanwa',
|
||||
bmp: '\u1760-\u176C\u176E-\u1770\u1772\u1773'
|
||||
},
|
||||
{
|
||||
name: 'Tai_Le',
|
||||
bmp: '\u1950-\u196D\u1970-\u1974'
|
||||
},
|
||||
{
|
||||
name: 'Tai_Tham',
|
||||
bmp: '\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA0-\u1AAD'
|
||||
},
|
||||
{
|
||||
name: 'Tai_Viet',
|
||||
bmp: '\uAA80-\uAAC2\uAADB-\uAADF'
|
||||
},
|
||||
{
|
||||
name: 'Takri',
|
||||
astral: '\uD805[\uDE80-\uDEB7\uDEC0-\uDEC9]'
|
||||
},
|
||||
{
|
||||
name: 'Tamil',
|
||||
bmp: '\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BFA'
|
||||
},
|
||||
{
|
||||
name: 'Telugu',
|
||||
bmp: '\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C78-\u0C7F'
|
||||
},
|
||||
{
|
||||
name: 'Thaana',
|
||||
bmp: '\u0780-\u07B1'
|
||||
},
|
||||
{
|
||||
name: 'Thai',
|
||||
bmp: '\u0E01-\u0E3A\u0E40-\u0E5B'
|
||||
},
|
||||
{
|
||||
name: 'Tibetan',
|
||||
bmp: '\u0F00-\u0F47\u0F49-\u0F6C\u0F71-\u0F97\u0F99-\u0FBC\u0FBE-\u0FCC\u0FCE-\u0FD4\u0FD9\u0FDA'
|
||||
},
|
||||
{
|
||||
name: 'Tifinagh',
|
||||
bmp: '\u2D30-\u2D67\u2D6F\u2D70\u2D7F'
|
||||
},
|
||||
{
|
||||
name: 'Ugaritic',
|
||||
astral: '\uD800[\uDF80-\uDF9D\uDF9F]'
|
||||
},
|
||||
{
|
||||
name: 'Vai',
|
||||
bmp: '\uA500-\uA62B'
|
||||
},
|
||||
{
|
||||
name: 'Yi',
|
||||
bmp: '\uA000-\uA48C\uA490-\uA4C6'
|
||||
}
|
||||
]);
|
||||
|
||||
}(XRegExp));
|
||||
1665
public/vendor/xregexp/xregexp.js
vendored
Normal file
1665
public/vendor/xregexp/xregexp.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -80,6 +80,7 @@ var db = require('./database.js'),
|
||||
'category_id': category_id,
|
||||
'active_users': [],
|
||||
'topics': [],
|
||||
'disableSocialButtons': meta.config.disableSocialButtons !== undefined ? parseInt(meta.config.disableSocialButtons, 10) !== 0 : false,
|
||||
'twitter-intent-url': 'https://twitter.com/intent/tweet?url=' + encodeURIComponent(nconf.get('url') + 'category/' + category_slug) + '&text=' + encodeURIComponent(category_name),
|
||||
'facebook-share-url': 'https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(nconf.get('url') + 'category/' + category_slug),
|
||||
'google-share-url': 'https://plus.google.com/share?url=' + encodeURIComponent(nconf.get('url') + 'category/' + category_slug),
|
||||
@@ -216,6 +217,10 @@ var db = require('./database.js'),
|
||||
};
|
||||
|
||||
Categories.getRecentReplies = function(cid, count, callback) {
|
||||
if(count === 0) {
|
||||
return callback(null, []);
|
||||
}
|
||||
|
||||
db.getSortedSetRevRange('categories:recent_posts:cid:' + cid, 0, count - 1, function(err, pids) {
|
||||
|
||||
if (err) {
|
||||
@@ -400,4 +405,25 @@ var db = require('./database.js'),
|
||||
db.setRemove('cid:' + cid + ':active_users', uid);
|
||||
};
|
||||
|
||||
Categories.onNewPostMade = function(uid, tid, pid, timestamp) {
|
||||
topics.getTopicFields(tid, ['cid', 'pinned'], function(err, topicData) {
|
||||
|
||||
var cid = topicData.cid;
|
||||
|
||||
db.sortedSetAdd('categories:recent_posts:cid:' + cid, timestamp, pid);
|
||||
|
||||
if(parseInt(topicData.pinned, 10) === 0) {
|
||||
db.sortedSetAdd('categories:' + cid + ':tid', timestamp, tid);
|
||||
}
|
||||
|
||||
db.setCount('cid:' + cid + ':active_users', function(err, amount) {
|
||||
if (amount > 15) {
|
||||
db.setRemoveRandom('cid:' + cid + ':active_users');
|
||||
}
|
||||
|
||||
Categories.addActiveUser(cid, uid);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}(exports));
|
||||
@@ -50,13 +50,20 @@
|
||||
function createCollections() {
|
||||
db.createCollection('objects', function(err, collection) {
|
||||
if(err) {
|
||||
winston.error("Error creating collection " + err.message);
|
||||
winston.error('Error creating collection ' + err.message);
|
||||
return;
|
||||
}
|
||||
|
||||
if(collection) {
|
||||
collection.ensureIndex({_key :1}, {background:true}, function(err, name){
|
||||
collection.ensureIndex({_key :1}, {background:true}, function(err, name) {
|
||||
if(err) {
|
||||
winston.error("Error creating index " + err.message);
|
||||
winston.error('Error creating index ' + err.message);
|
||||
}
|
||||
});
|
||||
|
||||
collection.ensureIndex({'expireAt':1}, {expireAfterSeconds:0, background:true}, function(err, name) {
|
||||
if(err) {
|
||||
winston.error('Error creating index ' + err.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -64,13 +71,13 @@
|
||||
|
||||
db.createCollection('search', function(err, collection) {
|
||||
if(err) {
|
||||
winston.error("Error creating collection " + err.message);
|
||||
winston.error('Error creating collection ' + err.message);
|
||||
return;
|
||||
}
|
||||
if(collection) {
|
||||
collection.ensureIndex({content:'text'}, {background:true}, function(err, name){
|
||||
if(err) {
|
||||
winston.error("Error creating index " + err.message);
|
||||
winston.error('Error creating index ' + err.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -241,6 +248,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
module.expire = function(key, seconds, callback) {
|
||||
module.expireAt(key, Math.round(Date.now() / 1000) + seconds, callback);
|
||||
}
|
||||
|
||||
module.expireAt = function(key, timestamp, callback) {
|
||||
module.setObjectField(key, 'expireAt', new Date(timestamp * 1000), callback);
|
||||
}
|
||||
|
||||
//hashes
|
||||
module.setObject = function(key, data, callback) {
|
||||
data['_key'] = key;
|
||||
@@ -254,6 +269,9 @@
|
||||
module.setObjectField = function(key, field, value, callback) {
|
||||
var data = {};
|
||||
// if there is a '.' in the field name it inserts subdocument in mongo, replace '.'s with \uff0E
|
||||
if(typeof field !== 'string') {
|
||||
field = field.toString();
|
||||
}
|
||||
field = field.replace(/\./g, '\uff0E');
|
||||
data[field] = value;
|
||||
db.collection('objects').update({_key:key}, {$set:data}, {upsert:true, w: 1}, function(err, result) {
|
||||
@@ -303,7 +321,11 @@
|
||||
|
||||
var _fields = {};
|
||||
for(var i=0; i<fields.length; ++i) {
|
||||
_fields[fields[i].replace(/\./g, '\uff0E')] = 1;
|
||||
if(typeof fields[i] !== 'string') {
|
||||
_fields[fields[i].toString().replace(/\./g, '\uff0E')] = 1;
|
||||
} else {
|
||||
_fields[fields[i].replace(/\./g, '\uff0E')] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
db.collection('objects').findOne({_key:key}, _fields, function(err, item) {
|
||||
@@ -344,6 +366,9 @@
|
||||
|
||||
module.isObjectField = function(key, field, callback) {
|
||||
var data = {};
|
||||
if(typeof field !== 'string') {
|
||||
field = field.toString();
|
||||
}
|
||||
field = field.replace(/\./g, '\uff0E');
|
||||
data[field] = '';
|
||||
db.collection('objects').findOne({_key:key}, {fields:data}, function(err, item) {
|
||||
@@ -356,6 +381,9 @@
|
||||
|
||||
module.deleteObjectField = function(key, field, callback) {
|
||||
var data = {};
|
||||
if(typeof field !== 'string') {
|
||||
field = field.toString();
|
||||
}
|
||||
field = field.replace(/\./g, '\uff0E');
|
||||
data[field] = "";
|
||||
db.collection('objects').update({_key:key}, {$unset : data}, function(err, result) {
|
||||
@@ -375,6 +403,9 @@
|
||||
|
||||
module.incrObjectFieldBy = function(key, field, value, callback) {
|
||||
var data = {};
|
||||
if(typeof field !== 'string') {
|
||||
field = field.toString();
|
||||
}
|
||||
field = field.replace(/\./g, '\uff0E');
|
||||
data[field] = value;
|
||||
db.collection('objects').update({_key:key}, {$inc : data}, {upsert:true}, function(err, result) {
|
||||
@@ -707,6 +738,21 @@
|
||||
});
|
||||
}
|
||||
|
||||
module.listRemoveAll = function(key, value, callback) {
|
||||
db.collection('objects').update({_key: key }, { $pull: { array: value } }, function(err, result) {
|
||||
if(err) {
|
||||
if(callback) {
|
||||
return callback(err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(callback) {
|
||||
callback(null, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.getListRange = function(key, start, stop, callback) {
|
||||
|
||||
if(stop === -1) {
|
||||
|
||||
@@ -211,6 +211,14 @@
|
||||
redisClient.keys(key, callback);
|
||||
}
|
||||
|
||||
module.expire = function(key, seconds, callback) {
|
||||
redisClient.expire(key, seconds, callback);
|
||||
}
|
||||
|
||||
module.expireAt = function(key, timestamp, callback) {
|
||||
redisClient.expireat(key, timestamp, callback);
|
||||
}
|
||||
|
||||
//hashes
|
||||
|
||||
module.setObject = function(key, data, callback) {
|
||||
@@ -394,6 +402,10 @@
|
||||
redisClient.rpop(key, callback);
|
||||
}
|
||||
|
||||
module.listRemoveAll = function(key, value, callback) {
|
||||
redisClient.lrem(key, 0, value, callback);
|
||||
}
|
||||
|
||||
module.getListRange = function(key, start, stop, callback) {
|
||||
redisClient.lrange(key, start, stop, callback);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ var fs = require('fs'),
|
||||
|
||||
|
||||
(function(events) {
|
||||
var logFileName = 'events.log';
|
||||
|
||||
events.logPasswordChange = function(uid) {
|
||||
log(uid, 'changed password');
|
||||
}
|
||||
@@ -54,7 +56,7 @@ var fs = require('fs'),
|
||||
var date = new Date().toUTCString();
|
||||
|
||||
var msg = '[' + date + '] - ' + username + '(uid ' + uid + ') ' + string + '\n';
|
||||
var logFile = path.join(nconf.get('base_dir'), 'events.log');
|
||||
var logFile = path.join(nconf.get('base_dir'), logFileName);
|
||||
|
||||
fs.appendFile(logFile, msg, function(err) {
|
||||
if(err) {
|
||||
@@ -63,8 +65,12 @@ var fs = require('fs'),
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
events.getLog = function(callback) {
|
||||
var logFile = path.join(nconf.get('base_dir'), logFileName);
|
||||
|
||||
fs.readFile(logFile, callback);
|
||||
}
|
||||
|
||||
}(module.exports));
|
||||
18
src/feed.js
18
src/feed.js
@@ -69,13 +69,15 @@
|
||||
|
||||
next();
|
||||
}, function() {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
winston.info('[rss] Re-generated RSS Feed for tid ' + tid + '.');
|
||||
}
|
||||
Feed.saveFeed('feeds/topics/' + tid + '.rss', feed, function (err) {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
winston.info('[rss] Re-generated RSS Feed for tid ' + tid + '.');
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -111,7 +113,9 @@
|
||||
winston.info('[rss] Re-generated RSS Feed for cid ' + cid + '.');
|
||||
}
|
||||
|
||||
if (callback) callback();
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,6 +20,7 @@ var request = require('request'),
|
||||
|
||||
try {
|
||||
var response = JSON.parse(body);
|
||||
|
||||
if(response.success) {
|
||||
callback(null, response.data);
|
||||
} else {
|
||||
|
||||
@@ -134,6 +134,11 @@ var async = require('async'),
|
||||
return next(new Error('unknown database : ' + config.database));
|
||||
}
|
||||
|
||||
var allQuestions = install.redisQuestions.concat(install.mongoQuestions);
|
||||
for(var x=0;x<allQuestions.length;x++) {
|
||||
delete config[allQuestions[x].name];
|
||||
}
|
||||
|
||||
config.bcrypt_rounds = 12;
|
||||
config.upload_path = '/public/uploads';
|
||||
config.use_port = config.use_port.slice(0, 1) === 'y';
|
||||
@@ -212,9 +217,18 @@ var async = require('async'),
|
||||
}, {
|
||||
field: 'allowRegistration',
|
||||
value: 1
|
||||
}, {
|
||||
field: 'allowFileUploads',
|
||||
value: 0,
|
||||
}, {
|
||||
filed: 'maximumFileSize',
|
||||
value: 2048
|
||||
}, {
|
||||
field: 'minimumTitleLength',
|
||||
value: 3
|
||||
}, {
|
||||
field: 'maximumTitleLength',
|
||||
value: 255
|
||||
}, {
|
||||
field: 'minimumUsernameLength',
|
||||
value: 2
|
||||
@@ -233,6 +247,9 @@ var async = require('async'),
|
||||
}, {
|
||||
field: 'maximumProfileImageSize',
|
||||
value: 256
|
||||
}, {
|
||||
field: 'chatMessagesToDisplay',
|
||||
value: 50
|
||||
}, {
|
||||
field: 'theme:type',
|
||||
value: 'local'
|
||||
@@ -246,6 +263,21 @@ var async = require('async'),
|
||||
}, function (err) {
|
||||
meta.configs.init(next);
|
||||
});
|
||||
|
||||
if (install.values) {
|
||||
if (install.values['social:twitter:key'] && install.values['social:twitter:secret']) {
|
||||
meta.configs.setOnEmpty('social:twitter:key', install.values['social:twitter:key']);
|
||||
meta.configs.setOnEmpty('social:twitter:secret', install.values['social:twitter:secret']);
|
||||
}
|
||||
if (install.values['social:google:id'] && install.values['social:google:secret']) {
|
||||
meta.configs.setOnEmpty('social:google:id', install.values['social:google:id']);
|
||||
meta.configs.setOnEmpty('social:google:secret', install.values['social:google:secret']);
|
||||
}
|
||||
if (install.values['social:facebook:key'] && install.values['social:facebook:secret']) {
|
||||
meta.configs.setOnEmpty('social:facebook:app_id', install.values['social:facebook:app_id']);
|
||||
meta.configs.setOnEmpty('social:facebook:secret', install.values['social:facebook:secret']);
|
||||
}
|
||||
}
|
||||
},
|
||||
function (next) {
|
||||
// Check if an administrator needs to be created
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
*/
|
||||
|
||||
var fs = require('fs'),
|
||||
path = require('path'),
|
||||
express = require('express'),
|
||||
winston = require('winston'),
|
||||
util = require('util'),
|
||||
socketio = require('socket.io'),
|
||||
meta = require('./meta.js');
|
||||
meta = require('./meta');
|
||||
|
||||
var opts = {
|
||||
/*
|
||||
@@ -71,11 +72,29 @@ var opts = {
|
||||
Logger.open = function(value) {
|
||||
/* Open the streams to log to: either a path or stdout */
|
||||
var stream;
|
||||
if(value && fs.existsSync(value)) {
|
||||
stream = fs.createWriteStream(value, {flags: 'a'});
|
||||
}
|
||||
else
|
||||
if(value) {
|
||||
if(fs.existsSync(value)) {
|
||||
stats = fs.statSync(value);
|
||||
if(stats) {
|
||||
if(stats.isDirectory()) {
|
||||
stream = fs.createWriteStream(path.join(value, 'nodebb.log'), {flags: 'a'});
|
||||
} else {
|
||||
stream = fs.createWriteStream(value, {flags: 'a'});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stream = fs.createWriteStream(value, {flags: 'a'});
|
||||
|
||||
}
|
||||
|
||||
if(stream) {
|
||||
stream.on('error', function(err) {
|
||||
winston.error(err.message);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
stream = process.stdout;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
@@ -112,8 +131,7 @@ var opts = {
|
||||
*/
|
||||
if(meta.config.loggerStatus > 0) {
|
||||
return opts.express.ofn(req,res,next);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
@@ -140,11 +158,13 @@ var opts = {
|
||||
for(var v in clients) {
|
||||
var client = clients[v];
|
||||
|
||||
if(client.oEmit != undefined && client.oEmit != client.emit)
|
||||
if(client.oEmit != undefined && client.oEmit != client.emit) {
|
||||
client.emit = client.oEmit;
|
||||
}
|
||||
|
||||
if(client.$oEmit != undefined && client.$oEmit != client.$emit)
|
||||
if(client.$oEmit != undefined && client.$oEmit != client.$emit) {
|
||||
client.$emit = client.$oEmit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,8 +197,9 @@ var opts = {
|
||||
var emit = socket.emit;
|
||||
socket.emit = function() {
|
||||
if(opts.streams.log.f != null) {
|
||||
opts.streams.log.f.write(Logger.prepare_io_string("emit",uid,arguments));
|
||||
opts.streams.log.f.write(Logger.prepare_io_string("emit", uid, arguments));
|
||||
}
|
||||
|
||||
try {
|
||||
emit.apply(socket, arguments);
|
||||
} catch(err) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
var db = require('./database'),
|
||||
async = require('async'),
|
||||
user = require('./user');
|
||||
user = require('./user'),
|
||||
meta = require('./meta');
|
||||
|
||||
|
||||
(function(Messaging) {
|
||||
@@ -38,7 +39,7 @@ var db = require('./database'),
|
||||
Messaging.getMessages = function(fromuid, touid, callback) {
|
||||
var uids = sortUids(fromuid, touid);
|
||||
|
||||
db.getListRange('messages:' + uids[0] + ':' + uids[1], 0, -1, function(err, mids) {
|
||||
db.getListRange('messages:' + uids[0] + ':' + uids[1], -((meta.config.chatMessagesToDisplay || 50) - 1), -1, function(err, mids) {
|
||||
if (err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
@@ -49,6 +50,9 @@ var db = require('./database'),
|
||||
|
||||
|
||||
user.getUserField(touid, 'username', function(err, tousername) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
|
||||
var messages = [];
|
||||
|
||||
@@ -78,7 +82,7 @@ var db = require('./database'),
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Messaging.updateChatTime = function(uid, toUid, callback) {
|
||||
db.sortedSetAdd('uid:' + uid + ':chats', Date.now(), toUid, function(err) {
|
||||
@@ -90,11 +94,11 @@ var db = require('./database'),
|
||||
|
||||
Messaging.getRecentChats = function(uid, callback) {
|
||||
db.getSortedSetRevRange('uid:' + uid + ':chats', 0, 9, function(err, uids) {
|
||||
if (!err) {
|
||||
user.getMultipleUserFields(uids, ['username', 'picture', 'uid'], callback);
|
||||
} else {
|
||||
callback(err);
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
user.getMultipleUserFields(uids, ['username', 'picture', 'uid'], callback);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
32
src/meta.js
32
src/meta.js
@@ -196,6 +196,8 @@ var fs = require('fs'),
|
||||
'vendor/requirejs/require.js',
|
||||
'vendor/bootbox/bootbox.min.js',
|
||||
'vendor/tinycon/tinycon.js',
|
||||
'vendor/xregexp/xregexp.js',
|
||||
'vendor/xregexp/unicode/unicode-base.js',
|
||||
'src/app.js',
|
||||
'src/templates.js',
|
||||
'src/ajaxify.js',
|
||||
@@ -207,22 +209,36 @@ var fs = require('fs'),
|
||||
plugins.fireHook('filter:scripts.get', this.scripts, function(err, scripts) {
|
||||
var mtime,
|
||||
jsPaths = scripts.map(function (jsPath) {
|
||||
return path.join(__dirname, '..', '/public', jsPath);
|
||||
if (jsPath.substring(0, 7) === 'plugins') {
|
||||
var paths = jsPath.split('/'),
|
||||
pluginID = paths[1];
|
||||
|
||||
jsPath = jsPath.replace(path.join('plugins', pluginID), '');
|
||||
return path.join(plugins.staticDirs[pluginID], jsPath);
|
||||
} else {
|
||||
return path.join(__dirname, '..', '/public', jsPath);
|
||||
}
|
||||
});
|
||||
|
||||
Meta.js.scripts = jsPaths;
|
||||
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
async.parallel({
|
||||
mtime: function (next) {
|
||||
async.map(jsPaths, fs.stat, function (err, stats) {
|
||||
async.reduce(stats, 0, function (memo, item, callback) {
|
||||
mtime = +new Date(item.mtime);
|
||||
callback(null, mtime > memo ? mtime : memo);
|
||||
if(item) {
|
||||
mtime = +new Date(item.mtime);
|
||||
callback(null, mtime > memo ? mtime : memo);
|
||||
} else {
|
||||
callback(null, memo);
|
||||
}
|
||||
}, next);
|
||||
});
|
||||
},
|
||||
minFile: function (next) {
|
||||
if (!fs.existsSync(Meta.js.minFile)) {
|
||||
if (process.env.NODE_ENV === 'development') winston.warn('No minified client-side library found');
|
||||
winston.warn('No minified client-side library found');
|
||||
return next(null, 0);
|
||||
}
|
||||
|
||||
@@ -232,12 +248,12 @@ var fs = require('fs'),
|
||||
}
|
||||
}, function (err, results) {
|
||||
if (results.minFile > results.mtime) {
|
||||
if (process.env.NODE_ENV === 'development') winston.info('No changes to client-side libraries -- skipping minification');
|
||||
winston.info('No changes to client-side libraries -- skipping minification');
|
||||
callback(null, [path.relative(path.join(__dirname, '../public'), Meta.js.minFile)]);
|
||||
} else {
|
||||
Meta.js.minify(function () {
|
||||
callback(null, [
|
||||
path.relative(path.join(__dirname, '../public'), Meta.js.minFile) + (meta.config['cache-buster'] ? '?v=' + meta.config['cache-buster'] : '')
|
||||
path.relative(path.join(__dirname, '../public'), Meta.js.minFile) + (meta.config['cache-buster'] ? '?vs=' + meta.config['cache-buster'] : '')
|
||||
]);
|
||||
});
|
||||
}
|
||||
@@ -254,9 +270,7 @@ var fs = require('fs'),
|
||||
},
|
||||
minify: function (callback) {
|
||||
var uglifyjs = require('uglify-js'),
|
||||
jsPaths = this.scripts.map(function (jsPath) {
|
||||
return path.join(__dirname, '..', '/public', jsPath);
|
||||
}),
|
||||
jsPaths = this.scripts,
|
||||
minified;
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
|
||||
@@ -85,7 +85,7 @@ var async = require('async'),
|
||||
remove_by_uniqueId(notif_data.uniqueId, uid, function() {
|
||||
db.sortedSetAdd('uid:' + uid + ':notifications:unread', notif_data.datetime, nid);
|
||||
|
||||
websockets.in('uid_' + uid).emit('event:new_notification');
|
||||
websockets.in('uid_' + uid).emit('event:new_notification', notif_data);
|
||||
|
||||
if (callback) {
|
||||
callback(true);
|
||||
|
||||
@@ -137,7 +137,7 @@ var winston = require('winston'),
|
||||
events.logPostDelete(uid, pid);
|
||||
|
||||
posts.getPostFields(pid, ['tid', 'uid'], function(err, postData) {
|
||||
db.incrObjectFieldBy('topic:' + postData.tid, 'postcount', -1);
|
||||
topics.decreasePostCount(postData.tid);
|
||||
|
||||
user.decrementUserFieldBy(postData.uid, 'postcount', 1, function(err, postcount) {
|
||||
db.sortedSetAdd('users:postcount', postcount, postData.uid);
|
||||
@@ -152,7 +152,7 @@ var winston = require('winston'),
|
||||
// Delete the thread if it is the last undeleted post
|
||||
threadTools.getLatestUndeletedPid(postData.tid, function(err, pid) {
|
||||
if (err && err.message === 'no-undeleted-pids-found') {
|
||||
threadTools.delete(postData.tid, function(err) {
|
||||
threadTools.delete(postData.tid, uid, function(err) {
|
||||
if (err) {
|
||||
winston.error('Could not delete topic (tid: ' + postData.tid + ')', err.stack);
|
||||
}
|
||||
@@ -193,7 +193,7 @@ var winston = require('winston'),
|
||||
events.logPostRestore(uid, pid);
|
||||
|
||||
posts.getPostFields(pid, ['tid', 'uid', 'content'], function(err, postData) {
|
||||
db.incrObjectFieldBy('topic:' + postData.tid, 'postcount', 1);
|
||||
topics.increasePostCount(postData.tid);
|
||||
|
||||
user.incrementUserFieldBy(postData.uid, 'postcount', 1);
|
||||
|
||||
|
||||
252
src/posts.js
252
src/posts.js
@@ -12,10 +12,13 @@ var db = require('./database'),
|
||||
meta = require('./meta'),
|
||||
|
||||
async = require('async'),
|
||||
path = require('path'),
|
||||
fs = require('fs'),
|
||||
nconf = require('nconf'),
|
||||
validator = require('validator'),
|
||||
winston = require('winston'),
|
||||
gravatar = require('gravatar');
|
||||
gravatar = require('gravatar'),
|
||||
S = require('string');
|
||||
|
||||
(function(Posts) {
|
||||
var customUserInfo = {};
|
||||
@@ -25,146 +28,73 @@ var db = require('./database'),
|
||||
return callback(new Error('invalid-user'), null);
|
||||
}
|
||||
|
||||
topics.isLocked(tid, function(err, locked) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
} else if(locked) {
|
||||
return callback(new Error('topic-locked'), null);
|
||||
}
|
||||
|
||||
db.incrObjectField('global', 'nextPid', function(err, pid) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
topics.isLocked(tid, next);
|
||||
},
|
||||
function(locked, next) {
|
||||
if(locked) {
|
||||
return next(new Error('topic-locked'));
|
||||
}
|
||||
|
||||
db.incrObjectField('global', 'nextPid', next);
|
||||
},
|
||||
function(pid, next) {
|
||||
plugins.fireHook('filter:post.save', content, function(err, newContent) {
|
||||
next(err, pid, newContent)
|
||||
});
|
||||
},
|
||||
function(pid, newContent, next) {
|
||||
var timestamp = Date.now(),
|
||||
postData = {
|
||||
'pid': pid,
|
||||
'uid': uid,
|
||||
'tid': tid,
|
||||
'content': newContent,
|
||||
'timestamp': timestamp,
|
||||
'reputation': 0,
|
||||
'editor': '',
|
||||
'edited': 0,
|
||||
'deleted': 0
|
||||
};
|
||||
|
||||
db.setObject('post:' + pid, postData, function(err) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
return next(err);
|
||||
}
|
||||
|
||||
var timestamp = Date.now(),
|
||||
postData = {
|
||||
'pid': pid,
|
||||
'uid': uid,
|
||||
'tid': tid,
|
||||
'content': newContent,
|
||||
'timestamp': timestamp,
|
||||
'reputation': 0,
|
||||
'editor': '',
|
||||
'edited': 0,
|
||||
'deleted': 0
|
||||
};
|
||||
|
||||
db.setObject('post:' + pid, postData);
|
||||
|
||||
postData.favourited = false;
|
||||
postData.display_moderator_tools = true;
|
||||
postData.relativeTime = new Date(timestamp).toISOString();
|
||||
|
||||
topics.addPostToTopic(tid, pid);
|
||||
topics.increasePostCount(tid);
|
||||
topics.updateTimestamp(tid, timestamp);
|
||||
|
||||
db.incrObjectField('global', 'postCount');
|
||||
|
||||
topics.getTopicFields(tid, ['cid', 'pinned'], function(err, topicData) {
|
||||
|
||||
var cid = topicData.cid;
|
||||
|
||||
feed.updateTopic(tid);
|
||||
feed.updateRecent();
|
||||
|
||||
db.sortedSetAdd('categories:recent_posts:cid:' + cid, timestamp, pid);
|
||||
|
||||
if(parseInt(topicData.pinned, 10) === 0) {
|
||||
db.sortedSetAdd('categories:' + cid + ':tid', timestamp, tid);
|
||||
}
|
||||
|
||||
db.setCount('cid:' + cid + ':active_users', function(err, amount) {
|
||||
if (amount > 15) {
|
||||
db.setRemoveRandom('cid:' + cid + ':active_users');
|
||||
}
|
||||
|
||||
categories.addActiveUser(cid, uid);
|
||||
});
|
||||
});
|
||||
|
||||
topics.onNewPostMade(tid, pid, timestamp);
|
||||
categories.onNewPostMade(uid, tid, pid, timestamp);
|
||||
user.onNewPostMade(uid, tid, pid, timestamp);
|
||||
|
||||
plugins.fireHook('filter:post.get', postData, function(err, newPostData) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
|
||||
postData = newPostData;
|
||||
|
||||
postTools.parse(postData.content, function(err, content) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
postData.content = content;
|
||||
|
||||
plugins.fireHook('action:post.save', postData);
|
||||
|
||||
db.searchIndex('post', content, pid);
|
||||
|
||||
callback(null, postData);
|
||||
});
|
||||
});
|
||||
next(null, postData);
|
||||
});
|
||||
});
|
||||
},
|
||||
function(postData, next) {
|
||||
plugins.fireHook('filter:post.get', postData, next);
|
||||
},
|
||||
function(postData, next) {
|
||||
postTools.parse(postData.content, function(err, content) {
|
||||
if(err) {
|
||||
return next(err, null);
|
||||
}
|
||||
|
||||
postData.content = content;
|
||||
|
||||
plugins.fireHook('action:post.save', postData);
|
||||
|
||||
db.searchIndex('post', content, postData.pid);
|
||||
|
||||
next(null, postData);
|
||||
});
|
||||
}
|
||||
], function(err, postData) {
|
||||
callback(err, postData);
|
||||
});
|
||||
};
|
||||
|
||||
Posts.reply = function(tid, uid, content, callback) {
|
||||
threadTools.privileges(tid, uid, function(err, privileges) {
|
||||
if (content) {
|
||||
content = content.trim();
|
||||
}
|
||||
|
||||
if (!content || content.length < meta.config.minimumPostLength) {
|
||||
return callback(new Error('content-too-short'));
|
||||
} else if (!privileges.write) {
|
||||
return callback(new Error('no-privileges'));
|
||||
}
|
||||
|
||||
Posts.create(uid, tid, content, function(err, postData) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
} else if(!postData) {
|
||||
callback(new Error('reply-error'), null);
|
||||
}
|
||||
|
||||
Posts.getCidByPid(postData.pid, function(err, cid) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
|
||||
db.delete('cid:' + cid + ':read_by_uid');
|
||||
});
|
||||
|
||||
topics.markAsUnreadForAll(tid, function(err) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
|
||||
topics.markAsRead(tid, uid);
|
||||
topics.pushUnreadCount();
|
||||
});
|
||||
|
||||
threadTools.notifyFollowers(tid, uid);
|
||||
|
||||
Posts.addUserInfoToPost(postData, function(err) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
|
||||
callback(null, postData);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Posts.getPostsByTid = function(tid, start, end, callback) {
|
||||
db.getListRange('tid:' + tid + ':posts', start, end, function(err, pids) {
|
||||
if(err) {
|
||||
@@ -294,7 +224,7 @@ var db = require('./database'),
|
||||
}
|
||||
|
||||
if(stripTags) {
|
||||
postData.content = utils.strip_tags(content);
|
||||
postData.content = S(content).stripTags().s;
|
||||
} else {
|
||||
postData.content = content;
|
||||
}
|
||||
@@ -435,38 +365,56 @@ var db = require('./database'),
|
||||
});
|
||||
}
|
||||
|
||||
Posts.emitContentTooShortAlert = function(socket) {
|
||||
socket.emit('event:alert', {
|
||||
type: 'danger',
|
||||
timeout: 2000,
|
||||
title: 'Content too short',
|
||||
message: "Please enter a longer post. At least " + meta.config.minimumPostLength + " characters.",
|
||||
alert_id: 'post_error'
|
||||
});
|
||||
}
|
||||
|
||||
Posts.emitTooManyPostsAlert = function(socket) {
|
||||
socket.emit('event:alert', {
|
||||
title: 'Too many posts!',
|
||||
message: 'You can only post every ' + meta.config.postDelay + ' seconds.',
|
||||
type: 'danger',
|
||||
timeout: 2000
|
||||
});
|
||||
}
|
||||
|
||||
Posts.uploadPostImage = function(image, callback) {
|
||||
|
||||
if(!image) {
|
||||
return callback('invalid image', null);
|
||||
if(meta.config.imgurClientID) {
|
||||
if(!image) {
|
||||
return callback('invalid image', null);
|
||||
}
|
||||
|
||||
require('./imgur').upload(meta.config.imgurClientID, image.data, 'base64', function(err, data) {
|
||||
if(err) {
|
||||
callback(err.message, null);
|
||||
} else {
|
||||
callback(null, {
|
||||
url: data.link,
|
||||
name: image.name
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (meta.config.allowFileUploads) {
|
||||
Posts.uploadPostFile(image, callback);
|
||||
} else {
|
||||
callback('Uploads are disabled!');
|
||||
}
|
||||
}
|
||||
|
||||
Posts.uploadPostFile = function(file, callback) {
|
||||
|
||||
if(!meta.config.allowFileUploads) {
|
||||
return callback('File uploads are not allowed');
|
||||
}
|
||||
|
||||
require('./imgur').upload(meta.config.imgurClientID, image.data, 'base64', function(err, data) {
|
||||
if(!file) {
|
||||
return callback('invalid file');
|
||||
}
|
||||
|
||||
var buffer = new Buffer(file.data, 'base64');
|
||||
|
||||
if(buffer.length > parseInt(meta.config.maximumFileSize, 10) * 1024) {
|
||||
return callback('File too big');
|
||||
}
|
||||
|
||||
var filename = 'upload-' + utils.generateUUID() + path.extname(file.name);
|
||||
var uploadPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), filename);
|
||||
|
||||
fs.writeFile(uploadPath, buffer, function (err) {
|
||||
if(err) {
|
||||
callback(err.message, null);
|
||||
} else {
|
||||
callback(null, {
|
||||
url: data.link,
|
||||
name: image.name
|
||||
url: nconf.get('upload_url') + filename,
|
||||
name: file.name
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@ var nconf = require('nconf'),
|
||||
categories = require('./../categories'),
|
||||
meta = require('../meta'),
|
||||
plugins = require('../plugins'),
|
||||
events = require('./../events'),
|
||||
utils = require('./../../public/src/utils.js');
|
||||
|
||||
|
||||
@@ -56,7 +57,7 @@ var nconf = require('nconf'),
|
||||
(function () {
|
||||
var routes = [
|
||||
'categories/active', 'categories/disabled', 'users', 'topics', 'settings', 'themes',
|
||||
'twitter', 'facebook', 'gplus', 'database', 'motd', 'groups', 'plugins', 'logger',
|
||||
'twitter', 'facebook', 'gplus', 'database', 'events', 'motd', 'groups', 'plugins', 'logger',
|
||||
'users/latest', 'users/sort-posts', 'users/sort-reputation',
|
||||
'users/search'
|
||||
];
|
||||
@@ -103,6 +104,14 @@ var nconf = require('nconf'),
|
||||
return res.redirect('/403');
|
||||
|
||||
var allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'];
|
||||
var params = null;
|
||||
try {
|
||||
params = JSON.parse(req.body.params);
|
||||
} catch (e) {
|
||||
return res.send({
|
||||
error: 'Error uploading file! Error :' + e.message
|
||||
});
|
||||
}
|
||||
|
||||
if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) {
|
||||
res.send({
|
||||
@@ -111,38 +120,9 @@ var nconf = require('nconf'),
|
||||
return;
|
||||
}
|
||||
|
||||
var tempPath = req.files.userPhoto.path;
|
||||
var extension = path.extname(req.files.userPhoto.name);
|
||||
var filename = 'category-' + params.cid + path.extname(req.files.userPhoto.name);
|
||||
|
||||
if (!extension) {
|
||||
res.send({
|
||||
error: 'Error uploading file! Error : Invalid extension!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var filename = 'category' + utils.generateUUID() + extension;
|
||||
var uploadPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), filename);
|
||||
|
||||
winston.info('Attempting upload to: ' + uploadPath);
|
||||
|
||||
var is = fs.createReadStream(tempPath);
|
||||
var os = fs.createWriteStream(uploadPath);
|
||||
|
||||
is.on('end', function () {
|
||||
fs.unlinkSync(tempPath);
|
||||
console.log(nconf.get('upload_url') + filename);
|
||||
res.json({
|
||||
path: nconf.get('upload_url') + filename
|
||||
});
|
||||
});
|
||||
|
||||
os.on('error', function (err) {
|
||||
fs.unlinkSync(tempPath);
|
||||
winston.err(err);
|
||||
});
|
||||
|
||||
is.pipe(os);
|
||||
uploadImage(filename, req, res);
|
||||
});
|
||||
|
||||
app.post('/uploadfavicon', function(req, res) {
|
||||
@@ -158,38 +138,7 @@ var nconf = require('nconf'),
|
||||
return;
|
||||
}
|
||||
|
||||
var tempPath = req.files.userPhoto.path;
|
||||
var extension = path.extname(req.files.userPhoto.name);
|
||||
|
||||
if (!extension) {
|
||||
res.send({
|
||||
error: 'Error uploading file! Error : Invalid extension!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var filename = 'favicon.ico';
|
||||
var uploadPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), filename);
|
||||
|
||||
winston.info('Attempting upload to: ' + uploadPath);
|
||||
|
||||
var is = fs.createReadStream(tempPath);
|
||||
var os = fs.createWriteStream(uploadPath);
|
||||
|
||||
is.on('end', function () {
|
||||
fs.unlinkSync(tempPath);
|
||||
|
||||
res.json({
|
||||
path: nconf.get('upload_url') + filename
|
||||
});
|
||||
});
|
||||
|
||||
os.on('error', function (err) {
|
||||
fs.unlinkSync(tempPath);
|
||||
winston.err(err);
|
||||
});
|
||||
|
||||
is.pipe(os);
|
||||
uploadImage('favicon.ico', req, res);
|
||||
});
|
||||
|
||||
app.post('/uploadlogo', function(req, res) {
|
||||
@@ -206,41 +155,46 @@ var nconf = require('nconf'),
|
||||
return;
|
||||
}
|
||||
|
||||
var tempPath = req.files.userPhoto.path;
|
||||
var extension = path.extname(req.files.userPhoto.name);
|
||||
var filename = 'site-logo' + path.extname(req.files.userPhoto.name);
|
||||
|
||||
if (!extension) {
|
||||
res.send({
|
||||
error: 'Error uploading file! Error : Invalid extension!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var filename = 'site-logo' + extension;
|
||||
var uploadPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), filename);
|
||||
|
||||
winston.info('Attempting upload to: ' + uploadPath);
|
||||
|
||||
var is = fs.createReadStream(tempPath);
|
||||
var os = fs.createWriteStream(uploadPath);
|
||||
|
||||
is.on('end', function () {
|
||||
fs.unlinkSync(tempPath);
|
||||
|
||||
res.json({
|
||||
path: nconf.get('upload_url') + filename
|
||||
});
|
||||
});
|
||||
|
||||
os.on('error', function (err) {
|
||||
fs.unlinkSync(tempPath);
|
||||
winston.err(err);
|
||||
});
|
||||
|
||||
is.pipe(os);
|
||||
uploadImage(filename, req, res);
|
||||
});
|
||||
});
|
||||
|
||||
function uploadImage(filename, req, res) {
|
||||
|
||||
var tempPath = req.files.userPhoto.path;
|
||||
var extension = path.extname(req.files.userPhoto.name);
|
||||
|
||||
if (!extension) {
|
||||
res.send({
|
||||
error: 'Error uploading file! Error : Invalid extension!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var uploadPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), filename);
|
||||
|
||||
winston.info('Attempting upload to: ' + uploadPath);
|
||||
var is = fs.createReadStream(tempPath);
|
||||
var os = fs.createWriteStream(uploadPath);
|
||||
|
||||
is.on('end', function () {
|
||||
fs.unlinkSync(tempPath);
|
||||
|
||||
res.json({
|
||||
path: nconf.get('upload_url') + filename
|
||||
});
|
||||
});
|
||||
|
||||
os.on('error', function (err) {
|
||||
fs.unlinkSync(tempPath);
|
||||
winston.err(err);
|
||||
});
|
||||
|
||||
is.pipe(os);
|
||||
}
|
||||
|
||||
|
||||
var custom_routes = {
|
||||
'routes': [],
|
||||
@@ -403,6 +357,15 @@ var nconf = require('nconf'),
|
||||
// });
|
||||
});
|
||||
|
||||
app.get('/events', function(req, res, next) {
|
||||
events.getLog(function(err, data) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
res.json(200, {eventdata: data.toString()});
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/plugins', function (req, res) {
|
||||
plugins.showInstalled(function (err, plugins) {
|
||||
if (err || !Array.isArray(plugins)) plugins = [];
|
||||
|
||||
@@ -30,6 +30,7 @@ var path = require('path'),
|
||||
|
||||
config.postDelay = meta.config.postDelay;
|
||||
config.minimumTitleLength = meta.config.minimumTitleLength;
|
||||
config.maximumTitleLength = meta.config.maximumTitleLength;
|
||||
config.minimumPostLength = meta.config.minimumPostLength;
|
||||
config.imgurClientIDSet = !! meta.config.imgurClientID;
|
||||
config.minimumUsernameLength = meta.config.minimumUsernameLength;
|
||||
@@ -39,6 +40,8 @@ var path = require('path'),
|
||||
config.useOutgoingLinksPage = meta.config.useOutgoingLinksPage;
|
||||
config.allowGuestPosting = meta.config.allowGuestPosting;
|
||||
config.allowRegistration = meta.config.allowRegistration || '1';
|
||||
config.allowFileUploads = meta.config.allowFileUploads;
|
||||
config.maximumFileSize = meta.config.maximumFileSize;
|
||||
config.emailSetup = !!meta.config['email:from'];
|
||||
|
||||
res.json(200, config);
|
||||
@@ -52,9 +55,9 @@ var path = require('path'),
|
||||
});
|
||||
|
||||
function iterator(category, callback) {
|
||||
categories.getRecentReplies(category.cid, 2, function (err, posts) {
|
||||
categories.getRecentReplies(category.cid, parseInt(category.numRecentReplies, 10), function (err, posts) {
|
||||
category.posts = posts;
|
||||
category.post_count = posts.length > 2 ? 2 : posts.length;
|
||||
category.post_count = posts.length > 2 ? 2 : posts.length; // this was a hack to make metro work back in the day, post_count should just = length
|
||||
callback(null);
|
||||
});
|
||||
}
|
||||
@@ -63,7 +66,7 @@ var path = require('path'),
|
||||
data.motd_class = (parseInt(meta.config.show_motd, 10) === 1 || meta.config.show_motd === undefined) ? '' : ' none';
|
||||
data.motd_class += (meta.config.motd && meta.config.motd.length > 0 ? '' : ' default');
|
||||
|
||||
data.motd = require('marked')(meta.config.motd || "<div class=\"pull-right btn-group\"><a target=\"_blank\" href=\"http://www.nodebb.org\" class=\"btn btn-default btn-lg\"><i class=\"fa fa-comment\"></i><span class='hidden-mobile'> Get NodeBB</span></a> <a target=\"_blank\" href=\"https://github.com/designcreateplay/NodeBB\" class=\"btn btn-default btn-lg\"><i class=\"fa fa-github\"></i><span class='hidden-mobile'> Fork us on Github</span></a> <a target=\"_blank\" href=\"https://twitter.com/dcplabs\" class=\"btn btn-default btn-lg\"><i class=\"fa fa-twitter\"></i><span class='hidden-mobile'> @NodeBB</span></a></div>\n\n# NodeBB <span>v" + pkg.version + "</span>\nWelcome to NodeBB, the discussion platform of the future.");
|
||||
data.motd = require('marked')(meta.config.motd || "<div class=\"pull-right btn-group\"><a target=\"_blank\" href=\"http://www.nodebb.org\" class=\"btn btn-default btn-lg\"><i class=\"fa fa-comment\"></i><span class='hidden-mobile'> Get NodeBB</span></a> <a target=\"_blank\" href=\"https://github.com/designcreateplay/NodeBB\" class=\"btn btn-default btn-lg\"><i class=\"fa fa-github\"></i><span class='hidden-mobile'> Fork us on Github</span></a> <a target=\"_blank\" href=\"https://twitter.com/NodeBB\" class=\"btn btn-default btn-lg\"><i class=\"fa fa-twitter\"></i><span class='hidden-mobile'> @NodeBB</span></a></div>\n\n# NodeBB <span>v" + pkg.version + "</span>\nWelcome to NodeBB, the discussion platform of the future.");
|
||||
res.json(data);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -161,12 +161,7 @@ var fs = require('fs'),
|
||||
is.on('end', function () {
|
||||
fs.unlinkSync(tempPath);
|
||||
|
||||
im.crop({
|
||||
srcPath: uploadPath,
|
||||
dstPath: uploadPath,
|
||||
width: 128,
|
||||
height: 128
|
||||
}, function (err, stdout, stderr) {
|
||||
function done(err) {
|
||||
if (err) {
|
||||
winston.err(err);
|
||||
res.send({
|
||||
@@ -180,7 +175,7 @@ var fs = require('fs'),
|
||||
user.setUserField(uid, 'uploadedpicture', imageUrl);
|
||||
user.setUserField(uid, 'picture', imageUrl);
|
||||
|
||||
if (convertToPNG) {
|
||||
if (convertToPNG && extension !== '.png') {
|
||||
im.convert([uploadPath, 'png:-'],
|
||||
function(err, stdout){
|
||||
if (err) {
|
||||
@@ -195,11 +190,25 @@ var fs = require('fs'),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
res.json({
|
||||
path: imageUrl
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if(extension === '.gif') {
|
||||
im.convert([uploadPath, '-coalesce', '-repage', '0x0', '-crop', '128x128+0+0', '+repage', 'uploadPath'], function(err, stdout) {
|
||||
done(err);
|
||||
});
|
||||
} else {
|
||||
im.crop({
|
||||
srcPath: uploadPath,
|
||||
dstPath: uploadPath,
|
||||
width: 128,
|
||||
height: 128
|
||||
}, function (err, stdout, stderr) {
|
||||
done(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
os.on('error', function (err) {
|
||||
@@ -521,11 +530,16 @@ var fs = require('fs'),
|
||||
user.getUserData(uid, function (err, data) {
|
||||
if (data) {
|
||||
data.joindate = new Date(parseInt(data.joindate, 10)).toISOString();
|
||||
if(data.lastonline) {
|
||||
data.lastonline = new Date(parseInt(data.lastonline, 10)).toISOString();
|
||||
} else {
|
||||
data.lastonline = data.joindate;
|
||||
}
|
||||
|
||||
if (!data.birthday) {
|
||||
data.age = '';
|
||||
} else {
|
||||
data.age = new Date().getFullYear() - new Date(data.birthday).getFullYear();
|
||||
data.age = Math.floor((new Date().getTime() - new Date(data.birthday).getTime()) / 31536000000);
|
||||
}
|
||||
|
||||
function canSeeEmail() {
|
||||
@@ -567,4 +581,4 @@ var fs = require('fs'),
|
||||
|
||||
};
|
||||
|
||||
}(exports));
|
||||
}(exports));
|
||||
|
||||
@@ -91,7 +91,7 @@ var winston = require('winston'),
|
||||
}
|
||||
}
|
||||
|
||||
ThreadTools.delete = function(tid, callback) {
|
||||
ThreadTools.delete = function(tid, uid, callback) {
|
||||
topics.delete(tid);
|
||||
|
||||
db.decrObjectField('global', 'topicCount');
|
||||
@@ -112,7 +112,7 @@ var winston = require('winston'),
|
||||
}
|
||||
}
|
||||
|
||||
ThreadTools.restore = function(tid, socket, callback) {
|
||||
ThreadTools.restore = function(tid, uid, callback) {
|
||||
topics.restore(tid);
|
||||
db.incrObjectField('global', 'topicCount');
|
||||
ThreadTools.unlock(tid);
|
||||
|
||||
220
src/topics.js
220
src/topics.js
@@ -2,6 +2,7 @@ var async = require('async'),
|
||||
gravatar = require('gravatar'),
|
||||
nconf = require('nconf'),
|
||||
validator = require('validator'),
|
||||
S = require('string'),
|
||||
|
||||
db = require('./database'),
|
||||
posts = require('./posts'),
|
||||
@@ -22,6 +23,50 @@ var async = require('async'),
|
||||
|
||||
(function(Topics) {
|
||||
|
||||
Topics.create = function(uid, title, cid, callback) {
|
||||
db.incrObjectField('global', 'nextTid', function(err, tid) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.setAdd('topics:tid', tid);
|
||||
|
||||
var slug = tid + '/' + utils.slugify(title),
|
||||
timestamp = Date.now();
|
||||
|
||||
db.setObject('topic:' + tid, {
|
||||
'tid': tid,
|
||||
'uid': uid,
|
||||
'cid': cid,
|
||||
'title': title,
|
||||
'slug': slug,
|
||||
'timestamp': timestamp,
|
||||
'lastposttime': 0,
|
||||
'postcount': 0,
|
||||
'viewcount': 0,
|
||||
'locked': 0,
|
||||
'deleted': 0,
|
||||
'pinned': 0
|
||||
}, function(err) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
db.searchIndex('topic', title, tid);
|
||||
|
||||
user.addTopicIdToUser(uid, tid);
|
||||
|
||||
// in future it may be possible to add topics to several categories, so leaving the door open here.
|
||||
db.sortedSetAdd('categories:' + cid + ':tid', timestamp, tid);
|
||||
db.incrObjectField('category:' + cid, 'topic_count');
|
||||
db.incrObjectField('global', 'topicCount');
|
||||
|
||||
feed.updateCategory(cid);
|
||||
|
||||
callback(null, tid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Topics.post = function(uid, title, content, cid, callback) {
|
||||
|
||||
categoryTools.privileges(cid, uid, function(err, privileges) {
|
||||
@@ -32,8 +77,10 @@ var async = require('async'),
|
||||
return callback(new Error('no-privileges'));
|
||||
} else if (!cid) {
|
||||
return callback(new Error('invalid-cid'));
|
||||
} else if (!title || title.length < meta.config.minimumTitleLength) {
|
||||
} else if (!title || title.length < parseInt(meta.config.minimumTitleLength, 10)) {
|
||||
return callback(new Error('title-too-short'), null);
|
||||
} else if(title.length > parseInt(meta.config.maximumTitleLength, 10)) {
|
||||
return callback(new Error('title-too-long'), null);
|
||||
} else if (!content || content.length < meta.config.miminumPostLength) {
|
||||
return callback(new Error('content-too-short'), null);
|
||||
}
|
||||
@@ -58,58 +105,20 @@ var async = require('async'),
|
||||
return callback(new Error('too-many-posts'), null);
|
||||
}
|
||||
|
||||
db.incrObjectField('global', 'nextTid', function(err, tid) {
|
||||
Topics.create(uid, title, cid, function(err, tid) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.setAdd('topics:tid', tid);
|
||||
|
||||
var slug = tid + '/' + utils.slugify(title);
|
||||
var timestamp = Date.now();
|
||||
db.setObject('topic:' + tid, {
|
||||
'tid': tid,
|
||||
'uid': uid,
|
||||
'cid': cid,
|
||||
'title': title,
|
||||
'slug': slug,
|
||||
'timestamp': timestamp,
|
||||
'lastposttime': 0,
|
||||
'postcount': 0,
|
||||
'viewcount': 0,
|
||||
'locked': 0,
|
||||
'deleted': 0,
|
||||
'pinned': 0
|
||||
});
|
||||
|
||||
db.searchIndex('topic', title, tid);
|
||||
|
||||
user.addTopicIdToUser(uid, tid);
|
||||
|
||||
// let everyone know that there is an unread topic in this category
|
||||
db.delete('cid:' + cid + ':read_by_uid', function(err, data) {
|
||||
Topics.markAsRead(tid, uid);
|
||||
});
|
||||
|
||||
// in future it may be possible to add topics to several categories, so leaving the door open here.
|
||||
db.sortedSetAdd('categories:' + cid + ':tid', timestamp, tid);
|
||||
db.incrObjectField('category:' + cid, 'topic_count');
|
||||
db.incrObjectField('global', 'topicCount');
|
||||
|
||||
feed.updateCategory(cid);
|
||||
|
||||
posts.create(uid, tid, content, function(err, postData) {
|
||||
Topics.reply(tid, uid, content, function(err, postData) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
} else if(!postData) {
|
||||
return callback(new Error('invalid-post'), null);
|
||||
}
|
||||
|
||||
// Auto-subscribe the post creator to the newly created topic
|
||||
threadTools.toggleFollow(tid, uid);
|
||||
|
||||
Topics.pushUnreadCount();
|
||||
|
||||
Topics.getTopicForCategoryView(tid, uid, function(topicData) {
|
||||
topicData.unreplied = 1;
|
||||
|
||||
@@ -124,6 +133,105 @@ var async = require('async'),
|
||||
});
|
||||
};
|
||||
|
||||
Topics.reply = function(tid, uid, content, callback) {
|
||||
threadTools.privileges(tid, uid, function(err, privileges) {
|
||||
if (content) {
|
||||
content = content.trim();
|
||||
}
|
||||
|
||||
if (!content || content.length < meta.config.minimumPostLength) {
|
||||
return callback(new Error('content-too-short'));
|
||||
} else if (!privileges.write) {
|
||||
return callback(new Error('no-privileges'));
|
||||
}
|
||||
|
||||
posts.create(uid, tid, content, function(err, postData) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
} else if(!postData) {
|
||||
callback(new Error('reply-error'), null);
|
||||
}
|
||||
|
||||
posts.getCidByPid(postData.pid, function(err, cid) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
|
||||
db.delete('cid:' + cid + ':read_by_uid', function(err) {
|
||||
Topics.markAsUnreadForAll(tid, function(err) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
|
||||
Topics.markAsRead(tid, uid);
|
||||
Topics.pushUnreadCount();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
db.getObjectField('tid:lastFeedUpdate', tid, function(err, lastFeedUpdate) {
|
||||
var now = Date.now();
|
||||
if(!lastFeedUpdate || parseInt(lastFeedUpdate, 10) < now - 3600000) {
|
||||
feed.updateTopic(tid);
|
||||
db.setObjectField('tid:lastFeedUpdate', tid, now);
|
||||
}
|
||||
});
|
||||
|
||||
feed.updateRecent();
|
||||
|
||||
threadTools.notifyFollowers(tid, uid);
|
||||
|
||||
user.sendPostNotificationToFollowers(uid, tid, postData.pid);
|
||||
|
||||
posts.addUserInfoToPost(postData, function(err) {
|
||||
if(err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
|
||||
postData.favourited = false;
|
||||
postData.display_moderator_tools = true;
|
||||
postData.relativeTime = new Date(postData.timestamp).toISOString();
|
||||
|
||||
callback(null, postData);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Topics.createTopicFromPost = function(pid, callback) {
|
||||
posts.getPostData(pid, function(err, postData) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
posts.getCidByPid(pid, function(err, cid) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
// TODO : title should be given by client
|
||||
var title = postData.content.substr(0, 20);
|
||||
|
||||
Topics.create(postData.uid, title, cid, function(err, tid) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
Topics.removePostFromTopic(postData.tid, postData.pid);
|
||||
Topics.decreasePostCount(postData.tid);
|
||||
|
||||
posts.setPostField(pid, 'tid', tid);
|
||||
|
||||
Topics.onNewPostMade(tid, postData.pid, postData.timestamp);
|
||||
|
||||
Topics.getTopicData(tid, function(err, topicData) {
|
||||
callback(err, topicData);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Topics.getTopicData = function(tid, callback) {
|
||||
db.getObject('topic:' + tid, function(err, data) {
|
||||
if(err) {
|
||||
@@ -398,9 +506,10 @@ var async = require('async'),
|
||||
}
|
||||
|
||||
function sendUnreadTopics(topicIds) {
|
||||
|
||||
Topics.getTopicsByTids(topicIds, uid, function(topicData) {
|
||||
unreadTopics.topics = topicData;
|
||||
unreadTopics.nextStart = start + topicIds.length;
|
||||
unreadTopics.nextStart = stop + 1;
|
||||
if (!topicData || topicData.length === 0) {
|
||||
unreadTopics.no_topics_message = 'show';
|
||||
}
|
||||
@@ -606,6 +715,7 @@ var async = require('async'),
|
||||
'unreplied': parseInt(topicData.postcount, 10) > 1,
|
||||
'topic_id': tid,
|
||||
'expose_tools': privileges.editable ? 1 : 0,
|
||||
'disableSocialButtons': meta.config.disableSocialButtons !== undefined ? parseInt(meta.config.disableSocialButtons, 10) !== 0 : false,
|
||||
'posts': topicPosts
|
||||
});
|
||||
});
|
||||
@@ -826,7 +936,7 @@ var async = require('async'),
|
||||
if (postData.content) {
|
||||
stripped = postData.content.replace(/>.+\n\n/, '');
|
||||
postTools.parse(stripped, function(err, stripped) {
|
||||
returnObj.text = utils.strip_tags(stripped);
|
||||
returnObj.text = S(stripped).stripTags().s;
|
||||
callback(null, returnObj);
|
||||
});
|
||||
} else {
|
||||
@@ -838,16 +948,6 @@ var async = require('async'),
|
||||
});
|
||||
}
|
||||
|
||||
Topics.emitTitleTooShortAlert = function(socket) {
|
||||
socket.emit('event:alert', {
|
||||
type: 'danger',
|
||||
timeout: 2000,
|
||||
title: 'Title too short',
|
||||
message: "Please enter a longer title. At least " + meta.config.minimumTitleLength + " characters.",
|
||||
alert_id: 'post_error'
|
||||
});
|
||||
}
|
||||
|
||||
Topics.getTopicField = function(tid, field, callback) {
|
||||
db.getObjectField('topic:' + tid, field, callback);
|
||||
}
|
||||
@@ -864,6 +964,10 @@ var async = require('async'),
|
||||
db.incrObjectField('topic:' + tid, 'postcount', callback);
|
||||
}
|
||||
|
||||
Topics.decreasePostCount = function(tid, callback) {
|
||||
db.decrObjectField('topic:' + tid, 'postcount', callback);
|
||||
}
|
||||
|
||||
Topics.increaseViewCount = function(tid, callback) {
|
||||
db.incrObjectField('topic:' + tid, 'viewcount', callback);
|
||||
}
|
||||
@@ -882,10 +986,20 @@ var async = require('async'),
|
||||
Topics.setTopicField(tid, 'lastposttime', timestamp);
|
||||
}
|
||||
|
||||
Topics.onNewPostMade = function(tid, pid, timestamp) {
|
||||
Topics.addPostToTopic(tid, pid);
|
||||
Topics.increasePostCount(tid);
|
||||
Topics.updateTimestamp(tid, timestamp);
|
||||
}
|
||||
|
||||
Topics.addPostToTopic = function(tid, pid) {
|
||||
db.listAppend('tid:' + tid + ':posts', pid);
|
||||
}
|
||||
|
||||
Topics.removePostFromTopic = function(tid, pid) {
|
||||
db.listRemoveAll('tid:' + tid + ':posts', pid);
|
||||
}
|
||||
|
||||
Topics.getPids = function(tid, callback) {
|
||||
db.getListRange('tid:' + tid + ':posts', 0, -1, callback);
|
||||
}
|
||||
|
||||
267
src/upgrade.js
267
src/upgrade.js
@@ -3,16 +3,20 @@
|
||||
var db = require('./database'),
|
||||
async = require('async'),
|
||||
winston = require('winston'),
|
||||
|
||||
User = require('./user'),
|
||||
Topics = require('./topics'),
|
||||
Utils = require('../public/src/utils'),
|
||||
notifications = require('./notifications'),
|
||||
categories = require('./categories'),
|
||||
nconf = require('nconf'),
|
||||
|
||||
Upgrade = {},
|
||||
|
||||
schemaDate, thisSchemaDate;
|
||||
|
||||
Upgrade.check = function(callback) {
|
||||
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
|
||||
var latestSchema = new Date(2013, 11, 11).getTime();
|
||||
var latestSchema = new Date(2014, 0, 4).getTime();
|
||||
|
||||
db.get('schemaDate', function(err, value) {
|
||||
if (parseInt(value, 10) >= latestSchema) {
|
||||
@@ -24,28 +28,13 @@ Upgrade.check = function(callback) {
|
||||
};
|
||||
|
||||
Upgrade.upgrade = function(callback) {
|
||||
var databaseType = nconf.get('database');
|
||||
var updatesMade = false;
|
||||
|
||||
if(databaseType === 'redis') {
|
||||
Upgrade.upgradeRedis(callback);
|
||||
} else if(databaseType === 'mongo') {
|
||||
Upgrade.upgradeMongo(callback);
|
||||
} else {
|
||||
winston.error('Unknown database type. Aborting upgrade');
|
||||
callback(new Error('unknown-database'));
|
||||
}
|
||||
};
|
||||
|
||||
Upgrade.upgradeRedis = function(callback) {
|
||||
|
||||
var RDB = db.client,
|
||||
updatesMade = false;
|
||||
|
||||
winston.info('Beginning Redis database schema update');
|
||||
winston.info('Beginning database schema update');
|
||||
|
||||
async.series([
|
||||
function(next) {
|
||||
RDB.get('schemaDate', function(err, value) {
|
||||
db.get('schemaDate', function(err, value) {
|
||||
schemaDate = value;
|
||||
next();
|
||||
});
|
||||
@@ -56,11 +45,11 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
updatesMade = true;
|
||||
async.series([
|
||||
function(next) {
|
||||
RDB.keys('uid:*:notifications:flag', function(err, keys) {
|
||||
db.keys('uid:*:notifications:flag', function(err, keys) {
|
||||
if (keys.length > 0) {
|
||||
winston.info('[2013/10/03] Removing deprecated Notification Flags');
|
||||
async.each(keys, function(key, next) {
|
||||
RDB.del(key, next);
|
||||
db.delete(key, next);
|
||||
}, next);
|
||||
} else {
|
||||
winston.info('[2013/10/03] No Notification Flags found. Good.');
|
||||
@@ -70,13 +59,13 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
},
|
||||
function(next) {
|
||||
winston.info('[2013/10/03] Updating Notifications');
|
||||
RDB.keys('uid:*:notifications:*', function(err, keys) {
|
||||
db.keys('uid:*:notifications:*', function(err, keys) {
|
||||
async.each(keys, function(key, next) {
|
||||
RDB.zrange(key, 0, -1, function(err, nids) {
|
||||
db.getSortedSetRange(key, 0, -1, function(err, nids) {
|
||||
async.each(nids, function(nid, next) {
|
||||
notifications.get(nid, null, function(notif_data) {
|
||||
if (notif_data) {
|
||||
RDB.zadd(key, notif_data.datetime, nid, next);
|
||||
db.sortedSetAdd(key, notif_data.datetime, nid, next);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
@@ -87,7 +76,7 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
RDB.keys('notifications:*', function(err, keys) {
|
||||
db.keys('notifications:*', function(err, keys) {
|
||||
if (keys.length > 0) {
|
||||
winston.info('[2013/10/03] Removing Notification Scores');
|
||||
async.each(keys, function(key, next) {
|
||||
@@ -95,7 +84,7 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
return next();
|
||||
}
|
||||
|
||||
RDB.hdel(key, 'score', next);
|
||||
db.deleteObjectField(key, 'score', next);
|
||||
}, next);
|
||||
} else {
|
||||
winston.info('[2013/10/03] No Notification Scores found. Good.');
|
||||
@@ -113,7 +102,7 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
thisSchemaDate = new Date(2013, 9, 23).getTime();
|
||||
if (schemaDate < thisSchemaDate) {
|
||||
updatesMade = true;
|
||||
RDB.keys('notifications:*', function(err, keys) {
|
||||
db.keys('notifications:*', function(err, keys) {
|
||||
|
||||
keys = keys.filter(function(key) {
|
||||
if (key === 'notifications:next_nid') {
|
||||
@@ -129,9 +118,11 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
|
||||
if(keys && Array.isArray(keys)) {
|
||||
async.each(keys, function(key, cb) {
|
||||
RDB.sadd('notifications', key, cb);
|
||||
db.setAdd('notifications', key, cb);
|
||||
}, next);
|
||||
} else next();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
@@ -143,7 +134,7 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
thisSchemaDate = new Date(2013, 10, 11).getTime();
|
||||
if (schemaDate < thisSchemaDate) {
|
||||
updatesMade = true;
|
||||
RDB.hset('config', 'postDelay', 10, function(err, success) {
|
||||
db.setObjectField('config', 'postDelay', 10, function(err, success) {
|
||||
winston.info('[2013/11/11] Updated postDelay to 10 seconds.');
|
||||
next();
|
||||
});
|
||||
@@ -156,10 +147,10 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
thisSchemaDate = new Date(2013, 10, 22).getTime();
|
||||
if (schemaDate < thisSchemaDate) {
|
||||
updatesMade = true;
|
||||
RDB.keys('category:*', function(err, categories) {
|
||||
db.keys('category:*', function(err, categories) {
|
||||
async.each(categories, function(categoryStr, next) {
|
||||
var hex;
|
||||
RDB.hgetall(categoryStr, function(err, categoryObj) {
|
||||
db.getObject(categoryStr, function(err, categoryObj) {
|
||||
switch(categoryObj.blockclass) {
|
||||
case 'category-purple':
|
||||
hex = '#ab1290';
|
||||
@@ -186,8 +177,8 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
break;
|
||||
}
|
||||
|
||||
RDB.hset(categoryStr, 'bgColor', hex, next);
|
||||
RDB.hdel(categoryStr, 'blockclass');
|
||||
db.setObjectField(categoryStr, 'bgColor', hex, next);
|
||||
db.deleteObjectField(categoryStr, 'blockclass');
|
||||
});
|
||||
}, function() {
|
||||
winston.info('[2013/11/22] Updated Category colours.');
|
||||
@@ -217,7 +208,7 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
icon = category.icon.replace('icon-', 'fa-');
|
||||
}
|
||||
|
||||
RDB.hset('category:' + category.cid, 'icon', icon, next);
|
||||
db.setObjectField('category:' + category.cid, 'icon', icon, next);
|
||||
}
|
||||
|
||||
async.each(categories.categories, updateIcon, function(err) {
|
||||
@@ -236,15 +227,15 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
function(next) {
|
||||
|
||||
function updateKeyToHash(key, next) {
|
||||
RDB.get(key, function(err, value) {
|
||||
db.get(key, function(err, value) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if(value === null) {
|
||||
RDB.hset('global', newKeys[key], initialValues[key], next);
|
||||
db.setObjectField('global', newKeys[key], initialValues[key], next);
|
||||
} else {
|
||||
RDB.hset('global', newKeys[key], value, next);
|
||||
db.setObjectField('global', newKeys[key], value, next);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -305,67 +296,6 @@ Upgrade.upgradeRedis = function(callback) {
|
||||
}
|
||||
},
|
||||
function(next) {
|
||||
thisSchemaDate = new Date(2013, 11, 11).getTime();
|
||||
if (schemaDate < thisSchemaDate) {
|
||||
updatesMade = true;
|
||||
|
||||
RDB.hset('config', 'allowGuestSearching', '0', function(err){
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
winston.info('[2013/12/11] Updated guest search config.');
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
winston.info('[2013/12/11] Update to guest search skipped');
|
||||
next();
|
||||
}
|
||||
}
|
||||
// Add new schema updates here
|
||||
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 12!!!
|
||||
], function(err) {
|
||||
if (!err) {
|
||||
RDB.set('schemaDate', thisSchemaDate, function(err) {
|
||||
if (!err) {
|
||||
if(updatesMade) {
|
||||
winston.info('[upgrade] Redis schema update complete!');
|
||||
} else {
|
||||
winston.info('[upgrade] Redis schema already up to date!');
|
||||
}
|
||||
if (callback) {
|
||||
callback(err);
|
||||
} else {
|
||||
process.exit();
|
||||
}
|
||||
} else {
|
||||
winston.error('[upgrade] Could not update NodeBB schema date!');
|
||||
process.exit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
winston.error('[upgrade] Errors were encountered while updating the NodeBB schema: ' + err.message);
|
||||
process.exit();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Upgrade.upgradeMongo = function(callback) {
|
||||
// why can't we just use the abstracted db module here? and in upgradeRedis()?
|
||||
var MDB = db.client,
|
||||
updatesMade = false;
|
||||
|
||||
winston.info('Beginning Mongo database schema update');
|
||||
|
||||
async.series([
|
||||
function(next) {
|
||||
db.get('schemaDate', function(err, value) {
|
||||
schemaDate = value;
|
||||
thisSchemaDate = new Date(2013, 11, 6).getTime();
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
|
||||
thisSchemaDate = new Date(2013, 11, 11).getTime();
|
||||
if (schemaDate < thisSchemaDate) {
|
||||
updatesMade = true;
|
||||
@@ -381,17 +311,144 @@ Upgrade.upgradeMongo = function(callback) {
|
||||
winston.info('[2013/12/11] Update to guest search skipped');
|
||||
next();
|
||||
}
|
||||
},
|
||||
function(next) {
|
||||
thisSchemaDate = new Date(2013, 11, 31).getTime();
|
||||
if (schemaDate < thisSchemaDate) {
|
||||
updatesMade = true;
|
||||
|
||||
async.parallel([
|
||||
function(next) {
|
||||
// Re-slugify all topics
|
||||
db.getSortedSetRange('topics:recent', 0, -1, function(err, tids) {
|
||||
var newTitle;
|
||||
|
||||
async.each(tids, function(tid, next) {
|
||||
Topics.getTopicField(tid, 'title', function(err, title) {
|
||||
newTitle = tid + '/' + Utils.slugify(title);
|
||||
Topics.setTopicField(tid, 'slug', newTitle, next);
|
||||
});
|
||||
}, function(err) {
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
// Re-slugify all users
|
||||
db.getObjectValues('username:uid', function(err, uids) {
|
||||
var newUserSlug;
|
||||
|
||||
async.each(uids, function(uid, next) {
|
||||
User.getUserField(uid, 'username', function(err, username) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
if(username) {
|
||||
newUserSlug = Utils.slugify(username);
|
||||
User.setUserField(uid, 'userslug', newUserSlug, next);
|
||||
} else {
|
||||
winston.warn('uid '+ uid + ' doesn\'t have a valid username (' + username + '), skipping');
|
||||
next(null);
|
||||
}
|
||||
});
|
||||
}, function(err) {
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
], function(err) {
|
||||
winston.info('[2013/12/31] Re-slugify Topics and Users');
|
||||
next(err);
|
||||
});
|
||||
} else {
|
||||
winston.info('[2013/12/31] Re-slugify Topics and Users skipped');
|
||||
next();
|
||||
}
|
||||
},
|
||||
function(next) {
|
||||
thisSchemaDate = new Date(2014, 0, 1).getTime();
|
||||
if (schemaDate < thisSchemaDate) {
|
||||
updatesMade = true;
|
||||
|
||||
db.isObjectField('config', 'maximumTitleLength', function(err, isField) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
if(!isField) {
|
||||
db.setObjectField('config', 'maximumTitleLength', 255, function(err) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
winston.info('[2013/12/31] Added maximumTitleLength');
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
winston.info('[2013/12/31] maximumTitleLength already set');
|
||||
next();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
winston.info('[2013/12/31] maximumTitleLength skipped');
|
||||
next();
|
||||
}
|
||||
},
|
||||
function(next) {
|
||||
// Custom classes for each category, adding link field for each category
|
||||
thisSchemaDate = new Date(2014, 0, 3).getTime();
|
||||
if (schemaDate < thisSchemaDate) {
|
||||
updatesMade = true;
|
||||
|
||||
db.getListRange('categories:cid', 0, -1, function(err, cids) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
for (var cid in cids) {
|
||||
db.setObjectField('category:' + cids[cid], 'link', '');
|
||||
db.setObjectField('category:' + cids[cid], 'class', 'col-md-3 col-xs-6');
|
||||
}
|
||||
|
||||
winston.info('[2013/12/31] Added categories.class, categories.link fields');
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
winston.info('[2014/1/3] categories.class, categories.link fields skipped');
|
||||
next();
|
||||
}
|
||||
},
|
||||
function(next) {
|
||||
// Custom classes for each category, adding link field for each category
|
||||
thisSchemaDate = new Date(2014, 0, 4).getTime();
|
||||
if (schemaDate < thisSchemaDate) {
|
||||
updatesMade = true;
|
||||
|
||||
db.getListRange('categories:cid', 0, -1, function(err, cids) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
for (var cid in cids) {
|
||||
db.setObjectField('category:' + cids[cid], 'numRecentReplies', '2');
|
||||
}
|
||||
|
||||
winston.info('[2013/12/31] Added categories.numRecentReplies fields');
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
winston.info('[2014/1/3] categories.numRecentReplies fields skipped');
|
||||
next();
|
||||
}
|
||||
}
|
||||
// Add new schema updates here
|
||||
|
||||
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 17!!!
|
||||
], function(err) {
|
||||
if (!err) {
|
||||
db.set('schemaDate', thisSchemaDate, function(err) {
|
||||
if (!err) {
|
||||
if(updatesMade) {
|
||||
winston.info('[upgrade] Mongo schema update complete!');
|
||||
winston.info('[upgrade] Schema update complete!');
|
||||
} else {
|
||||
winston.info('[upgrade] Mongo schema already up to date!');
|
||||
winston.info('[upgrade] Schema already up to date!');
|
||||
}
|
||||
if (callback) {
|
||||
callback(err);
|
||||
@@ -399,7 +456,7 @@ Upgrade.upgradeMongo = function(callback) {
|
||||
process.exit();
|
||||
}
|
||||
} else {
|
||||
winston.error('[upgrade] Could not update NodeBB schema date!');
|
||||
winston.error('[upgrade] Could not update NodeBB schema data!');
|
||||
process.exit();
|
||||
}
|
||||
});
|
||||
@@ -408,6 +465,6 @@ Upgrade.upgradeMongo = function(callback) {
|
||||
process.exit();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Upgrade;
|
||||
@@ -6,6 +6,7 @@ var bcrypt = require('bcrypt'),
|
||||
gravatar = require('gravatar'),
|
||||
check = require('validator').check,
|
||||
sanitize = require('validator').sanitize,
|
||||
S = require('string'),
|
||||
|
||||
utils = require('./../public/src/utils'),
|
||||
plugins = require('./plugins'),
|
||||
@@ -266,7 +267,7 @@ var bcrypt = require('bcrypt'),
|
||||
});
|
||||
return;
|
||||
} else if (field === 'signature') {
|
||||
data[field] = utils.strip_tags(data[field]);
|
||||
data[field] = S(data[field]).stripTags().s;
|
||||
} else if (field === 'website') {
|
||||
if(data[field].substr(0, 7) !== 'http://' && data[field].substr(0, 8) !== 'https://') {
|
||||
data[field] = 'http://' + data[field];
|
||||
@@ -432,8 +433,6 @@ var bcrypt = require('bcrypt'),
|
||||
});
|
||||
|
||||
User.setUserField(uid, 'lastposttime', timestamp);
|
||||
|
||||
User.sendPostNotificationToFollowers(uid, tid, pid);
|
||||
};
|
||||
|
||||
User.addPostIdToUser = function(uid, pid) {
|
||||
@@ -756,7 +755,7 @@ var bcrypt = require('bcrypt'),
|
||||
// Generate a new reset code
|
||||
var reset_code = utils.generateUUID();
|
||||
db.setObjectField('reset:uid', reset_code, uid);
|
||||
db.setobjectField('reset:expiry', reset_code, (60 * 60) + new Date() / 1000 | 0); // Active for one hour
|
||||
db.setObjectField('reset:expiry', reset_code, (60 * 60) + new Date() / 1000 | 0); // Active for one hour
|
||||
|
||||
var reset_link = nconf.get('url') + 'reset/' + reset_code,
|
||||
reset_email = global.templates['emails/reset'].parse({
|
||||
|
||||
127
src/webserver.js
127
src/webserver.js
@@ -9,6 +9,7 @@ var path = require('path'),
|
||||
winston = require('winston'),
|
||||
validator = require('validator'),
|
||||
async = require('async'),
|
||||
S = require('string'),
|
||||
|
||||
pkg = require('../package.json'),
|
||||
|
||||
@@ -54,7 +55,7 @@ var path = require('path'),
|
||||
|
||||
/**
|
||||
* `options` object requires: req, res
|
||||
* accepts: metaTags
|
||||
* accepts: metaTags, linkTags
|
||||
*/
|
||||
app.build_header = function (options, callback) {
|
||||
var custom_header = {
|
||||
@@ -82,8 +83,6 @@ var path = require('path'),
|
||||
rel: 'apple-touch-icon',
|
||||
href: meta.config['brand:logo'] || nconf.get('relative_path') + '/logo.png'
|
||||
}],
|
||||
metaString = utils.buildMetaTags(defaultMetaTags.concat(options.metaTags || [])),
|
||||
linkTags = utils.buildLinkTags(defaultLinkTags.concat(options.linkTags || [])),
|
||||
templateValues = {
|
||||
cssSrc: meta.config['theme:src'] || nconf.get('relative_path') + '/vendor/bootstrap/css/bootstrap.min.css',
|
||||
pluginCSS: plugins.cssFiles.map(function(file) { return { path: file + (meta.config['cache-buster'] ? '?v=' + meta.config['cache-buster'] : '') }; }),
|
||||
@@ -95,16 +94,30 @@ var path = require('path'),
|
||||
browserTitle: meta.config.title || 'NodeBB',
|
||||
csrf: options.res.locals.csrf_token,
|
||||
relative_path: nconf.get('relative_path'),
|
||||
meta_tags: metaString,
|
||||
link_tags: linkTags,
|
||||
clientScripts: clientScripts,
|
||||
navigation: custom_header.navigation,
|
||||
'cache-buster': meta.config['cache-buster'] ? 'v=' + meta.config['cache-buster'] : '',
|
||||
allowRegistration: meta.config.allowRegistration === undefined || parseInt(meta.config.allowRegistration, 10) === 1
|
||||
},
|
||||
escapeList = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
"'": ''',
|
||||
'"': '"'
|
||||
};
|
||||
|
||||
var uid = '0';
|
||||
|
||||
// Meta Tags
|
||||
templateValues.meta_tags = utils.buildMetaTags(defaultMetaTags.concat(options.metaTags || []).map(function(tag) {
|
||||
tag.content = tag.content.replace(/[&<>'"]/g, function(tag) {
|
||||
return escapeList[tag] || tag;
|
||||
});
|
||||
return tag;
|
||||
}));
|
||||
templateValues.link_tags = utils.buildLinkTags(defaultLinkTags.concat(options.linkTags || []));
|
||||
|
||||
if(options.req.user && options.req.user.uid) {
|
||||
uid = options.req.user.uid;
|
||||
}
|
||||
@@ -182,6 +195,13 @@ var path = require('path'),
|
||||
// Authentication Routes
|
||||
auth.initialize(app);
|
||||
|
||||
app.use(function(req, res, next) {
|
||||
if(req.user) {
|
||||
user.setUserField(req.user.uid, 'lastonline', Date.now());
|
||||
}
|
||||
next();
|
||||
})
|
||||
|
||||
next();
|
||||
},
|
||||
function(next) {
|
||||
@@ -507,8 +527,17 @@ var path = require('path'),
|
||||
},
|
||||
function (topicData, next) {
|
||||
var lastMod = 0,
|
||||
timestamp,
|
||||
sanitize = validator.sanitize;
|
||||
sanitize = validator.sanitize,
|
||||
description = (function() {
|
||||
var content = S(topicData.posts[0].content).stripTags().s;
|
||||
|
||||
if (content.length > 255) {
|
||||
content = content.substr(0, 255) + '...';
|
||||
}
|
||||
|
||||
return sanitize(content).escape();
|
||||
})(),
|
||||
timestamp;
|
||||
|
||||
for (var x = 0, numPosts = topicData.posts.length; x < numPosts; x++) {
|
||||
timestamp = parseInt(topicData.posts[x].timestamp, 10);
|
||||
@@ -520,34 +549,48 @@ var path = require('path'),
|
||||
app.build_header({
|
||||
req: req,
|
||||
res: res,
|
||||
metaTags: [{
|
||||
name: "title",
|
||||
content: topicData.topic_name
|
||||
}, {
|
||||
name: "description",
|
||||
content: sanitize(topicData.posts[0].content.substr(0, 255)).escape().replace('\n', '')
|
||||
}, {
|
||||
property: 'og:title',
|
||||
content: topicData.topic_name + ' | ' + (meta.config.title || 'NodeBB')
|
||||
}, {
|
||||
property: "og:type",
|
||||
content: 'article'
|
||||
}, {
|
||||
property: "og:url",
|
||||
content: nconf.get('url') + 'topic/' + topicData.slug
|
||||
}, {
|
||||
property: 'og:image',
|
||||
content: topicData.posts[0].picture
|
||||
}, {
|
||||
property: "article:published_time",
|
||||
content: new Date(parseInt(topicData.posts[0].timestamp, 10)).toISOString()
|
||||
}, {
|
||||
property: 'article:modified_time',
|
||||
content: new Date(lastMod).toISOString()
|
||||
}, {
|
||||
property: 'article:section',
|
||||
content: topicData.category_name
|
||||
}],
|
||||
metaTags: [
|
||||
{
|
||||
name: "title",
|
||||
content: topicData.topic_name
|
||||
},
|
||||
{
|
||||
name: "description",
|
||||
content: description
|
||||
},
|
||||
{
|
||||
property: 'og:title',
|
||||
content: topicData.topic_name + ' | ' + (meta.config.title || 'NodeBB')
|
||||
},
|
||||
{
|
||||
property: 'og:description',
|
||||
content: description
|
||||
},
|
||||
{
|
||||
property: "og:type",
|
||||
content: 'article'
|
||||
},
|
||||
{
|
||||
property: "og:url",
|
||||
content: nconf.get('url') + 'topic/' + topicData.slug
|
||||
},
|
||||
{
|
||||
property: 'og:image',
|
||||
content: topicData.posts[0].picture
|
||||
},
|
||||
{
|
||||
property: "article:published_time",
|
||||
content: new Date(parseInt(topicData.posts[0].timestamp, 10)).toISOString()
|
||||
},
|
||||
{
|
||||
property: 'article:modified_time',
|
||||
content: new Date(lastMod).toISOString()
|
||||
},
|
||||
{
|
||||
property: 'article:section',
|
||||
content: topicData.category_name
|
||||
}
|
||||
],
|
||||
linkTags: [
|
||||
{
|
||||
rel: 'alternate',
|
||||
@@ -783,7 +826,8 @@ var path = require('path'),
|
||||
|
||||
var custom_routes = {
|
||||
'routes': [],
|
||||
'api': []
|
||||
'api': [],
|
||||
'templates': []
|
||||
};
|
||||
|
||||
plugins.ready(function() {
|
||||
@@ -819,6 +863,17 @@ var path = require('path'),
|
||||
}
|
||||
}
|
||||
|
||||
var templateRoutes = custom_routes.templates;
|
||||
for (var route in templateRoutes) {
|
||||
if (templateRoutes.hasOwnProperty(route)) {
|
||||
(function(route) {
|
||||
app.get('/templates/' + templateRoutes[route].template, function(req, res) {
|
||||
res.send(templateRoutes[route].content);
|
||||
});
|
||||
}(route));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ var cookie = require('cookie'),
|
||||
nconf = require('nconf'),
|
||||
gravatar = require('gravatar'),
|
||||
winston = require('winston'),
|
||||
S = require('string'),
|
||||
|
||||
db = require('./database'),
|
||||
|
||||
@@ -105,12 +106,12 @@ websockets.init = function(io) {
|
||||
|
||||
socket.on('disconnect', function() {
|
||||
|
||||
var index = userSockets[uid].indexOf(socket);
|
||||
var index = (userSockets[uid] || []).indexOf(socket);
|
||||
if (index !== -1) {
|
||||
userSockets[uid].splice(index, 1);
|
||||
}
|
||||
|
||||
if (userSockets[uid].length === 0) {
|
||||
if (userSockets[uid] && userSockets[uid].length === 0) {
|
||||
delete users[sessionID];
|
||||
delete userSockets[uid];
|
||||
if (uid) {
|
||||
@@ -361,6 +362,35 @@ websockets.init = function(io) {
|
||||
}
|
||||
});
|
||||
|
||||
function emitAlert(socket, title, message) {
|
||||
socket.emit('event:alert', {
|
||||
type: 'danger',
|
||||
timeout: 2000,
|
||||
title: title,
|
||||
message: message,
|
||||
alert_id: 'post_error'
|
||||
});
|
||||
}
|
||||
|
||||
function emitContentTooShortAlert(socket) {
|
||||
socket.emit('event:alert', {
|
||||
type: 'danger',
|
||||
timeout: 2000,
|
||||
title: 'Content too short',
|
||||
message: "Please enter a longer post. At least " + meta.config.minimumPostLength + " characters.",
|
||||
alert_id: 'post_error'
|
||||
});
|
||||
}
|
||||
|
||||
function emitTooManyPostsAlert(socket) {
|
||||
socket.emit('event:alert', {
|
||||
title: 'Too many posts!',
|
||||
message: 'You can only post every ' + meta.config.postDelay + ' seconds.',
|
||||
type: 'danger',
|
||||
timeout: 2000
|
||||
});
|
||||
}
|
||||
|
||||
socket.on('api:topics.post', function(data) {
|
||||
if (uid < 1 && parseInt(meta.config.allowGuestPosting, 10) === 0) {
|
||||
socket.emit('event:alert', {
|
||||
@@ -375,11 +405,13 @@ websockets.init = function(io) {
|
||||
topics.post(uid, data.title, data.content, data.category_id, function(err, result) {
|
||||
if(err) {
|
||||
if (err.message === 'title-too-short') {
|
||||
topics.emitTitleTooShortAlert(socket);
|
||||
emitAlert(socket, 'Title too short', 'Please enter a longer title. At least ' + meta.config.minimumTitleLength + ' characters.');
|
||||
} else if (err.message === 'title-too-long') {
|
||||
emitAlert(socket, 'Title too long', 'Please enter a shorter title. Titles can\'t be longer than ' + meta.config.maximumTitleLength + ' characters.');
|
||||
} else if (err.message === 'content-too-short') {
|
||||
posts.emitContentTooShortAlert(socket);
|
||||
emitContentTooShortAlert(socket);
|
||||
} else if (err.message === 'too-many-posts') {
|
||||
posts.emitTooManyPostsAlert(socket);
|
||||
emitTooManyPostsAlert(socket);
|
||||
} else if (err.message === 'no-privileges') {
|
||||
socket.emit('event:alert', {
|
||||
title: 'Unable to post',
|
||||
@@ -444,16 +476,16 @@ websockets.init = function(io) {
|
||||
}
|
||||
|
||||
if (Date.now() - lastPostTime < meta.config.postDelay * 1000) {
|
||||
posts.emitTooManyPostsAlert(socket);
|
||||
emitTooManyPostsAlert(socket);
|
||||
return;
|
||||
}
|
||||
|
||||
posts.reply(data.topic_id, uid, data.content, function(err, postData) {
|
||||
topics.reply(data.topic_id, uid, data.content, function(err, postData) {
|
||||
if(err) {
|
||||
if (err.message === 'content-too-short') {
|
||||
posts.emitContentTooShortAlert(socket);
|
||||
emitContentTooShortAlert(socket);
|
||||
} else if (err.message === 'too-many-posts') {
|
||||
posts.emitTooManyPostsAlert(socket);
|
||||
emitTooManyPostsAlert(socket);
|
||||
} else if (err.message === 'reply-error') {
|
||||
socket.emit('event:alert', {
|
||||
title: 'Reply Unsuccessful',
|
||||
@@ -530,7 +562,7 @@ websockets.init = function(io) {
|
||||
socket.on('api:topic.delete', function(data) {
|
||||
threadTools.privileges(data.tid, uid, function(err, privileges) {
|
||||
if (!err && privileges.editable) {
|
||||
threadTools.delete(data.tid, function(err) {
|
||||
threadTools.delete(data.tid, uid, function(err) {
|
||||
if (!err) {
|
||||
emitTopicPostStats();
|
||||
socket.emit('api:topic.delete', {
|
||||
@@ -546,7 +578,7 @@ websockets.init = function(io) {
|
||||
socket.on('api:topic.restore', function(data) {
|
||||
threadTools.privileges(data.tid, uid, function(err, privileges) {
|
||||
if (!err && privileges.editable) {
|
||||
threadTools.restore(data.tid, socket, function(err) {
|
||||
threadTools.restore(data.tid, uid, function(err) {
|
||||
emitTopicPostStats();
|
||||
|
||||
socket.emit('api:topic.restore', {
|
||||
@@ -590,6 +622,12 @@ websockets.init = function(io) {
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('api:topic.createTopicFromPost', function(data, callback) {
|
||||
topics.createTopicFromPost(data.pid, function(err, data) {
|
||||
callback(err?{message:err.message}:null, data);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('api:topic.move', function(data) {
|
||||
threadTools.move(data.tid, data.cid, socket);
|
||||
});
|
||||
@@ -606,6 +644,10 @@ websockets.init = function(io) {
|
||||
posts.uploadPostImage(data, callback);
|
||||
});
|
||||
|
||||
socket.on('api:posts.uploadFile', function(data, callback) {
|
||||
posts.uploadPostFile(data, callback);
|
||||
});
|
||||
|
||||
socket.on('api:posts.getRawPost', function(data, callback) {
|
||||
posts.getPostField(data.pid, 'content', function(err, raw) {
|
||||
callback({
|
||||
@@ -627,7 +669,7 @@ websockets.init = function(io) {
|
||||
topics.emitTitleTooShortAlert(socket);
|
||||
return;
|
||||
} else if (!data.content || data.content.length < parseInt(meta.config.minimumPostLength, 10)) {
|
||||
posts.emitContentTooShortAlert(socket);
|
||||
emitContentTooShortAlert(socket);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -712,7 +754,7 @@ websockets.init = function(io) {
|
||||
return;
|
||||
}
|
||||
|
||||
var msg = utils.strip_tags(data.message);
|
||||
var msg = S(data.message).stripTags().s;
|
||||
|
||||
user.getMultipleUserFields([uid, touid], ['username'], function(err, usersData) {
|
||||
if(err) {
|
||||
|
||||
Reference in New Issue
Block a user