use path instead of resource

This commit is contained in:
John McLear 2014-11-28 00:08:10 +00:00
commit 3f27bdff0b
75 changed files with 1642 additions and 539 deletions

1
bin/backendTests.sh Executable file
View file

@ -0,0 +1 @@
src/node_modules/mocha/bin/mocha --timeout 5000 --reporter nyan tests/backend/specs/api

View file

@ -99,7 +99,7 @@ fi
echo "Clear minfified cache..."
rm -f var/minified*
echo "ensure custom css/js files are created..."
echo "Ensure custom css/js files are created..."
for f in "index" "pad" "timeslider"
do

View file

@ -1,9 +0,0 @@
#!/bin/sh
if [ -d "../bin" ]; then
cd "../"
fi
JSHINT=./node_modules/jshint/bin/hint
$JSHINT ./node/

View file

@ -1,79 +0,0 @@
This is the new load testing file: https://bitbucket.org/rbraakman/etherpad-stresstest
BELOW is the original load testing file.
This load tester is extremely useful for testing how many dormant clients can connect to etherpad.
TODO:
Emulate characters being typed into a pad
HOW TO USE (from @mjd75) proper formatting at: https://github.com/ether/etherpad-lite/issues/360
Server 1:
Installed Node.js (etc), EtherPad and MySQL
Server 2:
Installed Xvfb and PhantomJS
I installed Xvfb following (roughly) this guide: http://blog.martin-lyness.com/archives/installing-xvfb-on-ubuntu-9-10-karmic-koala
#sudo apt-get install xvfb
#sudo apt-get install xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic
Launched two instances of Xvfb directly from the terminal:
#Xvfb :0 -ac
#Xvfb :1 -ac
I installed PhantomJS following this guide: http://code.google.com/p/phantomjs/wiki/Installation
#sudo add-apt-repository ppa:jerome-etienne/neoip
#sudo apt-get update
#sudo apt-get install phantomjs
I created a small JavaScript file for PhatomJS to use to control the browser instances:
### BEGIN JAVASCRIPT ###
var page = new WebPage(),
t, address;
if (phantom.args.length === 0) {
console.log('Usage: loader.js <some URL>');
phantom.exit();
} else {
t = Date.now();
address = phantom.args[0];
var page = new WebPage();
page.onResourceRequested = function (request) {
console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function (response) {
console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
page.open(address);
}
### END JAVASCRIPT ###
And finally a launcher script that uses screen to run 400 instances of PhantomJS with the above script:
### BEGIN SHELL SCRIPT ###
#!/bin/bash
# connect 200 instances to display :0
for i in {1..200}
do
DISPLAY=:0 screen -d -m phantomjs loader.js http://ec2-50-17-168-xx.compute-1.amazonaws.com:9001/p/pad2 && sleep 2
done
# connect 200 instances to display :1
for i in {1..200}
do
DISPLAY=:1 screen -d -m phantomjs loader.js http://ec2-50-17-168-xx.compute-1.amazonaws.com:9001/p/pad2 && sleep 2
done
### END SHELL SCRIPT ###

View file

@ -1,16 +0,0 @@
#!/bin/bash
# connect 500 instances to display :0
for i in {1..500}
do
echo $i
echo "Displaying Some shit"
DISPLAY=:0 screen -d -m /home/phantomjs/bin/phantomjs loader.js http://10.0.0.55:9001/p/pad2 && sleep 2
done
# connect 500 instances to display :1
for i in {1..500}
do
echo $i
DISPLAY=:1 screen -d -m /home/phantomjs/bin/phantomjs loader.js http://10.0.0.55:9001/p/pad2 && sleep 2
done

View file

@ -1,20 +0,0 @@
var page = new WebPage(),
t, address;
if (phantom.args.length === 0) {
console.log('Usage: loader.js <some URL>');
phantom.exit();
} else {
t = Date.now();
address = phantom.args[0];
var page = new WebPage();
page.onResourceRequested = function (request) {
console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function (response) {
console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
page.open(address);
}

View file

@ -32,7 +32,7 @@ fi
bin/installDeps.sh $* || exit 1
#Move to the node folder and start
echo "start..."
echo "Started Etherpad..."
SCRIPTPATH=`pwd -P`
node $SCRIPTPATH/node_modules/ep_etherpad-lite/node/server.js $*

View file

@ -450,6 +450,7 @@ exports.handle = function(apiVersion, functionName, fields, req, res)
if(fields["apikey"] != apikey.trim())
{
res.statusCode = 401;
res.send({code: 4, message: "no or wrong API Key", data: null});
return;
}

View file

@ -234,7 +234,19 @@ exports.doImport = function(req, res, padId)
ERR(err);
//close the connection
res.send("<head><script type='text/javascript' src='../../static/js/jquery.js'></script><script type='text/javascript' src='../../static/js/jquery_browser.js'></script></head><script>$(window).load(function(){if ( (!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf(\"1.8.\") == 0)) ){document.domain = document.domain;}var impexp = window.parent.padimpexp.handleFrameCall('" + status + "');})</script>", 200);
res.send(
"<head> \
<script type='text/javascript' src='../../static/js/jquery.js'></script> \
</head> \
<script> \
$(window).load(function(){ \
if(navigator.userAgent.indexOf('MSIE') === -1){ \
document.domain = document.domain; \
} \
var impexp = window.parent.padimpexp.handleFrameCall('" + status + "'); \
}) \
</script>"
, 200);
});
}

View file

@ -94,8 +94,18 @@ exports.handleConnect = function(client)
*/
exports.kickSessionsFromPad = function(padID)
{
if(typeof socketio.sockets['clients'] !== 'function')
return;
//skip if there is nobody on this pad
if(socketio.sockets.clients(padID).length == 0)
var roomClients = [], room = socketio.sockets.adapter.rooms[padID];
if (room) {
for (var id in room) {
roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
}
}
if(roomClients.length == 0)
return;
//disconnect everyone from this pad
@ -496,14 +506,19 @@ function handleSuggestUserName(client, message)
return;
}
var padId = sessioninfos[client.id].padId,
clients = socketio.sockets.clients(padId);
var padId = sessioninfos[client.id].padId;
var roomClients = [], room = socketio.sockets.adapter.rooms[padId];
if (room) {
for (var id in room) {
roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
}
}
//search the author and send him this message
for(var i = 0; i < clients.length; i++) {
var session = sessioninfos[clients[i].id];
for(var i = 0; i < roomClients.length; i++) {
var session = sessioninfos[roomClients[i].id];
if(session && session.author == message.data.payload.unnamedId) {
clients[i].json.send(message);
roomClients[i].json.send(message);
break;
}
}
@ -1581,8 +1596,16 @@ function composePadChangesets(padId, startNum, endNum, callback)
* Get the number of users in a pad
*/
exports.padUsersCount = function (padID, callback) {
var roomClients = [], room = socketio.sockets.adapter.rooms[padID];
if (room) {
for (var id in room) {
roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
}
}
callback(null, {
padUsersCount: socketio.sockets.clients(padID).length
padUsersCount: roomClients.length
});
}
@ -1592,7 +1615,14 @@ exports.padUsersCount = function (padID, callback) {
exports.padUsers = function (padID, callback) {
var result = [];
async.forEach(socketio.sockets.clients(padID), function(roomClient, callback) {
var roomClients = [], room = socketio.sockets.adapter.rooms[padID];
if (room) {
for (var id in room) {
roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
}
}
async.forEach(roomClients, function(roomClient, callback) {
var s = sessioninfos[roomClient.id];
if(s) {
authorManager.getAuthor(s.author, function(err, author) {

View file

@ -14,7 +14,6 @@ exports.expressCreateServer = function (hook_name, args, cb) {
search_results: {},
errors: [],
};
res.send( eejs.require("ep_etherpad-lite/templates/admin/plugins.html", render_args) );
});
args.app.get('/admin/plugins/info', function(req, res) {
@ -25,7 +24,8 @@ exports.expressCreateServer = function (hook_name, args, cb) {
exports.socketio = function (hook_name, args, cb) {
var io = args.io.of("/pluginfw/installer");
io.on('connection', function (socket) {
if (!socket.handshake.session.user || !socket.handshake.session.user.is_admin) return;
if (!socket.conn.request.session || !socket.conn.request.session.user || !socket.conn.request.session.user.is_admin) return;
socket.on("getInstalled", function (query) {
// send currently installed plugins

View file

@ -22,7 +22,8 @@ exports.expressCreateServer = function (hook_name, args, cb) {
exports.socketio = function (hook_name, args, cb) {
var io = args.io.of("/settings");
io.on('connection', function (socket) {
if (!socket.handshake.session.user || !socket.handshake.session.user.is_admin) return;
if (!socket.conn.request.session || !socket.conn.request.session.user || !socket.conn.request.session.user.is_admin) return;
socket.on("load", function (query) {
fs.readFile('settings.json', 'utf8', function (err,data) {

View file

@ -1,24 +1,22 @@
var log4js = require('log4js');
var settings = require('../../utils/Settings');
var socketio = require('socket.io');
var socketIORouter = require("../../handler/SocketIORouter");
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
var webaccess = require("ep_etherpad-lite/node/hooks/express/webaccess");
// there shouldn't be a browser that isn't compatible to all
// transports in this list at once
// e.g. XHR is disabled in IE by default, so in IE it should use jsonp-polling
var socketio = require('socket.io')({
transports: settings.socketTransportProtocols
});
var padMessageHandler = require("../../handler/PadMessageHandler");
var connect = require('connect');
exports.expressCreateServer = function (hook_name, args, cb) {
//init socket.io and redirect all requests to the MessageHandler
var io = socketio.listen(args.server);
// there shouldn't be a browser that isn't compatible to all
// transports in this list at once
// e.g. XHR is disabled in IE by default, so in IE it should use jsonp-polling
var io = socketio({
transports: settings.socketTransportProtocols
}).listen(args.server);
/* Require an express session cookie to be present, and load the
* session. See http://www.danielbaulig.de/socket-ioexpress for more

View file

@ -14,23 +14,22 @@
* limitations under the License.
*/
var jsdom = require('jsdom-nocontextifiy').jsdom;
var log4js = require('log4js');
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
var contentcollector = require("ep_etherpad-lite/static/js/contentcollector");
var cheerio = require("cheerio");
function setPadHTML(pad, html, callback)
{
var apiLogger = log4js.getLogger("ImportHtml");
// Parse the incoming HTML with jsdom
try{
var doc = jsdom(html.replace(/>\n+</g, '><'));
}catch(e){
apiLogger.warn("Error importing, possibly caused by malformed HTML");
var doc = jsdom("<html><body><div>Error during import, possibly malformed HTML</div></body></html>");
}
var $ = cheerio.load(html);
// Appends a line break, used by Etherpad to ensure a caret is available
// below the last line of an import
$('body').append("<p></p>");
var doc = $('html')[0];
apiLogger.debug('html:');
apiLogger.debug(html);
@ -38,7 +37,7 @@ function setPadHTML(pad, html, callback)
// using the content collector object
var cc = contentcollector.makeContentCollector(true, null, pad.pool);
try{ // we use a try here because if the HTML is bad it will blow up
cc.collectContent(doc.childNodes[0]);
cc.collectContent(doc);
}catch(e){
apiLogger.warn("HTML was not properly formed", e);
return; // We don't process the HTML because it was bad..

View file

@ -2,6 +2,7 @@
"pad.js": [
"pad.js"
, "pad_utils.js"
, "browser.js"
, "pad_cookie.js"
, "pad_editor.js"
, "pad_editbar.js"
@ -24,6 +25,7 @@
, "colorutils.js"
, "draggable.js"
, "pad_utils.js"
, "browser.js"
, "pad_cookie.js"
, "pad_editor.js"
, "pad_editbar.js"
@ -42,6 +44,7 @@
]
, "ace2_inner.js": [
"ace2_inner.js"
, "browser.js"
, "AttributePool.js"
, "Changeset.js"
, "ChangesetUtils.js"
@ -58,6 +61,7 @@
]
, "ace2_common.js": [
"ace2_common.js"
, "browser.js"
, "jquery.js"
, "rjquery.js"
, "$async.js"

View file

@ -25,7 +25,7 @@
"formidable" : "1.0.9",
"log4js" : "0.6.6",
"nodemailer" : "0.3.x",
"jsdom-nocontextifiy" : "0.2.10",
"cheerio" : "0.18.0",
"async-stacktrace" : "0.0.2",
"npm" : "1.4.x",
"ejs" : "0.6.1",
@ -40,7 +40,9 @@
"swagger-node-express" : ">=2.1.0",
"channels" : "0.0.x",
"jsonminify" : "0.2.2",
"measured" : "0.1.3"
"measured" : "0.1.3",
"mocha" : ">=2.0.1",
"supertest" : ">=0.15.0"
},
"bin": { "etherpad-lite": "./node/server.js" },
"devDependencies": {

View file

@ -1,76 +0,0 @@
@font-face {
font-family: 'fontawesome-etherpad';
src: url('../font/fontawesome-etherpad.eot?81419457');
src: url('../font/fontawesome-etherpad.eot?81419457#iefix') format('embedded-opentype'),
url('../font/fontawesome-etherpad.woff?81419457') format('woff'),
url('../font/fontawesome-etherpad.ttf?81419457') format('truetype'),
url('../font/fontawesome-etherpad.svg?81419457#fontawesome-etherpad') format('svg');
font-weight: normal;
font-style: normal;
}
/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
/*
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'fontawesome-etherpad';
src: url('../font/fontawesome-etherpad.svg?81419457#fontawesome-etherpad') format('svg');
}
}
*/
[class^="icon-"]:before, [class*=" icon-"]:before {
font-family: "fontawesome-etherpad";
font-style: normal;
font-weight: normal;
speak: none;
display: inline-block;
text-decoration: inherit;
width: 1em;
margin-right: .2em;
text-align: center;
/* opacity: .8; */
/* For safety - reset parent styles, that can break glyph codes*/
font-variant: normal;
text-transform: none;
/* fix buttons height, for twitter bootstrap */
line-height: 1em;
/* Animation center compensation - margins should be symmetric */
/* remove if not needed */
margin-left: .2em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
/* Uncomment for 3D effect */
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
}
.icon-users:before { content: '\e800'; } /* '' */
.icon-star:before { content: '\e801'; } /* '' */
.icon-cog:before { content: '\e802'; } /* '' */
.icon-bold:before { content: '\e803'; } /* '' */
.icon-italic:before { content: '\e804'; } /* '' */
.icon-indent-left:before { content: '\e805'; } /* '' */
.icon-indent-right:before { content: '\e806'; } /* '' */
.icon-list-bullet:before { content: '\e807'; } /* '' */
.icon-list-numbered:before { content: '\e808'; } /* '' */
.icon-strike:before { content: '\e809'; } /* '' */
.icon-underline:before { content: '\e80a'; } /* '' */
.icon-cw:before { content: '\e80b'; } /* '' */
.icon-ccw:before { content: '\e80c'; } /* '' */
.icon-clock:before { content: '\e80d'; } /* '' */
.icon-eye-off:before { content: '\e80e'; } /* '' */
.icon-eye:before { content: '\e80f'; } /* '' */
.icon-play:before { content: '\e810'; } /* '' */
.icon-fast-bw:before { content: '\e811'; } /* '' */
.icon-fast-fw:before { content: '\e812'; } /* '' */
.icon-pause:before { content: '\e813'; } /* '' */
.icon-glass:before { content: '\e814'; } /* '' */
.icon-code:before { content: '\e815'; } /* '' */
.icon-exchange:before { content: '\e816'; } /* '' */
.icon-chat:before { content: '\e817'; } /* '' */

View file

@ -224,6 +224,41 @@ li[data-key=showusers] > a #online_count {
padding:10px;
}
.loadingAnimation{
-webkit-animation: loadingAnimation 2s infinite linear;
animation: loadingAnimation 2s infinite linear;
font-family: "fontawesome-etherpad";
font-size:24px;
z-index:150;
width:25px;
height:25px;
}
.loadingAnimation:before{
content: "\e80e";
}
@-webkit-keyframes loadingAnimation {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes loadingAnimation {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
#editorcontainerbox {
position: absolute;
bottom: 0;
@ -611,38 +646,49 @@ table#otheruserstable {
margin-top: 4px;
background-repeat: no-repeat;
padding-left: 25px;
background-image: url("../../static/img/etherpad_lite_icons.png");
color: #333;
text-decoration: none;
padding-bottom:2px;
display:inline;
padding-left:5px;
font-family: "Arial";
}
#exporthtml {
background-position: 0px -299px
.exportlink{
font-family: "fontawesome-etherpad";
display:block;
margin:5px;
color:#666;
}
#exportplain {
background-position: 0px -395px
#exporthtmla:before {
content: "\e826";
}
#exportword {
background-position: 0px -275px
#exportplaina:before {
content: "\e802";
}
#exportpdf {
background-position: 0px -371px
#exportworda:before {
content: "\e804";
}
#exportopen {
background-position: 0px -347px
#exportpdfa:before {
content: "\e803";
}
#exportdokuwiki {
background-position: 0px -459px
#exportopena:before {
content: "\e805";
}
#exportdokuwikia:before {
content: "\e805";
}
/* hidden element */
#importstatusball,
#importarrow,
#importmessagesuccess,
#importmessageabiword {
display: none;
}
.throbbold{
font-weight:bold;
}
#importmessageabiword {
color: #900;
font-size: small;
@ -652,9 +698,6 @@ table#otheruserstable {
margin-top: 12px;
padding:2px 4px 2px 4px;
}
#importstatusball {
height: 50px
}
#chatthrob {
display: none;
position: absolute;
@ -689,58 +732,58 @@ table#otheruserstable {
color: #666;
}
.buttonicon-bold:before {
content: "\e803";
content: "\e81c";
}
.buttonicon-italic:before {
content: "\e804";
content: "\e81d";
}
.buttonicon-underline:before {
content: "\e80a";
}
.buttonicon-strikethrough:before {
content: "\e809";
}
.buttonicon-insertorderedlist:before {
content: "\e808";
}
.buttonicon-insertunorderedlist:before {
content: "\e807";
}
.buttonicon-indent:before {
content: "\e806";
}
.buttonicon-outdent:before {
content: "\e805";
}
.buttonicon-undo:before {
content: "\e80c";
}
.buttonicon-redo:before {
content: "\e80b";
}
.buttonicon-clearauthorship:before {
content: "\e80e";
}
.buttonicon-settings:before {
content: "\e802";
}
.buttonicon-import_export:before {
content: "\e816";
}
.buttonicon-embed:before {
content: "\e815";
}
.buttonicon-history:before {
content: "\e80d";
}
.buttonicon-chat:before {
content: "\e817";
}
.buttonicon-strikethrough:before {
content: "\e818";
}
.buttonicon-insertorderedlist:before {
content: "\e816";
}
.buttonicon-insertunorderedlist:before {
content: "\e815";
}
.buttonicon-indent:before {
content: "\e814";
}
.buttonicon-outdent:before {
content: "\e813";
}
.buttonicon-undo:before {
content: "\e823";
}
.buttonicon-redo:before {
content: "\e824";
}
.buttonicon-clearauthorship:before {
content: "\e80d";
}
.buttonicon-settings:before {
content: "\e833";
}
.buttonicon-import_export:before {
content: "\e834";
}
.buttonicon-embed:before {
content: "\e827";
}
.buttonicon-history:before {
content: "\e837";
}
.buttonicon-chat:before {
content: "\e829";
}
.buttonicon-showusers:before {
content: "\e800";
content: "\e808";
}
.buttonicon-savedRevision:before {
content: "\e801";
content: "\e835";
}
#focusprotector {
z-index: 100;
@ -1096,5 +1139,43 @@ input[type=checkbox] {
.gritter-light .gritter-title {
text-shadow: none;
}
/* End of gritter stuff */
@font-face {
font-family: "fontawesome-etherpad";
src:url("../font/fontawesome-etherpad.eot");
src:url("../font/fontawesome-etherpad.eot?#iefix") format("embedded-opentype"),
url("../font/fontawesome-etherpad.woff") format("woff"),
url("../font/fontawesome-etherpad.ttf") format("truetype"),
url("../font/fontawesome-etherpad.svg#fontawesome-etherpad") format("svg");
font-weight: normal;
font-style: normal;
}
[data-icon]:before {
font-family: "fontawesome-etherpad" !important;
content: attr(data-icon);
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
[class^="icon-"]:before,
[class*=" icon-"]:before {
font-family: "fontawesome-etherpad" !important;
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

View file

@ -14,14 +14,14 @@
top: 0;
}
#timeslider-left {
background-image: url(../../static/img/timeslider_left.png);
background-color:#fff;
height: 63px;
left: 0;
position: absolute;
width: 134px;
}
#timeslider-right {
background-image: url(../../static/img/timeslider_right.png);
background-color:#fff;
height: 63px;
position: absolute;
right: 0;
@ -29,7 +29,6 @@
width: 155px;
}
#timeslider {
background-image: url(../../static/img/timeslider_background.png);
height: 63px;
margin: 0 9px;
-webkit-touch-callout: none;
@ -50,7 +49,7 @@
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
background-image: url(../../static/img/crushed_current_location.png);
background-color: #666;
cursor: pointer;
height: 61px;
left: 0;
@ -63,66 +62,97 @@
-moz-user-select: none;
user-select: none;
cursor: pointer;
height: 35px;
height: 60px;
margin-left: 5px;
margin-right: 150px;
position: relative;
top: 20px;
top: 0px;
}
#playpause_button,
#playpause_button_icon {
height: 47px;
height: 44px;
position: absolute;
width: 47px;
width: 44px;
text-align:center;
vertical-align:middle;
}
#playpause_button {
background-image: url(../../static/img/crushed_button_undepressed.png);
right: 77px;
top: 9px;
height:50px;
height:50px;
background: background-linear-gradient( #F7F7F7, #F1F1F1 80%) repeat scroll 0 0 transparent;
border-radius:24px;
cursor:hand;
}
#playpause_button_icon:before {
line-height:44px;
padding-left:2px;
font-family: fontawesome-etherpad;
content: "\e82c";
font-size:24px;
color:#666;
}
#playpause_button_icon {
background-image: url(../../static/img/play.png);
left: 0;
top: 0;
border-radius:48px;
border: solid 1px #666;
}
.pause#playpause_button_icon {
background-image: url(../../static/img/pause.png)
.pause:before {
line-height:44px;
padding-left:2px;
font-family: fontawesome-etherpad;
content: "\e82e" !important;
font-size:24px;
color:#666;
padding-left:0 !important;
}
#leftstar,
#rightstar,
#leftstep,
#rightstep {
background: url(../../static/img/stepper_buttons.png) 0 0 no-repeat;
height: 21px;
background-color: white;
overflow: hidden;
position: absolute;
}
#leftstar {
background-position: 0 -44px;
right: 34px;
top: 8px;
width: 30px;
.stepper{
font-family: fontawesome-etherpad;
border-radius:2px;
border: #666 solid 1px;
line-height:18px;
text-align:center;
height:22px;
color:#666;
}
#rightstar {
background-position: -29px -44px;
right: 5px;
top: 8px;
width: 29px;
stepper:active{
color:#000;
}
#leftstep {
background-position: 0 -22px;
right: 34px;
right: 38px;
top: 20px;
width: 30px;
width: 25px;
}
#leftstep:before{
content: '\e821';
vertical-align:middle;
}
#rightstep:before{
content: "\e822";
vertical-align:middle;
}
#rightstep {
background-position: -29px -22px;
right: 5px;
right: 12px;
top: 20px;
width: 30px;
width: 25px;
}
#timeslider .star {
background-image: url(../../static/img/star.png);
cursor: pointer;
height: 16px;
position: absolute;
@ -130,7 +160,9 @@
width: 15px;
}
#timeslider #timer {
color: #fff;
background: linear-gradient(#F7F7F7, #F1F1F1 80%) repeat scroll 0% 0% transparent;
padding:2px;
border-radius:2px;
font-family: Arial, sans-serif;
font-size: 11px;
left: 7px;
@ -291,16 +323,3 @@ OL {
.list-number6 {
list-style-type: lower-roman
}
/* IE 6/7 fixes */
* HTML #ui-slider-handle {
background-image: url(../../static/img/current_location.gif)
}
* HTML #timeslider .star {
background-image: url(../../static/img/star.gif)
}
* HTML #playpause_button_icon {
background-image: url(../../static/img/play.gif)
}
* HTML .pause#playpause_button_icon {
background-image: url(../../static/img/pause.gif)
}

346
src/static/font/config.json Normal file
View file

@ -0,0 +1,346 @@
{
"name": "fontawesome-etherpad",
"css_prefix_text": "icon-",
"css_use_suffix": false,
"hinting": true,
"units_per_em": 1000,
"ascent": 850,
"glyphs": [
{
"uid": "bf882b30900da12fca090d9796bc3030",
"css": "mail",
"code": 59402,
"src": "fontawesome"
},
{
"uid": "474656633f79ea2f1dad59ff63f6bf07",
"css": "star",
"code": 59446,
"src": "fontawesome"
},
{
"uid": "d17030afaecc1e1c22349b99f3c4992a",
"css": "star-empty",
"code": 59445,
"src": "fontawesome"
},
{
"uid": "8b80d36d4ef43889db10bc1f0dc9a862",
"css": "user",
"code": 59401,
"src": "fontawesome"
},
{
"uid": "31972e4e9d080eaa796290349ae6c1fd",
"css": "users",
"code": 59400,
"src": "fontawesome"
},
{
"uid": "0f99ab40ab0b4d64a74f2d0deeb03e42",
"css": "videocam",
"code": 59403,
"src": "fontawesome"
},
{
"uid": "381da2c2f7fd51f8de877c044d7f439d",
"css": "picture",
"code": 59404,
"src": "fontawesome"
},
{
"uid": "7fd683b2c518ceb9e5fa6757f2276faa",
"css": "eye-off",
"code": 59405,
"src": "fontawesome"
},
{
"uid": "7034e4d22866af82bef811f52fb1ba46",
"css": "code",
"code": 59431,
"src": "fontawesome"
},
{
"uid": "7277ded7695b2a307a5f9d50097bb64c",
"css": "print",
"code": 59393,
"src": "fontawesome"
},
{
"uid": "dcedf50ab1ede3283d7a6c70e2fe32f3",
"css": "chat",
"code": 59432,
"src": "fontawesome"
},
{
"uid": "9c1376672bb4f1ed616fdd78a23667e9",
"css": "comment-empty",
"code": 59433,
"src": "fontawesome"
},
{
"uid": "f48ae54adfb27d8ada53d0fd9e34ee10",
"css": "trash-empty",
"code": 59434,
"src": "fontawesome"
},
{
"uid": "1b5a5d7b7e3c71437f5a26befdd045ed",
"css": "doc",
"code": 59394,
"src": "fontawesome"
},
{
"uid": "9daa1fdf0838118518a7e22715e83abc",
"css": "file-pdf",
"code": 59395,
"src": "fontawesome"
},
{
"uid": "310ffd629da85142bc8669f010556f2d",
"css": "file-word",
"code": 59396,
"src": "fontawesome"
},
{
"uid": "f761c3bbe16ba2d332914ecb28e7a042",
"css": "file-excel",
"code": 59397,
"src": "fontawesome"
},
{
"uid": "edcd4022de8d8df266ef7c42d2658ca5",
"css": "file-powerpoint",
"code": 59398,
"src": "fontawesome"
},
{
"uid": "3c961c1a8d874815856fc6637dc5a13c",
"css": "file-image",
"code": 59399,
"src": "fontawesome"
},
{
"uid": "26613a2e6bc41593c54bead46f8c8ee3",
"css": "file-code",
"code": 59430,
"src": "fontawesome"
},
{
"uid": "e99461abfef3923546da8d745372c995",
"css": "cog",
"code": 59443,
"src": "fontawesome"
},
{
"uid": "19c50c52858a81de58f9db488aba77bc",
"css": "mic",
"code": 59435,
"src": "fontawesome"
},
{
"uid": "598a5f2bcf3521d1615de8e1881ccd17",
"css": "clock",
"code": 59447,
"src": "fontawesome"
},
{
"uid": "bc71f4c6e53394d5ba46b063040014f1",
"css": "cw",
"code": 59428,
"src": "fontawesome"
},
{
"uid": "f9c3205df26e7778abac86183aefdc99",
"css": "ccw",
"code": 59427,
"src": "fontawesome"
},
{
"uid": "a73c5deb486c8d66249811642e5d719a",
"css": "arrows-cw",
"code": 59429,
"src": "fontawesome"
},
{
"uid": "6020aff067fc3c119cdd75daa5249220",
"css": "exchange",
"code": 59444,
"src": "fontawesome"
},
{
"uid": "ce06b5805120d0c2f8d60cd3f1a4fdb5",
"css": "play",
"code": 59436,
"src": "fontawesome"
},
{
"uid": "b624a1e512819d410ddbee84e6918b9d",
"css": "stop",
"code": 59437,
"src": "fontawesome"
},
{
"uid": "0b28050bac9d3facf2f0226db643ece0",
"css": "pause",
"code": 59438,
"src": "fontawesome"
},
{
"uid": "c47efa0e3e74f6ba4c2562c1258fff1f",
"css": "to-end",
"code": 59426,
"src": "fontawesome"
},
{
"uid": "12052b30d23a1a70d6b32962d5464cae",
"css": "to-start",
"code": 59425,
"src": "fontawesome"
},
{
"uid": "f9cbf7508cd04145ade2800169959eef",
"css": "font",
"code": 59419,
"src": "fontawesome"
},
{
"uid": "02cca871bb69da75e8ee286b7055832c",
"css": "bold",
"code": 59420,
"src": "fontawesome"
},
{
"uid": "a8cb1c217f02b073db3670c061cc54d2",
"css": "italic",
"code": 59421,
"src": "fontawesome"
},
{
"uid": "0c708edd8fae2376b3370aa56d40cf9e",
"css": "header",
"code": 59422,
"src": "fontawesome"
},
{
"uid": "c009d417f87d6a27bb5a1cefd30b6cbd",
"css": "text-height",
"code": 59423,
"src": "fontawesome"
},
{
"uid": "13a971bcccd2dda26d4d4eccd8593f8a",
"css": "text-width",
"code": 59424,
"src": "fontawesome"
},
{
"uid": "f4f0e849b805be1f6d76b65581cb3b8b",
"css": "align-left",
"code": 59392,
"src": "fontawesome"
},
{
"uid": "ae6336c46d73af999fe7460c089abb4d",
"css": "align-center",
"code": 59407,
"src": "fontawesome"
},
{
"uid": "e1e7306b47c3c5e6faecce9d32571381",
"css": "align-right",
"code": 59408,
"src": "fontawesome"
},
{
"uid": "25a81737628d1e654a30ad412d7d6dd7",
"css": "align-justify",
"code": 59409,
"src": "fontawesome"
},
{
"uid": "48b87105bd38c20315f1b705b8c7b38c",
"css": "list",
"code": 59410,
"src": "fontawesome"
},
{
"uid": "594e9271c08ff732c04b3bf3117b9040",
"css": "indent-left",
"code": 59411,
"src": "fontawesome"
},
{
"uid": "4d2dfc45d8176b1f26aed973fa84a91e",
"css": "indent-right",
"code": 59412,
"src": "fontawesome"
},
{
"uid": "a2a74f5e7b7d9ba054897d8c795a326a",
"css": "list-bullet",
"code": 59413,
"src": "fontawesome"
},
{
"uid": "f6766a8b042c2453a4e153af03294383",
"css": "list-numbered",
"code": 59414,
"src": "fontawesome"
},
{
"uid": "61c242c9e2134d5864d7fdd57b3c9289",
"css": "strike",
"code": 59416,
"src": "fontawesome"
},
{
"uid": "d4a4a38a40b728f46dad1de4ac950231",
"css": "underline",
"code": 59415,
"src": "fontawesome"
},
{
"uid": "4e88371fb8857dacc1f66afe6314e426",
"css": "superscript",
"code": 59417,
"src": "fontawesome"
},
{
"uid": "3d1c929dbc966992185ce749548c1b2c",
"css": "subscript",
"code": 59418,
"src": "fontawesome"
},
{
"uid": "9396b2d8849e0213a0f11c5fd7fcc522",
"css": "tasks",
"code": 59442,
"src": "fontawesome"
},
{
"uid": "0bda4bc779d4c32623dec2e43bd67ee8",
"css": "gauge",
"code": 59439,
"src": "fontawesome"
},
{
"uid": "cda0cdcfd38f5f1d9255e722dad42012",
"css": "spinner",
"code": 59406,
"src": "fontawesome"
},
{
"uid": "fa9a0b7e788c2d78e24cef1de6b70e80",
"css": "brush",
"code": 59440,
"src": "fontawesome"
},
{
"uid": "be13b8c668eb18839d5d53107725f1de",
"css": "slideshare",
"code": 59441,
"src": "fontawesome"
}
]
}

View file

@ -6,30 +6,62 @@
<font id="fontawesome-etherpad" horiz-adv-x="1000" >
<font-face font-family="fontawesome-etherpad" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
<missing-glyph horiz-adv-x="1000" />
<glyph glyph-name="users" unicode="&#xe800;" d="m0 367q0 197 69 197 4 0 25-11t54-24 66-12q38 0 75 13-3-21-3-37 0-78 45-143-90-3-148-72h-75q-45 0-77 23t-31 66z m71 340q0 59 42 101t101 42 101-42 42-101-42-101-101-42-101 42-42 101z m72-713q0 30 2 58t8 61 14 61 24 54 35 45 48 30 62 11q6 0 24-12t41-26 59-27 76-12 75 12 60 27 41 26 23 12q35 0 63-11t47-30 35-45 24-54 15-61 8-61 2-58q0-66-41-105t-108-39h-488q-68 0-108 39t-41 105z m178 499q0 89 63 151t152 63 151-63 63-151-63-152-151-63-152 63-63 152z m393 214q0 59 42 101t101 42 101-42 42-101-42-101-101-42-101 42-42 101z m27-357q45 65 45 143 0 16-3 37 37-13 74-13 33 0 67 12t54 24 24 11q69 0 69-197 0-43-31-66t-77-22h-75q-57 68-147 71z" horiz-adv-x="1071.4" />
<glyph glyph-name="star" unicode="&#xe801;" d="m0 489q0 21 31 26l280 40 126 254q11 23 27 23t28-23l125-254 280-40q32-5 32-26 0-12-15-27l-203-197 48-279q1-4 1-12 0-11-6-19t-17-9q-10 0-22 7l-251 132-250-132q-13-7-23-7-11 0-17 9t-6 19q0 4 1 12l48 279-203 197q-14 15-14 27z" horiz-adv-x="928.6" />
<glyph glyph-name="cog" unicode="&#xe802;" d="m0 289v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 15 20 15h124q7 0 13-4t7-12l15-103q28-9 50-21l80 60q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-13 0-6-4-12-9-12-29-38t-30-39q14-28 23-55l102-15q7-1 12-7t4-13v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-28 59-77 6-6 6-14t-5-12q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 20l-79-59q-6-5-14-5-8 0-14 6-70 63-92 94-4 5-4 12 0 7 5 13 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13z m286 61q0-59 42-101t101-42 101 42 41 101-41 101-101 42-101-42-42-101z" horiz-adv-x="857.1" />
<glyph glyph-name="bold" unicode="&#xe803;" d="m0-79l1 53q9 2 48 9t59 15q4 7 7 15t4 19 4 18 1 21 0 19v36q0 548-12 572-2 5-12 8t-25 6-28 4-27 3-17 2l-2 46q55 1 190 6t208 5q13 0 38 0t38 0q39 0 76-7t72-24 60-39 41-59 16-76q0-29-9-54t-22-40-36-32-41-25-47-22q86-20 144-75t57-139q0-55-20-100t-52-73-77-47-91-27-98-8q-25 0-74 2t-74 1q-59 0-171-6t-129-7z m297 793q0-28 3-84t2-85q0-15 0-45t-1-44q0-26 1-38 23-4 61-4 46 0 80 7t61 25 41 50 15 79q0 39-16 68t-45 46-60 24-69 8q-28 0-73-7z m4-629q0-21 2-47t7-37q41-18 78-18 210 0 210 187 0 64-23 101-15 24-35 41t-37 26-45 14-47 6-53 1q-40 0-56-6 0-29 0-88t-1-89q0-4 0-37t0-54z" horiz-adv-x="785.7" />
<glyph glyph-name="italic" unicode="&#xe804;" d="m0-78l10 48q3 1 45 12t62 21q16 19 23 56 1 4 35 162t63 303 29 165v14q-13 7-30 11t-39 4-32 3l10 58q19-2 67-4t84-4 67-1q27 0 55 1t67 4 55 4q-2-22-10-50-17-6-57-16t-60-19q-5-10-8-23t-5-23-4-25-4-24q-15-82-49-234t-43-198q-1-5-7-32t-11-51-9-46-4-32l1-10q9-3 103-18-2-24-9-55-6 0-18-1t-18-1q-16 0-49 6t-48 6q-77 1-115 1-28 0-79-5t-68-6z" horiz-adv-x="571.4" />
<glyph glyph-name="indent-left" unicode="&#xe805;" d="m0 11v107q0 7 5 12t13 6h964q7 0 13-6t5-12v-107q0-8-5-13t-13-5h-964q-7 0-13 5t-5 13z m0 643v107q0 7 5 12t13 6h964q7 0 13-6t5-12v-107q0-8-5-13t-13-5h-964q-7 0-13 5t-5 13z m18-268q0 8 5 13l161 160q5 5 12 5 8 0 13-5t5-13v-321q0-7-5-13t-13-5q-7 0-12 5l-161 161q-5 5-5 13z m339-161v107q0 7 5 13t13 5h607q7 0 13-5t5-13v-107q0-7-5-13t-13-5h-607q-7 0-13 5t-5 13z m0 214v107q0 8 5 13t13 5h607q7 0 13-5t5-13v-107q0-7-5-12t-13-6h-607q-7 0-13 6t-5 12z" horiz-adv-x="1000" />
<glyph glyph-name="indent-right" unicode="&#xe806;" d="m0 11v107q0 7 5 12t13 6h964q7 0 13-6t5-12v-107q0-8-5-13t-13-5h-964q-7 0-13 5t-5 13z m0 214v321q0 8 5 13t13 5q8 0 13-5l160-160q5-5 5-13t-5-13l-160-161q-5-5-13-5-7 0-13 5t-5 13z m0 429v107q0 7 5 12t13 6h964q7 0 13-6t5-12v-107q0-8-5-13t-13-5h-964q-7 0-13 5t-5 13z m357-429v107q0 7 5 13t13 5h607q7 0 13-5t5-13v-107q0-7-5-13t-13-5h-607q-7 0-13 5t-5 13z m0 214v107q0 8 5 13t13 5h607q7 0 13-5t5-13v-107q0-7-5-12t-13-6h-607q-7 0-13 6t-5 12z" horiz-adv-x="1000" />
<glyph glyph-name="list-bullet" unicode="&#xe807;" d="m0 64q0 45 31 76t76 31 76-31 31-76-31-76-76-31-76 31-31 76z m0 286q0 45 31 76t76 31 76-31 31-76-31-76-76-31-76 31-31 76z m0 286q0 44 31 76t76 31 76-31 31-76-31-76-76-31-76 31-31 76z m286-625v107q0 7 5 12t13 6h678q7 0 13-6t5-12v-107q0-7-5-13t-13-5h-678q-8 0-13 5t-5 13z m0 285v108q0 7 5 12t13 5h678q7 0 13-5t5-12v-108q0-7-5-12t-13-5h-678q-8 0-13 5t-5 12z m0 286v107q0 8 5 13t13 5h678q7 0 13-5t5-13v-107q0-7-5-12t-13-6h-678q-8 0-13 6t-5 12z" horiz-adv-x="1000" />
<glyph glyph-name="list-numbered" unicode="&#xe808;" d="m8 237q0 29 14 52t31 38 37 27 31 24 14 25q0 14-9 22t-22 7q-25 0-45-32l-47 33q13 28 40 44t59 16q40 0 68-23t28-63q0-28-19-51t-42-36-42-28-20-30h71v34h59v-89h-202q-4 20-4 30z m3-350l31 49q28-25 60-25 16 0 28 8t12 24q0 35-59 31l-14 31q4 6 18 24t24 31 20 21v1q-9 0-27-1t-27 0v-30h-59v85h186v-49l-53-65q28-6 45-27t17-49q0-45-31-70t-75-26q-60 0-96 37z m8 887l76 71h59v-225h60v-56h-187v56h60q0 22 0 68t1 67v7h-1q-5-10-28-30z m267-763v107q0 8 5 13t13 5h678q7 0 13-6t5-12v-107q0-8-5-13t-13-5h-678q-8 0-13 5t-5 13z m0 285v108q0 7 5 12t13 5h678q7 0 13-5t5-12v-108q0-7-5-12t-13-5h-678q-8 0-13 5t-5 12z m0 286v107q0 8 5 13t13 5h678q7 0 13-5t5-13v-107q0-7-5-12t-13-6h-678q-8 0-13 6t-5 12z" horiz-adv-x="1000" />
<glyph glyph-name="strike" unicode="&#xe809;" d="m0 296v36q0 8 5 13t13 5h964q8 0 13-5t5-13v-36q0-7-5-12t-13-5h-964q-8 0-13 5t-5 12z m214 239q0 101 75 173 74 71 219 71 28 0 94-11 36-7 98-27 6-21 12-66 8-68 8-102 0-10-3-25l-7-2-46 4-8 1q-28 83-58 114-49 51-117 51-64 0-102-33-37-32-37-81 0-41 37-79t156-72q38-11 96-36 33-16 53-29h-414q-16 19-29 44-27 54-27 105z m17-456q0 17 0 38l1 20v25l57 1q8-19 17-40t12-31 7-15q20-32 45-52 24-20 59-32 33-12 73-12 36 0 78 15 43 14 68 48 26 34 26 72 0 47-45 87-19 16-77 40h230q4-22 4-51 0-62-23-119-13-30-40-58-20-19-61-45-44-27-85-37-45-12-113-12-64 0-109 13l-78 23q-32 9-40 15-5 5-5 13v7q0 60-1 87z" horiz-adv-x="1000" />
<glyph glyph-name="underline" unicode="&#xe80a;" d="m0-25v-36q0-8 5-13t13-5h821q8 0 13 5t5 13v36q0 8-5 13t-13 5h-821q-8 0-13-5t-5-13z m0 802q7 0 22 0 34 0 63-2 74-4 92-4 48 0 94 2 65 2 82 3 31 0 48 1l-1-8 1-36v-5q-33-5-69-5-33 0-44-14-7-7-7-73 0-8 0-18t0-15l1-128 8-156q3-69 28-112 20-33 54-52 49-26 98-26 58 0 107 16 31 10 55 28 27 20 37 36 20 31 29 63 12 41 12 128 0 44-2 72t-6 68-8 89l-2 33q-3 37-13 49-19 20-43 19l-56-1-8 2 1 48h47l114-6q43-2 110 6l10-2q3-21 3-28 0-4-2-17-25-7-47-8-41-6-44-9-8-9-8-23 0-4 0-15t1-17q5-11 13-221 3-109-9-170-8-42-23-68-21-36-62-69-42-32-102-49-61-19-142-19-93 0-159 26-66 26-99 68-34 42-47 109-9 44-9 132v186q0 105-9 119-14 20-82 21-21 2-25 3z" horiz-adv-x="857.1" />
<glyph glyph-name="cw" unicode="&#xe80b;" d="m0 350q0 87 34 166t92 137 136 92 167 34q82 0 158-31t137-88l72 72q16 18 39 8 22-9 22-33v-250q0-14-10-25t-26-11h-250q-23 0-32 23-10 22 7 38l77 77q-82 77-194 77-58 0-111-23t-91-61-62-91-22-111 22-111 62-91 91-61 111-23q66 0 125 29t100 82q4 6 13 7 8 0 14-5l76-77q5-4 6-11t-5-13q-60-74-147-114t-182-41q-87 0-167 34t-136 92-92 137-34 166z" horiz-adv-x="857.1" />
<glyph glyph-name="ccw" unicode="&#xe80c;" d="m0 457v250q0 24 22 33 22 10 39-8l72-72q60 57 137 88t159 31q87 0 166-34t137-92 91-137 34-166-34-166-91-137-137-92-166-34q-96 0-183 41t-147 114q-4 6-4 12t5 12l76 77q6 5 14 5 9-1 13-7 41-53 100-82t126-29q58 0 110 23t92 61 61 91 22 111-22 111-61 91-92 61-110 23q-55 0-105-20t-90-57l77-77q17-16 8-38-10-23-33-23h-250q-15 0-25 11t-11 25z" horiz-adv-x="857.1" />
<glyph glyph-name="clock" unicode="&#xe80d;" d="m0 350q0 117 58 215t155 156 216 58 215-58 156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215z m125 0q0-83 41-152t110-111 153-41 152 41 110 111 41 152-41 152-110 111-152 41-153-41-110-111-41-152z m161-54v36q0 8 5 13t13 5h125v196q0 8 5 13t12 5h36q8 0 13-5t5-13v-250q0-7-5-12t-13-5h-178q-8 0-13 5t-5 12z" horiz-adv-x="857.1" />
<glyph glyph-name="eye-off" unicode="&#xe80e;" d="m0 314q0 22 11 39 86 131 212 207t277 76q50 0 100-10l31 54q5 9 15 9 3 0 10-3t18-9 18-10 18-10 10-7q9-5 9-15 0-4 0-5-59-105-176-316t-176-316l-28-50q-5-9-15-9-7 0-75 39-9 6-9 16 0 7 25 48-80 37-147 97t-117 137q-11 17-11 38z m71 0q94-144 239-209l43 79q-48 35-76 88t-27 114q0 67 34 125-128-65-213-197z m259 72q0-11 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19-8 19-19 7q-70 0-120-50t-50-119z m170-393l41 74q119 10 219 76t169 171q-65 100-158 164l35 63q53-36 102-86t81-102q11-19 11-39t-11-38q-22-36-61-81-84-96-194-149t-234-53z m89 159l157 281q4-26 4-47 0-78-44-142t-117-92z" horiz-adv-x="1000" />
<glyph glyph-name="eye" unicode="&#xe80f;" d="m0 314q0 19 11 39 78 128 210 205t279 78 279-78 210-205q11-20 11-39t-11-38q-78-129-210-206t-279-77-279 77-210 206q-11 19-11 38z m71 0q75-114 187-182t242-68 242 68 187 182q-85 132-213 197 34-58 34-125 0-104-73-177t-177-73-177 73-73 177q0 67 34 125-128-65-213-197z m259 72q0-11 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19-8 19-19 7q-70 0-120-50t-50-119z" horiz-adv-x="1000" />
<glyph glyph-name="play" unicode="&#xe810;" d="m0-61v822q0 14 9 20t22-2l741-412q13-7 13-17t-13-17l-741-412q-13-7-22-2t-9 20z" horiz-adv-x="785.7" />
<glyph glyph-name="fast-bw" unicode="&#xe811;" d="m68 350q0 15 11 25l396 396q11 11 18 8t7-18v-396q3 6 7 10l396 396q11 11 18 8t8-18v-822q0-14-8-18t-18 8l-396 396q-4 5-7 11v-397q0-14-7-18t-18 8l-396 396q-11 11-11 25z" horiz-adv-x="928.6" />
<glyph glyph-name="fast-fw" unicode="&#xe812;" d="m0-61v822q0 14 7 18t18-8l396-396q5-4 8-11v397q0 14 7 18t18-8l396-396q10-11 10-25t-10-25l-396-396q-11-11-18-8t-7 18v396q-3-5-8-10l-396-396q-10-11-18-8t-7 18z" horiz-adv-x="928.6" />
<glyph glyph-name="pause" unicode="&#xe813;" d="m0-43v786q0 14 11 25t25 11h285q15 0 26-11t10-25v-786q0-14-10-25t-26-11h-285q-15 0-25 11t-11 25z m500 0v786q0 14 11 25t25 11h285q15 0 26-11t10-25v-786q0-14-10-25t-26-11h-285q-15 0-25 11t-11 25z" horiz-adv-x="857.1" />
<glyph glyph-name="glass" unicode="&#xe814;" d="m52 746q0 13 10 21t21 9 24 3h786q13 0 24-3t21-9 10-21q0-19-24-43l-353-353v-429h179q15 0 25-10t11-25-11-25-25-11h-500q-14 0-25 11t-11 25 11 25 25 10h179v429l-353 353q-24 24-24 43z" horiz-adv-x="1000" />
<glyph glyph-name="code" unicode="&#xe815;" d="m25 314q0 8 6 13l260 260q5 6 13 6t12-6l28-28q6-5 6-13t-6-12l-219-220 219-219q6-6 6-13t-6-13l-28-28q-5-5-12-5t-13 5l-260 260q-6 6-6 13z m372-350l208 720q3 8 9 11t13 2l35-10q7-2 11-9t1-13l-208-721q-2-7-9-11t-13-1l-34 9q-8 3-11 9t-2 14z m325 118q0 7 5 13l219 219-219 220q-5 5-5 12t5 13l28 28q6 6 13 6t13-6l260-260q5-5 5-13t-5-13l-260-260q-6-5-13-5t-13 5l-28 28q-5 6-5 13z" horiz-adv-x="1071.4" />
<glyph glyph-name="exchange" unicode="&#xe816;" d="m0 136q0 8 5 13l179 178q5 5 12 5 8 0 13-5t5-13v-107h768q7 0 13-5t5-13v-107q0-7-5-12t-13-6h-768v-107q0-7-5-12t-13-6q-6 0-13 6l-178 178q-5 5-5 13z m0 303v107q0 8 5 13t13 5h768v107q0 8 5 13t13 5q6 0 13-5l178-178q5-5 5-13t-5-13l-179-179q-5-5-12-5-8 0-13 6t-5 12v107h-768q-7 0-13 6t-5 12z" horiz-adv-x="1000" />
<glyph glyph-name="chat" unicode="&#xe817;" d="m0 421q0 78 53 144t143 104 197 38 197-38 143-104 53-144-53-143-143-104-197-38q-48 0-98 9-70-50-155-72-21-5-48-9h-2q-6 0-12 5t-6 11q-1 2-1 4t1 4 1 3l1 3t2 3 2 3 3 2 2 3q3 3 13 14t15 16 12 17 14 21 11 25q-69 40-108 98t-40 125z m344-354q32-3 49-3 90 0 172 25t148 72q69 52 107 119t37 141q0 43-13 85 72-39 114-99t42-128q0-67-40-126t-108-98q5-14 11-25t14-21 13-16 14-17 13-14q0 0 2-2t3-3 2-3 2-3l1-3t1-3 1-4-1-3q-2-8-7-13t-13-4q-27 4-48 9-85 23-155 72-50-9-98-9-151 0-263 74z" horiz-adv-x="1000" />
<glyph glyph-name="align-left" unicode="&#xe800;" d="m1000 100v-71q0-15-11-25t-25-11h-928q-15 0-25 11t-11 25v71q0 15 11 25t25 11h928q15 0 25-11t11-25z m-214 214v-71q0-15-11-25t-25-11h-714q-15 0-25 11t-11 25v71q0 15 11 25t25 11h714q15 0 25-11t11-25z m143 215v-72q0-14-11-25t-25-11h-857q-15 0-25 11t-11 25v72q0 14 11 25t25 10h857q14 0 25-10t11-25z m-215 214v-72q0-14-10-25t-25-10h-643q-15 0-25 10t-11 25v72q0 14 11 25t25 11h643q14 0 25-11t10-25z" horiz-adv-x="1000" />
<glyph glyph-name="print" unicode="&#xe801;" d="m214-7h500v143h-500v-143z m0 357h500v214h-89q-22 0-38 16t-16 38v89h-357v-357z m643-36q0 15-10 25t-26 11-25-11-10-25 10-25 25-10 26 10 10 25z m72 0v-232q0-7-6-12t-12-6h-125v-89q0-22-16-38t-38-16h-536q-22 0-37 16t-16 38v89h-125q-7 0-13 6t-5 12v232q0 44 32 76t75 31h36v304q0 22 16 38t37 16h375q23 0 50-12t42-26l85-85q15-16 27-43t11-49v-143h35q45 0 76-31t32-76z" horiz-adv-x="928.6" />
<glyph glyph-name="doc" unicode="&#xe802;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z" horiz-adv-x="857.1" />
<glyph glyph-name="file-pdf" unicode="&#xe803;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-287 331q18-14 47-31 33 4 65 4 82 0 99-27 9-13 1-29 0-1-1-1l-1-2v0q-3-21-39-21-27 0-65 11t-72 29q-123-13-219-46-85-146-135-146-8 0-15 4l-14 6q0 1-3 3-6 6-4 20 5 23 32 51t73 54q8 5 13-3 1-1 1-2 29 47 60 110 38 76 58 146-13 46-17 89t4 71q6 22 23 22h12q13 0 20-8 10-12 5-38-1-3-2-4 0-2 0-5v-17q-1-68-8-107 31-91 82-133z m-322-229q30 13 77 88-29-22-49-47t-28-41z m223 513q-9-23-2-73 1 4 4 24 0 2 4 24 1 3 3 5-1 0-1 1t0 1-1 1q0 12-7 20 0-1 0-1v-2z m-70-368q76 30 159 45-1 0-7 5t-9 8q-43 37-71 98-15-48-47-110-16-31-25-46z m361 8q-14 14-78 14 42-16 69-16 8 0 10 1 0 0-1 1z" horiz-adv-x="857.1" />
<glyph glyph-name="file-word" unicode="&#xe804;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-656 500v-59h39l92-369h88l72 271q4 11 5 25 1 9 1 14h3l1-14q1-1 2-11t3-14l72-271h89l91 369h39v59h-167v-59h50l-55-245q-3-11-4-25l-1-12h-3l-1 12q-1 2-2 11t-3 14l-81 304h-63l-81-304q-1-5-2-13t-2-12l-2-12h-2l-2 12q-1 14-4 25l-55 245h50v59h-167z" horiz-adv-x="857.1" />
<glyph glyph-name="file-excel" unicode="&#xe805;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-547 131v-59h157v59h-42l58 90q3 4 5 9t5 8 2 2h1q0-2 2-6 2-2 3-4t3-4 4-5l60-90h-43v-59h163v59h-38l-107 152 108 158h38v59h-156v-59h41l-57-89q-2-4-6-9t-5-8l-1-1h-1q-1 2-3 5-3 6-9 13l-59 89h42v59h-162v-59h38l106-152-109-158h-38z" horiz-adv-x="857.1" />
<glyph glyph-name="file-powerpoint" unicode="&#xe806;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-554 131v-59h183v59h-52v93h76q43 0 66 9 37 12 59 48t23 82q0 45-21 78t-56 49q-27 10-72 10h-206v-59h52v-310h-52z m197 156h-66v150h67q29 0 46-10 31-19 31-64 0-50-34-67-18-9-44-9z" horiz-adv-x="857.1" />
<glyph glyph-name="file-image" unicode="&#xe807;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-72 250v-178h-571v107l107 107 71-71 215 214z m-464 108q-45 0-76 31t-31 76 31 76 76 31 76-31 31-76-31-76-76-31z" horiz-adv-x="857.1" />
<glyph glyph-name="users" unicode="&#xe808;" d="m331 350q-90-3-148-71h-75q-45 0-77 22t-31 66q0 197 69 197 4 0 25-11t54-24 66-12q38 0 75 13-3-21-3-37 0-78 45-143z m598-356q0-66-41-105t-108-39h-488q-68 0-108 39t-41 105q0 30 2 58t8 61 14 61 24 54 35 45 48 30 62 11q6 0 24-12t41-26 59-27 76-12 75 12 60 27 41 26 23 12q35 0 63-11t47-30 35-45 24-54 15-61 8-61 2-58z m-572 713q0-59-42-101t-101-42-101 42-42 101 42 101 101 42 101-42 42-101z m393-214q0-89-63-152t-151-62-152 62-63 152 63 151 152 63 151-63 63-151z m321-126q0-43-31-66t-77-22h-75q-57 68-147 71 45 65 45 143 0 16-3 37 37-13 74-13 33 0 67 12t54 24 24 11q69 0 69-197z m-71 340q0-59-42-101t-101-42-101 42-42 101 42 101 101 42 101-42 42-101z" horiz-adv-x="1071.4" />
<glyph glyph-name="user" unicode="&#xe809;" d="m786 66q0-67-41-106t-108-39h-488q-67 0-108 39t-41 106q0 30 2 58t8 61 15 60 24 55 34 45 48 30 62 11q5 0 24-12t41-27 60-27 75-12 74 12 61 27 41 27 24 12q34 0 62-11t48-30 34-45 24-55 15-60 8-61 2-58z m-179 498q0-88-63-151t-151-63-152 63-62 151 62 152 152 63 151-63 63-152z" horiz-adv-x="785.7" />
<glyph glyph-name="mail" unicode="&#xe80a;" d="m929 11v428q-18-20-39-37-149-114-238-188-28-24-46-38t-48-27-57-13h-2q-26 0-57 13t-48 27-46 38q-88 74-238 188-21 17-39 37v-428q0-8 6-13t12-5h822q7 0 12 5t6 13z m0 586v14t-1 7-1 7-3 5-5 4-8 2h-822q-7 0-12-6t-6-12q0-94 82-159 108-85 224-177 4-2 20-16t25-21 25-18 28-15 24-5h2q11 0 24 5t28 15 25 18 25 21 20 16q116 92 224 177 30 24 56 65t26 73z m71 21v-607q0-37-26-63t-63-27h-822q-36 0-63 27t-26 63v607q0 37 26 63t63 26h822q37 0 63-26t26-63z" horiz-adv-x="1000" />
<glyph glyph-name="videocam" unicode="&#xe80b;" d="m1000 654v-608q0-23-22-32-7-3-14-3-15 0-25 10l-225 225v-92q0-67-47-114t-113-47h-393q-67 0-114 47t-47 114v392q0 67 47 114t114 47h393q66 0 113-47t47-114v-92l225 225q10 10 25 10 7 0 14-3 22-9 22-32z" horiz-adv-x="1000" />
<glyph glyph-name="picture" unicode="&#xe80c;" d="m357 529q0-45-31-76t-76-32-76 32-31 76 31 75 76 32 76-32 31-75z m572-215v-250h-786v107l178 179 90-89 285 285z m53 393h-893q-7 0-12-5t-6-13v-678q0-8 6-13t12-5h893q7 0 13 5t5 13v678q0 7-5 13t-13 5z m89-18v-678q0-37-26-63t-63-27h-893q-36 0-63 27t-26 63v678q0 37 26 63t63 27h893q37 0 63-27t26-63z" horiz-adv-x="1071.4" />
<glyph glyph-name="eye-off" unicode="&#xe80d;" d="m310 105l43 79q-48 35-76 88t-27 114q0 67 34 125-128-65-213-197 94-144 239-209z m217 424q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-12 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m202 106q0-4 0-5-59-105-176-316t-176-316l-28-50q-5-9-15-9-7 0-75 39-9 6-9 16 0 7 25 49-80 36-147 96t-117 137q-11 17-11 38t11 39q86 131 212 207t277 76q50 0 100-10l31 54q5 9 15 9 3 0 10-3t18-9 18-10 18-10 10-7q9-5 9-15z m21-249q0-78-44-142t-117-92l157 281q4-26 4-47z m250-72q0-19-11-38-22-36-61-81-84-96-194-149t-234-53l41 74q119 10 219 76t169 171q-65 100-158 164l35 63q53-36 102-86t81-102q11-19 11-39z" horiz-adv-x="1000" />
<glyph glyph-name="spinner" unicode="&#xe80e;" d="m277 100q0-33-24-57t-57-23q-33 0-56 23t-24 57 24 57 56 23q33 0 57-23t24-57z m241-107q0-30-21-51t-51-21-50 21-21 51 21 50 50 21 51-21 21-50z m-339 357q0-37-27-63t-63-26-63 26-26 63 26 63 63 26 63-26 27-63z m580-250q0-26-18-44t-45-18-44 18-18 44 18 44 44 19 45-19 18-44z m-464 500q0-41-29-69t-70-29-69 29-29 69 29 69 69 29 70-29 29-69z m259 107q0-45-32-76t-76-31-75 31-32 76 32 76 75 31 76-31 32-76z m303-357q0-22-15-38t-38-16-38 16-16 38 16 38 38 16 38-16 15-38z m-116 250q0-18-13-32t-32-13-31 13-13 32 13 31 31 14 32-14 13-31z" horiz-adv-x="875" />
<glyph glyph-name="align-center" unicode="&#xe80f;" d="m1000 100v-71q0-15-11-25t-25-11h-928q-15 0-25 11t-11 25v71q0 15 11 25t25 11h928q15 0 25-11t11-25z m-214 214v-71q0-15-11-25t-25-11h-500q-14 0-25 11t-11 25v71q0 15 11 25t25 11h500q15 0 25-11t11-25z m143 215v-72q0-14-11-25t-25-11h-786q-14 0-25 11t-11 25v72q0 14 11 25t25 10h786q14 0 25-10t11-25z m-215 214v-72q0-14-10-25t-25-10h-358q-14 0-25 10t-10 25v72q0 14 10 25t25 11h358q14 0 25-11t10-25z" horiz-adv-x="1000" />
<glyph glyph-name="align-right" unicode="&#xe810;" d="m1000 100v-71q0-15-11-25t-25-11h-928q-15 0-25 11t-11 25v71q0 15 11 25t25 11h928q15 0 25-11t11-25z m0 214v-71q0-15-11-25t-25-11h-714q-14 0-25 11t-11 25v71q0 15 11 25t25 11h714q15 0 25-11t11-25z m0 215v-72q0-14-11-25t-25-11h-857q-14 0-25 11t-11 25v72q0 14 11 25t25 10h857q15 0 25-10t11-25z m0 214v-72q0-14-11-25t-25-10h-643q-14 0-25 10t-10 25v72q0 14 10 25t25 11h643q15 0 25-11t11-25z" horiz-adv-x="1000" />
<glyph glyph-name="align-justify" unicode="&#xe811;" d="m1000 100v-71q0-15-11-25t-25-11h-928q-15 0-25 11t-11 25v71q0 15 11 25t25 11h928q15 0 25-11t11-25z m0 214v-71q0-15-11-25t-25-11h-928q-15 0-25 11t-11 25v71q0 15 11 25t25 11h928q15 0 25-11t11-25z m0 215v-72q0-14-11-25t-25-11h-928q-15 0-25 11t-11 25v72q0 14 11 25t25 10h928q15 0 25-10t11-25z m0 214v-72q0-14-11-25t-25-10h-928q-15 0-25 10t-11 25v72q0 14 11 25t25 11h928q15 0 25-11t11-25z" horiz-adv-x="1000" />
<glyph glyph-name="list" unicode="&#xe812;" d="m143 118v-107q0-7-5-13t-13-5h-107q-7 0-13 5t-5 13v107q0 7 5 12t13 6h107q7 0 13-6t5-12z m0 214v-107q0-7-5-13t-13-5h-107q-7 0-13 5t-5 13v107q0 7 5 13t13 5h107q7 0 13-5t5-13z m0 214v-107q0-7-5-12t-13-6h-107q-7 0-13 6t-5 12v107q0 8 5 13t13 5h107q7 0 13-5t5-13z m857-428v-107q0-7-5-13t-13-5h-750q-7 0-12 5t-6 13v107q0 7 6 12t12 6h750q7 0 13-6t5-12z m-857 643v-107q0-8-5-13t-13-5h-107q-7 0-13 5t-5 13v107q0 7 5 12t13 6h107q7 0 13-6t5-12z m857-429v-107q0-7-5-13t-13-5h-750q-7 0-12 5t-6 13v107q0 7 6 13t12 5h750q7 0 13-5t5-13z m0 214v-107q0-7-5-12t-13-6h-750q-7 0-12 6t-6 12v107q0 8 6 13t12 5h750q7 0 13-5t5-13z m0 215v-107q0-8-5-13t-13-5h-750q-7 0-12 5t-6 13v107q0 7 6 12t12 6h750q7 0 13-6t5-12z" horiz-adv-x="1000" />
<glyph glyph-name="indent-left" unicode="&#xe813;" d="m214 546v-321q0-7-5-13t-13-5q-7 0-12 5l-161 161q-5 5-5 13t5 13l161 160q5 5 12 5 8 0 13-5t5-13z m786-428v-107q0-7-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z m0 214v-107q0-7-5-13t-13-5h-607q-7 0-13 5t-5 13v107q0 7 5 13t13 5h607q7 0 13-5t5-13z m0 214v-107q0-7-5-12t-13-6h-607q-7 0-13 6t-5 12v107q0 8 5 13t13 5h607q7 0 13-5t5-13z m0 215v-107q0-8-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z" horiz-adv-x="1000" />
<glyph glyph-name="indent-right" unicode="&#xe814;" d="m196 386q0-8-5-13l-160-161q-5-5-13-5-7 0-13 5t-5 13v321q0 8 5 13t13 5q8 0 13-5l160-160q5-5 5-13z m804-268v-107q0-7-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z m0 214v-107q0-7-5-13t-13-5h-607q-7 0-13 5t-5 13v107q0 7 5 13t13 5h607q7 0 13-5t5-13z m0 214v-107q0-7-5-12t-13-6h-607q-7 0-13 6t-5 12v107q0 8 5 13t13 5h607q7 0 13-5t5-13z m0 215v-107q0-8-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z" horiz-adv-x="1000" />
<glyph glyph-name="list-bullet" unicode="&#xe815;" d="m214 64q0-44-31-76t-76-31-76 31-31 76 31 76 76 31 76-31 31-76z m0 286q0-45-31-76t-76-31-76 31-31 76 31 76 76 31 76-31 31-76z m786-232v-107q0-7-5-13t-13-5h-678q-8 0-13 5t-5 13v107q0 7 5 12t13 6h678q7 0 13-6t5-12z m-786 518q0-45-31-76t-76-31-76 31-31 76 31 76 76 31 76-31 31-76z m786-232v-108q0-7-5-12t-13-5h-678q-8 0-13 5t-5 12v108q0 7 5 12t13 5h678q7 0 13-5t5-12z m0 285v-107q0-7-5-12t-13-6h-678q-8 0-13 6t-5 12v107q0 8 5 13t13 5h678q7 0 13-5t5-13z" horiz-adv-x="1000" />
<glyph glyph-name="list-numbered" unicode="&#xe816;" d="m213-54q0-45-31-70t-75-26q-60 0-96 37l31 49q28-25 60-25 16 0 28 8t12 24q0 35-59 31l-14 31q4 6 18 24t24 31 20 21v1q-9 0-27-1t-27 0v-30h-59v85h186v-49l-53-65q28-6 45-27t17-49z m1 350v-89h-202q-4 20-4 30 0 29 14 52t31 38 37 27 31 24 14 25q0 14-9 22t-22 7q-25 0-45-32l-47 33q13 28 40 44t59 16q40 0 68-23t28-63q0-28-19-51t-42-36-42-28-20-30h71v34h59z m786-178v-107q0-8-5-13t-13-5h-678q-8 0-13 5t-5 13v107q0 8 5 13t13 5h678q7 0 13-6t5-12z m-786 502v-56h-187v56h60q0 22 0 68t1 67v7h-1q-5-10-28-30l-40 42 76 71h59v-225h60z m786-216v-108q0-7-5-12t-13-5h-678q-8 0-13 5t-5 12v108q0 7 5 12t13 5h678q7 0 13-5t5-12z m0 285v-107q0-7-5-12t-13-6h-678q-8 0-13 6t-5 12v107q0 8 5 13t13 5h678q7 0 13-5t5-13z" horiz-adv-x="1000" />
<glyph glyph-name="underline" unicode="&#xe817;" d="m27 726q-21 1-25 2l-2 49q7 0 22 0 34 0 63-2 74-4 92-4 48 0 94 2 65 2 82 3 31 0 48 1l-1-8 1-36v-5q-33-5-69-5-33 0-44-14-7-7-7-73 0-8 0-18t0-15l1-128 8-156q3-69 28-112 20-33 54-52 49-26 98-26 58 0 107 16 31 10 55 28 27 20 37 36 20 31 29 63 12 41 12 128 0 44-2 72t-6 68-8 89l-2 33q-3 37-13 49-19 20-43 19l-56-1-8 2 1 48h47l114-6q43-2 110 6l10-2q3-21 3-28 0-4-2-17-25-7-47-8-41-6-44-9-8-9-8-23 0-4 0-15t1-17q5-11 13-221 3-109-9-170-8-42-23-68-21-36-62-69-42-32-102-49-61-19-142-19-93 0-159 26-66 26-99 68-34 42-47 109-9 44-9 132v186q0 105-9 119-14 20-82 21z m830-787v36q0 8-5 13t-13 5h-821q-8 0-13-5t-5-13v-36q0-8 5-13t13-5h821q8 0 13 5t5 13z" horiz-adv-x="857.1" />
<glyph glyph-name="strike" unicode="&#xe818;" d="m982 350q8 0 13-5t5-13v-36q0-7-5-12t-13-5h-964q-8 0-13 5t-5 12v36q0 8 5 13t13 5h964z m-712 36q-16 19-29 44-27 54-27 105 0 101 75 173 74 71 219 71 28 0 94-11 36-7 98-27 6-21 12-66 8-68 8-102 0-10-3-25l-7-2-46 4-8 1q-28 83-58 114-49 51-117 51-64 0-102-33-37-32-37-81 0-41 37-79t156-72q38-11 96-36 33-16 53-29h-414z m282-143h230q4-22 4-51 0-62-23-119-13-30-40-58-20-19-61-45-44-27-85-37-45-12-113-12-64 0-109 13l-78 23q-32 8-40 15-5 5-5 12v8q0 60-1 87 0 17 0 38l1 20v25l57 1q8-19 17-40t12-31 7-15q20-32 45-52 24-20 59-32 33-12 73-12 36 0 78 15 43 14 68 48 26 34 26 72 0 47-45 87-19 16-77 40z" horiz-adv-x="1000" />
<glyph glyph-name="superscript" unicode="&#xe819;" d="m501 86v-93h-139l-89 141-13 23q-4 5-6 12h-2l-5-12q-5-11-14-25l-86-139h-144v93h71l110 162-103 152h-76v94h154l77-127q1-2 13-24 4-5 6-11h2q1 5 6 11l14 24 78 127h143v-94h-69l-103-149 114-165h61z m355 379v-115h-287l-1 15q-3 16-3 26 0 35 15 65t36 48 47 37 47 30 36 30 15 36q0 21-17 35t-39 13q-29 0-54-21-8-7-20-22l-59 52q15 20 35 37 46 36 105 36 61 0 99-33t38-89q0-31-13-57t-35-43-45-33-46-28-37-29-17-35h130v45h70z" horiz-adv-x="857.1" />
<glyph glyph-name="subscript" unicode="&#xe81a;" d="m501 86v-93h-139l-89 141-13 23q-4 5-6 12h-2l-5-12q-5-11-14-25l-86-139h-144v93h71l110 162-103 152h-76v94h154l77-127q1-2 13-24 4-5 6-11h2q1 5 6 11l14 24 78 127h143v-94h-69l-103-149 114-165h61z m356-121v-115h-287l-2 15q-2 25-2 26 0 35 15 65t36 48 47 37 47 30 36 30 15 36q0 21-17 35t-39 13q-29 0-54-21-8-6-20-22l-59 52q15 20 35 37 45 36 105 36 62 0 99-33t38-89q0-37-19-66t-47-48-55-35-49-35-23-41h130v45h70z" horiz-adv-x="857.1" />
<glyph glyph-name="font" unicode="&#xe81b;" d="m405 538l-95-251q18 0 76-1t89-1q11 0 32 1-48 141-102 252z m-405-617l1 44q13 4 31 7t32 6 28 8 25 17 17 28l132 344 156 404h72q4-8 6-12l114-268q19-44 60-144t63-153q9-19 33-81t40-94q11-25 19-31 11-9 49-17t47-11q4-22 4-32 0-2-1-7t0-8q-35 0-106 5t-107 4q-42 0-120-4t-99-4q0 24 2 43l73 16q1 0 7 1t9 2 8 3 9 4 6 4 5 6 1 8q0 9-17 54t-40 99-24 56l-251 1q-14-33-43-109t-28-91q0-12 8-21t24-14 27-7 32-5 23-2q1-11 1-32 0-5-2-16-32 0-97 6t-97 6q-5 0-15-3t-12-2q-45-8-105-8z" horiz-adv-x="928.6" />
<glyph glyph-name="bold" unicode="&#xe81c;" d="m310 1q41-18 78-18 210 0 210 187 0 64-23 101-15 24-35 41t-37 26-45 14-47 6-53 1q-40 0-56-6 0-29 0-88t-1-89q0-4 0-37t0-54 2-47 7-37z m-8 417q23-4 61-4 46 0 80 7t61 25 41 50 15 79q0 39-16 68t-45 46-60 24-69 8q-28 0-73-7 0-28 3-84t2-85q0-15 0-45t-1-44q0-26 1-38z m-302-497l1 53q9 2 48 9t59 15q4 7 7 15t4 19 4 18 1 21 0 19v36q0 548-12 572-2 5-12 8t-25 6-28 4-27 3-17 2l-2 46q55 1 190 6t208 5q13 0 38 0t38 0q39 0 76-7t72-24 60-39 41-59 16-76q0-29-9-54t-22-40-36-32-41-25-47-22q86-20 144-75t57-139q0-55-20-100t-52-73-77-47-91-27-98-8q-25 0-74 2t-74 1q-59 0-171-6t-129-7z" horiz-adv-x="785.7" />
<glyph glyph-name="italic" unicode="&#xe81d;" d="m0-78l10 48q3 1 45 12t62 21q16 19 23 56 1 4 35 162t63 303 29 165v14q-13 7-30 11t-39 4-32 3l10 58q19-2 67-4t84-4 67-1q27 0 55 1t67 4 55 4q-2-22-10-50-17-6-57-16t-60-19q-5-10-8-23t-5-23-4-25-4-24q-15-82-49-234t-43-198q-1-5-7-32t-11-51-9-46-4-32l1-10q9-3 103-18-2-24-9-55-6 0-18-1t-18-1q-16 0-49 6t-48 6q-77 1-115 1-28 0-79-5t-68-6z" horiz-adv-x="571.4" />
<glyph glyph-name="header" unicode="&#xe81e;" d="m939-79q-25 0-74 2t-75 2q-24 0-73-2t-74-2q-14 0-21 12t-7 25q0 17 9 26t22 9 29 4 25 9q18 11 18 78l0 218q0 12-1 17-7 3-28 3h-376q-22 0-29-3 0-5 0-17l-1-207q0-79 21-92 9-5 26-7t32-2 25-8 11-26q0-14-7-26t-20-13q-26 0-78 2t-77 2q-24 0-71-2t-71-2q-13 0-20 12t-7 25q0 17 9 25t20 10 26 4 24 9q18 13 18 80l-1 31v454q0 2 1 14t0 21-1 21-2 24-4 20-6 18-9 10q-8 5-25 6t-29 2-23 7-10 26q0 14 6 26t20 13q26 0 78-2t77-2q23 0 71 2t70 2q14 0 21-13t7-26q0-17-9-25t-22-8-28-2-24-7q-19-12-19-90l1-178q0-12 0-18 7-2 22-2h390q14 0 21 2 1 6 1 18l0 178q0 78-19 90-10 6-33 7t-37 7-14 28q0 14 7 26t21 13q24 0 74-2t73-2q24 0 72 2t72 2q14 0 21-13t7-26q0-17-10-25t-22-8-29-2-24-7q-20-13-20-90l1-526q0-66 19-78 9-6 25-7t30-3 23-9 10-24q0-15-6-27t-20-13z" horiz-adv-x="1000" />
<glyph glyph-name="text-height" unicode="&#xe81f;" d="m973 64q19 0 24-10t-6-25l-71-90q-11-15-27-15t-27 15l-71 90q-11 15-6 25t23 10h45v572h-45q-18 0-23 10t6 25l71 90q11 15 27 15t27-15l71-90q11-15 6-25t-24-10h-44v-572h44z m-928 714l30-15q7-3 118-3 25 0 74 1t73 1q21 0 60 0t60 0h164q3 0 12 0t11 0 9 1 10 5 8 10l24 1q2 0 7-1t8 0q1-62 1-187 0-45-2-61-22-8-38-10-14 24-31 71-1 5-6 27t-8 41-4 20q-3 4-7 7t-8 3-8 1-10 1-9-1q-9 0-37 1t-42 0-35-1-40-4q-5-45-4-75 0-53 1-217t1-254q0-9-1-40t0-51 7-38q22-12 69-24t67-21q2-22 2-28 0-8-1-16l-19-1q-43-1-122 5t-115 5q-28 0-85-5t-84-5q-2 29-2 29v5q9 15 34 24t55 17 44 15q10 23 10 213 0 57-1 169t-2 170v65q0 1 0 8t1 14-1 15-2 13-3 8q-6 7-90 7-18 0-52-7t-44-15q-11-7-19-40t-18-62-24-30q-23 15-31 25v213z" horiz-adv-x="1000" />
<glyph glyph-name="text-width" unicode="&#xe820;" d="m45 778l30-15q7-3 118-3 25 0 74 1t73 1q39 0 138 1t170 0 138-2q18-1 31 17l23 0q3 0 8 0t8 0q1-63 1-188 0-44-3-60-21-8-38-10-14 24-30 71-1 5-6 26t-8 41-4 21q-6 7-15 10-3 1-37 1-17 0-52 1t-57 1-53-2-53-4q-5-45-5-75l1-85v29q0-31 0-86t1-101 0-85q0-9-1-40t0-51 7-38q22-12 69-24t67-21q3-22 3-28 0-8-2-16l-19-1q-42-1-121 5t-116 5q-28 0-84-5t-85-5q-2 29-2 29v5q10 15 35 24t55 16 43 16q4 8 7 41t3 81 1 86-1 86 0 50q0 4-1 12t-2 12q0 4 1 25t0 41 0 42-1 38-4 18q-6 7-90 7-23 0-91-8t-77-14q-11-6-19-40t-18-62-24-30q-23 15-31 25v213z m686-715q7 0 23-11t33-23 33-28 20-17q14-11 14-27t-14-27q-2-2-20-17t-33-27-33-23-23-11q-7 0-11 5t-6 16-1 19 0 18 1 11h-571q0-1 1-11t1-18-2-19-5-16-12-5q-7 0-23 11t-32 23-34 27-20 17q-14 11-14 27t14 27q3 2 20 17t34 28 32 23 23 11q7 0 12-6t5-16 2-19-1-18-1-11h571q0 1-1 11t0 18 1 19 6 16 11 6z" horiz-adv-x="857.1" />
<glyph glyph-name="to-start" unicode="&#xe821;" d="m546 771q11 11 18 8t7-18v-822q0-14-7-18t-18 8l-396 396q-5 5-7 11v-379q0-14-11-25t-25-11h-71q-15 0-25 11t-11 25v786q0 14 11 25t25 11h71q15 0 25-11t11-25v-379q2 7 7 11z" horiz-adv-x="571.4" />
<glyph glyph-name="to-end" unicode="&#xe822;" d="m25-71q-10-11-18-8t-7 18v822q0 14 7 18t18-8l396-396q5-4 8-11v379q0 14 10 25t25 11h72q14 0 25-11t10-25v-786q0-14-10-25t-25-11h-72q-14 0-25 11t-10 25v379q-3-6-8-11z" horiz-adv-x="571.4" />
<glyph glyph-name="ccw" unicode="&#xe823;" d="m857 350q0-87-34-166t-91-137-137-92-166-34q-96 0-183 41t-147 114q-4 6-4 13t5 11l76 77q6 5 14 5 9-1 13-7 41-53 100-82t126-29q58 0 110 23t92 61 61 91 22 111-22 111-61 91-92 61-110 23q-55 0-105-20t-90-57l77-77q17-16 8-38-10-23-33-23h-250q-15 0-25 11t-11 25v250q0 24 22 33 22 10 39-8l72-72q60 57 137 88t159 31q87 0 166-34t137-92 91-137 34-166z" horiz-adv-x="857.1" />
<glyph glyph-name="cw" unicode="&#xe824;" d="m857 707v-250q0-14-10-25t-26-11h-250q-23 0-32 23-10 22 7 38l77 77q-82 77-194 77-58 0-111-23t-91-61-62-91-22-111 22-111 62-91 91-61 111-23q66 0 125 29t100 82q4 6 13 7 8 0 14-5l76-77q5-4 6-11t-5-13q-60-74-147-114t-182-41q-87 0-167 34t-136 92-92 137-34 166 34 166 92 137 136 92 167 34q82 0 158-31t137-88l72 72q16 18 39 8 22-9 22-33z" horiz-adv-x="857.1" />
<glyph glyph-name="arrows-cw" unicode="&#xe825;" d="m843 261q0-3 0-4-36-150-150-243t-267-93q-81 0-157 31t-136 88l-72-72q-11-11-25-11t-25 11-11 25v250q0 14 11 25t25 11h250q14 0 25-11t10-25-10-25l-77-77q40-37 90-57t105-20q74 0 139 37t104 99q6 10 29 66 5 13 17 13h107q8 0 13-6t5-12z m14 446v-250q0-14-10-25t-26-11h-250q-14 0-25 11t-10 25 10 25l77 77q-82 77-194 77-75 0-140-37t-104-99q-6-10-29-66-5-13-17-13h-111q-7 0-13 6t-5 12v4q36 150 151 243t268 93q81 0 158-31t137-88l72 72q11 11 25 11t26-11 10-25z" horiz-adv-x="857.1" />
<glyph glyph-name="file-code" unicode="&#xe826;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-518 500q4 7 12 7t13-3l28-21q7-5 7-12t-3-14l-102-135 102-136q4-6 3-13t-7-12l-28-21q-6-4-13-4t-12 7l-126 168q-8 11 0 21z m447-168q8-10 0-21l-126-168q-4-6-11-7t-14 4l-28 21q-6 5-7 12t3 13l102 136-102 135q-4 7-3 14t7 12l28 21q6 4 14 3t11-7z m-346-257q-7 1-11 7t-3 14l77 464q1 7 7 11t14 3l35-5q7-2 11-8t3-13l-77-464q-1-7-7-11t-13-3z" horiz-adv-x="857.1" />
<glyph glyph-name="code" unicode="&#xe827;" d="m344 69l-28-28q-5-5-12-5t-13 5l-260 260q-6 6-6 13t6 13l260 260q5 6 13 6t12-6l28-28q6-5 6-13t-6-12l-219-220 219-219q6-6 6-13t-6-13z m330 596l-208-721q-2-7-9-11t-13-1l-34 9q-8 3-11 9t-2 14l208 720q3 8 9 11t13 2l35-10q7-2 11-9t1-13z m367-364l-260-260q-6-5-13-5t-13 5l-28 28q-5 6-5 13t5 13l219 219-219 220q-5 5-5 12t5 13l28 28q6 6 13 6t13-6l260-260q5-5 5-13t-5-13z" horiz-adv-x="1071.4" />
<glyph glyph-name="chat" unicode="&#xe828;" d="m786 421q0-77-53-143t-143-104-197-38q-48 0-98 9-70-49-155-72-21-5-48-9h-2q-6 0-12 5t-6 12q-1 1-1 3t1 4 1 3l1 3t2 3 2 3 3 3 2 2q3 3 13 14t15 16 12 17 14 21 11 25q-69 40-108 98t-40 125q0 78 53 144t143 104 197 38 197-38 143-104 53-144z m214-142q0-67-40-126t-108-98q5-14 11-25t14-21 13-16 14-17 13-14q0 0 2-2t3-3 2-3 2-3l1-3t1-3 1-4-1-3q-2-8-7-13t-13-4q-27 4-48 9-85 23-155 72-50-9-98-9-151 0-263 74 32-3 49-3 90 0 172 25t148 72q69 52 107 119t37 141q0 43-13 85 72-39 114-99t42-128z" horiz-adv-x="1000" />
<glyph glyph-name="comment-empty" unicode="&#xe829;" d="m500 636q-114 0-213-39t-157-105-59-142q0-62 40-119t113-98l48-28-15-54q-13-50-39-95 85 35 154 95l24 21 31-3q39-5 73-5 114 0 213 39t157 105 59 142-59 142-157 105-213 39z m500-286q0-97-67-179t-182-130-251-48q-39 0-81 4-110-97-257-135-27-7-63-12h-3q-8 0-15 6t-9 15v1q-2 2 0 7t1 5 2 5l4 5t4 5 4 5q4 5 17 19t20 22 17 22 18 28 15 33 15 42q-88 50-138 123t-51 157q0 97 67 179t182 130 251 48 251-48 182-130 67-179z" horiz-adv-x="1000" />
<glyph glyph-name="trash-empty" unicode="&#xe82a;" d="m286 439v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m143 0v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m142 0v-321q0-8-5-13t-12-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q7 0 12-5t5-13z m72-404v529h-500v-529q0-12 4-22t8-15 6-5h464q2 0 6 5t8 15 4 22z m-375 601h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q22 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" />
<glyph glyph-name="mic" unicode="&#xe82b;" d="m643 457v-71q0-124-82-215t-204-104v-74h143q15 0 25-11t11-25-11-25-25-11h-357q-15 0-25 11t-11 25 11 25 25 11h143v74q-121 13-204 104t-82 215v71q0 15 11 25t25 11 25-11 10-25v-71q0-104 74-177t176-73 177 73 73 177v71q0 15 11 25t25 11 25-11 11-25z m-143 214v-285q0-74-52-126t-127-53-126 53-52 126v285q0 74 52 127t126 52 127-52 52-127z" horiz-adv-x="642.9" />
<glyph glyph-name="play" unicode="&#xe82c;" d="m772 333l-741-412q-13-7-22-2t-9 20v822q0 14 9 20t22-2l741-412q13-7 13-17t-13-17z" horiz-adv-x="785.7" />
<glyph glyph-name="stop" unicode="&#xe82d;" d="m857 743v-786q0-14-10-25t-26-11h-785q-15 0-25 11t-11 25v786q0 14 11 25t25 11h785q15 0 26-11t10-25z" horiz-adv-x="857.1" />
<glyph glyph-name="pause" unicode="&#xe82e;" d="m857 743v-786q0-14-10-25t-26-11h-285q-15 0-25 11t-11 25v786q0 14 11 25t25 11h285q15 0 26-11t10-25z m-500 0v-786q0-14-10-25t-26-11h-285q-15 0-25 11t-11 25v786q0 14 11 25t25 11h285q15 0 26-11t10-25z" horiz-adv-x="857.1" />
<glyph glyph-name="gauge" unicode="&#xe82f;" d="m214 207q0 30-21 51t-50 21-51-21-21-51 21-50 51-21 50 21 21 50z m107 250q0 30-20 51t-51 21-50-21-21-51 21-50 50-21 51 21 20 50z m239-268l57 213q3 14-5 27t-21 16-27-3-17-22l-56-213q-33-3-60-25t-35-55q-11-43 11-81t66-50 81 11 50 66q9 33-4 65t-40 51z m369 18q0 30-21 51t-51 21-50-21-21-51 21-50 50-21 51 21 21 50z m-358 357q0 30-20 51t-51 21-50-21-21-51 21-50 50-21 51 21 20 50z m250-107q0 30-20 51t-51 21-50-21-21-51 21-50 50-21 51 21 20 50z m179-250q0-145-79-269-10-17-30-17h-782q-20 0-30 17-79 123-79 269 0 102 40 194t106 160 160 107 194 39 194-39 160-107 106-160 40-194z" horiz-adv-x="1000" />
<glyph glyph-name="brush" unicode="&#xe830;" d="m901 850q39 0 69-26t29-65q0-35-25-84-185-351-260-420-54-51-121-51-71 0-121 52t-51 122q0 72 52 119l356 323q33 30 72 30z m-507-577q22-42 59-73t84-42l1-40q2-119-72-193t-195-75q-68 0-121 26t-86 71-48 102-16 123q4-3 23-17t35-25 32-20 26-9q23 0 31 20 14 37 32 63t39 42 49 27 57 14 70 6z" horiz-adv-x="1000" />
<glyph glyph-name="slideshare" unicode="&#xe831;" d="m487 437q0-46-35-79t-85-34-85 34-36 79q0 47 36 80t85 33 85-33 35-80z m280 0q0-46-35-79t-85-34q-50 0-85 34t-36 79q0 47 36 80t85 33q50 0 85-33t35-80z m126-100v372q0 48-18 69t-62 20h-620q-47 0-63-19t-17-70v-376q24-13 50-22t45-16 45-10 40-6 39-2 32-1 32 1 25 1q38 1 53-15 3-3 5-5 15-14 34-28 4 51 66 48 3 0 21 0t24-1 25-1 30 1 30 2 34 5 35 7 37 11 38 15 40 20z m91 2q-68-83-208-140 47-159-13-260-36-63-102-82-58-18-101 8-48 28-46 92l-1 182v0q-4 1-13 3t-13 3l-1-188q2-64-46-92-44-26-102-8-66 20-102 83-59 101-12 259-140 57-208 140-14 21-2 36t33-1q2-1 7-4t6-4v387q0 40 26 69t64 28h701q37 0 64-28t26-69v-387l12 8q21 15 33 0t-2-35z" horiz-adv-x="1000" />
<glyph glyph-name="tasks" unicode="&#xe832;" d="m571 64h358v72h-358v-72z m-214 286h572v71h-572v-71z m357 286h215v71h-215v-71z m286-465v-142q0-15-11-25t-25-11h-928q-15 0-25 11t-11 25v142q0 15 11 26t25 10h928q15 0 25-10t11-26z m0 286v-143q0-14-11-25t-25-10h-928q-15 0-25 10t-11 25v143q0 15 11 25t25 11h928q15 0 25-11t11-25z m0 286v-143q0-15-11-25t-25-11h-928q-15 0-25 11t-11 25v143q0 14 11 25t25 11h928q15 0 25-11t11-25z" horiz-adv-x="1000" />
<glyph glyph-name="cog" unicode="&#xe833;" d="m571 350q0 59-41 101t-101 42-101-42-42-101 42-101 101-42 101 42 41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-27 59-77 6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5-8 0-14 6-70 64-92 94-4 5-4 13 0 6 5 12 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 15 20 15h124q7 0 13-4t7-12l15-103q28-9 50-21l80 60q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-13 0-6-4-12-9-12-29-38t-30-39q14-28 23-55l102-15q7-1 12-7t4-13z" horiz-adv-x="857.1" />
<glyph glyph-name="exchange" unicode="&#xe834;" d="m1000 189v-107q0-7-5-12t-13-6h-768v-107q0-7-5-12t-13-6q-6 0-13 6l-178 178q-5 5-5 13 0 8 5 13l179 178q5 5 12 5 8 0 13-5t5-13v-107h768q7 0 13-5t5-13z m0 304q0-8-5-13l-179-179q-5-5-12-5-8 0-13 6t-5 12v107h-768q-7 0-13 6t-5 12v107q0 8 5 13t13 5h768v107q0 8 5 13t13 5q6 0 13-5l178-178q5-5 5-13z" horiz-adv-x="1000" />
<glyph glyph-name="star-empty" unicode="&#xe835;" d="m634 290l171 165-235 35-106 213-105-213-236-35 171-165-41-235 211 111 211-111z m295 199q0-12-15-27l-203-197 48-279q1-4 1-12 0-28-23-28-10 0-22 7l-251 132-250-132q-13-7-23-7-11 0-17 9t-6 19q0 4 1 12l48 279-203 197q-14 15-14 27 0 21 31 26l280 40 126 254q11 23 27 23t28-23l125-254 280-40q32-5 32-26z" horiz-adv-x="928.6" />
<glyph glyph-name="star" unicode="&#xe836;" d="m929 489q0-12-15-27l-203-197 48-279q1-4 1-12 0-11-6-19t-17-9q-10 0-22 7l-251 132-250-132q-13-7-23-7-11 0-17 9t-6 19q0 4 1 12l48 279-203 197q-14 15-14 27 0 21 31 26l280 40 126 254q11 23 27 23t28-23l125-254 280-40q32-5 32-26z" horiz-adv-x="928.6" />
<glyph glyph-name="clock" unicode="&#xe837;" d="m500 546v-250q0-7-5-12t-13-5h-178q-8 0-13 5t-5 12v36q0 8 5 13t13 5h125v196q0 8 5 13t12 5h36q8 0 13-5t5-13z m232-196q0 83-41 152t-110 111-152 41-153-41-110-111-41-152 41-152 110-111 153-41 152 41 110 111 41 152z m125 0q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
</font>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,009 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 517 B

View file

@ -28,7 +28,6 @@ $ = jQuery = require('./rjquery').$;
_ = require("./underscore");
var isNodeText = Ace2Common.isNodeText,
browser = $.browser,
getAssoc = Ace2Common.getAssoc,
setAssoc = Ace2Common.setAssoc,
isTextNode = Ace2Common.isTextNode,
@ -36,7 +35,7 @@ var isNodeText = Ace2Common.isNodeText,
htmlPrettyEscape = Ace2Common.htmlPrettyEscape,
noop = Ace2Common.noop;
var hooks = require('./pluginfw/hooks');
var browser = require('./browser').browser;
function Ace2Inner(){
@ -3700,7 +3699,7 @@ function Ace2Inner(){
}, 0);
specialHandled = true;
}
if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "s" && (evt.metaKey || evt.ctrlKey)) /* Do a saved revision on ctrl S */
if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "s" && (evt.metaKey || evt.ctrlKey) && !evt.altKey) /* Do a saved revision on ctrl S */
{
evt.preventDefault();
var originalBackground = parent.parent.$('#revisionlink').css("background")
@ -3857,7 +3856,7 @@ function Ace2Inner(){
/* Attempt to apply some sanity to cursor handling in Chrome after a copy / paste event
We have to do this the way we do because rep. doesn't hold the value for keyheld events IE if the user
presses and holds the arrow key .. Sorry if this is ugly, blame Chrome's weird handling of viewports after new content is added*/
if((evt.which == 37 || evt.which == 38 || evt.which == 39 || evt.which == 40) && $.browser.chrome){
if((evt.which == 37 || evt.which == 38 || evt.which == 39 || evt.which == 40) && browser.chrome){
var viewport = getViewPortTopBottom();
var myselection = document.getSelection(); // get the current caret selection, can't use rep. here because that only gives us the start position not the current
var caretOffsetTop = myselection.focusNode.parentNode.offsetTop || myselection.focusNode.offsetTop; // get the carets selection offset in px IE 214

View file

@ -66,7 +66,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
}
// for IE
if ($.browser.msie)
if (browser.msie)
{
try
{

View file

@ -379,16 +379,16 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
{
var self = this;
$(self).css('background-image', 'url(/static/img/crushed_button_depressed.png)');
// $(self).css('background-image', 'url(/static/img/crushed_button_depressed.png)');
$(self).mouseup(function(evt2)
{
$(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
// $(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(self).unbind('mouseup');
BroadcastSlider.playpause();
});
$(document).mouseup(function(evt2)
{
$(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
// $(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(document).unbind('mouseup');
});
});

240
src/static/js/browser.js Normal file
View file

@ -0,0 +1,240 @@
/*!
* Bowser - a browser detector
* https://github.com/ded/bowser
* MIT License | (c) Dustin Diaz 2014
*/
!function (name, definition) {
if (typeof module != 'undefined' && module.exports) module.exports['browser'] = definition()
else if (typeof define == 'function' && define.amd) define(definition)
else this[name] = definition()
}('bowser', function () {
/**
* See useragents.js for examples of navigator.userAgent
*/
var t = true
function detect(ua) {
function getFirstMatch(regex) {
var match = ua.match(regex);
return (match && match.length > 1 && match[1]) || '';
}
var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase()
, likeAndroid = /like android/i.test(ua)
, android = !likeAndroid && /android/i.test(ua)
, versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i)
, tablet = /tablet/i.test(ua)
, mobile = !tablet && /[^-]mobi/i.test(ua)
, result
if (/opera|opr/i.test(ua)) {
result = {
name: 'Opera'
, opera: t
, version: versionIdentifier || getFirstMatch(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i)
}
}
else if (/windows phone/i.test(ua)) {
result = {
name: 'Windows Phone'
, windowsphone: t
, msie: t
, version: getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i)
}
}
else if (/msie|trident/i.test(ua)) {
result = {
name: 'Internet Explorer'
, msie: t
, version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i)
}
}
else if (/chrome|crios|crmo/i.test(ua)) {
result = {
name: 'Chrome'
, chrome: t
, version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)
}
}
else if (iosdevice) {
result = {
name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod'
}
// WTF: version is not part of user agent in web apps
if (versionIdentifier) {
result.version = versionIdentifier
}
}
else if (/sailfish/i.test(ua)) {
result = {
name: 'Sailfish'
, sailfish: t
, version: getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i)
}
}
else if (/seamonkey\//i.test(ua)) {
result = {
name: 'SeaMonkey'
, seamonkey: t
, version: getFirstMatch(/seamonkey\/(\d+(\.\d+)?)/i)
}
}
else if (/firefox|iceweasel/i.test(ua)) {
result = {
name: 'Firefox'
, firefox: t
, version: getFirstMatch(/(?:firefox|iceweasel)[ \/](\d+(\.\d+)?)/i)
}
if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) {
result.firefoxos = t
}
}
else if (/silk/i.test(ua)) {
result = {
name: 'Amazon Silk'
, silk: t
, version : getFirstMatch(/silk\/(\d+(\.\d+)?)/i)
}
}
else if (android) {
result = {
name: 'Android'
, version: versionIdentifier
}
}
else if (/phantom/i.test(ua)) {
result = {
name: 'PhantomJS'
, phantom: t
, version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i)
}
}
else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) {
result = {
name: 'BlackBerry'
, blackberry: t
, version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i)
}
}
else if (/(web|hpw)os/i.test(ua)) {
result = {
name: 'WebOS'
, webos: t
, version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i)
};
/touchpad\//i.test(ua) && (result.touchpad = t)
}
else if (/bada/i.test(ua)) {
result = {
name: 'Bada'
, bada: t
, version: getFirstMatch(/dolfin\/(\d+(\.\d+)?)/i)
};
}
else if (/tizen/i.test(ua)) {
result = {
name: 'Tizen'
, tizen: t
, version: getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || versionIdentifier
};
}
else if (/safari/i.test(ua)) {
result = {
name: 'Safari'
, safari: t
, version: versionIdentifier
}
}
else result = {}
// set webkit or gecko flag for browsers based on these engines
if (/(apple)?webkit/i.test(ua)) {
result.name = result.name || "Webkit"
result.webkit = t
if (!result.version && versionIdentifier) {
result.version = versionIdentifier
}
} else if (!result.opera && /gecko\//i.test(ua)) {
result.name = result.name || "Gecko"
result.gecko = t
result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i)
}
// set OS flags for platforms that have multiple browsers
if (android || result.silk) {
result.android = t
} else if (iosdevice) {
result[iosdevice] = t
result.ios = t
}
// OS version extraction
var osVersion = '';
if (iosdevice) {
osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i);
osVersion = osVersion.replace(/[_\s]/g, '.');
} else if (android) {
osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i);
} else if (result.windowsphone) {
osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i);
} else if (result.webos) {
osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i);
} else if (result.blackberry) {
osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i);
} else if (result.bada) {
osVersion = getFirstMatch(/bada\/(\d+(\.\d+)*)/i);
} else if (result.tizen) {
osVersion = getFirstMatch(/tizen[\/\s](\d+(\.\d+)*)/i);
}
if (osVersion) {
result.osversion = osVersion;
}
// device type extraction
var osMajorVersion = osVersion.split('.')[0];
if (tablet || iosdevice == 'ipad' || (android && (osMajorVersion == 3 || (osMajorVersion == 4 && !mobile))) || result.silk) {
result.tablet = t
} else if (mobile || iosdevice == 'iphone' || iosdevice == 'ipod' || android || result.blackberry || result.webos || result.bada) {
result.mobile = t
}
// Graded Browser Support
// http://developer.yahoo.com/yui/articles/gbs
if ((result.msie && result.version >= 10) ||
(result.chrome && result.version >= 20) ||
(result.firefox && result.version >= 20.0) ||
(result.safari && result.version >= 6) ||
(result.opera && result.version >= 10.0) ||
(result.ios && result.osversion && result.osversion.split(".")[0] >= 6) ||
(result.blackberry && result.version >= 10.1)
) {
result.a = t;
}
else if ((result.msie && result.version < 10) ||
(result.chrome && result.version < 20) ||
(result.firefox && result.version < 20.0) ||
(result.safari && result.version < 6) ||
(result.opera && result.version < 10.0) ||
(result.ios && result.osversion && result.osversion.split(".")[0] < 6)
) {
result.c = t
} else result.x = t
return result
}
var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : '')
/*
* Set our detect method to the main bowser object so we can
* reuse it to test other user agents.
* This is needed to implement future tests.
*/
bowser._detect = detect;
return bowser
});

View file

@ -82,7 +82,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
{}
};
if ($.browser.mozilla)
if (browser.mozilla)
{
// Prevent "escape" from taking effect and canceling a comet connection;
// doesn't work if focus is on an iframe.

View file

@ -54,10 +54,14 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
},
nodeNumChildren: function(n)
{
if(n.childNodes == null) return 0;
return n.childNodes.length;
},
nodeChild: function(n, i)
{
if(n.childNodes.item == null){
return n.childNodes[i];
}
return n.childNodes.item(i);
},
nodeProp: function(n, p)
@ -66,6 +70,7 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
},
nodeAttr: function(n, a)
{
if(n.getAttribute == null) return null;
return n.getAttribute(a);
},
optNodeInnerHTML: function(n)

View file

@ -170,7 +170,7 @@ $._farbtastic = function (container, options) {
// New color
color2 = fb.pack(fb.HSLToRGB([d2, 1, 0.5]));
if (i > 0) {
if ($.browser.msie) {
if (browser.msie) {
// IE's gradient calculations mess up the colors. Correct along the diagonals.
var corr = (1 + Math.min(Math.abs(Math.tan(angle1)), Math.abs(Math.tan(Math.PI / 2 - angle1)))) / n;
color1 = fb.pack(fb.HSLToRGB([d1 - 0.15 * corr, 1, 0.5]));
@ -254,7 +254,7 @@ $._farbtastic = function (container, options) {
fb.ctxMask.drawImage(buffer, 0, 0, sz + 1, sz + 1, -sq, -sq, sq * 2, sq * 2);
}
// Method #2: drawing commands (old Canvas).
else if (!$.browser.msie) {
else if (!browser.msie) {
// Render directly at half-resolution
var sz = Math.floor(size / 2);
calculateMask(sz, sz, function (x, y, c, a) {

View file

@ -1,50 +0,0 @@
/*
Copied from jQuery 1.8, the last jquery version with browser recognition support
*/
(function(){
// Use of jQuery.browser is frowned upon.
// More details: http://api.jquery.com/jQuery.browser
// jQuery.uaMatch maintained for back-compat
var uaMatch = function( ua ) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
/(msie) ([\w.]+)/.exec( ua ) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
var userAgent = navigator.userAgent;
var matched = uaMatch(userAgent);
var browser = {};
if ( matched.browser ) {
browser[ matched.browser ] = true;
browser.version = matched.version;
}
// Chrome is Webkit, but Webkit is also Safari.
if ( browser.chrome ) {
browser.webkit = true;
} else if ( browser.webkit ) {
browser.safari = true;
}
//custom extensions, the original jquery didn't have these
browser.windows = /windows/i.test(userAgent);
browser.mobile = /mobile/i.test(userAgent) || /android/i.test(userAgent);
if(typeof exports !== 'undefined'){
exports.browser = browser;
} else{
$.browser = browser;
}
})();

View file

@ -43,7 +43,6 @@ var padsavedrevs = require('./pad_savedrevs');
var paduserlist = require('./pad_userlist').paduserlist;
var padutils = require('./pad_utils').padutils;
var colorutils = require('./colorutils').colorutils;
var createCookie = require('./pad_utils').createCookie;
var readCookie = require('./pad_utils').readCookie;
var randomString = require('./pad_utils').randomString;
@ -386,7 +385,6 @@ var pad = {
diagnosticInfo: {},
initTime: 0,
clientTimeOffset: null,
preloadedImages: false,
padOptions: {},
// these don't require init; clientVars should all go through here
@ -454,13 +452,13 @@ var pad = {
pad.initTime = +(new Date());
pad.padOptions = clientVars.initialOptions;
if ((!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0)))
if ((!browser.msie) && (!(browser.mozilla && browser.version.indexOf("1.8.") == 0)))
{
document.domain = document.domain; // for comet
}
// for IE
if ($.browser.msie)
if (browser.msie)
{
try
{
@ -728,19 +726,6 @@ var pad = {
},
handleIsFullyConnected: function(isConnected, isInitialConnect)
{
// load all images referenced from CSS, one at a time,
// starting one second after connection is first established.
if (isConnected && !pad.preloadedImages)
{
window.setTimeout(function()
{
if (!pad.preloadedImages)
{
pad.preloadImages();
pad.preloadedImages = true;
}
}, 1000);
}
pad.determineChatVisibility(isConnected && !isInitialConnect);
pad.determineAuthorshipColorsVisibility();
@ -837,34 +822,6 @@ var pad = {
{
pad.collabClient.addHistoricalAuthors(data);
}
},
preloadImages: function()
{
var images = ["../static/img/connectingbar.gif"];
function loadNextImage()
{
if (images.length == 0)
{
return;
}
var img = new Image();
img.src = images.shift();
if (img.complete)
{
scheduleLoadNextImage();
}
else
{
$(img).bind('error load onreadystatechange', scheduleLoadNextImage);
}
}
function scheduleLoadNextImage()
{
window.setTimeout(loadNextImage, 0);
}
scheduleLoadNextImage();
}
};

View file

@ -35,32 +35,10 @@ var padimpexp = (function()
function fileInputUpdated()
{
$('#importsubmitinput').addClass('throbbold');
$('#importformfilediv').addClass('importformenabled');
$('#importsubmitinput').removeAttr('disabled');
$('#importmessagefail').fadeOut("fast");
$('#importarrow').show();
$('#importarrow').animate(
{
paddingLeft: "0px"
}, 500).animate(
{
paddingLeft: "10px"
}, 150, 'swing').animate(
{
paddingLeft: "0px"
}, 150, 'swing').animate(
{
paddingLeft: "10px"
}, 150, 'swing').animate(
{
paddingLeft: "0px"
}, 150, 'swing').animate(
{
paddingLeft: "10px"
}, 150, 'swing').animate(
{
paddingLeft: "0px"
}, 150, 'swing');
$('#importmessagefail').fadeOut('fast');
}
function fileInputSubmit()

View file

@ -730,7 +730,7 @@ var paduserlist = (function()
$("#myswatch").css({'background-color': myUserInfo.colorId});
if ($.browser.msie && parseInt($.browser.version) <= 8) {
if (browser.msie && parseInt(browser.version) <= 8) {
$("li[data-key=showusers] > a").css({'box-shadow': 'inset 0 0 30px ' + myUserInfo.colorId,'background-color': myUserInfo.colorId});
}
else

View file

@ -1,10 +1,5 @@
// Proviedes a require'able version of jQuery without leaking $ and jQuery;
require('./jquery');
var jq = window.$.noConflict(true);
//added the old browser recognition
jq.browser = require('./jquery_browser').browser;
exports.jQuery = exports.$ = jq;

View file

@ -10,7 +10,7 @@
<body>
<div id="wrapper">
<div class="menu">
<h1><a href="../../">Etherpad</a></h1>
<h1><a href="../">Etherpad</a></h1>
<ul>
<% e.begin_block("adminMenu"); %>
<li><a href="plugins">Plugin manager</a> </li>

View file

@ -11,7 +11,7 @@
<body>
<div id="wrapper">
<div class="menu">
<h1><a href="../../../">Etherpad</a></h1>
<h1><a href="../../">Etherpad</a></h1>
<ul>
<% e.begin_block("adminMenu"); %>
<li><a href="../plugins">Plugin manager</a> </li>

View file

@ -20,7 +20,7 @@
<% } %>
<div class="menu">
<h1><a href="../../">Etherpad</a></h1>
<h1><a href="../">Etherpad</a></h1>
<ul>
<% e.begin_block("adminMenu"); %>
<li><a href="plugins">Plugin manager</a> </li>
@ -49,7 +49,7 @@
<td>
<div class="actions">
<input type="button" value="Uninstall" class="do-uninstall">
<div class="progress"><p><img src="../static/img/loading.gif"/></p><p><span class="message"></span></p></div>
<div class="progress"><p class="loadingAnimation"></p><p><span class="message"></span></p></div>
</div>
</td>
</tr>
@ -59,7 +59,7 @@
<tbody class="messages">
<tr><td></td><td>
<p class="nothing-installed">You haven't installed any plugins yet.</p>
<p class="fetching"><img src="../static/img/loading.gif"/><br/>Fetching installed plugins...</p>
<p class="fetching"><p class="loadingAnimation"></p><br/>Fetching installed plugins...</p>
</td><td></td></tr>
</tbody>
</table>
@ -89,7 +89,7 @@
<td>
<div class="actions">
<input type="button" value="Install" class="do-install">
<div class="progress"><p><img src="../static/img/loading.gif"/></p><p><span class="message"></span></p></div>
<div class="progress"><p><p class="loadingAnimation"></p></p><p><span class="message"></span></p></div>
</div>
</td>
</tr>
@ -101,7 +101,7 @@
<div class="messages">
<div id="search-progress" class="progress"><p>&nbsp;</p></div>
<p class="nothing-found">No plugins found.</p>
<p class="fetching"><img src="../static/img/loading.gif"/><br/>Fetching...</p>
<p class="fetching"><p class="loadingAnimation"></p><br/>Fetching...</p>
</div>
</td><td></td></tr>
</tbody>

View file

@ -24,7 +24,7 @@
<div class="menu">
<h1><a href="../../">Etherpad</a></h1>
<h1><a href="../">Etherpad</a></h1>
<ul>
<% e.begin_block("adminMenu"); %>
<li><a href="plugins">Plugin manager</a> </li>

View file

@ -40,7 +40,6 @@
<link rel="shortcut icon" href="<%=settings.faviconPad%>">
<% e.begin_block("styles"); %>
<link href="../static/css/fontawesome-etherpad.css" rel="stylesheet">
<link href="../static/css/pad.css" rel="stylesheet">
<% e.begin_block("customStyles"); %>
@ -195,8 +194,7 @@
<div class="importformdiv" id="importformsubmitdiv">
<span class="nowrap">
<input type="submit" name="submit" value="Import Now" disabled="disabled" id="importsubmitinput">
<img alt="" id="importstatusball" src="../static/img/loading.gif" align="top">
<img alt="" id="importarrow" src="../static/img/leftarrow.png" align="top">
<div alt="" id="importstatusball" class="loadingAnimation" align="top"></div>
</span>
</div>
</form>
@ -222,7 +220,7 @@
</div>
<div class="reconnecting">
<h1 data-l10n-id="pad.modals.reconnecting"></h1>
<p><img alt="" border="0" src="../static/img/connectingbar.gif" /></p>
<p class='loadingAnimation'></p>
</div>
<div class="userdup">
<h1 data-l10n-id="pad.modals.userdup"></h1>
@ -313,7 +311,7 @@
<a id="titlesticky" onClick="chat.stickToScreen(true);$('#options-stickychat').prop('checked', true);return false;" title="Stick chat to screen">&nbsp;&nbsp;</a>
</div>
<div id="chattext" class="authorColors">
<img alt="loading.." id="chatloadmessagesball" class="chatloadmessages" src="../static/img/loading.gif" align="top">
<div alt="loading.." id="chatloadmessagesball" class="chatloadmessages loadingAnimation" align="top"></div>
<button id="chatloadmessagesbutton" class="chatloadmessages" data-l10n-id="pad.chat.loadmessages"></button>
</div>
<div id="chatinputbox">
@ -369,8 +367,8 @@
require.setGlobalKeyPath("require");
$ = jQuery = require('ep_etherpad-lite/static/js/rjquery').jQuery; // Expose jQuery #HACK
if ((!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0))) {
browser = require('ep_etherpad-lite/static/js/browser').browser;
if ((!browser.msie) && (!(browser.mozilla && browser.version.indexOf("1.8.") == 0))) {
document.domain = document.domain; // for comet
}

View file

@ -116,7 +116,7 @@
</div>
<div class="reconnecting">
<h1 data-l10n-id="pad.modals.reconnecting"></h1>
<p><img alt="" border="0" src="../../static/img/connectingbar.gif" /></p>
<p class="loadingAnimation"></p>
</div>
<div class="userdup">
<h1 data-l10n-id="pad.modals.userdup"></h1>
@ -215,8 +215,9 @@
require.setGlobalKeyPath("require");
$ = jQuery = require('ep_etherpad-lite/static/js/rjquery').jQuery; // Expose jQuery #HACK
browser = require('ep_etherpad-lite/static/js/browser').browser;
if ((!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0))) {
if ((!browser.msie) && (!(browser.mozilla && browser.version.indexOf("1.8.") == 0))) {
document.domain = document.domain; // for comet
}

View file

@ -3,3 +3,7 @@
## Frontend
To run the tests, point your browser to `<yourdomainhere>/tests/frontend`
## Backend
To run the tests, run ``bin/backendTests.sh``

View file

@ -0,0 +1,269 @@
var assert = require('assert')
supertest = require(__dirname+'/../../../../src/node_modules/supertest'),
fs = require('fs'),
api = supertest('http://localhost:9001');
path = require('path');
var filePath = path.join(__dirname, '../../../../APIKEY.txt');
var apiKey = fs.readFileSync(filePath, {encoding: 'utf-8'});
var apiVersion = 1;
var testPadId = makeid();
var lastEdited = "";
describe('Connectivity', function(){
it('errors if can not connect', function(done) {
api.get('/api/')
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('API Versioning', function(){
it('errors if can not connect', function(done) {
api.get('/api/')
.expect(function(res){
apiVersion = res.body.currentVersion;
if (!res.body.currentVersion) throw new Error("No version set in API");
return;
})
.expect(200, done)
});
})
describe('Permission', function(){
it('errors if can connect without correct APIKey', function(done) {
// This is broken because Etherpad doesn't handle HTTP codes properly see #2343
// If your APIKey is password you deserve to fail all tests anyway
var permErrorURL = '/api/'+apiVersion+'/createPad?apikey=password&padID=test';
api.get(permErrorURL)
.expect(401, done)
});
})
/* Pad Tests Order of execution
-> deletePad -- This gives us a guaranteed clear environment
-> createPad
-> getRevisions -- Should be 0
-> getHTML -- Should be the default pad text in HTML format
-> deletePad -- Should just delete a pad
-> getHTML -- Should return an error
-> createPad(withText)
-> getText -- Should have the text specified above as the pad text
-> setText
-> getText -- Should be the text set before
-> getRevisions -- Should be 0 still?
-> padUsersCount -- Should be 0
-> getReadOnlyId -- Should be a value
-> listAuthorsOfPad(padID) -- should be empty array?
-> getLastEdited(padID) -- Should be when pad was made
-> setText(padId)
-> getLastEdited(padID) -- Should be when setText was performed
*/
describe('deletePad', function(){
it('deletes a Pad', function(done) {
api.get(endPoint('deletePad')+"&padID="+testPadId)
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('createPad', function(){
it('creates a new Pad', function(done) {
api.get(endPoint('createPad')+"&padID="+testPadId)
.expect(function(res){
if(res.body.code !== 0) throw new Error("Unable to create new Pad");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getRevisionsCount', function(){
it('gets revision count of Pad', function(done) {
api.get(endPoint('getRevisionsCount')+"&padID="+testPadId)
.expect(function(res){
if(res.body.code !== 0) throw new Error("Unable to get Revision Count");
if(res.body.data.revisions !== 0) throw new Error("Incorrect Revision Count");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getHTML', function(){
it('get the HTML of Pad', function(done) {
api.get(endPoint('getHTML')+"&padID="+testPadId)
.expect(function(res){
if(res.body.data.html.length <= 1) throw new Error("Unable to get Revision Count");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('deletePad', function(){
it('deletes a Pad', function(done) {
api.get(endPoint('deletePad')+"&padID="+testPadId)
.expect(function(res){
if(res.body.code !== 0) throw new Error("Pad Deletion failed")
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getHTML', function(){
it('get the HTML of a Pad -- Should return a failure', function(done) {
api.get(endPoint('getHTML')+"&padID="+testPadId)
.expect(function(res){
if(res.body.code !== 1) throw new Error("Pad deletion failed")
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('createPad', function(){
it('creates a new Pad with text', function(done) {
api.get(endPoint('createPad')+"&padID="+testPadId+"&text=testText")
.expect(function(res){
if(res.body.code !== 0) throw new Error("Pad Creation failed")
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getText', function(){
it('gets the Pad text and expect it to be testText with \n which is a line break', function(done) {
api.get(endPoint('getText')+"&padID="+testPadId)
.expect(function(res){
if(res.body.data.text !== "testText\n") throw new Error("Pad Creation with text")
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('setText', function(){
it('creates a new Pad with text', function(done) {
api.get(endPoint('setText')+"&padID="+testPadId+"&text=testTextTwo")
.expect(function(res){
if(res.body.code !== 0) throw new Error("Pad setting text failed");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getText', function(){
it('gets the Pad text', function(done) {
api.get(endPoint('getText')+"&padID="+testPadId)
.expect(function(res){
if(res.body.data.text !== "testTextTwo\n") throw new Error("Setting Text")
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getRevisionsCount', function(){
it('gets Revision Coutn of a Pad', function(done) {
api.get(endPoint('getRevisionsCount')+"&padID="+testPadId)
.expect(function(res){
if(res.body.data.revisions !== 1) throw new Error("Unable to set text revision count")
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('padUsersCount', function(){
it('gets User Count of a Pad', function(done) {
api.get(endPoint('padUsersCount')+"&padID="+testPadId)
.expect(function(res){
if(res.body.data.padUsersCount !== 0) throw new Error("Incorrect Pad User count")
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getReadOnlyID', function(){
it('Gets the Read Only ID of a Pad', function(done) {
api.get(endPoint('getReadOnlyID')+"&padID="+testPadId)
.expect(function(res){
if(!res.body.data.readOnlyID) throw new Error("No Read Only ID for Pad")
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('listAuthorsOfPad', function(){
it('Get Authors of the Pad', function(done) {
api.get(endPoint('listAuthorsOfPad')+"&padID="+testPadId)
.expect(function(res){
if(res.body.data.authorIDs.length !== 0) throw new Error("# of Authors of pad is not 0")
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getLastEdited', function(){
it('Get When Pad was left Edited', function(done) {
api.get(endPoint('getLastEdited')+"&padID="+testPadId)
.expect(function(res){
if(!res.body.data.lastEdited){
throw new Error("# of Authors of pad is not 0")
}else{
lastEdited = res.body.data.lastEdited;
}
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('setText', function(){
it('creates a new Pad with text', function(done) {
api.get(endPoint('setText')+"&padID="+testPadId+"&text=testTextTwo")
.expect(function(res){
if(res.body.code !== 0) throw new Error("Pad setting text failed");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getLastEdited', function(){
it('Get When Pad was left Edited', function(done) {
api.get(endPoint('getLastEdited')+"&padID="+testPadId)
.expect(function(res){
if(res.body.data.lastEdited <= lastEdited){
throw new Error("Editing A Pad is not updating when it was last edited")
}
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
var endPoint = function(point){
return '/api/'+apiVersion+'/'+point+'?apikey='+apiKey;
}
function makeid()
{
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 5; i++ ){
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}

View file

@ -0,0 +1,363 @@
var assert = require('assert')
supertest = require(__dirname+'/../../../../src/node_modules/supertest'),
fs = require('fs'),
api = supertest('http://localhost:9001');
path = require('path');
var filePath = path.join(__dirname, '../../../../APIKEY.txt');
var apiKey = fs.readFileSync(filePath, {encoding: 'utf-8'});
var apiVersion = 1;
var testPadId = makeid();
var groupID = "";
var authorID = "";
var sessionID = "";
var padID = makeid();
describe('API Versioning', function(){
it('errors if can not connect', function(done) {
api.get('/api/')
.expect(function(res){
apiVersion = res.body.currentVersion;
if (!res.body.currentVersion) throw new Error("No version set in API");
return;
})
.expect(200, done)
});
})
// BEGIN GROUP AND AUTHOR TESTS
/////////////////////////////////////
/////////////////////////////////////
/* Tests performed
-> createGroup() -- should return a groupID
-> listSessionsOfGroup(groupID) -- should be 0
-> deleteGroup(groupID)
-> createGroupIfNotExistsFor(groupMapper) -- should return a groupID
-> createAuthor([name]) -- should return an authorID
-> createAuthorIfNotExistsFor(authorMapper [, name]) -- should return an authorID
-> getAuthorName(authorID) -- should return a name IE "john"
-> createSession(groupID, authorID, validUntil)
-> getSessionInfo(sessionID)
-> listSessionsOfGroup(groupID) -- should be 1
-> deleteSession(sessionID)
-> getSessionInfo(sessionID) -- should have author id etc in
-> listPads(groupID) -- should be empty array
-> createGroupPad(groupID, padName [, text])
-> listPads(groupID) -- should be empty array
-> getPublicStatus(padId)
-> setPublicStatus(padId, status)
-> getPublicStatus(padId)
-> isPasswordProtected(padID) -- should be false
-> setPassword(padID, password)
-> isPasswordProtected(padID) -- should be true
-> listPadsOfAuthor(authorID)
*/
describe('createGroup', function(){
it('creates a new group', function(done) {
api.get(endPoint('createGroup'))
.expect(function(res){
if(res.body.code !== 0 || !res.body.data.groupID) throw new Error("Unable to create new Pad");
groupID = res.body.data.groupID;
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('listSessionsOfGroup', function(){
it('Lists the session of a group', function(done) {
api.get(endPoint('listSessionsOfGroup')+"&groupID="+groupID)
.expect(function(res){
if(res.body.code !== 0 || res.body.data !== null) throw new Error("Sessions show as existing for this group");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('deleteGroup', function(){
it('Deletes a group', function(done) {
api.get(endPoint('deleteGroup')+"&groupID="+groupID)
.expect(function(res){
if(res.body.code !== 0) throw new Error("Group failed to be deleted");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('createGroupIfNotExistsFor', function(){
it('Creates a group if one doesnt exist for mapper 0', function(done) {
api.get(endPoint('createGroupIfNotExistsFor')+"&groupMapper=management")
.expect(function(res){
if(res.body.code !== 0 || !res.body.data.groupID) throw new Error("Sessions show as existing for this group");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('createGroup', function(){
it('creates a new group', function(done) {
api.get(endPoint('createGroup'))
.expect(function(res){
if(res.body.code !== 0 || !res.body.data.groupID) throw new Error("Unable to create new Pad");
groupID = res.body.data.groupID;
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('createAuthor', function(){
it('Creates an author with a name set', function(done) {
api.get(endPoint('createAuthor'))
.expect(function(res){
if(res.body.code !== 0 || !res.body.data.authorID) throw new Error("Unable to create author");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('createAuthor', function(){
it('Creates an author with a name set', function(done) {
api.get(endPoint('createAuthor')+"&name=john")
.expect(function(res){
if(res.body.code !== 0 || !res.body.data.authorID) throw new Error("Unable to create user with name set");
authorID = res.body.data.authorID; // we will be this author for the rest of the tests
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('createAuthorIfNotExistsFor', function(){
it('Creates an author if it doesnt exist already and provides mapping', function(done) {
api.get(endPoint('createAuthorIfNotExistsFor')+"&authorMapper=chris")
.expect(function(res){
if(res.body.code !== 0 || !res.body.data.authorID) throw new Error("Unable to create author with mapper");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getAuthorName', function(){
it('Gets the author name', function(done) {
api.get(endPoint('getAuthorName')+"&authorID="+authorID)
.expect(function(res){
if(res.body.code !== 0 || !res.body.data === "john") throw new Error("Unable to get Author Name from Author ID");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
// BEGIN SESSION TESTS
///////////////////////////////////////
///////////////////////////////////////
describe('createSession', function(){
it('Creates a session for an Author', function(done) {
api.get(endPoint('createSession')+"&authorID="+authorID+"&groupID="+groupID+"&validUntil=999999999999")
.expect(function(res){
if(res.body.code !== 0 || !res.body.data.sessionID) throw new Error("Unable to create Session");
sessionID = res.body.data.sessionID;
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getSessionInfo', function(){
it('Gets session inf', function(done) {
api.get(endPoint('getSessionInfo')+"&sessionID="+sessionID)
.expect(function(res){
if(res.body.code !== 0 || !res.body.data.groupID || !res.body.data.authorID || !res.body.data.validUntil) throw new Error("Unable to get Session info");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('listSessionsOfGroup', function(){
it('Gets sessions of a group', function(done) {
api.get(endPoint('listSessionsOfGroup')+"&groupID="+groupID)
.expect(function(res){
if(res.body.code !== 0 || typeof res.body.data !== "object") throw new Error("Unable to get sessions of a group");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('deleteSession', function(){
it('Deletes a session', function(done) {
api.get(endPoint('deleteSession')+"&sessionID="+sessionID)
.expect(function(res){
if(res.body.code !== 0) throw new Error("Unable to delete a session");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getSessionInfo', function(){
it('Gets session info', function(done) {
api.get(endPoint('getSessionInfo')+"&sessionID="+sessionID)
.expect(function(res){
if(res.body.code !== 1) throw new Error("Session was not properly deleted");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
// GROUP PAD MANAGEMENT
///////////////////////////////////////
///////////////////////////////////////
describe('listPads', function(){
it('Lists Pads of a Group', function(done) {
api.get(endPoint('listPads')+"&groupID="+groupID)
.expect(function(res){
if(res.body.code !== 0 || res.body.data.padIDs.length !== 0) throw new Error("Group already had pads for some reason"+res.body.data.padIDs);
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('createGroupPad', function(){
it('Creates a Group Pad', function(done) {
api.get(endPoint('createGroupPad')+"&groupID="+groupID+"&padName="+padID)
.expect(function(res){
if(res.body.code !== 0) throw new Error("Unable to create group pad");
padID = res.body.data.padID;
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('listPads', function(){
it('Lists Pads of a Group', function(done) {
api.get(endPoint('listPads')+"&groupID="+groupID)
.expect(function(res){
if(res.body.code !== 0 || res.body.data.padIDs.length !== 1) throw new Error("Group isnt listing this pad");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
// PAD SECURITY /-_-\
///////////////////////////////////////
///////////////////////////////////////
describe('getPublicStatus', function(){
it('Gets the public status of a pad', function(done) {
api.get(endPoint('getPublicStatus')+"&padID="+padID)
.expect(function(res){
if(res.body.code !== 0 || res.body.data.publicstatus) throw new Error("Unable to get public status of this pad");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('setPublicStatus', function(){
it('Sets the public status of a pad', function(done) {
api.get(endPoint('setPublicStatus')+"&padID="+padID+"&publicStatus=true")
.expect(function(res){
if(res.body.code !== 0) throw new Error("Setting status did not work");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('getPublicStatus', function(){
it('Gets the public status of a pad', function(done) {
api.get(endPoint('getPublicStatus')+"&padID="+padID)
.expect(function(res){
if(res.body.code !== 0 || !res.body.data.publicStatus) throw new Error("Setting public status of this pad did not work");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('isPasswordProtected', function(){
it('Gets the public status of a pad', function(done) {
api.get(endPoint('isPasswordProtected')+"&padID="+padID)
.expect(function(res){
if(res.body.code !== 0 || res.body.data.isPasswordProtected) throw new Error("Pad is password protected by default");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('setPassword', function(){
it('Gets the public status of a pad', function(done) {
api.get(endPoint('setPassword')+"&padID="+padID+"&password=test")
.expect(function(res){
if(res.body.code !== 0) throw new Error("Unabe to set password");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
describe('isPasswordProtected', function(){
it('Gets the public status of a pad', function(done) {
api.get(endPoint('isPasswordProtected')+"&padID="+padID)
.expect(function(res){
if(res.body.code !== 0 || !res.body.data.isPasswordProtected) throw new Error("Pad password protection has not applied");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
// NOT SURE HOW TO POPULAT THIS /-_-\
///////////////////////////////////////
///////////////////////////////////////
describe('listPadsOfAuthor', function(){
it('Gets the Pads of an Author', function(done) {
api.get(endPoint('listPadsOfAuthor')+"&authorID="+authorID)
.expect(function(res){
if(res.body.code !== 0 || res.body.data.padIDs.length !== 0) throw new Error("Pad password protection has not applied");
})
.expect('Content-Type', /json/)
.expect(200, done)
});
})
var endPoint = function(point){
return '/api/'+apiVersion+'/'+point+'?apikey='+apiKey;
}
function makeid()
{
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 5; i++ ){
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}

View file

@ -10,7 +10,7 @@
<div id="iframe-container"></div>
<script src="/static/js/jquery.js"></script>
<script src="/static/js/jquery_browser.js"></script>
<script src="/static/js/browser.js"></script>
<script src="lib/underscore.js"></script>
<script src="lib/mocha.js"></script>
@ -22,6 +22,5 @@
<script src="helper.js"></script>
<script src="specs_list.js"></script>
<script src="runner.js"></script>
</html>

View file

@ -2,8 +2,9 @@
(function($) {
$.fn.purgeFrame = function() {
var deferred;
var browser = bowser;
if ($.browser.msie && parseFloat($.browser.version, 10) < 9) {
if (browser.msie && parseFloat(browser.version, 10) < 9) {
deferred = purge(this);
} else {
this.remove();

View file

@ -162,7 +162,8 @@ $(function(){
}
//allow cross iframe access
if ((!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0))) {
var browser = bowser;
if ((!browser.msie) && (!(browser.mozilla && browser.version.indexOf("1.8.") == 0))) {
document.domain = document.domain; // for comet
}

View file

@ -43,7 +43,9 @@ describe("bold button", function(){
//select this text element
$firstTextElement.sendkeys('{selectall}');
if(inner$.browser.mozilla){ // if it's a mozilla browser
console.log(inner$(window)[0].bowser);
if(inner$(window)[0].bowser.firefox){ // if it's a mozilla browser
var evtType = "keypress";
}else{
var evtType = "keydown";

View file

@ -1,11 +1,19 @@
describe("As the caret is moved is the UI properly updated?", function(){
var padName;
var numberOfRows = 50;
/*
it("creates a pad", function(done) {
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
xit("creates a pad", function(done) {
padName = helper.newPad(done);
this.timeout(60000);
});
*/
/* Tests to do
* Keystroke up (38), down (40), left (37), right (39) with and without special keys IE control / shift
@ -20,10 +28,12 @@ describe("As the caret is moved is the UI properly updated?", function(){
* How do we keep the authors focus on a line if the lines above the author are modified? We should only redraw the user to a location if they are typing and make sure shift and arrow keys aren't redrawing the UI else highlight - copy/paste would get broken
* How can we simulate an edit event in the test framework?
*/
// THIS DOESNT WORK AS IT DOESNT MOVE THE CURSOR!
/*
// THIS DOESNT WORK IN CHROME AS IT DOESNT MOVE THE CURSOR!
it("down arrow", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var $newFirstTextElement = inner$("div").first();
$newFirstTextElement.focus();
keyEvent(inner$, 37, false, false); // arrow down
@ -31,9 +41,10 @@ describe("As the caret is moved is the UI properly updated?", function(){
done();
});
/*
it("Creates N lines", function(done){
var inner$ = helper.padInner$;
console.log(inner$);
var chrome$ = helper.padChrome$;
var $newFirstTextElement = inner$("div").first();
@ -224,7 +235,6 @@ describe("As the caret is moved is the UI properly updated?", function(){
});
var i = 0;
while(i < numberOfRows){ // press down arrow
console.log("dwn");
keyEvent(inner$, 40, false, false);
i++;
}
@ -287,7 +297,7 @@ function prepareDocument(n, target){ // generates a random document with random
}
function keyEvent(target, charCode, ctrl, shift){ // sends a charCode to the window
if(target.browser.mozilla){ // if it's a mozilla browser
if(inner$(window)[0].bowser.firefox){ // if it's a mozilla browser
var evtType = "keypress";
}else{
var evtType = "keydown";

View file

@ -15,7 +15,7 @@ describe("indentation button", function(){
//select this text element
$firstTextElement.sendkeys('{selectall}');
if(inner$.browser.mozilla){ // if it's a mozilla browser
if(inner$(window)[0].bowser.firefox){ // if it's a mozilla browser
var evtType = "keypress";
}else{
var evtType = "keydown";

View file

@ -44,7 +44,7 @@ describe("italic some text", function(){
//select this text element
$firstTextElement.sendkeys('{selectall}');
if(inner$.browser.mozilla){ // if it's a mozilla browser
if(inner$(window)[0].bowser.firefox){ // if it's a mozilla browser
var evtType = "keypress";
}else{
var evtType = "keydown";

View file

@ -47,7 +47,7 @@ describe("undo button then redo button", function(){
var modifiedValue = $firstTextElement.text(); // get the modified value
expect(modifiedValue).not.to.be(originalValue); // expect the value to change
if(inner$.browser.mozilla){ // if it's a mozilla browser
if(inner$(window)[0].bowser.firefox){ // if it's a mozilla browser
var evtType = "keypress";
}else{
var evtType = "keydown";

View file

@ -19,7 +19,7 @@ describe('Responsiveness of Editor', function() {
helper.newPad(cb);
this.timeout(6000);
});
it('Fast response to keypress in pad with large amount of contents', function(done) {
xit('Fast response to keypress in pad with large amount of contents', function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var chars = '0000000000'; // row of placeholder chars

View file

@ -4,7 +4,8 @@ describe("timeslider", function(){
helper.newPad(cb);
this.timeout(6000);
});
it("loads adds a hundred revisions", function(done) {
it("loads adds a hundred revisions", function(done) { // passes
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
@ -56,7 +57,10 @@ describe("timeslider", function(){
}, 6000);
}, revs*timePerRev);
});
it("changes the url when clicking on the timeslider", function(done) {
// Disabled as jquery trigger no longer works properly
xit("changes the url when clicking on the timeslider", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
@ -80,7 +84,6 @@ describe("timeslider", function(){
var $sliderBar = timeslider$('#ui-slider-bar');
var latestContents = timeslider$('#padcontent').text();
var oldUrl = $('#iframe-container iframe')[0].contentWindow.location.hash;
// Click somewhere on the timeslider
@ -111,6 +114,7 @@ describe("timeslider", function(){
var oldLength = inner$('body').text().length + newLines / 2;
expect( oldLength ).to.not.eql( 0 );
inner$("div").first().sendkeys('a');
var timeslider$;
// wait for our additional revision to be added
helper.waitFor(function(){
@ -140,6 +144,7 @@ describe("timeslider", function(){
});
});
});
it("checks the export url", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;

View file

@ -44,7 +44,7 @@ describe("undo button", function(){
var modifiedValue = $firstTextElement.text(); // get the modified value
expect(modifiedValue).not.to.be(originalValue); // expect the value to change
if(inner$.browser.mozilla){ // if it's a mozilla browser
if(inner$(window)[0].bowser.firefox){ // if it's a mozilla browser
var evtType = "keypress";
}else{
var evtType = "keydown";