Merge branch 'master' into send-receive-chat-from-js-api
@ -1,3 +1,21 @@
|
||||
#
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
#
|
||||
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
BigBlueButton LTI Integration
|
||||
=============================
|
||||
BigBlueButton is an open source web conferencing system that enables universities and colleges to deliver a high-quality learning experience to remote students.
|
||||
@ -10,37 +28,39 @@ With this plugin you can
|
||||
|
||||
Development
|
||||
=============
|
||||
The plugin is a grails project that can be compiled using the bbb-web components installed in any BigBlueButton development environment.
|
||||
bbb-lti is a grails project that can be compiled using the bbb-web components installed in any BigBlueButton development environment.
|
||||
|
||||
To generate the war file
|
||||
grails clean
|
||||
grails war
|
||||
To generate the war file
|
||||
grails clean
|
||||
grails war
|
||||
|
||||
Deployment
|
||||
=============
|
||||
Place the war file into the tomcat webapps directory and restart tomcat
|
||||
Place the war file into the tomcat webapps directory and restart tomcat
|
||||
|
||||
sudo cp lti-0.1.war /var/lib/tomcat6/webapps/lti.war
|
||||
sudo cp lti-0.1.war /var/lib/tomcat6/webapps/lti.war
|
||||
|
||||
Configure the properties
|
||||
|
||||
Configure the properties
|
||||
|
||||
sudo vi /var/lib/tomcat6/webapps/lti/WEB-INF/classes/lti.properties
|
||||
sudo vi /var/lib/tomcat6/webapps/lti/WEB-INF/classes/lti.properties
|
||||
|
||||
Edit the URL and Salt of the BigBlueButton server you are going to connect to
|
||||
Edit the URL and Salt of the BigBlueButton server you are going to connect to
|
||||
|
||||
bigbluebuttonURL=http://yourbigbluebuttonserver.com/bigbluebutton
|
||||
bigbluebuttonSalt=yoursalt
|
||||
|
||||
Edit the LTI basic information
|
||||
bigbluebuttonURL=http://yourbigbluebuttonserver.com/bigbluebutton
|
||||
|
||||
ltiEndPoint=http://yourbigbluebuttonserver.com/lti/tool.xml
|
||||
ltiConsumers=demo:welcome,consumer1:secret1
|
||||
bigbluebuttonSalt=yoursalt
|
||||
|
||||
Edit the LTI basic information
|
||||
|
||||
Restart tomcat
|
||||
ltiEndPoint=http://yourbigbluebuttonserver.com/lti/tool.xml
|
||||
|
||||
sudo service tomcat6 restart
|
||||
ltiConsumers=demo:welcome,consumer1:secret1
|
||||
|
||||
Restart tomcat
|
||||
|
||||
When running on the BigBlueButton server, create the map to this new application on nginx
|
||||
sudo service tomcat6 restart
|
||||
|
||||
When running on the BigBlueButton server, create the map to this new application on nginx
|
||||
|
||||
|
||||
|
||||
@ -61,36 +81,34 @@ Add a new external tool
|
||||
|
||||
The BigBlueButton roles are assigned according to the roles in the LMS.
|
||||
|
||||
MODERATOR
|
||||
Faculty
|
||||
urn:lti:instrole:ims/lis/Faculty
|
||||
Instructor
|
||||
urn:lti:instrole:ims/lis/Instructor
|
||||
Mentor
|
||||
urn:lti:instrole:ims/lis/Mentor
|
||||
Administrator
|
||||
urn:lti:instrole:ims/lis/Administrator
|
||||
MODERATOR
|
||||
-Faculty
|
||||
-urn:lti:instrole:ims/lis/Faculty
|
||||
-Instructor
|
||||
-urn:lti:instrole:ims/lis/Instructor
|
||||
-Mentor
|
||||
-urn:lti:instrole:ims/lis/Mentor
|
||||
-Administrator
|
||||
-urn:lti:instrole:ims/lis/Administrator
|
||||
|
||||
ATTENDEE
|
||||
Student
|
||||
urn:lti:instrole:ims/lis/Student
|
||||
Member
|
||||
urn:lti:instrole:ims/lis/Member
|
||||
Learner
|
||||
urn:lti:instrole:ims/lis/Learner
|
||||
Staff
|
||||
urn:lti:instrole:ims/lis/Staff
|
||||
Alumni
|
||||
urn:lti:instrole:ims/lis/Alumni
|
||||
ProspectiveStudent
|
||||
urn:lti:instrole:ims/lis/ProspectiveStudent
|
||||
Guest
|
||||
urn:lti:instrole:ims/lis/Guest
|
||||
Other
|
||||
urn:lti:instrole:ims/lis/Other
|
||||
Observer
|
||||
urn:lti:instrole:ims/lis/Observer
|
||||
None
|
||||
urn:lti:instrole:ims/lis/None
|
||||
|
||||
|
||||
ATTENDEE
|
||||
-Student
|
||||
-urn:lti:instrole:ims/lis/Student
|
||||
-Member
|
||||
-urn:lti:instrole:ims/lis/Member
|
||||
-Learner
|
||||
-urn:lti:instrole:ims/lis/Learner
|
||||
-Staff
|
||||
-urn:lti:instrole:ims/lis/Staff
|
||||
-Alumni
|
||||
-urn:lti:instrole:ims/lis/Alumni
|
||||
-ProspectiveStudent
|
||||
-urn:lti:instrole:ims/lis/ProspectiveStudent
|
||||
-Guest
|
||||
-urn:lti:instrole:ims/lis/Guest
|
||||
-Other
|
||||
-urn:lti:instrole:ims/lis/Other
|
||||
-Observer
|
||||
-urn:lti:instrole:ims/lis/Observer
|
||||
-None
|
||||
-urn:lti:instrole:ims/lis/None
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
class BootStrap {
|
||||
|
||||
def init = { servletContext ->
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// locations to search for config files that get merged into the main config
|
||||
// config files can either be Java properties files or ConfigSlurper scripts
|
||||
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
dataSource {
|
||||
pooled = true
|
||||
driverClassName = "org.hsqldb.jdbcDriver"
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
class UrlMappings {
|
||||
static mappings = {
|
||||
"/$controller/$action?/$id?"{
|
||||
|
@ -1,4 +1,21 @@
|
||||
#
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
#
|
||||
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
# These are the default properites for the BigBlueButton LTI interface
|
||||
|
||||
# BigBlueButton integration information
|
||||
|
@ -1,4 +1,21 @@
|
||||
// Place your Spring DSL code here
|
||||
/*
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
beans = {
|
||||
|
||||
}
|
@ -1,22 +1,20 @@
|
||||
/*
|
||||
BigBlueButton - http://www.bigbluebutton.org
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2008-2012 by respective authors (see below). All rights reserved.
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
BigBlueButton is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jesus Federico <jesus@blindsidenetworks.com>
|
||||
*/
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
@ -60,38 +58,33 @@ class ToolController {
|
||||
if (consumer != null) {
|
||||
log.debug "Found consumer with key " + consumer.get("key") //+ " and sharedSecret " + consumer.get("secret")
|
||||
if (checkValidSignature(request.getMethod().toUpperCase(), retrieveLtiEndpoint(), consumer.get("secret"), sanitizedParams, params.get(Parameter.OAUTH_SIGNATURE))) {
|
||||
if (hasValidStudentId(params, consumer)) {
|
||||
log.debug "The message has a valid signature."
|
||||
|
||||
String locale = params.get(Parameter.LAUNCH_LOCALE)
|
||||
log.debug "Locale code =" + locale
|
||||
String[] localeCodes = locale.split("_")
|
||||
//Localize the default welcome message
|
||||
if( localeCodes.length > 1 )
|
||||
session['org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE'] = new Locale(localeCodes[0], localeCodes[1])
|
||||
else
|
||||
session['org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE'] = new Locale(localeCodes[0])
|
||||
|
||||
log.debug "Locale has been set to " + locale
|
||||
String welcome = message(code: "bigbluebutton.welcome", args: ["\"{0}\"", "\"{1}\""])
|
||||
log.debug "Localized default welcome message: [" + welcome + "]"
|
||||
|
||||
//String destinationURL = "http://www.bigbluebutton.org/"
|
||||
String destinationURL = bigbluebuttonService.getJoinURL(params, welcome)
|
||||
|
||||
log.debug "redirecting to " + destinationURL
|
||||
if( destinationURL != null ) {
|
||||
success = true
|
||||
redirect(url:destinationURL)
|
||||
} else {
|
||||
resultMessageKey = 'BigBlueButtonServerError'
|
||||
resultMessage = "The join could not be completed"
|
||||
log.debug resultMessage
|
||||
}
|
||||
|
||||
log.debug "The message has a valid signature."
|
||||
|
||||
String locale = params.get(Parameter.LAUNCH_LOCALE)
|
||||
locale = (locale == null || locale.equals("")?"en":locale)
|
||||
log.debug "Locale code =" + locale
|
||||
String[] localeCodes = locale.split("_")
|
||||
//Localize the default welcome message
|
||||
if( localeCodes.length > 1 )
|
||||
session['org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE'] = new Locale(localeCodes[0], localeCodes[1])
|
||||
else
|
||||
session['org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE'] = new Locale(localeCodes[0])
|
||||
|
||||
log.debug "Locale has been set to " + locale
|
||||
String welcome = message(code: "bigbluebutton.welcome", args: ["\"{0}\"", "\"{1}\""])
|
||||
log.debug "Localized default welcome message: [" + welcome + "]"
|
||||
|
||||
//String destinationURL = "http://www.bigbluebutton.org/"
|
||||
String destinationURL = bigbluebuttonService.getJoinURL(params, welcome)
|
||||
|
||||
log.debug "redirecting to " + destinationURL
|
||||
if( destinationURL != null ) {
|
||||
success = true
|
||||
redirect(url:destinationURL)
|
||||
} else {
|
||||
resultMessageKey = 'InvalidStudentId'
|
||||
resultMessage = "Can not determine user because of missing student id or email."
|
||||
resultMessageKey = 'BigBlueButtonServerError'
|
||||
resultMessage = "The join could not be completed"
|
||||
log.debug resultMessage
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -136,11 +129,6 @@ class ToolController {
|
||||
|
||||
}
|
||||
|
||||
def retrieveLtiEndpoint() {
|
||||
String endPoint = ltiService.endPoint
|
||||
return endPoint
|
||||
}
|
||||
|
||||
def test = {
|
||||
log.debug CONTROLLER_NAME + "#index"
|
||||
|
||||
@ -159,6 +147,11 @@ class ToolController {
|
||||
|
||||
}
|
||||
|
||||
private String retrieveLtiEndpoint() {
|
||||
String endPoint = ltiService.endPoint
|
||||
return endPoint
|
||||
}
|
||||
|
||||
/**
|
||||
* Assemble all parameters passed that is required to sign the request.
|
||||
* @param the HTTP request parameters
|
||||
@ -195,25 +188,6 @@ class ToolController {
|
||||
hasAllParams = false;
|
||||
}
|
||||
|
||||
if (! ((Map<String, String>)params).containsKey(Parameter.USER_ID) && ! ((Map<String, String>)params).containsKey(Parameter.CUSTOM_USER_ID)) {
|
||||
if (! ((Map<String, String>)params).containsKey(Parameter.USER_EMAIL)) {
|
||||
((ArrayList<String>)missingParams).add(Parameter.USER_EMAIL);
|
||||
if (! ((Map<String, String>)params).containsKey(Parameter.USER_ID)) {
|
||||
((ArrayList<String>)missingParams).add(Parameter.USER_ID);
|
||||
} else {
|
||||
((ArrayList<String>)missingParams).add(Parameter.CUSTOM_USER_ID);
|
||||
}
|
||||
|
||||
hasAllParams = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (! ((Map<String, String>)params).containsKey(Parameter.COURSE_ID)) {
|
||||
((ArrayList<String>)missingParams).add(Parameter.COURSE_ID);
|
||||
hasAllParams = false;
|
||||
}
|
||||
|
||||
if (! ((Map<String, String>)params).containsKey(Parameter.OAUTH_SIGNATURE)) {
|
||||
((ArrayList<String>)missingParams).add(Parameter.OAUTH_SIGNATURE);
|
||||
hasAllParams = false;
|
||||
@ -222,19 +196,6 @@ class ToolController {
|
||||
return hasAllParams
|
||||
}
|
||||
|
||||
private boolean hasValidStudentId(params, consumer) {
|
||||
if (((Map<String, String>)params).containsKey(Parameter.USER_ID) || ((Map<String, String>)params).containsKey(Parameter.CUSTOM_USER_ID)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((Map<String, String>)params).containsKey(Parameter.USER_EMAIL)) {
|
||||
((Map<String, String>)params).put(Parameter.USER_ID, ((Map<String, String>)consumer).get(Parameter.USER_EMAIL))
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the passed signature is valid.
|
||||
* @param method - POST or GET method used to make the request
|
||||
|
@ -1 +1,19 @@
|
||||
#
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
#
|
||||
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
bigbluebutton.welcome=<br>Welcome to <b>{0}</b>!<br><br>To understand how BigBlueButton works see our <a href=\"event:http://www.bigbluebutton.org/content/videos\"><u>tutorial videos</u></a>.<br><br>To join the audio bridge click the headset icon (upper-left hand corner). <b>Please use a headset to avoid causing noise for others.</b>
|
||||
|
@ -1 +1,19 @@
|
||||
#
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
#
|
||||
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
bigbluebutton.welcome=<br>Bienvenido a <b>{0}</b>!<br><br>Para entender como funciona BigBlueButton consulte estos <a href=\"event:http://www.bigbluebutton.org/content/videos\"><u>videos tutoriales</u></a>.<br><br>Para activar el audio haga click en el icono de auricular (equina superior izquierda). <b>Por favor utilice auricular para evitar causar ruido.</b>
|
||||
|
@ -1 +1,19 @@
|
||||
#
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
#
|
||||
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
bigbluebutton.welcome=<br>Bienvenue au <b>{0}</b>!<br><br>Pour comprendre comment fonctionne BigBlueButton, consultez les <a href=\"event:http://www.bigbluebutton.org/content/videos\"><u>didacticiels vidéo</u></a>.<br><br>Pour activer l'audio cliquez sur l'icône du casque à écouteurs (coin supérieur gauche). <b>S'il vous plaît utiliser le casque pour éviter de causer du bruit.</b>
|
||||
|
@ -1,23 +1,20 @@
|
||||
/*
|
||||
BigBlueButton - http://www.bigbluebutton.org
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2008-2012 by respective authors (see below). All rights reserved.
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
BigBlueButton is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jesus Federico <jesus@blindsidenetworks.com>
|
||||
*/
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@ -73,7 +70,6 @@ class BigbluebuttonService {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public String getJoinURL(params, welcome){
|
||||
//Set the injected values
|
||||
if( !url.equals(bbbProxy.url) && !url.equals("") ) bbbProxy.setUrl(url)
|
||||
@ -82,12 +78,12 @@ class BigbluebuttonService {
|
||||
String joinURL = null
|
||||
|
||||
String meetingName = getValidatedMeetingName(params.get(Parameter.RESOURCE_LINK_TITLE))
|
||||
String meetingID = getValidatedMeetingId(params.get(Parameter.RESOURCE_LINK_ID), params.get(Parameter.COURSE_ID), params.get(Parameter.CONSUMER_ID))
|
||||
String attendeePW = DigestUtils.shaHex("ap" + params.get(Parameter.RESOURCE_LINK_ID))
|
||||
String moderatorPW = DigestUtils.shaHex("mp" + params.get(Parameter.RESOURCE_LINK_ID))
|
||||
String meetingID = getValidatedMeetingId(params.get(Parameter.RESOURCE_LINK_ID), params.get(Parameter.CONSUMER_ID))
|
||||
String attendeePW = DigestUtils.shaHex("ap" + params.get(Parameter.RESOURCE_LINK_ID) + params.get(Parameter.CONSUMER_ID))
|
||||
String moderatorPW = DigestUtils.shaHex("mp" + params.get(Parameter.RESOURCE_LINK_ID) + params.get(Parameter.CONSUMER_ID))
|
||||
String logoutURL = getValidatedLogoutURL(params.get(Parameter.LAUNCH_RETURN_URL))
|
||||
boolean isModerator = Role.isModerator(params.get(Parameter.ROLES))
|
||||
String userFullName = getValidatedUserFullName(params.get(Parameter.USER_FULL_NAME), isModerator)
|
||||
boolean isModerator = params.get(Parameter.ROLES) != null? Role.isModerator(params.get(Parameter.ROLES)): true
|
||||
String userFullName = getValidatedUserFullName(params, isModerator)
|
||||
String courseTitle = getValidatedCourseTitle(params.get(Parameter.COURSE_TITLE))
|
||||
String userID = getValidatedUserId(params.get(Parameter.USER_ID))
|
||||
|
||||
@ -125,16 +121,32 @@ class BigbluebuttonService {
|
||||
return (meetingName == null || meetingName == "")? "Meeting": meetingName
|
||||
}
|
||||
|
||||
private String getValidatedMeetingId(String meetingId, String courseId, String consumerId){
|
||||
return DigestUtils.shaHex(meetingId + courseId + consumerId)
|
||||
private String getValidatedMeetingId(String meetingId, String consumerId){
|
||||
return DigestUtils.shaHex(meetingId + consumerId)
|
||||
}
|
||||
|
||||
private String getValidatedLogoutURL(String logoutURL){
|
||||
return (logoutURL == null)? "": logoutURL
|
||||
}
|
||||
|
||||
private String getValidatedUserFullName(String userFullName, boolean isModerator){
|
||||
return (userFullName == null || userFullName == "")? (isModerator? "Moderator" : "Attendee"): userFullName
|
||||
private String getValidatedUserFullName(params, boolean isModerator){
|
||||
String userFullName = params.get(Parameter.USER_FULL_NAME)
|
||||
String userFirstName = params.get(Parameter.USER_FIRSTNAME)
|
||||
String userLastName = params.get(Parameter.USER_LASTNAME)
|
||||
if( userFullName == null || userFullName == "" ){
|
||||
if( userFirstName != null && userFirstName != "" ){
|
||||
userFullName = userFirstName
|
||||
}
|
||||
if( userLastName != null && userLastName != "" ){
|
||||
userFullName = userFullName.length() > 0? " ": ""
|
||||
userFullName += userLastName
|
||||
}
|
||||
if( userFullName == null || userFullName == "" ){
|
||||
userFullName = isModerator? "Moderator" : "Attendee"
|
||||
}
|
||||
}
|
||||
|
||||
return userFullName
|
||||
}
|
||||
|
||||
private String getValidatedCourseTitle(String courseTitle){
|
||||
@ -231,7 +243,6 @@ class BigbluebuttonService {
|
||||
log.debug("doAPICall.Exception: Message=" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Get all nodes under the specified element tag name as a Java map */
|
||||
private Map<String, Object> getNodesAsMap(Document dom, String elementTagName) {
|
||||
@ -240,37 +251,38 @@ class BigbluebuttonService {
|
||||
}
|
||||
|
||||
private Map<String, Object> processNode(Node _node) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
NodeList responseNodes = _node.getChildNodes();
|
||||
for (int i = 0; i < responseNodes.getLength(); i++) {
|
||||
Node node = responseNodes.item(i);
|
||||
String nodeName = node.getNodeName().trim();
|
||||
if (node.getChildNodes().getLength() == 1
|
||||
&& ( node.getChildNodes().item(0).getNodeType() == org.w3c.dom.Node.TEXT_NODE || node.getChildNodes().item(0).getNodeType() == org.w3c.dom.Node.CDATA_SECTION_NODE) ) {
|
||||
if (node.getChildNodes().getLength() == 1 && node.getChildNodes().item(0).getNodeType() == org.w3c.dom.Node.TEXT_NODE) {
|
||||
String nodeValue = node.getTextContent();
|
||||
map.put(nodeName, nodeValue != null ? nodeValue.trim() : null);
|
||||
|
||||
} else if (node.getChildNodes().getLength() == 0
|
||||
&& node.getNodeType() != org.w3c.dom.Node.TEXT_NODE
|
||||
&& node.getNodeType() != org.w3c.dom.Node.CDATA_SECTION_NODE) {
|
||||
} else if (node.getChildNodes().getLength() == 0 && node.getNodeType() != org.w3c.dom.Node.TEXT_NODE) {
|
||||
map.put(nodeName, "");
|
||||
|
||||
} else if ( node.getChildNodes().getLength() >= 1
|
||||
&& node.getChildNodes().item(0).getChildNodes().item(0).getNodeType() != org.w3c.dom.Node.TEXT_NODE
|
||||
&& node.getChildNodes().item(0).getChildNodes().item(0).getNodeType() != org.w3c.dom.Node.CDATA_SECTION_NODE ) {
|
||||
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (int c = 0; c < node.getChildNodes().getLength(); c++) {
|
||||
Node n = node.getChildNodes().item(c);
|
||||
list.add(processNode(n));
|
||||
}
|
||||
map.put(nodeName, list);
|
||||
|
||||
} else {
|
||||
map.put(nodeName, processNode(node));
|
||||
if( !map.containsKey(nodeName) ) {
|
||||
map.put(nodeName, processNode(node));
|
||||
|
||||
} else {
|
||||
Object curObject = map.get(nodeName);
|
||||
List<Object> list;
|
||||
|
||||
if( curObject.getClass().equals(LinkedHashMap.class) ){
|
||||
list = new LinkedList<Object>();
|
||||
list.add(curObject);
|
||||
list.add(processNode(node));
|
||||
map.remove(nodeName);
|
||||
map.put(nodeName, list);
|
||||
} else {
|
||||
list = (List<Object>)curObject;
|
||||
list.add(processNode(node));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,22 +1,21 @@
|
||||
/*
|
||||
BigBlueButton - http://www.bigbluebutton.org
|
||||
/*
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2008-2012 by respective authors (see below). All rights reserved.
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
BigBlueButton is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jesus Federico <jesus@blindsidenetworks.com>
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.bigbluebutton.lti;
|
||||
|
||||
public class Parameter {
|
||||
|
@ -1,22 +1,21 @@
|
||||
/*
|
||||
BigBlueButton - http://www.bigbluebutton.org
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2008-2012 by respective authors (see below). All rights reserved.
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
BigBlueButton is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
Author: Jesus Federico <jesus@blindsidenetworks.com>
|
||||
*/
|
||||
package org.bigbluebutton.lti;
|
||||
|
||||
public class Role {
|
||||
|
267
bbb-lti/src/java/org/imsglobal/basiclti/Base64.java
Normal file
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/Attic/Base64.java,v 1.6.2.1 2004/02/22 18:21:16 olegk Exp $
|
||||
* $Revision: 98512 $
|
||||
* $Date: 2011-09-22 13:59:08 -0400 (Thu, 22 Sep 2011) $
|
||||
*
|
||||
* Copyright 1999-2004 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.imsglobal.basiclti;
|
||||
// package org.apache.commons.httpclient.util;
|
||||
|
||||
// import org.apache.commons.httpclient.HttpConstants;
|
||||
|
||||
/**
|
||||
* Base64 encoder and decoder.
|
||||
*
|
||||
|
||||
* This class provides encoding/decoding methods for the Base64 encoding as
|
||||
* defined by RFC 2045, N. Freed and N. Borenstein. RFC 2045: Multipurpose
|
||||
* Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies.
|
||||
* Reference 1996. Available at:
|
||||
* http://www.ietf.org/rfc/rfc2045.txt
|
||||
*
|
||||
|
||||
|
||||
*
|
||||
* @author Jeffrey Rodriguez
|
||||
* @author Mike Bowler
|
||||
* @version $Revision: 98512 $ $Date: 2011-09-22 13:59:08 -0400 (Thu, 22 Sep 2011) $
|
||||
*
|
||||
*/
|
||||
public final class Base64 {
|
||||
|
||||
/** */
|
||||
private static final int BASELENGTH = 255;
|
||||
|
||||
/** */
|
||||
private static final int LOOKUPLENGTH = 64;
|
||||
|
||||
/** */
|
||||
private static final int TWENTYFOURBITGROUP = 24;
|
||||
|
||||
/** */
|
||||
private static final int EIGHTBIT = 8;
|
||||
|
||||
/** */
|
||||
private static final int SIXTEENBIT = 16;
|
||||
|
||||
/** */
|
||||
private static final int SIXBIT = 6;
|
||||
|
||||
/** */
|
||||
private static final int FOURBYTE = 4;
|
||||
|
||||
/** The sign bit as an int */
|
||||
private static final int SIGN = -128;
|
||||
|
||||
/** The padding character */
|
||||
private static final byte PAD = (byte) '=';
|
||||
|
||||
/** The alphabet */
|
||||
private static final byte [] BASE64_ALPHABET = new byte[BASELENGTH];
|
||||
|
||||
/** The lookup alphabet */
|
||||
private static final byte [] LOOKUP_BASE64_ALPHABET = new byte[LOOKUPLENGTH];
|
||||
|
||||
static {
|
||||
|
||||
for (int i = 0; i < BASELENGTH; i++) {
|
||||
BASE64_ALPHABET[i] = -1;
|
||||
}
|
||||
for (int i = 'Z'; i >= 'A'; i--) {
|
||||
BASE64_ALPHABET[i] = (byte) (i - 'A');
|
||||
}
|
||||
for (int i = 'z'; i >= 'a'; i--) {
|
||||
BASE64_ALPHABET[i] = (byte) (i - 'a' + 26);
|
||||
}
|
||||
|
||||
for (int i = '9'; i >= '0'; i--) {
|
||||
BASE64_ALPHABET[i] = (byte) (i - '0' + 52);
|
||||
}
|
||||
|
||||
BASE64_ALPHABET['+'] = 62;
|
||||
BASE64_ALPHABET['/'] = 63;
|
||||
|
||||
for (int i = 0; i <= 25; i++) {
|
||||
LOOKUP_BASE64_ALPHABET[i] = (byte) ('A' + i);
|
||||
}
|
||||
|
||||
for (int i = 26, j = 0; i <= 51; i++, j++) {
|
||||
LOOKUP_BASE64_ALPHABET[i] = (byte) ('a' + j);
|
||||
}
|
||||
|
||||
for (int i = 52, j = 0; i <= 61; i++, j++) {
|
||||
LOOKUP_BASE64_ALPHABET[i] = (byte) ('0' + j);
|
||||
}
|
||||
LOOKUP_BASE64_ALPHABET[62] = (byte) '+';
|
||||
LOOKUP_BASE64_ALPHABET[63] = (byte) '/';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance.
|
||||
*/
|
||||
private Base64() {
|
||||
// the constructor is intentionally private
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes hex octects into Base64
|
||||
*
|
||||
* @param binaryData Array containing binaryData
|
||||
* @return Base64-encoded array
|
||||
*/
|
||||
public static byte[] encode(byte[] binaryData) {
|
||||
|
||||
int lengthDataBits = binaryData.length * EIGHTBIT;
|
||||
int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
|
||||
int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
|
||||
byte encodedData[] = null;
|
||||
|
||||
|
||||
if (fewerThan24bits != 0) { //data not divisible by 24 bit
|
||||
encodedData = new byte[(numberTriplets + 1) * 4];
|
||||
} else { // 16 or 8 bit
|
||||
encodedData = new byte[numberTriplets * 4];
|
||||
}
|
||||
|
||||
byte k = 0;
|
||||
byte l = 0;
|
||||
byte b1 = 0;
|
||||
byte b2 = 0;
|
||||
byte b3 = 0;
|
||||
int encodedIndex = 0;
|
||||
int dataIndex = 0;
|
||||
int i = 0;
|
||||
for (i = 0; i < numberTriplets; i++) {
|
||||
|
||||
dataIndex = i * 3;
|
||||
b1 = binaryData[dataIndex];
|
||||
b2 = binaryData[dataIndex + 1];
|
||||
b3 = binaryData[dataIndex + 2];
|
||||
|
||||
l = (byte) (b2 & 0x0f);
|
||||
k = (byte) (b1 & 0x03);
|
||||
|
||||
encodedIndex = i * 4;
|
||||
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
|
||||
: (byte) ((b1) >> 2 ^ 0xc0);
|
||||
|
||||
byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
|
||||
: (byte) ((b2) >> 4 ^ 0xf0);
|
||||
byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6)
|
||||
: (byte) ((b3) >> 6 ^ 0xfc);
|
||||
|
||||
encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1];
|
||||
encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[val2
|
||||
| (k << 4)];
|
||||
encodedData[encodedIndex + 2] = LOOKUP_BASE64_ALPHABET[(l << 2)
|
||||
| val3];
|
||||
encodedData[encodedIndex + 3] = LOOKUP_BASE64_ALPHABET[b3 & 0x3f];
|
||||
}
|
||||
|
||||
// form integral number of 6-bit groups
|
||||
dataIndex = i * 3;
|
||||
encodedIndex = i * 4;
|
||||
if (fewerThan24bits == EIGHTBIT) {
|
||||
b1 = binaryData[dataIndex];
|
||||
k = (byte) (b1 & 0x03);
|
||||
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
|
||||
: (byte) ((b1) >> 2 ^ 0xc0);
|
||||
encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1];
|
||||
encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[k << 4];
|
||||
encodedData[encodedIndex + 2] = PAD;
|
||||
encodedData[encodedIndex + 3] = PAD;
|
||||
} else if (fewerThan24bits == SIXTEENBIT) {
|
||||
b1 = binaryData[dataIndex];
|
||||
b2 = binaryData[dataIndex + 1];
|
||||
l = (byte) (b2 & 0x0f);
|
||||
k = (byte) (b1 & 0x03);
|
||||
|
||||
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
|
||||
: (byte) ((b1) >> 2 ^ 0xc0);
|
||||
byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
|
||||
: (byte) ((b2) >> 4 ^ 0xf0);
|
||||
|
||||
encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1];
|
||||
encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[val2
|
||||
| (k << 4)];
|
||||
encodedData[encodedIndex + 2] = LOOKUP_BASE64_ALPHABET[l << 2];
|
||||
encodedData[encodedIndex + 3] = PAD;
|
||||
}
|
||||
return encodedData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decodes Base64 data into octects
|
||||
*
|
||||
* @param base64Data byte array containing Base64 data
|
||||
* @return Array containing decoded data.
|
||||
*/
|
||||
public static byte[] decode(byte[] base64Data) {
|
||||
// Should we throw away anything not in base64Data ?
|
||||
|
||||
// handle the edge case, so we don't have to worry about it later
|
||||
if (base64Data.length == 0) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
int numberQuadruple = base64Data.length / FOURBYTE;
|
||||
byte decodedData[] = null;
|
||||
byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;
|
||||
|
||||
int encodedIndex = 0;
|
||||
int dataIndex = 0;
|
||||
{
|
||||
// this block sizes the output array properly - rlw
|
||||
int lastData = base64Data.length;
|
||||
// ignore the '=' padding
|
||||
while (base64Data[lastData - 1] == PAD) {
|
||||
if (--lastData == 0) { return new byte[0]; }
|
||||
}
|
||||
decodedData = new byte[lastData - numberQuadruple];
|
||||
}
|
||||
|
||||
for (int i = 0; i < numberQuadruple; i++) {
|
||||
dataIndex = i * 4;
|
||||
marker0 = base64Data[dataIndex + 2];
|
||||
marker1 = base64Data[dataIndex + 3];
|
||||
|
||||
b1 = BASE64_ALPHABET[base64Data[dataIndex]];
|
||||
b2 = BASE64_ALPHABET[base64Data[dataIndex + 1]];
|
||||
|
||||
if (marker0 != PAD && marker1 != PAD) { //No PAD e.g 3cQl
|
||||
b3 = BASE64_ALPHABET[marker0];
|
||||
b4 = BASE64_ALPHABET[marker1];
|
||||
|
||||
decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
|
||||
decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4)
|
||||
| ((b3 >> 2) & 0xf));
|
||||
decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
|
||||
} else if (marker0 == PAD) { //Two PAD e.g. 3c[Pad][Pad]
|
||||
decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4) ;
|
||||
} else if (marker1 == PAD) { //One PAD e.g. 3cQ[Pad]
|
||||
b3 = BASE64_ALPHABET[marker0];
|
||||
decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
|
||||
decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4)
|
||||
| ((b3 >> 2) & 0xf));
|
||||
}
|
||||
encodedIndex += 3;
|
||||
}
|
||||
return decodedData;
|
||||
}
|
||||
}
|
414
bbb-lti/src/java/org/imsglobal/basiclti/BasicLTIConstants.java
Normal file
@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (c) 2008 IMS GLobal Learning Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
package org.imsglobal.basiclti;
|
||||
|
||||
public class BasicLTIConstants {
|
||||
/**
|
||||
* context_id=8213060-006f-27b2066ac545
|
||||
* <p>
|
||||
* This is an opaque identifier that uniquely identifies the context that
|
||||
* contains the link being launched.
|
||||
*/
|
||||
public static final String CONTEXT_ID = "context_id";
|
||||
/**
|
||||
* context_label=SI182
|
||||
* <p>
|
||||
* A label for the context - intended to fit in a column.
|
||||
*/
|
||||
public static final String CONTEXT_LABEL = "context_label";
|
||||
/**
|
||||
* context_title=Design of Personal Environments
|
||||
* <p>
|
||||
* A title of the context - it should be about the length of a line.
|
||||
*/
|
||||
public static final String CONTEXT_TITLE = "context_title";
|
||||
|
||||
/**
|
||||
* context_type=CourseSection
|
||||
* <p>
|
||||
* This string is a comma-separated list of URN values that identify the type
|
||||
* of context. At a minimum, the list MUST include a URN value drawn from the
|
||||
* LIS vocabulary (see Appendix A). The assumed namespace of these URNs is the
|
||||
* LIS vocabulary so TCs can use the handles when the intent is to refer to an
|
||||
* LIS context type. If the TC wants to include a context type from another
|
||||
* namespace, a fully-qualified URN should be used.
|
||||
*/
|
||||
public static final String CONTEXT_TYPE = "context_type";
|
||||
public static final String CONTEXT_TYPE_COURSE_OFFERING = "CourseOffering";
|
||||
public static final String CONTEXT_TYPE_COURSE_SECTION = "CourseSection";
|
||||
public static final String CONTEXT_TYPE_COURSE_TEMPLATE = "CourseTemplate";
|
||||
public static final String CONTEXT_TYPE_GROUP = "GROUP";
|
||||
|
||||
/**
|
||||
* ext_param=value
|
||||
* <p>
|
||||
* Systems can add their own values to the launch but should prefix
|
||||
* any extensions with "ext_".
|
||||
*/
|
||||
public static final String EXTENSION_PREFIX = "ext_";
|
||||
/**
|
||||
* custom_keyname=value
|
||||
* <p>
|
||||
* The creator of a Basic LTI link can add custom key/value parameters to a
|
||||
* launch which are to be included with the launch of the Basic LTI link. The
|
||||
* Common Cartridge section below describes how these parameters are
|
||||
* represented when storing custom parameters in a Common Cartridge.
|
||||
* <p>
|
||||
* When there are custom name / value parameters in the launch, a POST
|
||||
* parameter is included for each custom parameter. The parameter names are
|
||||
* mapped to lower case and any character that is neither a number nor letter
|
||||
* in a parameter name is replaced with an "underscore". So if a custom entry
|
||||
* was as follows:
|
||||
* <p>
|
||||
* Review:Chapter=1.2.56
|
||||
* <p>
|
||||
* Would map to: custom_review_chapter=1.2.56
|
||||
* <p>
|
||||
* Creators of Basic LTI links would be well served to limit their parameter
|
||||
* names to lower case and to use no punctuation other than underscores. If
|
||||
* these custom parameters are included in the Basic LTI link, the TC must
|
||||
* include them in the launch data or the TP may fail to function.
|
||||
*/
|
||||
public static final String CUSTOM_PREFIX = "custom_";
|
||||
/**
|
||||
* Parameters with the OAuth prefix are also acceptible.
|
||||
*/
|
||||
public static final String OAUTH_PREFIX = "oauth_";
|
||||
/**
|
||||
* launch_presentation_document_target=iframe
|
||||
* <p>
|
||||
* The value should be either 'frame', 'iframe' or 'window'. This field
|
||||
* communicates the kind of browser window/frame where the TC has launched the
|
||||
* tool.
|
||||
*/
|
||||
public static final String LAUNCH_PRESENTATION_DOCUMENT_TARGET = "launch_presentation_document_target";
|
||||
/**
|
||||
* launch_presentation_height=240
|
||||
* <p>
|
||||
* The height of the window or frame where the content from the tool will be
|
||||
* displayed.
|
||||
*/
|
||||
public static final String LAUNCH_PRESENTATION_HEIGHT = "launch_presentation_height";
|
||||
/**
|
||||
* launch_presentation_locale=en_US_variant
|
||||
* <p>
|
||||
* Language, country and variant separated by underscores. Language is the
|
||||
* lower-case, two-letter code as defined by ISO-639 (list of codes available
|
||||
* at http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt). Country is the
|
||||
* upper-case, two-letter code as defined by ISO-3166 (list of codes available
|
||||
* at http://www.chemie.fu- berlin.de/diverse/doc/ISO_3166.html). Country and
|
||||
* variant codes are optional.
|
||||
*/
|
||||
public static final String LAUNCH_PRESENTATION_LOCALE = "launch_presentation_locale";
|
||||
/**
|
||||
* launch_presentation_return_url=http://lmsng.school.edu/portal/123/page/988/
|
||||
* <p>
|
||||
* Fully qualified URL where the TP can redirect the user back to the TC interface. This
|
||||
* URL can be used once the TP is finished or if the TP cannot start or has some
|
||||
* technical difficulty. In the case of an error, the TP may add a parameter called
|
||||
* lti_errormsg that includes some detail as to the nature of the error. The
|
||||
* lti_errormsg value should make sense if displayed to the user. If the tool has
|
||||
* displayed a message to the end user and only wants to give the TC a message to log,
|
||||
* use the parameter lti_errorlog instead of lti_errormsg. If the tool is terminating
|
||||
* normally, and wants a message displayed to the user it can include a text message as
|
||||
* the lti_msg parameter to the return URL. If the tool is terminating normally and
|
||||
* wants to give the TC a message to log, use the parameter lti_log. This data should be
|
||||
* sent on the URL as a GET - so the TP should take care to keep the overall length of
|
||||
* the parameters small enough to fit within the limitations of a GET request.
|
||||
*/
|
||||
public static final String LAUNCH_PRESENTATION_RETURN_URL = "launch_presentation_return_url";
|
||||
/**
|
||||
* launch_presentation_width=320
|
||||
* <p>
|
||||
* The width of the window or frame where the content from the tool will be
|
||||
* displayed.
|
||||
*/
|
||||
public static final String LAUNCH_PRESENTATION_WIDTH = "launch_presentation_width";
|
||||
/**
|
||||
* launch_presentation_css_url=http://www.toolconsumer.url/path/to/lti.css
|
||||
* <p>
|
||||
* This points to a fully qualified URL for a CSS which can be used to style the tool.
|
||||
* There are no officially defined CSS classes for this file, but the Consumer can
|
||||
* apply styles to paragraphs, body, and the various HTML elements. It is up to the
|
||||
* tool as to whether this CSS is used or not, and in what order this is included relative
|
||||
* to the tool-specific CSS.
|
||||
*/
|
||||
public static final String LAUNCH_PRESENTATION_CSS_URL = "launch_presentation_css_url";
|
||||
/**
|
||||
* lis_person_contact_email_primary=user@school.edu
|
||||
* <p>
|
||||
* These fields contain information about the user account that is performing
|
||||
* this launch. The names of these data items are taken from LIS. The precise
|
||||
* meaning of the content in these fields is defined by LIS.
|
||||
*/
|
||||
public static final String LIS_PERSON_CONTACT_EMAIL_PRIMARY = "lis_person_contact_email_primary";
|
||||
/**
|
||||
* lis_person_name_family=Public
|
||||
* <p>
|
||||
* These fields contain information about the user account that is performing
|
||||
* this launch. The names of these data items are taken from LIS. The precise
|
||||
* meaning of the content in these fields is defined by LIS.
|
||||
*/
|
||||
public static final String LIS_PERSON_NAME_FAMILY = "lis_person_name_family";
|
||||
/**
|
||||
* lis_person_name_full=Jane Q. Public
|
||||
* <p>
|
||||
* These fields contain information about the user account that is performing
|
||||
* this launch. The names of these data items are taken from LIS. The precise
|
||||
* meaning of the content in these fields is defined by LIS.
|
||||
*/
|
||||
public static final String LIS_PERSON_NAME_FULL = "lis_person_name_full";
|
||||
/**
|
||||
* lis_person_name_given=Jane
|
||||
* <p>
|
||||
* These fields contain information about the user account that is performing
|
||||
* this launch. The names of these data items are taken from LIS. The precise
|
||||
* meaning of the content in these fields is defined by LIS.
|
||||
*/
|
||||
public static final String LIS_PERSON_NAME_GIVEN = "lis_person_name_given";
|
||||
|
||||
/**
|
||||
* lis_person_sourcedid=school.edu:user
|
||||
* <p>
|
||||
* This field contains the LIS identifier for the user account that is
|
||||
* performing this launch. The example syntax of "school:user"
|
||||
* is not the required format – lis_person_sourcedid is simply a
|
||||
* globally unique identifier (i.e., a normalized string). This field
|
||||
* is optional and its content and meaning are defined by LIS.
|
||||
*/
|
||||
public static final String LIS_PERSON_SOURCEDID = "lis_person_sourcedid";
|
||||
|
||||
/**
|
||||
* lis_course_offering_sourcedid=school.edu:SI182-F08 <br/>
|
||||
* lis_course_section_sourcedid=school.edu:SI182-001-F08
|
||||
* <p>
|
||||
* These fields contain LIS course identifiers associated with the
|
||||
* context of this launch. These fields are optional and their
|
||||
* content and meaning are defined by LIS.
|
||||
*/
|
||||
public static final String LIS_COURSE_OFFERING_SOURCEDID = "lis_course_offering_sourcedid";
|
||||
public static final String LIS_COURSE_SECTION_SOURCEDID = "lis_course_section_sourcedid";
|
||||
|
||||
/**
|
||||
* lis_outcome_service_url=http://lmsng.school.edu/service/ltiout/
|
||||
* <p>
|
||||
* This field should be no more than 1023 characters long and the TP
|
||||
* should assume that the URL might change from launch to launch and
|
||||
* allow for the fact that a TC might change their service URL from
|
||||
* launch to launch and only use the most recent value for this
|
||||
* parameter. The service URL may support various operations / services.
|
||||
* The TC will respond with a response of 'unimplemented' for services
|
||||
* it does not support.
|
||||
*/
|
||||
public static final String LIS_OUTCOME_SERVICE_URL = "lis_outcome_service_url";
|
||||
|
||||
/**
|
||||
* lis_result_sourcedid=83873872987329873264783687634
|
||||
* <p>
|
||||
* This field contains an identifier that indicates the LIS Result
|
||||
* Identifier (if any) associated with this launch. This field is
|
||||
* optional and its content and meaning is defined by LIS.
|
||||
*/
|
||||
public static final String LIS_RESULT_SOURCEDID = "lis_result_sourcedid";
|
||||
|
||||
/**
|
||||
* lti_message_type=basic-lti-launch-request
|
||||
* <p>
|
||||
* This indicates that this is a Basic LTI Launch Message. This allows a TP to
|
||||
* accept a number of different LTI message types at the same launch URL. This
|
||||
* parameter is required.
|
||||
*/
|
||||
public static final String LTI_MESSAGE_TYPE = "lti_message_type";
|
||||
/**
|
||||
* lti_version=LTI-1p0
|
||||
* <p>
|
||||
* This indicates which version of the specification is being used for this
|
||||
* particular message. This parameter is required.
|
||||
*/
|
||||
public static final String LTI_VERSION = "lti_version";
|
||||
// launch settings per spec - computed not stored
|
||||
|
||||
/**
|
||||
* tool_consumer_info_product_family_code=desire2learn
|
||||
* <p>
|
||||
* In order to better assist tools in using extensions and also making their user
|
||||
* interface fit into the TC's user interface that they are being called from,
|
||||
* each TC is encouraged to include the this parameter. Possible example values
|
||||
* for this field might be:
|
||||
*
|
||||
* learn
|
||||
* desire2learn
|
||||
* sakai
|
||||
* eracer
|
||||
* olat
|
||||
* webct
|
||||
* This parameter is optional but recommended.
|
||||
*/
|
||||
public static final String TOOL_CONSUMER_INFO_PRODUCT_FAMILY_CODE = "tool_consumer_info_product_family_code";
|
||||
|
||||
/**
|
||||
* tool_consumer_info_version=9.2.4
|
||||
* <p>
|
||||
* This field should have a major release number followed by a period. The format of the minor release is flexible. Possible vaues for this field might be:
|
||||
*
|
||||
* 9.1.7081
|
||||
* 2.8-01
|
||||
* 7.1
|
||||
* 8
|
||||
* The Tool Provider should be flexible when parsing this field. This parameter is optional but recommended.
|
||||
|
||||
*/
|
||||
public static final String TOOL_CONSUMER_INFO_VERSION = "tool_consumer_info_version";
|
||||
|
||||
/**
|
||||
* resource_link_id=88391-e1919-bb3456
|
||||
* <p>
|
||||
* This is an opaque unique identifier that the TC guarantees will be unique
|
||||
* within the TC for every placement of the link. If the tool / activity is
|
||||
* placed multiple times in the same context, each of those placements will be
|
||||
* distinct. This value will also change if the item is exported from one
|
||||
* system or context and imported into another system or context. This
|
||||
* parameter is required.
|
||||
*/
|
||||
public static final String RESOURCE_LINK_ID = "resource_link_id";
|
||||
|
||||
/**
|
||||
* resource_link_title=My Weekly Wiki
|
||||
* <p>
|
||||
* A title for the resource. This is the clickable text that appears
|
||||
* in the link. This parameter is recommended.
|
||||
*/
|
||||
public static final String RESOURCE_LINK_TITLE = "resource_link_title";
|
||||
|
||||
/**
|
||||
* resource_link_description=…
|
||||
* <p>
|
||||
* A plain text description of the link’s destination, suitable for
|
||||
* display alongside the link. Typically no more than several lines
|
||||
* long. This parameter is optional.
|
||||
*/
|
||||
public static final String RESOURCE_LINK_DESCRIPTION = "resource_link_description";
|
||||
|
||||
/**
|
||||
* roles=Instructor,Student
|
||||
* <p>
|
||||
* A comma-separated list of URN values for roles. If this list is non-empty,
|
||||
* it should contain at least one role from the LIS System Role, LIS
|
||||
* Institution Role, or LIS Context Role vocabularies (See Appendix A). The
|
||||
* assumed namespace of these URNs is the LIS vocabulary of LIS Context Roles
|
||||
* so TCs can use the handles when the intent is to refer to an LIS context
|
||||
* role. If the TC wants to include a role from another namespace, a
|
||||
* fully-qualified URN should be used. Usage of roles from non-LIS
|
||||
* vocabularies is discouraged as it may limit interoperability. This
|
||||
* parameter is recommended.
|
||||
*/
|
||||
public static final String ROLES = "roles";
|
||||
/**
|
||||
* tool_consumer_instance_contact_email=System.Admin@school.edu
|
||||
* <p>
|
||||
* An email contact for the TC instance.
|
||||
*/
|
||||
public static final String TOOL_CONSUMER_INSTANCE_CONTACT_EMAIL = "tool_consumer_instance_contact_email";
|
||||
/**
|
||||
* tool_consumer_instance_description=University of School (LMSng)
|
||||
* <p>
|
||||
* This is a user visible field - it should be about the length of a line.
|
||||
*/
|
||||
public static final String TOOL_CONSUMER_INSTANCE_DESCRIPTION = "tool_consumer_instance_description";
|
||||
// global settings
|
||||
/**
|
||||
* tool_consumer_instance_guid=lmsng.school.edu
|
||||
* <p>
|
||||
* This is a key to be used when setting a TC-wide password. The TP uses this
|
||||
* as a key to look up the TC-wide secret when validating a message. A common
|
||||
* practice is to use the DNS of the organization or the DNS of the TC
|
||||
* instance. If the organization has multiple TC instances, then the best
|
||||
* practice is to prefix the domain name with a locally unique identifier for
|
||||
* the TC instance. This parameter is recommended.
|
||||
*/
|
||||
public static final String TOOL_CONSUMER_INSTANCE_GUID = "tool_consumer_instance_guid";
|
||||
/**
|
||||
* tool_consumer_instance_name=SchoolU
|
||||
* <p>
|
||||
* This is a user visible field - it should be about the length of a column.
|
||||
*/
|
||||
public static final String TOOL_CONSUMER_INSTANCE_NAME = "tool_consumer_instance_name";
|
||||
/**
|
||||
* Missing from implementation guide. Needs documentation. Not required, but
|
||||
* "tasty".
|
||||
*/
|
||||
public static final String TOOL_CONSUMER_INSTANCE_URL = "tool_consumer_instance_url";
|
||||
|
||||
/**
|
||||
* user_id=0ae836b9-7fc9-4060-006f-27b2066ac545
|
||||
* <p>
|
||||
* Uniquely identifies the user. This should not contain any identifying
|
||||
* information for the user. Best practice is that this field should be a
|
||||
* TC-generated long-term "primary key" to the user record - not the logical
|
||||
* key. This parameter is recommended.
|
||||
*/
|
||||
public static final String USER_ID = "user_id";
|
||||
|
||||
/**
|
||||
* user_image=http://my.sakai.org/direct/profile/0ae836b9-7fc9-4060-006f-27b2066ac545/image
|
||||
* <p>
|
||||
* This attribute specifies the URI for an image of the user who launched this request.
|
||||
* This image is suitable for use as a "profile picture" or an avatar representing the user.
|
||||
* It is expected to be a relatively small graphic image file using a widely supported image
|
||||
* format (i.e. PNG, JPG, or GIF) with a square aspect ratio. This parameter is optional.
|
||||
*/
|
||||
public static final String USER_IMAGE = "user_image";
|
||||
|
||||
/**
|
||||
* ext_sakai_provider_eid=jsmith26
|
||||
* <p>
|
||||
* If set, this will signal that the external application has provided an eid which
|
||||
* should be used preferentially. Many external applications will not have access to a user's uuid
|
||||
* in Sakai, so this allows integrations with those systems.
|
||||
* This parameter is optional and is unique to the Sakai Basic LTI provider.
|
||||
*/
|
||||
public static final String EXT_SAKAI_PROVIDER_EID = "ext_sakai_provider_eid";
|
||||
|
||||
/**
|
||||
* Utility array useful for validating property names when building launch
|
||||
* data.
|
||||
*/
|
||||
public static final String[] validPropertyNames = { CONTEXT_ID,
|
||||
CONTEXT_LABEL, CONTEXT_TITLE, CONTEXT_TYPE,
|
||||
LAUNCH_PRESENTATION_DOCUMENT_TARGET, LAUNCH_PRESENTATION_HEIGHT,
|
||||
LAUNCH_PRESENTATION_LOCALE, LAUNCH_PRESENTATION_RETURN_URL,
|
||||
LAUNCH_PRESENTATION_WIDTH, LIS_PERSON_CONTACT_EMAIL_PRIMARY,
|
||||
LAUNCH_PRESENTATION_CSS_URL,
|
||||
TOOL_CONSUMER_INFO_PRODUCT_FAMILY_CODE,
|
||||
TOOL_CONSUMER_INFO_VERSION,
|
||||
LIS_PERSON_NAME_FAMILY, LIS_PERSON_NAME_FULL, LIS_PERSON_NAME_GIVEN,
|
||||
LIS_PERSON_SOURCEDID, LIS_COURSE_OFFERING_SOURCEDID,
|
||||
LIS_COURSE_SECTION_SOURCEDID,
|
||||
LIS_OUTCOME_SERVICE_URL, LIS_RESULT_SOURCEDID,
|
||||
LTI_MESSAGE_TYPE, LTI_VERSION, RESOURCE_LINK_ID,
|
||||
RESOURCE_LINK_TITLE, RESOURCE_LINK_DESCRIPTION, ROLES,
|
||||
TOOL_CONSUMER_INSTANCE_CONTACT_EMAIL, TOOL_CONSUMER_INSTANCE_DESCRIPTION,
|
||||
TOOL_CONSUMER_INSTANCE_GUID, TOOL_CONSUMER_INSTANCE_NAME,
|
||||
TOOL_CONSUMER_INSTANCE_URL, USER_ID, USER_IMAGE };
|
||||
|
||||
/**
|
||||
* The default site type to use if a site needs to be created. Can be overriden in sakai.properties or as part of the launch.
|
||||
* This contains a number of preconfigured roles, so that the IMS role vocabulary can be used.
|
||||
* See BLTI-151
|
||||
*/
|
||||
public static final String NEW_SITE_TYPE = "lti";
|
||||
|
||||
}
|
849
bbb-lti/src/java/org/imsglobal/basiclti/BasicLTIUtil.java
Normal file
@ -0,0 +1,849 @@
|
||||
/*
|
||||
* $URL: https://source.sakaiproject.org/svn/basiclti/trunk/basiclti-util/src/java/org/imsglobal/basiclti/BasicLTIUtil.java $
|
||||
* $Id: BasicLTIUtil.java 98512 2011-09-22 17:59:08Z csev@umich.edu $
|
||||
*
|
||||
* Copyright (c) 2008 IMS GLobal Learning Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.imsglobal.basiclti;
|
||||
|
||||
import static org.imsglobal.basiclti.BasicLTIConstants.CUSTOM_PREFIX;
|
||||
import static org.imsglobal.basiclti.BasicLTIConstants.LTI_MESSAGE_TYPE;
|
||||
import static org.imsglobal.basiclti.BasicLTIConstants.LTI_VERSION;
|
||||
import static org.imsglobal.basiclti.BasicLTIConstants.TOOL_CONSUMER_INSTANCE_CONTACT_EMAIL;
|
||||
import static org.imsglobal.basiclti.BasicLTIConstants.TOOL_CONSUMER_INSTANCE_DESCRIPTION;
|
||||
import static org.imsglobal.basiclti.BasicLTIConstants.TOOL_CONSUMER_INSTANCE_GUID;
|
||||
import static org.imsglobal.basiclti.BasicLTIConstants.TOOL_CONSUMER_INSTANCE_NAME;
|
||||
import static org.imsglobal.basiclti.BasicLTIConstants.TOOL_CONSUMER_INSTANCE_URL;
|
||||
|
||||
import net.oauth.OAuthAccessor;
|
||||
import net.oauth.OAuthConsumer;
|
||||
import net.oauth.OAuthMessage;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/* Leave out until we have JTidy 0.8 in the repository
|
||||
import org.w3c.tidy.Tidy;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Some Utility code for IMS Basic LTI
|
||||
* http://www.anyexample.com/programming/java
|
||||
* /java_simple_class_to_compute_sha_1_hash.xml
|
||||
* <p>
|
||||
* Sample Descriptor
|
||||
*
|
||||
* <pre>
|
||||
* <?xml version="1.0" encoding="UTF-8"?>
|
||||
* <basic_lti_link xmlns="http://www.imsglobal.org/xsd/imsbasiclti_v1p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
* <title>generated by tp+user</title>
|
||||
* <description>generated by tp+user</description>
|
||||
* <custom>
|
||||
* <parameter key="keyname">value</parameter>
|
||||
* </custom>
|
||||
* <extensions platform="www.lms.com">
|
||||
* <parameter key="keyname">value</parameter>
|
||||
* </extensions>
|
||||
* <launch_url>url to the basiclti launch URL</launch_url>
|
||||
* <secure_launch_url>url to the basiclti launch URL</secure_launch_url>
|
||||
* <icon>url to an icon for this tool (optional)</icon>
|
||||
* <secure_icon>url to an icon for this tool (optional)</secure_icon>
|
||||
* <cartridge_icon identifierref="BLTI001_Icon"/>
|
||||
* <vendor>
|
||||
* <code>vendor.com</code>
|
||||
* <name>Vendor Name</name>
|
||||
* <description>
|
||||
* This is a Grade Book that supports many column types.
|
||||
* </description>
|
||||
* <contact>
|
||||
* <email>support@vendor.com</email>
|
||||
* </contact>
|
||||
* <url>http://www.vendor.com/product</url>
|
||||
* </vendor>
|
||||
* </basic_lti_link>
|
||||
* </pre>
|
||||
*/
|
||||
public class BasicLTIUtil {
|
||||
|
||||
// We use the built-in Java logger because this code needs to be very generic
|
||||
private static Logger M_log = Logger.getLogger(BasicLTIUtil.class.toString());
|
||||
|
||||
/** To turn on really verbose debugging */
|
||||
private static boolean verbosePrint = false;
|
||||
|
||||
public static final String BASICLTI_SUBMIT = "ext_basiclti_submit";
|
||||
|
||||
private static final Pattern CUSTOM_REGEX = Pattern.compile("[^A-Za-z0-9]");
|
||||
private static final String UNDERSCORE = "_";
|
||||
|
||||
// Simple Debug Print Mechanism
|
||||
public static void dPrint(String str) {
|
||||
if (verbosePrint)
|
||||
System.out.println(str);
|
||||
M_log.fine(str);
|
||||
}
|
||||
|
||||
public static String validateDescriptor(String descriptor) {
|
||||
if (descriptor == null)
|
||||
return null;
|
||||
if (descriptor.indexOf("<basic_lti_link") < 0)
|
||||
return null;
|
||||
|
||||
Map<String, Object> tm = XMLMap.getFullMap(descriptor.trim());
|
||||
if (tm == null)
|
||||
return null;
|
||||
|
||||
// We demand at least an endpoint
|
||||
String ltiSecureLaunch = XMLMap.getString(tm,
|
||||
"/basic_lti_link/secure_launch_url");
|
||||
// We demand at least an endpoint
|
||||
if (ltiSecureLaunch != null && ltiSecureLaunch.trim().length() > 0)
|
||||
return ltiSecureLaunch;
|
||||
String ltiLaunch = XMLMap.getString(tm, "/basic_lti_link/launch_url");
|
||||
if (ltiLaunch != null && ltiLaunch.trim().length() > 0)
|
||||
return ltiLaunch;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any properties which are not well known (i.e. in
|
||||
* {@link BasicLTIConstants#validPropertyNames}) will be mapped to custom
|
||||
* properties per the specified semantics. NOTE: no blacklisting of keys is
|
||||
* performed.
|
||||
*
|
||||
* @param rawProperties
|
||||
* A set of properties that will be cleaned.
|
||||
* @return A cleansed version of rawProperties.
|
||||
*/
|
||||
public static Map<String, String> cleanupProperties(
|
||||
final Map<String, String> rawProperties) {
|
||||
return cleanupProperties(rawProperties, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Any properties which are not well known (i.e. in
|
||||
* {@link BasicLTIConstants#validPropertyNames}) will be mapped to custom
|
||||
* properties per the specified semantics.
|
||||
*
|
||||
* @param rawProperties
|
||||
* A set of properties that will be cleaned.
|
||||
* @param blackList
|
||||
* An array of {@link String}s which are considered unsafe to be
|
||||
* included in launch data. Any matches will be removed from the
|
||||
* return.
|
||||
* @return A cleansed version of rawProperties.
|
||||
*/
|
||||
public static Map<String, String> cleanupProperties(
|
||||
final Map<String, String> rawProperties, final String[] blackList) {
|
||||
final Map<String, String> newProp = new HashMap<String, String>(
|
||||
rawProperties.size()); // roughly the same size
|
||||
for (String okey : rawProperties.keySet()) {
|
||||
final String key = okey.trim();
|
||||
if (blackList != null) {
|
||||
boolean blackListed = false;
|
||||
for (String blackKey : blackList) {
|
||||
if (blackKey.equals(key)) {
|
||||
blackListed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (blackListed) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
final String value = rawProperties.get(key);
|
||||
if (value == null || "".equals(value)) {
|
||||
// remove null or empty values
|
||||
continue;
|
||||
}
|
||||
if (isSpecifiedPropertyName(key)) {
|
||||
// a well known property name
|
||||
newProp.put(key, value);
|
||||
} else {
|
||||
// convert to a custom property name
|
||||
newProp.put(adaptToCustomPropertyName(key), value);
|
||||
}
|
||||
}
|
||||
return newProp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any properties which are not well known (i.e. in
|
||||
* {@link BasicLTIConstants#validPropertyNames}) will be mapped to custom
|
||||
* properties per the specified semantics.
|
||||
*
|
||||
* @deprecated See {@link #cleanupProperties(Map)}
|
||||
* @param rawProperties
|
||||
* A set of {@link Properties} that will be cleaned. Keys must be of
|
||||
* type {@link String}.
|
||||
* @return A cleansed version of {@link Properties}.
|
||||
*/
|
||||
public static Properties cleanupProperties(final Properties rawProperties) {
|
||||
final Map<String, String> map = cleanupProperties(
|
||||
convertToMap(rawProperties), null);
|
||||
return convertToProperties(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the passed propertyName is equal to one of the Strings
|
||||
* contained in {@link BasicLTIConstants#validPropertyNames}. String matching
|
||||
* is case sensitive.
|
||||
*
|
||||
* @param propertyName
|
||||
* @return true if propertyName is equal to one of the Strings contained in
|
||||
* {@link BasicLTIConstants#validPropertyNames}
|
||||
* or is a custom parameter oe extension parameter ;
|
||||
* else return false.
|
||||
*/
|
||||
public static boolean isSpecifiedPropertyName(final String propertyName) {
|
||||
boolean found = false;
|
||||
if ( propertyName.startsWith(BasicLTIConstants.CUSTOM_PREFIX) ) return true;
|
||||
if ( propertyName.startsWith(BasicLTIConstants.EXTENSION_PREFIX) ) return true;
|
||||
if ( propertyName.startsWith(BasicLTIConstants.OAUTH_PREFIX) ) return true;
|
||||
for (String key : BasicLTIConstants.validPropertyNames) {
|
||||
if (key.equals(propertyName)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple utility method which implements the specified semantics of custom
|
||||
* properties.
|
||||
* <p>
|
||||
* i.e. The parameter names are mapped to lower case and any character that is
|
||||
* neither a number nor letter in a parameter name is replaced with an
|
||||
* "underscore".
|
||||
* <p>
|
||||
* e.g. Review:Chapter=1.2.56 would map to custom_review_chapter=1.2.56.
|
||||
*
|
||||
* @param propertyName
|
||||
* @return
|
||||
*/
|
||||
public static String adaptToCustomPropertyName(final String propertyName) {
|
||||
if (propertyName == null || "".equals(propertyName)) {
|
||||
throw new IllegalArgumentException("propertyName cannot be null");
|
||||
}
|
||||
String customName = propertyName.toLowerCase();
|
||||
customName = CUSTOM_REGEX.matcher(customName).replaceAll(UNDERSCORE);
|
||||
if (!customName.startsWith(CUSTOM_PREFIX)) {
|
||||
customName = CUSTOM_PREFIX + customName;
|
||||
}
|
||||
return customName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the necessary fields and sign.
|
||||
*
|
||||
* @deprecated See:
|
||||
* {@link BasicLTIUtil#signProperties(Map, String, String, String, String, String, String, String, String, String)}
|
||||
*
|
||||
* @param postProp
|
||||
* @param url
|
||||
* @param method
|
||||
* @param oauth_consumer_key
|
||||
* @param oauth_consumer_secret
|
||||
* @param org_id
|
||||
* See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_GUID}
|
||||
* @param org_desc
|
||||
* See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_DESCRIPTION}
|
||||
* @param org_url
|
||||
* See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_URL}
|
||||
* @return
|
||||
*/
|
||||
public static Properties signProperties(Properties postProp, String url,
|
||||
String method, String oauth_consumer_key, String oauth_consumer_secret,
|
||||
String org_id, String org_desc, String org_url) {
|
||||
final Map<String, String> signedMap = signProperties(
|
||||
convertToMap(postProp), url, method, oauth_consumer_key,
|
||||
oauth_consumer_secret, org_id, org_desc, org_url, null, null);
|
||||
return convertToProperties(signedMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the necessary fields and sign.
|
||||
*
|
||||
* @param postProp
|
||||
* @param url
|
||||
* @param method
|
||||
* @param oauth_consumer_key
|
||||
* @param oauth_consumer_secret
|
||||
* @param tool_consumer_instance_guid
|
||||
* See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_GUID}
|
||||
* @param tool_consumer_instance_description
|
||||
* See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_DESCRIPTION}
|
||||
* @param tool_consumer_instance_url
|
||||
* See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_URL}
|
||||
* @param tool_consumer_instance_name
|
||||
* See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_NAME}
|
||||
* @param tool_consumer_instance_contact_email
|
||||
* See:
|
||||
* {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_CONTACT_EMAIL}
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, String> signProperties(
|
||||
Map<String, String> postProp, String url, String method,
|
||||
String oauth_consumer_key, String oauth_consumer_secret,
|
||||
String tool_consumer_instance_guid,
|
||||
String tool_consumer_instance_description,
|
||||
String tool_consumer_instance_url, String tool_consumer_instance_name,
|
||||
String tool_consumer_instance_contact_email) {
|
||||
postProp = BasicLTIUtil.cleanupProperties(postProp);
|
||||
postProp.put(LTI_VERSION, "LTI-1p0");
|
||||
postProp.put(LTI_MESSAGE_TYPE, "basic-lti-launch-request");
|
||||
// Allow caller to internationalize this for us...
|
||||
if (postProp.get(BASICLTI_SUBMIT) == null) {
|
||||
postProp.put(BASICLTI_SUBMIT, "Launch Endpoint with BasicLTI Data");
|
||||
}
|
||||
if (tool_consumer_instance_guid != null)
|
||||
postProp.put(TOOL_CONSUMER_INSTANCE_GUID, tool_consumer_instance_guid);
|
||||
if (tool_consumer_instance_description != null)
|
||||
postProp.put(TOOL_CONSUMER_INSTANCE_DESCRIPTION,
|
||||
tool_consumer_instance_description);
|
||||
if (tool_consumer_instance_url != null)
|
||||
postProp.put(TOOL_CONSUMER_INSTANCE_URL, tool_consumer_instance_url);
|
||||
if (tool_consumer_instance_name != null)
|
||||
postProp.put(TOOL_CONSUMER_INSTANCE_NAME, tool_consumer_instance_name);
|
||||
if (tool_consumer_instance_contact_email != null)
|
||||
postProp.put(TOOL_CONSUMER_INSTANCE_CONTACT_EMAIL,
|
||||
tool_consumer_instance_contact_email);
|
||||
|
||||
if (postProp.get("oauth_callback") == null)
|
||||
postProp.put("oauth_callback", "about:blank");
|
||||
|
||||
if (oauth_consumer_key == null || oauth_consumer_secret == null) {
|
||||
dPrint("No signature generated in signProperties");
|
||||
return postProp;
|
||||
}
|
||||
|
||||
OAuthMessage oam = new OAuthMessage(method, url, postProp.entrySet());
|
||||
OAuthConsumer cons = new OAuthConsumer("about:blank", oauth_consumer_key,
|
||||
oauth_consumer_secret, null);
|
||||
OAuthAccessor acc = new OAuthAccessor(cons);
|
||||
try {
|
||||
oam.addRequiredParameters(acc);
|
||||
// System.out.println("Base Message String\n"+OAuthSignatureMethod.getBaseString(oam)+"\n");
|
||||
|
||||
List<Map.Entry<String, String>> params = oam.getParameters();
|
||||
|
||||
Map<String, String> nextProp = new HashMap<String, String>();
|
||||
// Convert to Map<String, String>
|
||||
for (final Map.Entry<String, String> entry : params) {
|
||||
nextProp.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return nextProp;
|
||||
} catch (net.oauth.OAuthException e) {
|
||||
M_log.warning("BasicLTIUtil.signProperties OAuth Exception "
|
||||
+ e.getMessage());
|
||||
throw new Error(e);
|
||||
} catch (java.io.IOException e) {
|
||||
M_log.warning("BasicLTIUtil.signProperties IO Exception "
|
||||
+ e.getMessage());
|
||||
throw new Error(e);
|
||||
} catch (java.net.URISyntaxException e) {
|
||||
M_log.warning("BasicLTIUtil.signProperties URI Syntax Exception "
|
||||
+ e.getMessage());
|
||||
throw new Error(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the HTML to render a POST form and then automatically submit it.
|
||||
* Make sure to call {@link #cleanupProperties(Properties)} before signing.
|
||||
*
|
||||
* @deprecated Moved to {@link #postLaunchHTML(Map, String, boolean)}
|
||||
* @param cleanProperties
|
||||
* Assumes you have called {@link #cleanupProperties(Properties)}
|
||||
* beforehand.
|
||||
* @param endpoint
|
||||
* The LTI launch url.
|
||||
* @param debug
|
||||
* Useful for viewing the HTML before posting to end point.
|
||||
* @return the HTML ready for IFRAME src = inclusion.
|
||||
*/
|
||||
public static String postLaunchHTML(final Properties cleanProperties,
|
||||
String endpoint, boolean debug) {
|
||||
Map<String, String> map = convertToMap(cleanProperties);
|
||||
return postLaunchHTML(map, endpoint, debug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the HTML to render a POST form and then automatically submit it.
|
||||
* Make sure to call {@link #cleanupProperties(Properties)} before signing.
|
||||
*
|
||||
* @param cleanProperties
|
||||
* Assumes you have called {@link #cleanupProperties(Properties)}
|
||||
* beforehand.
|
||||
* @param endpoint
|
||||
* The LTI launch url.
|
||||
* @param debug
|
||||
* Useful for viewing the HTML before posting to end point.
|
||||
* @return the HTML ready for IFRAME src = inclusion.
|
||||
*/
|
||||
public static String postLaunchHTML(
|
||||
final Map<String, String> cleanProperties, String endpoint, boolean debug) {
|
||||
if (cleanProperties == null || cleanProperties.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"cleanProperties == null || cleanProperties.isEmpty()");
|
||||
}
|
||||
if (endpoint == null) {
|
||||
throw new IllegalArgumentException("endpoint == null");
|
||||
}
|
||||
Map<String, String> newMap = null;
|
||||
if (debug) {
|
||||
// sort the properties for readability
|
||||
newMap = new TreeMap<String, String>(cleanProperties);
|
||||
} else {
|
||||
newMap = cleanProperties;
|
||||
}
|
||||
StringBuilder text = new StringBuilder();
|
||||
// paint form
|
||||
text.append("<div id=\"ltiLaunchFormSubmitArea\">\n");
|
||||
text.append("<form action=\"");
|
||||
text.append(endpoint);
|
||||
text.append("\" name=\"ltiLaunchForm\" id=\"ltiLaunchForm\" method=\"post\" ");
|
||||
text.append(" encType=\"application/x-www-form-urlencoded\" accept-charset=\"utf-8\">\n");
|
||||
for (Entry<String, String> entry : newMap.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
if (value == null)
|
||||
continue;
|
||||
// This will escape the contents pretty much - at least
|
||||
// we will be safe and not generate dangerous HTML
|
||||
key = htmlspecialchars(key);
|
||||
value = htmlspecialchars(value);
|
||||
if (key.equals(BASICLTI_SUBMIT)) {
|
||||
text.append("<input type=\"submit\" name=\"");
|
||||
} else {
|
||||
text.append("<input type=\"hidden\" name=\"");
|
||||
}
|
||||
text.append(key);
|
||||
text.append("\" value=\"");
|
||||
text.append(value);
|
||||
text.append("\"/>\n");
|
||||
}
|
||||
text.append("</form>\n");
|
||||
text.append("</div>\n");
|
||||
// paint debug output
|
||||
if (debug) {
|
||||
text.append("<pre>\n");
|
||||
text.append("<b>BasicLTI Endpoint</b>\n");
|
||||
text.append(endpoint);
|
||||
text.append("\n\n");
|
||||
text.append("<b>BasicLTI Parameters:</b>\n");
|
||||
for (Entry<String, String> entry : newMap.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
if (value == null)
|
||||
continue;
|
||||
text.append(key);
|
||||
text.append("=");
|
||||
text.append(value);
|
||||
text.append("\n");
|
||||
}
|
||||
text.append("</pre>\n");
|
||||
} else {
|
||||
// paint auto submit script
|
||||
text
|
||||
.append(" <script language=\"javascript\"> \n"
|
||||
+ " document.getElementById(\"ltiLaunchFormSubmitArea\").style.display = \"none\";\n"
|
||||
+ " nei = document.createElement('input');\n"
|
||||
+ " nei.setAttribute('type', 'hidden');\n"
|
||||
+ " nei.setAttribute('name', '"
|
||||
+ BASICLTI_SUBMIT
|
||||
+ "');\n"
|
||||
+ " nei.setAttribute('value', '"
|
||||
+ newMap.get(BASICLTI_SUBMIT)
|
||||
+ "');\n"
|
||||
+ " document.getElementById(\"ltiLaunchForm\").appendChild(nei);\n"
|
||||
+ " document.ltiLaunchForm.submit(); \n" + " </script> \n");
|
||||
}
|
||||
|
||||
String htmltext = text.toString();
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated See: {@link #parseDescriptor(Map, Map, String)}
|
||||
* @param launch_info
|
||||
* Variable is mutated by this method.
|
||||
* @param postProp
|
||||
* Variable is mutated by this method.
|
||||
* @param descriptor
|
||||
* @return
|
||||
*/
|
||||
public static boolean parseDescriptor(Properties launch_info,
|
||||
Properties postProp, String descriptor) {
|
||||
// this is an ugly copy/paste of the non-@deprecated method
|
||||
// could not convert data types as they variables get mutated (ugh)
|
||||
Map<String, Object> tm = null;
|
||||
try {
|
||||
tm = XMLMap.getFullMap(descriptor.trim());
|
||||
} catch (Exception e) {
|
||||
M_log.warning("BasicLTIUtil exception parsing BasicLTI descriptor: "
|
||||
+ e.getMessage());
|
||||
return false;
|
||||
}
|
||||
if (tm == null) {
|
||||
M_log.warning("Unable to parse XML in parseDescriptor");
|
||||
return false;
|
||||
}
|
||||
|
||||
String launch_url = toNull(XMLMap.getString(tm,
|
||||
"/basic_lti_link/launch_url"));
|
||||
String secure_launch_url = toNull(XMLMap.getString(tm,
|
||||
"/basic_lti_link/secure_launch_url"));
|
||||
if (launch_url == null && secure_launch_url == null)
|
||||
return false;
|
||||
|
||||
setProperty(launch_info, "launch_url", launch_url);
|
||||
setProperty(launch_info, "secure_launch_url", secure_launch_url);
|
||||
|
||||
// Extensions for hand-authored placements - The export process should scrub
|
||||
// these
|
||||
setProperty(launch_info, "key", toNull(XMLMap.getString(tm,
|
||||
"/basic_lti_link/x-secure/launch_key")));
|
||||
setProperty(launch_info, "secret", toNull(XMLMap.getString(tm,
|
||||
"/basic_lti_link/x-secure/launch_secret")));
|
||||
|
||||
List<Map<String, Object>> theList = XMLMap.getList(tm,
|
||||
"/basic_lti_link/custom/parameter");
|
||||
for (Map<String, Object> setting : theList) {
|
||||
dPrint("Setting=" + setting);
|
||||
String key = XMLMap.getString(setting, "/!key"); // Get the key attribute
|
||||
String value = XMLMap.getString(setting, "/"); // Get the value
|
||||
if (key == null || value == null)
|
||||
continue;
|
||||
key = "custom_" + mapKeyName(key);
|
||||
dPrint("key=" + key + " val=" + value);
|
||||
postProp.setProperty(key, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param launch_info
|
||||
* Variable is mutated by this method.
|
||||
* @param postProp
|
||||
* Variable is mutated by this method.
|
||||
* @param descriptor
|
||||
* @return
|
||||
*/
|
||||
public static boolean parseDescriptor(Map<String, String> launch_info,
|
||||
Map<String, String> postProp, String descriptor) {
|
||||
Map<String, Object> tm = null;
|
||||
try {
|
||||
tm = XMLMap.getFullMap(descriptor.trim());
|
||||
} catch (Exception e) {
|
||||
M_log.warning("BasicLTIUtil exception parsing BasicLTI descriptor: "
|
||||
+ e.getMessage());
|
||||
return false;
|
||||
}
|
||||
if (tm == null) {
|
||||
M_log.warning("Unable to parse XML in parseDescriptor");
|
||||
return false;
|
||||
}
|
||||
|
||||
String launch_url = toNull(XMLMap.getString(tm,
|
||||
"/basic_lti_link/launch_url"));
|
||||
String secure_launch_url = toNull(XMLMap.getString(tm,
|
||||
"/basic_lti_link/secure_launch_url"));
|
||||
if (launch_url == null && secure_launch_url == null)
|
||||
return false;
|
||||
|
||||
setProperty(launch_info, "launch_url", launch_url);
|
||||
setProperty(launch_info, "secure_launch_url", secure_launch_url);
|
||||
|
||||
// Extensions for hand-authored placements - The export process should scrub
|
||||
// these
|
||||
setProperty(launch_info, "key", toNull(XMLMap.getString(tm,
|
||||
"/basic_lti_link/x-secure/launch_key")));
|
||||
setProperty(launch_info, "secret", toNull(XMLMap.getString(tm,
|
||||
"/basic_lti_link/x-secure/launch_secret")));
|
||||
|
||||
List<Map<String, Object>> theList = XMLMap.getList(tm,
|
||||
"/basic_lti_link/custom/parameter");
|
||||
for (Map<String, Object> setting : theList) {
|
||||
dPrint("Setting=" + setting);
|
||||
String key = XMLMap.getString(setting, "/!key"); // Get the key attribute
|
||||
String value = XMLMap.getString(setting, "/"); // Get the value
|
||||
if (key == null || value == null)
|
||||
continue;
|
||||
key = "custom_" + mapKeyName(key);
|
||||
dPrint("key=" + key + " val=" + value);
|
||||
postProp.put(key, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Remove fields that should not be exported
|
||||
public static String prepareForExport(String descriptor) {
|
||||
Map<String, Object> tm = null;
|
||||
try {
|
||||
tm = XMLMap.getFullMap(descriptor.trim());
|
||||
} catch (Exception e) {
|
||||
M_log.warning("BasicLTIUtil exception parsing BasicLTI descriptor"
|
||||
+ e.getMessage());
|
||||
return null;
|
||||
}
|
||||
if (tm == null) {
|
||||
M_log.warning("Unable to parse XML in prepareForExport");
|
||||
return null;
|
||||
}
|
||||
XMLMap.removeSubMap(tm, "/basic_lti_link/x-secure");
|
||||
String retval = XMLMap.getXML(tm, true);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* The parameter name is mapped to lower case and any character that is
|
||||
* neither a number or letter is replaced with an "underscore". So if a custom
|
||||
* entry was as follows:
|
||||
*
|
||||
* <parameter name="Vendor:Chapter">1.2.56</parameter>
|
||||
*
|
||||
* Would map to: custom_vendor_chapter=1.2.56
|
||||
*/
|
||||
public static String mapKeyName(String keyname) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (keyname == null)
|
||||
return null;
|
||||
keyname = keyname.trim();
|
||||
if (keyname.length() < 1)
|
||||
return null;
|
||||
for (int i = 0; i < keyname.length(); i++) {
|
||||
Character ch = Character.toLowerCase(keyname.charAt(i));
|
||||
if (Character.isLetter(ch) || Character.isDigit(ch)) {
|
||||
sb.append(ch);
|
||||
} else {
|
||||
sb.append('_');
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String toNull(String str) {
|
||||
if (str == null)
|
||||
return null;
|
||||
if (str.trim().length() < 1)
|
||||
return null;
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutates the passed Map<String, String> map variable. Puts the key,value
|
||||
* into the Map if the value is not null and is not empty.
|
||||
*
|
||||
* @param map
|
||||
* Variable is mutated by this method.
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setProperty(final Map<String, String> map,
|
||||
final String key, final String value) {
|
||||
if (value != null && !"".equals(value)) {
|
||||
map.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutates the passed Properties props variable. Puts the key,value into the
|
||||
* Map if the value is not null and is not empty.
|
||||
*
|
||||
* @deprecated See: {@link #setProperty(Map, String, String)}
|
||||
* @param props
|
||||
* Variable is mutated by this method.
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setProperty(Properties props, String key, String value) {
|
||||
if (value == null)
|
||||
return;
|
||||
if (value.trim().length() < 1)
|
||||
return;
|
||||
props.setProperty(key, value);
|
||||
}
|
||||
|
||||
// Basic utility to encode form text - handle the "safe cases"
|
||||
public static String htmlspecialchars(String input) {
|
||||
if (input == null)
|
||||
return null;
|
||||
String retval = input.replace("&", "&");
|
||||
retval = retval.replace("\"", """);
|
||||
retval = retval.replace("<", "<");
|
||||
retval = retval.replace(">", ">");
|
||||
retval = retval.replace(">", ">");
|
||||
retval = retval.replace("=", "=");
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple utility method to help with the migration from Properties to
|
||||
* Map<String, String>.
|
||||
*
|
||||
* @param properties
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, String> convertToMap(final Properties properties) {
|
||||
final Map<String, String> map = new HashMap(properties);
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple utility method to help with the migration from Map<String, String>
|
||||
* to Properties.
|
||||
*
|
||||
* @deprecated Should migrate to Map<String, String> signatures.
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
public static Properties convertToProperties(final Map<String, String> map) {
|
||||
final Properties properties = new Properties();
|
||||
if (map != null) {
|
||||
for (Entry<String, String> entry : map.entrySet()) {
|
||||
properties.setProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Checks if a String is whitespace, empty ("") or null.
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.isBlank(null) = true
|
||||
* StringUtils.isBlank("") = true
|
||||
* StringUtils.isBlank(" ") = true
|
||||
* StringUtils.isBlank("bob") = false
|
||||
* StringUtils.isBlank(" bob ") = false
|
||||
* </pre>
|
||||
*
|
||||
* @param str
|
||||
* the String to check, may be null
|
||||
* @return <code>true</code> if the String is null, empty or whitespace
|
||||
* @since 2.0
|
||||
*/
|
||||
public static boolean isBlank(String str) {
|
||||
int strLen;
|
||||
if (str == null || (strLen = str.length()) == 0) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < strLen; i++) {
|
||||
if ((Character.isWhitespace(str.charAt(i)) == false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Checks if a String is not empty (""), not null and not whitespace only.
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.isNotBlank(null) = false
|
||||
* StringUtils.isNotBlank("") = false
|
||||
* StringUtils.isNotBlank(" ") = false
|
||||
* StringUtils.isNotBlank("bob") = true
|
||||
* StringUtils.isNotBlank(" bob ") = true
|
||||
* </pre>
|
||||
*
|
||||
* @param str
|
||||
* the String to check, may be null
|
||||
* @return <code>true</code> if the String is not empty and not null and not
|
||||
* whitespace
|
||||
* @since 2.0
|
||||
*/
|
||||
public static boolean isNotBlank(String str) {
|
||||
return !isBlank(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Compares two Strings, returning <code>true</code> if they are equal.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <code>null</code>s are handled without exceptions. Two <code>null</code>
|
||||
* references are considered to be equal. The comparison is case sensitive.
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.equals(null, null) = true
|
||||
* StringUtils.equals(null, "abc") = false
|
||||
* StringUtils.equals("abc", null) = false
|
||||
* StringUtils.equals("abc", "abc") = true
|
||||
* StringUtils.equals("abc", "ABC") = false
|
||||
* </pre>
|
||||
*
|
||||
* @see java.lang.String#equals(Object)
|
||||
* @param str1
|
||||
* the first String, may be null
|
||||
* @param str2
|
||||
* the second String, may be null
|
||||
* @return <code>true</code> if the Strings are equal, case sensitive, or both
|
||||
* <code>null</code>
|
||||
*/
|
||||
public static boolean equals(String str1, String str2) {
|
||||
return str1 == null ? str2 == null : str1.equals(str2);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Compares two Strings, returning <code>true</code> if they are equal
|
||||
* ignoring the case.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <code>null</code>s are handled without exceptions. Two <code>null</code>
|
||||
* references are considered equal. Comparison is case insensitive.
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.equalsIgnoreCase(null, null) = true
|
||||
* StringUtils.equalsIgnoreCase(null, "abc") = false
|
||||
* StringUtils.equalsIgnoreCase("abc", null) = false
|
||||
* StringUtils.equalsIgnoreCase("abc", "abc") = true
|
||||
* StringUtils.equalsIgnoreCase("abc", "ABC") = true
|
||||
* </pre>
|
||||
*
|
||||
* @see java.lang.String#equalsIgnoreCase(String)
|
||||
* @param str1
|
||||
* the first String, may be null
|
||||
* @param str2
|
||||
* the second String, may be null
|
||||
* @return <code>true</code> if the Strings are equal, case insensitive, or
|
||||
* both <code>null</code>
|
||||
*/
|
||||
public static boolean equalsIgnoreCase(String str1, String str2) {
|
||||
return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2);
|
||||
}
|
||||
}
|
1324
bbb-lti/src/java/org/imsglobal/basiclti/XMLMap.java
Normal file
613
bbb-lti/src/java/org/imsglobal/pox/IMSPOXRequest.java
Normal file
@ -0,0 +1,613 @@
|
||||
package org.imsglobal.pox;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import java.lang.IllegalArgumentException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import javax.xml.xpath.*;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import net.oauth.OAuth;
|
||||
import net.oauth.OAuthMessage;
|
||||
import net.oauth.OAuthConsumer;
|
||||
import net.oauth.OAuthAccessor;
|
||||
import net.oauth.OAuthValidator;
|
||||
import net.oauth.SimpleOAuthValidator;
|
||||
import net.oauth.signature.OAuthSignatureMethod;
|
||||
import net.oauth.server.HttpRequestMessage;
|
||||
import net.oauth.server.OAuthServlet;
|
||||
import net.oauth.signature.OAuthSignatureMethod;
|
||||
import org.imsglobal.basiclti.Base64;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
|
||||
import org.imsglobal.basiclti.XMLMap;
|
||||
|
||||
public class IMSPOXRequest {
|
||||
|
||||
private final static Logger Log = Logger.getLogger(IMSPOXRequest.class .getName());
|
||||
|
||||
public final static String MAJOR_SUCCESS = "success";
|
||||
public final static String MAJOR_FAILURE = "failure";
|
||||
public final static String MAJOR_UNSUPPORTED = "unsupported";
|
||||
public final static String MAJOR_PROCESSING = "processing";
|
||||
|
||||
public final static String [] validMajor = {
|
||||
MAJOR_SUCCESS, MAJOR_FAILURE, MAJOR_UNSUPPORTED, MAJOR_PROCESSING };
|
||||
|
||||
public final static String SEVERITY_ERROR = "error";
|
||||
public final static String SEVERITY_WARNING = "warning";
|
||||
public final static String SEVERITY_STATUS = "status";
|
||||
|
||||
public final static String [] validSeverity = {
|
||||
SEVERITY_ERROR, SEVERITY_WARNING, SEVERITY_STATUS };
|
||||
|
||||
public final static String MINOR_FULLSUCCESS ="fullsuccess";
|
||||
public final static String MINOR_NOSOURCEDIDS = "nosourcedids";
|
||||
public final static String MINOR_IDALLOC = "idalloc";
|
||||
public final static String MINOR_OVERFLOWFAIL = "overflowfail";
|
||||
public final static String MINOR_IDALLOCINUSEFAIL = "idallocinusefail";
|
||||
public final static String MINOR_INVALIDDATAFAIL = "invaliddata";
|
||||
public final static String MINOR_INCOMPLETEDATA = "incompletedata";
|
||||
public final static String MINOR_PARTIALSTORAGE = "partialdatastorage";
|
||||
public final static String MINOR_UNKNOWNOBJECT = "unknownobject";
|
||||
public final static String MINOR_DELETEFAILURE = "deletefailure";
|
||||
public final static String MINOR_TARGETREADFAILURE = "targetreadfailure";
|
||||
public final static String MINOR_SAVEPOINTERROR = "savepointerror";
|
||||
public final static String MINOR_SAVEPOINTSYNCERROR = "savepointsyncerror";
|
||||
public final static String MINOR_UNKNOWNQUERY = "unknownquery";
|
||||
public final static String MINOR_UNKNOWNVOCAB = "unknownvocab";
|
||||
public final static String MINOR_TARGETISBUSY = "targetisbusy";
|
||||
public final static String MINOR_UNKNOWNEXTENSION = "unknownextension";
|
||||
public final static String MINOR_UNAUTHORIZEDREQUEST = "unauthorizedrequest";
|
||||
public final static String MINOR_LINKFAILURE = "linkfailure";
|
||||
public final static String MINOR_UNSUPPORTED = "unsupported";
|
||||
|
||||
public final static String [] validMinor = {
|
||||
MINOR_FULLSUCCESS, MINOR_NOSOURCEDIDS, MINOR_IDALLOC, MINOR_OVERFLOWFAIL,
|
||||
MINOR_IDALLOCINUSEFAIL, MINOR_INVALIDDATAFAIL, MINOR_INCOMPLETEDATA,
|
||||
MINOR_PARTIALSTORAGE, MINOR_UNKNOWNOBJECT, MINOR_DELETEFAILURE,
|
||||
MINOR_TARGETREADFAILURE, MINOR_SAVEPOINTERROR, MINOR_SAVEPOINTSYNCERROR,
|
||||
MINOR_UNKNOWNQUERY, MINOR_UNKNOWNVOCAB, MINOR_TARGETISBUSY,
|
||||
MINOR_UNKNOWNEXTENSION, MINOR_UNAUTHORIZEDREQUEST, MINOR_LINKFAILURE,
|
||||
MINOR_UNSUPPORTED
|
||||
} ;
|
||||
|
||||
public Document postDom = null;
|
||||
public Element bodyElement = null;
|
||||
public Element headerElement = null;
|
||||
public String postBody = null;
|
||||
private String header = null;
|
||||
private String oauth_body_hash = null;
|
||||
private String oauth_consumer_key = null;
|
||||
|
||||
public boolean valid = false;
|
||||
private String operation = null;
|
||||
public String errorMessage = null;
|
||||
public String base_string = null;
|
||||
private Map<String,String> bodyMap = null;
|
||||
private Map<String,String> headerMap = null;
|
||||
|
||||
public String getOperation()
|
||||
{
|
||||
return operation;
|
||||
}
|
||||
|
||||
public String getOAuthConsumerKey()
|
||||
{
|
||||
return oauth_consumer_key;
|
||||
}
|
||||
|
||||
public String getHeaderVersion()
|
||||
{
|
||||
return getHeaderItem("/imsx_version");
|
||||
}
|
||||
|
||||
public String getHeaderMessageIdentifier()
|
||||
{
|
||||
return getHeaderItem("/imsx_messageIdentifier");
|
||||
}
|
||||
|
||||
public String getHeaderItem(String path)
|
||||
{
|
||||
if ( getHeaderMap() == null ) return null;
|
||||
return headerMap.get(path);
|
||||
}
|
||||
|
||||
public Map<String,String> getHeaderMap()
|
||||
{
|
||||
if ( headerMap != null ) return headerMap;
|
||||
if ( headerElement == null ) return null;
|
||||
headerMap = XMLMap.getMap(headerElement);
|
||||
return headerMap;
|
||||
}
|
||||
|
||||
public Map<String,String> getBodyMap()
|
||||
{
|
||||
if ( bodyMap != null ) return bodyMap;
|
||||
if ( bodyElement == null ) return null;
|
||||
bodyMap = XMLMap.getMap(bodyElement);
|
||||
return bodyMap;
|
||||
}
|
||||
|
||||
public String getPostBody()
|
||||
{
|
||||
return postBody;
|
||||
}
|
||||
|
||||
// Normal Constructor
|
||||
public IMSPOXRequest(String oauth_consumer_key, String oauth_secret, HttpServletRequest request)
|
||||
{
|
||||
loadFromRequest(request);
|
||||
if ( ! valid ) return;
|
||||
validateRequest(oauth_consumer_key, oauth_secret, request);
|
||||
}
|
||||
|
||||
// Constructor for delayed validation
|
||||
public IMSPOXRequest(HttpServletRequest request)
|
||||
{
|
||||
loadFromRequest(request);
|
||||
}
|
||||
|
||||
// Constructor for testing...
|
||||
public IMSPOXRequest(String bodyString)
|
||||
{
|
||||
postBody = bodyString;
|
||||
parsePostBody();
|
||||
}
|
||||
|
||||
// Load but do not check the authentication
|
||||
public void loadFromRequest(HttpServletRequest request)
|
||||
{
|
||||
String contentType = request.getContentType();
|
||||
if ( ! "application/xml".equals(contentType) ) {
|
||||
errorMessage = "Content Type must be application/xml";
|
||||
Log.info(errorMessage+"\n"+contentType);
|
||||
return;
|
||||
}
|
||||
|
||||
header = request.getHeader("Authorization");
|
||||
oauth_body_hash = null;
|
||||
if ( header != null ) {
|
||||
if (header.startsWith("OAuth ")) header = header.substring(5);
|
||||
String [] parms = header.split(",");
|
||||
for ( String parm : parms ) {
|
||||
parm = parm.trim();
|
||||
if ( parm.startsWith("oauth_body_hash=") ) {
|
||||
String [] pieces = parm.split("\"");
|
||||
oauth_body_hash = URLDecoder.decode(pieces[1]);
|
||||
}
|
||||
if ( parm.startsWith("oauth_consumer_key=") ) {
|
||||
String [] pieces = parm.split("\"");
|
||||
oauth_consumer_key = URLDecoder.decode(pieces[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( oauth_body_hash == null ) {
|
||||
errorMessage = "Did not find oauth_body_hash";
|
||||
Log.info(errorMessage+"\n"+header);
|
||||
return;
|
||||
}
|
||||
|
||||
// System.out.println("OBH="+oauth_body_hash);
|
||||
final char[] buffer = new char[0x10000];
|
||||
try {
|
||||
StringBuilder out = new StringBuilder();
|
||||
Reader in = request.getReader();
|
||||
int read;
|
||||
do {
|
||||
read = in.read(buffer, 0, buffer.length);
|
||||
if (read>0) {
|
||||
out.append(buffer, 0, read);
|
||||
}
|
||||
} while (read>=0);
|
||||
postBody = out.toString();
|
||||
} catch(Exception e) {
|
||||
errorMessage = "Could not read message body:"+e.getMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA1");
|
||||
md.update(postBody.getBytes());
|
||||
byte[] output = Base64.encode(md.digest());
|
||||
String hash = new String(output);
|
||||
// System.out.println("HASH="+hash);
|
||||
if ( ! hash.equals(oauth_body_hash) ) {
|
||||
errorMessage = "Body hash does not match header";
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
errorMessage = "Could not compute body hash";
|
||||
return;
|
||||
}
|
||||
parsePostBody();
|
||||
}
|
||||
|
||||
public void parsePostBody()
|
||||
{
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
try {
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
postDom = db.parse(new ByteArrayInputStream(postBody.getBytes()));
|
||||
}catch(Exception e) {
|
||||
errorMessage = "Could not parse XML: "+e.getMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
XPathExpression expr = xpath.compile("/imsx_POXEnvelopeRequest/imsx_POXBody/*");
|
||||
Object result = expr.evaluate(postDom, XPathConstants.NODESET);
|
||||
NodeList nodes = (NodeList) result;
|
||||
bodyElement = (Element) nodes.item(0);
|
||||
operation = bodyElement.getNodeName();
|
||||
|
||||
expr = xpath.compile("/imsx_POXEnvelopeRequest/imsx_POXHeader/*");
|
||||
result = expr.evaluate(postDom, XPathConstants.NODESET);
|
||||
nodes = (NodeList) result;
|
||||
headerElement = (Element) nodes.item(0);
|
||||
}catch(Exception e) {
|
||||
errorMessage = "Could not parse PATH: "+e.getMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( operation == null || bodyElement == null ) {
|
||||
errorMessage = "Could not find operation";
|
||||
return;
|
||||
}
|
||||
valid = true;
|
||||
}
|
||||
|
||||
// Assumes data is all loaded
|
||||
public void validateRequest(String oauth_consumer_key, String oauth_secret, HttpServletRequest request)
|
||||
{
|
||||
valid = false;
|
||||
OAuthMessage oam = OAuthServlet.getMessage(request, null);
|
||||
OAuthValidator oav = new SimpleOAuthValidator();
|
||||
OAuthConsumer cons = new OAuthConsumer("about:blank#OAuth+CallBack+NotUsed",
|
||||
oauth_consumer_key, oauth_secret, null);
|
||||
|
||||
OAuthAccessor acc = new OAuthAccessor(cons);
|
||||
|
||||
try {
|
||||
base_string = OAuthSignatureMethod.getBaseString(oam);
|
||||
} catch (Exception e) {
|
||||
base_string = null;
|
||||
}
|
||||
|
||||
try {
|
||||
oav.validateMessage(oam,acc);
|
||||
} catch(Exception e) {
|
||||
errorMessage = "Launch fails OAuth validation: "+e.getMessage();
|
||||
return;
|
||||
}
|
||||
valid = true;
|
||||
}
|
||||
|
||||
public static String fetchTag(org.w3c.dom.Element element, String tag)
|
||||
{
|
||||
try {
|
||||
org.w3c.dom.NodeList elements = element.getElementsByTagName(tag);
|
||||
int numElements = elements.getLength();
|
||||
if (numElements > 0) {
|
||||
org.w3c.dom.Element e = (org.w3c.dom.Element)elements.item(0);
|
||||
if (e.hasChildNodes()) {
|
||||
return e.getFirstChild().getNodeValue();
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Log.warning(t.getMessage());
|
||||
// t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean inArray(final String [] theArray, final String theString)
|
||||
{
|
||||
if ( theString == null ) return false;
|
||||
for ( String str : theArray ) {
|
||||
if ( theString.equals(str) ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static final String fatalMessage =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<imsx_POXEnvelopeResponse xmlns = \"http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0\">\n" +
|
||||
" <imsx_POXHeader>\n" +
|
||||
" <imsx_POXResponseHeaderInfo>\n" +
|
||||
" <imsx_version>V1.0</imsx_version>\n" +
|
||||
" <imsx_messageIdentifier>%s</imsx_messageIdentifier>\n" +
|
||||
" <imsx_statusInfo>\n" +
|
||||
" <imsx_codeMajor>failure</imsx_codeMajor>\n" +
|
||||
" <imsx_severity>error</imsx_severity>\n" +
|
||||
" <imsx_description>%s</imsx_description>\n" +
|
||||
" </imsx_statusInfo>\n" +
|
||||
" </imsx_POXResponseHeaderInfo>\n" +
|
||||
" </imsx_POXHeader>\n" +
|
||||
" <imsx_POXBody/>\n" +
|
||||
"</imsx_POXEnvelopeResponse>";
|
||||
|
||||
public static String getFatalResponse(String description)
|
||||
{
|
||||
Date dt = new Date();
|
||||
String messageId = ""+dt.getTime();
|
||||
|
||||
return String.format(fatalMessage,
|
||||
StringEscapeUtils.escapeXml(messageId),
|
||||
StringEscapeUtils.escapeXml(description));
|
||||
}
|
||||
|
||||
static final String responseMessage =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<imsx_POXEnvelopeResponse xmlns = \"http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0\">\n" +
|
||||
" <imsx_POXHeader>\n" +
|
||||
" <imsx_POXResponseHeaderInfo>\n" +
|
||||
" <imsx_version>V1.0</imsx_version>\n" +
|
||||
" <imsx_messageIdentifier>%s</imsx_messageIdentifier>\n" +
|
||||
" <imsx_statusInfo>\n" +
|
||||
" <imsx_codeMajor>%s</imsx_codeMajor>\n" +
|
||||
" <imsx_severity>%s</imsx_severity>\n" +
|
||||
" <imsx_description>%s</imsx_description>\n" +
|
||||
" <imsx_messageRefIdentifier>%s</imsx_messageRefIdentifier>\n" +
|
||||
" <imsx_operationRefIdentifier>%s</imsx_operationRefIdentifier>" +
|
||||
"%s\n"+
|
||||
" </imsx_statusInfo>\n" +
|
||||
" </imsx_POXResponseHeaderInfo>\n" +
|
||||
" </imsx_POXHeader>\n" +
|
||||
" <imsx_POXBody>\n" +
|
||||
"%s%s"+
|
||||
" </imsx_POXBody>\n" +
|
||||
"</imsx_POXEnvelopeResponse>";
|
||||
|
||||
public String getResponseUnsupported(String desc)
|
||||
{
|
||||
return getResponse(desc, MAJOR_UNSUPPORTED, null, null, null, null);
|
||||
}
|
||||
|
||||
public String getResponseFailure(String desc, Properties minor)
|
||||
{
|
||||
return getResponse(desc, null, null, null, minor, null);
|
||||
}
|
||||
|
||||
public String getResponseSuccess(String desc, String bodyString)
|
||||
{
|
||||
return getResponse(desc, MAJOR_SUCCESS, null, null, null, bodyString);
|
||||
}
|
||||
|
||||
public String getResponse(String description, String major, String severity,
|
||||
String messageId, Properties minor, String bodyString)
|
||||
{
|
||||
StringBuffer internalError = new StringBuffer();
|
||||
if ( major == null ) major = MAJOR_FAILURE;
|
||||
if ( severity == null && MAJOR_PROCESSING.equals(major) ) severity = SEVERITY_STATUS;
|
||||
if ( severity == null && MAJOR_SUCCESS.equals(major) ) severity = SEVERITY_STATUS;
|
||||
if ( severity == null ) severity = SEVERITY_ERROR;
|
||||
if ( messageId == null ) {
|
||||
Date dt = new Date();
|
||||
messageId = ""+dt.getTime();
|
||||
}
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if ( minor != null && minor.size() > 0 ) {
|
||||
for(Object okey : minor.keySet() ) {
|
||||
String key = (String) okey;
|
||||
String value = minor.getProperty(key);
|
||||
if ( key == null || value == null ) continue;
|
||||
if ( !inArray(validMinor, value) ) {
|
||||
if ( internalError.length() > 0 ) sb.append(", ");
|
||||
internalError.append("Invalid imsx_codeMinorFieldValue="+major);
|
||||
continue;
|
||||
}
|
||||
if ( sb.length() == 0 ) sb.append("\n <imsx_codeMinor>\n");
|
||||
sb.append(" <imsx_codeMinorField>\n <imsx_codeMinorFieldName>");
|
||||
sb.append(key);
|
||||
sb.append("</imsx_codeMinorFieldName>\n <imsx_codeMinorFieldValue>");
|
||||
sb.append(StringEscapeUtils.escapeXml(value));
|
||||
sb.append("</imsx_codeMinorFieldValue>\n </imsx_codeMinorField>\n");
|
||||
}
|
||||
if ( sb.length() > 0 ) sb.append(" </imsx_codeMinor>");
|
||||
}
|
||||
String minorString = sb.toString();
|
||||
|
||||
if ( ! inArray(validMajor, major) ) {
|
||||
if ( internalError.length() > 0 ) sb.append(", ");
|
||||
internalError.append("Invalid imsx_codeMajor="+major);
|
||||
}
|
||||
if ( ! inArray(validSeverity, severity) ) {
|
||||
if ( internalError.length() > 0 ) sb.append(", ");
|
||||
internalError.append("Invalid imsx_severity="+major);
|
||||
}
|
||||
|
||||
if ( internalError.length() > 0 ) {
|
||||
description = description + " (Internal error: " + internalError.toString() + ")";
|
||||
Log.warning(internalError.toString());
|
||||
}
|
||||
|
||||
if ( bodyString == null ) bodyString = "";
|
||||
// Trim off XML header
|
||||
if ( bodyString.startsWith("<?xml") ) {
|
||||
int pos = bodyString.indexOf("<",1);
|
||||
if ( pos > 0 ) bodyString = bodyString.substring(pos);
|
||||
}
|
||||
bodyString = bodyString.trim();
|
||||
String newLine = "";
|
||||
if ( bodyString.length() > 0 ) newLine = "\n";
|
||||
return String.format(responseMessage,
|
||||
StringEscapeUtils.escapeXml(messageId),
|
||||
StringEscapeUtils.escapeXml(major),
|
||||
StringEscapeUtils.escapeXml(severity),
|
||||
StringEscapeUtils.escapeXml(description),
|
||||
StringEscapeUtils.escapeXml(getHeaderMessageIdentifier()),
|
||||
StringEscapeUtils.escapeXml(operation),
|
||||
StringEscapeUtils.escapeXml(minorString),
|
||||
bodyString, newLine);
|
||||
|
||||
}
|
||||
|
||||
/** Unit Tests */
|
||||
static final String inputTestData = "<?xml version = \"1.0\" encoding = \"UTF-8\"?>\n" +
|
||||
"<imsx_POXEnvelopeRequest xmlns = \"http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0\">\n" +
|
||||
"<imsx_POXHeader>\n" +
|
||||
"<imsx_POXRequestHeaderInfo>\n" +
|
||||
"<imsx_version>V1.0</imsx_version>\n" +
|
||||
"<imsx_messageIdentifier>999999123</imsx_messageIdentifier>\n" +
|
||||
"</imsx_POXRequestHeaderInfo>\n" +
|
||||
"</imsx_POXHeader>\n" +
|
||||
"<imsx_POXBody>\n" +
|
||||
"<replaceResultRequest>\n" +
|
||||
"<resultRecord>\n" +
|
||||
"<sourcedGUID>\n" +
|
||||
"<sourcedId>3124567</sourcedId>\n" +
|
||||
"</sourcedGUID>\n" +
|
||||
"<result>\n" +
|
||||
"<resultScore>\n" +
|
||||
"<language>en-us</language>\n" +
|
||||
"<textString>A</textString>\n" +
|
||||
"</resultScore>\n" +
|
||||
"</result>\n" +
|
||||
"</resultRecord>\n" +
|
||||
"</replaceResultRequest>\n" +
|
||||
"</imsx_POXBody>\n" +
|
||||
"</imsx_POXEnvelopeRequest>";
|
||||
|
||||
public static void runTest() {
|
||||
System.out.println("Runnig test.");
|
||||
IMSPOXRequest pox = new IMSPOXRequest(inputTestData);
|
||||
System.out.println("Version = "+pox.getHeaderVersion());
|
||||
System.out.println("Operation = "+pox.getOperation());
|
||||
Map<String,String> bodyMap = pox.getBodyMap();
|
||||
String guid = bodyMap.get("/resultRecord/sourcedGUID/sourcedId");
|
||||
System.out.println("guid="+guid);
|
||||
String grade = bodyMap.get("/resultRecord/result/resultScore/textString");
|
||||
System.out.println("grade="+grade);
|
||||
|
||||
String desc = "Message received and validated operation="+pox.getOperation()+
|
||||
" guid="+guid+" grade="+grade;
|
||||
|
||||
String output = pox.getResponseUnsupported(desc);
|
||||
System.out.println("---- Unsupported ----");
|
||||
System.out.println(output);
|
||||
|
||||
Properties props = new Properties();
|
||||
props.setProperty("fred","zap");
|
||||
props.setProperty("sam",IMSPOXRequest.MINOR_IDALLOC);
|
||||
System.out.println("---- Generate Log Error ----");
|
||||
output = pox.getResponseFailure(desc,props);
|
||||
System.out.println("---- Failure ----");
|
||||
System.out.println(output);
|
||||
|
||||
|
||||
|
||||
Map<String, Object> theMap = new TreeMap<String, Object> ();
|
||||
theMap.put("/readMembershipResponse/membershipRecord/sourcedId", "123course456");
|
||||
|
||||
List<Map<String,String>> lm = new ArrayList<Map<String,String>>();
|
||||
Map<String,String> mm = new TreeMap<String,String>();
|
||||
mm.put("/personSourcedId","123user456");
|
||||
mm.put("/role/roleType","Learner");
|
||||
lm.add(mm);
|
||||
|
||||
mm = new TreeMap<String,String>();
|
||||
mm.put("/personSourcedId","789user123");
|
||||
mm.put("/role/roleType","Instructor");
|
||||
lm.add(mm);
|
||||
theMap.put("/readMembershipResponse/membershipRecord/membership/member", lm);
|
||||
|
||||
String theXml = XMLMap.getXMLFragment(theMap, true);
|
||||
// System.out.println("th="+theXml);
|
||||
output = pox.getResponseSuccess(desc,theXml);
|
||||
System.out.println("---- Success String ----");
|
||||
System.out.println(output);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
roleType:
|
||||
Learner
|
||||
Instructor
|
||||
ContentDeveloper
|
||||
Member
|
||||
Manager
|
||||
Mentor
|
||||
Administrator
|
||||
TeachingAssistant
|
||||
|
||||
fieldType:
|
||||
Boolean
|
||||
Integer
|
||||
Real
|
||||
String
|
||||
|
||||
<readMembershipResponse
|
||||
xmlns="http://www.imsglobal.org/services/lis/mms2p0/wsdl11/sync/imsmms_v2p0">
|
||||
<membershipRecord>
|
||||
<sourcedId>GUID.TYPE</sourcedId>
|
||||
<membership>
|
||||
<collectionSourcedId>GUID.TYPE</collectionSourcedId>
|
||||
<membershipIdType>MEMBERSHIPIDTYPE.TYPE</membershipIdType>
|
||||
<member>
|
||||
<personSourcedId>GUID.TYPE</personSourcedId>
|
||||
<role>
|
||||
<roleType>STRING</roleType>
|
||||
<subRole>STRING</subRole>
|
||||
<timeFrame>
|
||||
<begin>DATETIME</begin>
|
||||
<end>DATETIME</end>
|
||||
<restrict>BOOLEAN</restrict>
|
||||
<adminPeriod>
|
||||
<language>LANGUAGESET.TYPE</language>
|
||||
<textString>STRING</textString>
|
||||
</adminPeriod>
|
||||
</timeFrame>
|
||||
<status>STATUS.TYPE</status>
|
||||
<dateTime>DATETIME</dateTime>
|
||||
<dataSource>GUID.TYPE</dataSource>
|
||||
<recordInfo>
|
||||
<extensionField>
|
||||
<fieldName>STRING</fieldName>
|
||||
<fieldType>FIELDTYPE.TYPE</fieldType>
|
||||
<fieldValue>STRING</fieldValue>
|
||||
</extensionField>
|
||||
</recordInfo>
|
||||
<extension>
|
||||
<extensionField>
|
||||
<fieldName>STRING</fieldName>
|
||||
<fieldType>FIELDTYPE.TYPE</fieldType>
|
||||
<fieldValue>STRING</fieldValue>
|
||||
</extensionField>
|
||||
</extension>
|
||||
</role>
|
||||
</member>
|
||||
<creditHours>INTEGER</creditHours>
|
||||
<dataSource>GUID.TYPE</dataSource>
|
||||
</membership>
|
||||
</membershipRecord>
|
||||
</readMembershipResponse>
|
||||
*/
|
||||
}
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import grails.test.*
|
||||
|
||||
class BigbluebuttonServiceTests extends GrailsUnitTestCase {
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import grails.test.*
|
||||
|
||||
class LtiServiceTests extends GrailsUnitTestCase {
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import grails.test.*
|
||||
|
||||
class ToolControllerTests extends ControllerUnitTestCase {
|
||||
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 1.1 KiB |
@ -86,7 +86,7 @@ public class MeetingService {
|
||||
log.debug("Storing Meeting with internal id:" + m.getInternalId());
|
||||
meetings.put(m.getInternalId(), m);
|
||||
if (m.isRecord()) {
|
||||
Map<String,String> metadata=new HashMap<String,String>();
|
||||
Map<String,String> metadata=new LinkedHashMap<String,String>();
|
||||
metadata.putAll(m.getMetadata());
|
||||
//TODO: Need a better way to store these values for recordings
|
||||
metadata.put("meetingId", m.getExternalId());
|
||||
|
3
labs/html5-embed/README
Normal file
@ -0,0 +1,3 @@
|
||||
Experimental HTML5 client embedding BigBlueButton Flash Client.
|
||||
|
||||
|
303
labs/html5-embed/public/css/font-awesome.css
vendored
Executable file
@ -0,0 +1,303 @@
|
||||
/* Font Awesome
|
||||
the iconic font designed for use with Twitter Bootstrap
|
||||
-------------------------------------------------------
|
||||
The full suite of pictographic icons, examples, and documentation
|
||||
can be found at: http://fortawesome.github.com/Font-Awesome/
|
||||
|
||||
License
|
||||
-------------------------------------------------------
|
||||
The Font Awesome webfont, CSS, and LESS files are licensed under CC BY 3.0:
|
||||
http://creativecommons.org/licenses/by/3.0/ A mention of
|
||||
'Font Awesome - http://fortawesome.github.com/Font-Awesome' in human-readable
|
||||
source code is considered acceptable attribution (most common on the web).
|
||||
If human readable source code is not available to the end user, a mention in
|
||||
an 'About' or 'Credits' screen is considered acceptable (most common in desktop
|
||||
or mobile software).
|
||||
|
||||
Contact
|
||||
-------------------------------------------------------
|
||||
Email: dave@davegandy.com
|
||||
Twitter: http://twitter.com/fortaweso_me
|
||||
Work: http://lemonwi.se co-founder
|
||||
|
||||
*/
|
||||
@font-face {
|
||||
font-family: "FontAwesome";
|
||||
src: url('../font/fontawesome-webfont.eot');
|
||||
src: url('../font/fontawesome-webfont.eot?#iefix') format('eot'), url('../font/fontawesome-webfont.woff') format('woff'), url('../font/fontawesome-webfont.ttf') format('truetype'), url('../font/fontawesome-webfont.svg#FontAwesome') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* Font Awesome styles
|
||||
------------------------------------------------------- */
|
||||
[class^="icon-"]:before, [class*=" icon-"]:before {
|
||||
font-family: FontAwesome;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a [class^="icon-"], a [class*=" icon-"] {
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
/* makes the font 33% larger relative to the icon container */
|
||||
.icon-large:before {
|
||||
vertical-align: top;
|
||||
font-size: 1.3333333333333333em;
|
||||
}
|
||||
.btn [class^="icon-"], .btn [class*=" icon-"] {
|
||||
/* keeps button heights with and without icons the same */
|
||||
|
||||
line-height: .9em;
|
||||
}
|
||||
li [class^="icon-"], li [class*=" icon-"] {
|
||||
display: inline-block;
|
||||
width: 1.25em;
|
||||
text-align: center;
|
||||
}
|
||||
li .icon-large[class^="icon-"], li .icon-large[class*=" icon-"] {
|
||||
/* 1.5 increased font size for icon-large * 1.25 width */
|
||||
|
||||
width: 1.875em;
|
||||
}
|
||||
li[class^="icon-"], li[class*=" icon-"] {
|
||||
margin-left: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
li[class^="icon-"]:before, li[class*=" icon-"]:before {
|
||||
text-indent: -2em;
|
||||
text-align: center;
|
||||
}
|
||||
li[class^="icon-"].icon-large:before, li[class*=" icon-"].icon-large:before {
|
||||
text-indent: -1.3333333333333333em;
|
||||
}
|
||||
/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
|
||||
readers do not read off random characters that represent icons */
|
||||
.icon-glass:before { content: "\f000"; }
|
||||
.icon-music:before { content: "\f001"; }
|
||||
.icon-search:before { content: "\f002"; }
|
||||
.icon-envelope:before { content: "\f003"; }
|
||||
.icon-heart:before { content: "\f004"; }
|
||||
.icon-star:before { content: "\f005"; }
|
||||
.icon-star-empty:before { content: "\f006"; }
|
||||
.icon-user:before { content: "\f007"; }
|
||||
.icon-film:before { content: "\f008"; }
|
||||
.icon-th-large:before { content: "\f009"; }
|
||||
.icon-th:before { content: "\f00a"; }
|
||||
.icon-th-list:before { content: "\f00b"; }
|
||||
.icon-ok:before { content: "\f00c"; }
|
||||
.icon-remove:before { content: "\f00d"; }
|
||||
.icon-zoom-in:before { content: "\f00e"; }
|
||||
|
||||
.icon-zoom-out:before { content: "\f010"; }
|
||||
.icon-off:before { content: "\f011"; }
|
||||
.icon-signal:before { content: "\f012"; }
|
||||
.icon-cog:before { content: "\f013"; }
|
||||
.icon-trash:before { content: "\f014"; }
|
||||
.icon-home:before { content: "\f015"; }
|
||||
.icon-file:before { content: "\f016"; }
|
||||
.icon-time:before { content: "\f017"; }
|
||||
.icon-road:before { content: "\f018"; }
|
||||
.icon-download-alt:before { content: "\f019"; }
|
||||
.icon-download:before { content: "\f01a"; }
|
||||
.icon-upload:before { content: "\f01b"; }
|
||||
.icon-inbox:before { content: "\f01c"; }
|
||||
.icon-play-circle:before { content: "\f01d"; }
|
||||
.icon-repeat:before { content: "\f01e"; }
|
||||
|
||||
/* \f020 doesn't work in Safari. all shifted one down */
|
||||
.icon-refresh:before { content: "\f021"; }
|
||||
.icon-list-alt:before { content: "\f022"; }
|
||||
.icon-lock:before { content: "\f023"; }
|
||||
.icon-flag:before { content: "\f024"; }
|
||||
.icon-headphones:before { content: "\f025"; }
|
||||
.icon-volume-off:before { content: "\f026"; }
|
||||
.icon-volume-down:before { content: "\f027"; }
|
||||
.icon-volume-up:before { content: "\f028"; }
|
||||
.icon-qrcode:before { content: "\f029"; }
|
||||
.icon-barcode:before { content: "\f02a"; }
|
||||
.icon-tag:before { content: "\f02b"; }
|
||||
.icon-tags:before { content: "\f02c"; }
|
||||
.icon-book:before { content: "\f02d"; }
|
||||
.icon-bookmark:before { content: "\f02e"; }
|
||||
.icon-print:before { content: "\f02f"; }
|
||||
|
||||
.icon-camera:before { content: "\f030"; }
|
||||
.icon-font:before { content: "\f031"; }
|
||||
.icon-bold:before { content: "\f032"; }
|
||||
.icon-italic:before { content: "\f033"; }
|
||||
.icon-text-height:before { content: "\f034"; }
|
||||
.icon-text-width:before { content: "\f035"; }
|
||||
.icon-align-left:before { content: "\f036"; }
|
||||
.icon-align-center:before { content: "\f037"; }
|
||||
.icon-align-right:before { content: "\f038"; }
|
||||
.icon-align-justify:before { content: "\f039"; }
|
||||
.icon-list:before { content: "\f03a"; }
|
||||
.icon-indent-left:before { content: "\f03b"; }
|
||||
.icon-indent-right:before { content: "\f03c"; }
|
||||
.icon-facetime-video:before { content: "\f03d"; }
|
||||
.icon-picture:before { content: "\f03e"; }
|
||||
|
||||
.icon-pencil:before { content: "\f040"; }
|
||||
.icon-map-marker:before { content: "\f041"; }
|
||||
.icon-adjust:before { content: "\f042"; }
|
||||
.icon-tint:before { content: "\f043"; }
|
||||
.icon-edit:before { content: "\f044"; }
|
||||
.icon-share:before { content: "\f045"; }
|
||||
.icon-check:before { content: "\f046"; }
|
||||
.icon-move:before { content: "\f047"; }
|
||||
.icon-step-backward:before { content: "\f048"; }
|
||||
.icon-fast-backward:before { content: "\f049"; }
|
||||
.icon-backward:before { content: "\f04a"; }
|
||||
.icon-play:before { content: "\f04b"; }
|
||||
.icon-pause:before { content: "\f04c"; }
|
||||
.icon-stop:before { content: "\f04d"; }
|
||||
.icon-forward:before { content: "\f04e"; }
|
||||
|
||||
.icon-fast-forward:before { content: "\f050"; }
|
||||
.icon-step-forward:before { content: "\f051"; }
|
||||
.icon-eject:before { content: "\f052"; }
|
||||
.icon-chevron-left:before { content: "\f053"; }
|
||||
.icon-chevron-right:before { content: "\f054"; }
|
||||
.icon-plus-sign:before { content: "\f055"; }
|
||||
.icon-minus-sign:before { content: "\f056"; }
|
||||
.icon-remove-sign:before { content: "\f057"; }
|
||||
.icon-ok-sign:before { content: "\f058"; }
|
||||
.icon-question-sign:before { content: "\f059"; }
|
||||
.icon-info-sign:before { content: "\f05a"; }
|
||||
.icon-screenshot:before { content: "\f05b"; }
|
||||
.icon-remove-circle:before { content: "\f05c"; }
|
||||
.icon-ok-circle:before { content: "\f05d"; }
|
||||
.icon-ban-circle:before { content: "\f05e"; }
|
||||
|
||||
.icon-arrow-left:before { content: "\f060"; }
|
||||
.icon-arrow-right:before { content: "\f061"; }
|
||||
.icon-arrow-up:before { content: "\f062"; }
|
||||
.icon-arrow-down:before { content: "\f063"; }
|
||||
.icon-share-alt:before { content: "\f064"; }
|
||||
.icon-resize-full:before { content: "\f065"; }
|
||||
.icon-resize-small:before { content: "\f066"; }
|
||||
.icon-plus:before { content: "\f067"; }
|
||||
.icon-minus:before { content: "\f068"; }
|
||||
.icon-asterisk:before { content: "\f069"; }
|
||||
.icon-exclamation-sign:before { content: "\f06a"; }
|
||||
.icon-gift:before { content: "\f06b"; }
|
||||
.icon-leaf:before { content: "\f06c"; }
|
||||
.icon-fire:before { content: "\f06d"; }
|
||||
.icon-eye-open:before { content: "\f06e"; }
|
||||
|
||||
.icon-eye-close:before { content: "\f070"; }
|
||||
.icon-warning-sign:before { content: "\f071"; }
|
||||
.icon-plane:before { content: "\f072"; }
|
||||
.icon-calendar:before { content: "\f073"; }
|
||||
.icon-random:before { content: "\f074"; }
|
||||
.icon-comment:before { content: "\f075"; }
|
||||
.icon-magnet:before { content: "\f076"; }
|
||||
.icon-chevron-up:before { content: "\f077"; }
|
||||
.icon-chevron-down:before { content: "\f078"; }
|
||||
.icon-retweet:before { content: "\f079"; }
|
||||
.icon-shopping-cart:before { content: "\f07a"; }
|
||||
.icon-folder-close:before { content: "\f07b"; }
|
||||
.icon-folder-open:before { content: "\f07c"; }
|
||||
.icon-resize-vertical:before { content: "\f07d"; }
|
||||
.icon-resize-horizontal:before { content: "\f07e"; }
|
||||
|
||||
.icon-bar-chart:before { content: "\f080"; }
|
||||
.icon-twitter-sign:before { content: "\f081"; }
|
||||
.icon-facebook-sign:before { content: "\f082"; }
|
||||
.icon-camera-retro:before { content: "\f083"; }
|
||||
.icon-key:before { content: "\f084"; }
|
||||
.icon-cogs:before { content: "\f085"; }
|
||||
.icon-comments:before { content: "\f086"; }
|
||||
.icon-thumbs-up:before { content: "\f087"; }
|
||||
.icon-thumbs-down:before { content: "\f088"; }
|
||||
.icon-star-half:before { content: "\f089"; }
|
||||
.icon-heart-empty:before { content: "\f08a"; }
|
||||
.icon-signout:before { content: "\f08b"; }
|
||||
.icon-linkedin-sign:before { content: "\f08c"; }
|
||||
.icon-pushpin:before { content: "\f08d"; }
|
||||
.icon-external-link:before { content: "\f08e"; }
|
||||
|
||||
.icon-signin:before { content: "\f090"; }
|
||||
.icon-trophy:before { content: "\f091"; }
|
||||
.icon-github-sign:before { content: "\f092"; }
|
||||
.icon-upload-alt:before { content: "\f093"; }
|
||||
.icon-lemon:before { content: "\f094"; }
|
||||
.icon-phone:before { content: "\f095"; }
|
||||
.icon-check-empty:before { content: "\f096"; }
|
||||
.icon-bookmark-empty:before { content: "\f097"; }
|
||||
.icon-phone-sign:before { content: "\f098"; }
|
||||
.icon-twitter:before { content: "\f099"; }
|
||||
.icon-facebook:before { content: "\f09a"; }
|
||||
.icon-github:before { content: "\f09b"; }
|
||||
.icon-unlock:before { content: "\f09c"; }
|
||||
.icon-credit-card:before { content: "\f09d"; }
|
||||
.icon-rss:before { content: "\f09e"; }
|
||||
|
||||
.icon-hdd:before { content: "\f0a0"; }
|
||||
.icon-bullhorn:before { content: "\f0a1"; }
|
||||
.icon-bell:before { content: "\f0a2"; }
|
||||
.icon-certificate:before { content: "\f0a3"; }
|
||||
.icon-hand-right:before { content: "\f0a4"; }
|
||||
.icon-hand-left:before { content: "\f0a5"; }
|
||||
.icon-hand-up:before { content: "\f0a6"; }
|
||||
.icon-hand-down:before { content: "\f0a7"; }
|
||||
.icon-circle-arrow-left:before { content: "\f0a8"; }
|
||||
.icon-circle-arrow-right:before { content: "\f0a9"; }
|
||||
.icon-circle-arrow-up:before { content: "\f0aa"; }
|
||||
.icon-circle-arrow-down:before { content: "\f0ab"; }
|
||||
.icon-globe:before { content: "\f0ac"; }
|
||||
.icon-wrench:before { content: "\f0ad"; }
|
||||
.icon-tasks:before { content: "\f0ae"; }
|
||||
|
||||
.icon-filter:before { content: "\f0b0"; }
|
||||
.icon-briefcase:before { content: "\f0b1"; }
|
||||
.icon-fullscreen:before { content: "\f0b2"; }
|
||||
|
||||
.icon-group:before { content: "\f0c0"; }
|
||||
.icon-link:before { content: "\f0c1"; }
|
||||
.icon-cloud:before { content: "\f0c2"; }
|
||||
.icon-beaker:before { content: "\f0c3"; }
|
||||
.icon-cut:before { content: "\f0c4"; }
|
||||
.icon-copy:before { content: "\f0c5"; }
|
||||
.icon-paper-clip:before { content: "\f0c6"; }
|
||||
.icon-save:before { content: "\f0c7"; }
|
||||
.icon-sign-blank:before { content: "\f0c8"; }
|
||||
.icon-reorder:before { content: "\f0c9"; }
|
||||
.icon-list-ul:before { content: "\f0ca"; }
|
||||
.icon-list-ol:before { content: "\f0cb"; }
|
||||
.icon-strikethrough:before { content: "\f0cc"; }
|
||||
.icon-underline:before { content: "\f0cd"; }
|
||||
.icon-table:before { content: "\f0ce"; }
|
||||
|
||||
.icon-magic:before { content: "\f0d0"; }
|
||||
.icon-truck:before { content: "\f0d1"; }
|
||||
.icon-pinterest:before { content: "\f0d2"; }
|
||||
.icon-pinterest-sign:before { content: "\f0d3"; }
|
||||
.icon-google-plus-sign:before { content: "\f0d4"; }
|
||||
.icon-google-plus:before { content: "\f0d5"; }
|
||||
.icon-money:before { content: "\f0d6"; }
|
||||
.icon-caret-down:before { content: "\f0d7"; }
|
||||
.icon-caret-up:before { content: "\f0d8"; }
|
||||
.icon-caret-left:before { content: "\f0d9"; }
|
||||
.icon-caret-right:before { content: "\f0da"; }
|
||||
.icon-columns:before { content: "\f0db"; }
|
||||
.icon-sort:before { content: "\f0dc"; }
|
||||
.icon-sort-down:before { content: "\f0dd"; }
|
||||
.icon-sort-up:before { content: "\f0de"; }
|
||||
|
||||
.icon-envelope-alt:before { content: "\f0e0"; }
|
||||
.icon-linkedin:before { content: "\f0e1"; }
|
||||
.icon-undo:before { content: "\f0e2"; }
|
||||
.icon-legal:before { content: "\f0e3"; }
|
||||
.icon-dashboard:before { content: "\f0e4"; }
|
||||
.icon-comment-alt:before { content: "\f0e5"; }
|
||||
.icon-comments-alt:before { content: "\f0e6"; }
|
||||
.icon-bolt:before { content: "\f0e7"; }
|
||||
.icon-sitemap:before { content: "\f0e8"; }
|
||||
.icon-umbrella:before { content: "\f0e9"; }
|
||||
.icon-paste:before { content: "\f0ea"; }
|
||||
|
||||
.icon-user-md:before { content: "\f200"; }
|
After Width: | Height: | Size: 260 B |
After Width: | Height: | Size: 251 B |
After Width: | Height: | Size: 178 B |
After Width: | Height: | Size: 104 B |
After Width: | Height: | Size: 125 B |
After Width: | Height: | Size: 105 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 90 B |
After Width: | Height: | Size: 129 B |
BIN
labs/html5-embed/public/css/images/ui-icons_222222_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
labs/html5-embed/public/css/images/ui-icons_228ef1_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
labs/html5-embed/public/css/images/ui-icons_ef8c08_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
labs/html5-embed/public/css/images/ui-icons_ffd27a_256x240.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
labs/html5-embed/public/css/images/ui-icons_ffffff_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
563
labs/html5-embed/public/css/jq-ui.css
Normal file
@ -0,0 +1,563 @@
|
||||
/*!
|
||||
* jQuery UI CSS Framework 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Theming/API
|
||||
*/
|
||||
|
||||
/* Layout helpers
|
||||
----------------------------------*/
|
||||
.ui-helper-hidden { display: none; }
|
||||
.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
|
||||
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
|
||||
.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
|
||||
.ui-helper-clearfix:after { clear: both; }
|
||||
.ui-helper-clearfix { zoom: 1; }
|
||||
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
|
||||
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-disabled { cursor: default !important; }
|
||||
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
||||
|
||||
|
||||
/*!
|
||||
* jQuery UI CSS Framework 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Theming/API
|
||||
*
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
|
||||
*/
|
||||
|
||||
|
||||
/* Component containers
|
||||
----------------------------------*/
|
||||
.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
|
||||
.ui-widget .ui-widget { font-size: 1em; }
|
||||
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
|
||||
.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
|
||||
.ui-widget-content a { color: #333333; }
|
||||
.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
|
||||
.ui-widget-header a { color: #ffffff; }
|
||||
|
||||
/* Interaction states
|
||||
----------------------------------*/
|
||||
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; }
|
||||
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; }
|
||||
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; }
|
||||
.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; }
|
||||
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; }
|
||||
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; }
|
||||
.ui-widget :active { outline: none; }
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
|
||||
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
|
||||
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
|
||||
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
|
||||
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
|
||||
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
|
||||
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
|
||||
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
|
||||
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
|
||||
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
|
||||
.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }
|
||||
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
|
||||
|
||||
/* positioning */
|
||||
.ui-icon-carat-1-n { background-position: 0 0; }
|
||||
.ui-icon-carat-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-carat-1-e { background-position: -32px 0; }
|
||||
.ui-icon-carat-1-se { background-position: -48px 0; }
|
||||
.ui-icon-carat-1-s { background-position: -64px 0; }
|
||||
.ui-icon-carat-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-carat-1-w { background-position: -96px 0; }
|
||||
.ui-icon-carat-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-carat-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-carat-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -64px -16px; }
|
||||
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
|
||||
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
|
||||
.ui-icon-arrow-1-n { background-position: 0 -32px; }
|
||||
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -64px -32px; }
|
||||
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
|
||||
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
||||
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
|
||||
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
|
||||
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
|
||||
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
|
||||
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
|
||||
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
|
||||
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
|
||||
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
|
||||
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
||||
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
||||
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
||||
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
||||
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
||||
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
||||
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
||||
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
||||
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
||||
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
||||
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
|
||||
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
|
||||
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
|
||||
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
|
||||
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
||||
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
||||
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
||||
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
||||
.ui-icon-arrow-4 { background-position: 0 -80px; }
|
||||
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
|
||||
.ui-icon-extlink { background-position: -32px -80px; }
|
||||
.ui-icon-newwin { background-position: -48px -80px; }
|
||||
.ui-icon-refresh { background-position: -64px -80px; }
|
||||
.ui-icon-shuffle { background-position: -80px -80px; }
|
||||
.ui-icon-transfer-e-w { background-position: -96px -80px; }
|
||||
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
|
||||
.ui-icon-folder-collapsed { background-position: 0 -96px; }
|
||||
.ui-icon-folder-open { background-position: -16px -96px; }
|
||||
.ui-icon-document { background-position: -32px -96px; }
|
||||
.ui-icon-document-b { background-position: -48px -96px; }
|
||||
.ui-icon-note { background-position: -64px -96px; }
|
||||
.ui-icon-mail-closed { background-position: -80px -96px; }
|
||||
.ui-icon-mail-open { background-position: -96px -96px; }
|
||||
.ui-icon-suitcase { background-position: -112px -96px; }
|
||||
.ui-icon-comment { background-position: -128px -96px; }
|
||||
.ui-icon-person { background-position: -144px -96px; }
|
||||
.ui-icon-print { background-position: -160px -96px; }
|
||||
.ui-icon-trash { background-position: -176px -96px; }
|
||||
.ui-icon-locked { background-position: -192px -96px; }
|
||||
.ui-icon-unlocked { background-position: -208px -96px; }
|
||||
.ui-icon-bookmark { background-position: -224px -96px; }
|
||||
.ui-icon-tag { background-position: -240px -96px; }
|
||||
.ui-icon-home { background-position: 0 -112px; }
|
||||
.ui-icon-flag { background-position: -16px -112px; }
|
||||
.ui-icon-calendar { background-position: -32px -112px; }
|
||||
.ui-icon-cart { background-position: -48px -112px; }
|
||||
.ui-icon-pencil { background-position: -64px -112px; }
|
||||
.ui-icon-clock { background-position: -80px -112px; }
|
||||
.ui-icon-disk { background-position: -96px -112px; }
|
||||
.ui-icon-calculator { background-position: -112px -112px; }
|
||||
.ui-icon-zoomin { background-position: -128px -112px; }
|
||||
.ui-icon-zoomout { background-position: -144px -112px; }
|
||||
.ui-icon-search { background-position: -160px -112px; }
|
||||
.ui-icon-wrench { background-position: -176px -112px; }
|
||||
.ui-icon-gear { background-position: -192px -112px; }
|
||||
.ui-icon-heart { background-position: -208px -112px; }
|
||||
.ui-icon-star { background-position: -224px -112px; }
|
||||
.ui-icon-link { background-position: -240px -112px; }
|
||||
.ui-icon-cancel { background-position: 0 -128px; }
|
||||
.ui-icon-plus { background-position: -16px -128px; }
|
||||
.ui-icon-plusthick { background-position: -32px -128px; }
|
||||
.ui-icon-minus { background-position: -48px -128px; }
|
||||
.ui-icon-minusthick { background-position: -64px -128px; }
|
||||
.ui-icon-close { background-position: -80px -128px; }
|
||||
.ui-icon-closethick { background-position: -96px -128px; }
|
||||
.ui-icon-key { background-position: -112px -128px; }
|
||||
.ui-icon-lightbulb { background-position: -128px -128px; }
|
||||
.ui-icon-scissors { background-position: -144px -128px; }
|
||||
.ui-icon-clipboard { background-position: -160px -128px; }
|
||||
.ui-icon-copy { background-position: -176px -128px; }
|
||||
.ui-icon-contact { background-position: -192px -128px; }
|
||||
.ui-icon-image { background-position: -208px -128px; }
|
||||
.ui-icon-video { background-position: -224px -128px; }
|
||||
.ui-icon-script { background-position: -240px -128px; }
|
||||
.ui-icon-alert { background-position: 0 -144px; }
|
||||
.ui-icon-info { background-position: -16px -144px; }
|
||||
.ui-icon-notice { background-position: -32px -144px; }
|
||||
.ui-icon-help { background-position: -48px -144px; }
|
||||
.ui-icon-check { background-position: -64px -144px; }
|
||||
.ui-icon-bullet { background-position: -80px -144px; }
|
||||
.ui-icon-radio-off { background-position: -96px -144px; }
|
||||
.ui-icon-radio-on { background-position: -112px -144px; }
|
||||
.ui-icon-pin-w { background-position: -128px -144px; }
|
||||
.ui-icon-pin-s { background-position: -144px -144px; }
|
||||
.ui-icon-play { background-position: 0 -160px; }
|
||||
.ui-icon-pause { background-position: -16px -160px; }
|
||||
.ui-icon-seek-next { background-position: -32px -160px; }
|
||||
.ui-icon-seek-prev { background-position: -48px -160px; }
|
||||
.ui-icon-seek-end { background-position: -64px -160px; }
|
||||
.ui-icon-seek-start { background-position: -80px -160px; }
|
||||
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
|
||||
.ui-icon-seek-first { background-position: -80px -160px; }
|
||||
.ui-icon-stop { background-position: -96px -160px; }
|
||||
.ui-icon-eject { background-position: -112px -160px; }
|
||||
.ui-icon-volume-off { background-position: -128px -160px; }
|
||||
.ui-icon-volume-on { background-position: -144px -160px; }
|
||||
.ui-icon-power { background-position: 0 -176px; }
|
||||
.ui-icon-signal-diag { background-position: -16px -176px; }
|
||||
.ui-icon-signal { background-position: -32px -176px; }
|
||||
.ui-icon-battery-0 { background-position: -48px -176px; }
|
||||
.ui-icon-battery-1 { background-position: -64px -176px; }
|
||||
.ui-icon-battery-2 { background-position: -80px -176px; }
|
||||
.ui-icon-battery-3 { background-position: -96px -176px; }
|
||||
.ui-icon-circle-plus { background-position: 0 -192px; }
|
||||
.ui-icon-circle-minus { background-position: -16px -192px; }
|
||||
.ui-icon-circle-close { background-position: -32px -192px; }
|
||||
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
|
||||
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
|
||||
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
|
||||
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
|
||||
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
|
||||
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
|
||||
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
|
||||
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
|
||||
.ui-icon-circle-zoomin { background-position: -176px -192px; }
|
||||
.ui-icon-circle-zoomout { background-position: -192px -192px; }
|
||||
.ui-icon-circle-check { background-position: -208px -192px; }
|
||||
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
|
||||
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
|
||||
.ui-icon-circlesmall-close { background-position: -32px -208px; }
|
||||
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
|
||||
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
|
||||
.ui-icon-squaresmall-close { background-position: -80px -208px; }
|
||||
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
|
||||
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
||||
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
|
||||
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
|
||||
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
||||
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Corner radius */
|
||||
.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
|
||||
.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/*!
|
||||
* jQuery UI Resizable 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Resizable#theming
|
||||
*/
|
||||
.ui-resizable { position: relative;}
|
||||
.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; }
|
||||
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
|
||||
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
|
||||
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
|
||||
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
|
||||
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
|
||||
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
|
||||
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*!
|
||||
* jQuery UI Selectable 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Selectable#theming
|
||||
*/
|
||||
.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
|
||||
/*!
|
||||
* jQuery UI Accordion 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Accordion#theming
|
||||
*/
|
||||
/* IE/Win - Fix animation bug - #4615 */
|
||||
.ui-accordion { width: 100%; }
|
||||
.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
|
||||
.ui-accordion .ui-accordion-li-fix { display: inline; }
|
||||
.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
|
||||
.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
|
||||
.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
|
||||
.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
|
||||
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
|
||||
.ui-accordion .ui-accordion-content-active { display: block; }
|
||||
/*!
|
||||
* jQuery UI Autocomplete 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Autocomplete#theming
|
||||
*/
|
||||
.ui-autocomplete { position: absolute; cursor: default; }
|
||||
|
||||
/* workarounds */
|
||||
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
|
||||
|
||||
/*
|
||||
* jQuery UI Menu 1.8.22
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Menu#theming
|
||||
*/
|
||||
.ui-menu {
|
||||
list-style:none;
|
||||
padding: 2px;
|
||||
margin: 0;
|
||||
display:block;
|
||||
float: left;
|
||||
}
|
||||
.ui-menu .ui-menu {
|
||||
margin-top: -3px;
|
||||
}
|
||||
.ui-menu .ui-menu-item {
|
||||
margin:0;
|
||||
padding: 0;
|
||||
zoom: 1;
|
||||
float: left;
|
||||
clear: left;
|
||||
width: 100%;
|
||||
}
|
||||
.ui-menu .ui-menu-item a {
|
||||
text-decoration:none;
|
||||
display:block;
|
||||
padding:.2em .4em;
|
||||
line-height:1.5;
|
||||
zoom:1;
|
||||
}
|
||||
.ui-menu .ui-menu-item a.ui-state-hover,
|
||||
.ui-menu .ui-menu-item a.ui-state-active {
|
||||
font-weight: normal;
|
||||
margin: -1px;
|
||||
}
|
||||
/*!
|
||||
* jQuery UI Button 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Button#theming
|
||||
*/
|
||||
.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
|
||||
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
|
||||
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
|
||||
.ui-button-icons-only { width: 3.4em; }
|
||||
button.ui-button-icons-only { width: 3.7em; }
|
||||
|
||||
/*button text element */
|
||||
.ui-button .ui-button-text { display: block; line-height: 1.4; }
|
||||
.ui-button-text-only .ui-button-text { padding: .4em 1em; }
|
||||
.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
|
||||
.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
|
||||
.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
|
||||
.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
|
||||
/* no icon support for input elements, provide padding by default */
|
||||
input.ui-button { padding: .4em 1em; }
|
||||
|
||||
/*button icon element(s) */
|
||||
.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
|
||||
.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
|
||||
.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
|
||||
.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
||||
.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
||||
|
||||
/*button sets*/
|
||||
.ui-buttonset { margin-right: 7px; }
|
||||
.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
|
||||
|
||||
/* workarounds */
|
||||
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
|
||||
/*!
|
||||
* jQuery UI Dialog 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Dialog#theming
|
||||
*/
|
||||
.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
|
||||
.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
|
||||
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
|
||||
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
|
||||
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
|
||||
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
|
||||
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
|
||||
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
|
||||
.ui-draggable .ui-dialog-titlebar { cursor: move; }
|
||||
/*!
|
||||
* jQuery UI Slider 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Slider#theming
|
||||
*/
|
||||
.ui-slider { position: relative; text-align: left; }
|
||||
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
|
||||
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
|
||||
|
||||
.ui-slider-horizontal { height: .8em; }
|
||||
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
|
||||
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
|
||||
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
|
||||
.ui-slider-horizontal .ui-slider-range-max { right: 0; }
|
||||
|
||||
.ui-slider-vertical { width: .8em; height: 100px; }
|
||||
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
|
||||
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
|
||||
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
|
||||
.ui-slider-vertical .ui-slider-range-max { top: 0; }/*!
|
||||
* jQuery UI Tabs 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Tabs#theming
|
||||
*/
|
||||
.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
|
||||
.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
|
||||
.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
|
||||
.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
|
||||
.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
|
||||
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
|
||||
.ui-tabs .ui-tabs-hide { display: none !important; }
|
||||
/*!
|
||||
* jQuery UI Datepicker 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Datepicker#theming
|
||||
*/
|
||||
.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
|
||||
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
|
||||
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
|
||||
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
|
||||
.ui-datepicker .ui-datepicker-prev { left:2px; }
|
||||
.ui-datepicker .ui-datepicker-next { right:2px; }
|
||||
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
|
||||
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
|
||||
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
|
||||
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
|
||||
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
|
||||
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
|
||||
.ui-datepicker select.ui-datepicker-month,
|
||||
.ui-datepicker select.ui-datepicker-year { width: 49%;}
|
||||
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
|
||||
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
|
||||
.ui-datepicker td { border: 0; padding: 1px; }
|
||||
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
|
||||
|
||||
/* with multiple calendars */
|
||||
.ui-datepicker.ui-datepicker-multi { width:auto; }
|
||||
.ui-datepicker-multi .ui-datepicker-group { float:left; }
|
||||
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
|
||||
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
|
||||
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
|
||||
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
|
||||
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
|
||||
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
|
||||
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
|
||||
.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
|
||||
|
||||
/* RTL support */
|
||||
.ui-datepicker-rtl { direction: rtl; }
|
||||
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
||||
|
||||
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
|
||||
.ui-datepicker-cover {
|
||||
position: absolute; /*must have*/
|
||||
z-index: -1; /*must have*/
|
||||
filter: mask(); /*must have*/
|
||||
top: -4px; /*must have*/
|
||||
left: -4px; /*must have*/
|
||||
width: 200px; /*must have*/
|
||||
height: 200px; /*must have*/
|
||||
}/*!
|
||||
* jQuery UI Progressbar 1.8.22
|
||||
*
|
||||
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Progressbar#theming
|
||||
*/
|
||||
.ui-progressbar { height:2em; text-align: left; overflow: hidden; }
|
||||
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
|
381
labs/html5-embed/public/css/layout.css
Executable file
@ -0,0 +1,381 @@
|
||||
body { width: 100%; height: 100%; overflow: hidden; }
|
||||
html { width: 100%; height: 100%; }
|
||||
|
||||
body { font: 12px Arial, Helvetica, "Helvetica Neue", sans-serif }
|
||||
|
||||
#layout {
|
||||
position: relative;
|
||||
background: #f00;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#presentation {
|
||||
position: absolute;
|
||||
background: #aaa;
|
||||
top: 0;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
bottom: 69px;
|
||||
-moz-transition: right 1s, left 1s;
|
||||
-webkit-transition: right 1s, left 1s;
|
||||
z-index: 1000;
|
||||
border-right: 1px solid #999;
|
||||
border-left: 1px solid #999;
|
||||
}
|
||||
|
||||
#users {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 65px;
|
||||
width: 200px;
|
||||
background: #f7f7f7;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#chat {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 65px;
|
||||
width: 300px;
|
||||
background: #f7f7f7;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.chat-enabled > #presentation {
|
||||
right: 300px;
|
||||
}
|
||||
.users-enabled > #presentation {
|
||||
left: 200px;
|
||||
}
|
||||
|
||||
#presentation object {
|
||||
display: block;
|
||||
position: absolute;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#navbar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 67px;
|
||||
background: #333;
|
||||
background: -moz-linear-gradient(top, #494c56, #42444c);
|
||||
background: -webkit-linear-gradient(top, #494c56, #42444c);
|
||||
border-top: 1px solid #2f3138;
|
||||
border-bottom: 1px solid #2f3138;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.navbar-btngroup {
|
||||
border-left: 1px solid #222;
|
||||
border-right: 1px solid #555;
|
||||
display: inline-block;
|
||||
font-size: 0;
|
||||
}
|
||||
.navbar-btngroup.pull-right {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
border-right: none;
|
||||
}
|
||||
.navbar-btn {
|
||||
display: inline-block;
|
||||
width: 74px;
|
||||
height: 67px;
|
||||
padding: 38px 3px 5px 3px;
|
||||
background: -moz-linear-gradient(top, #494c56, #42444c);
|
||||
background: -webkit-linear-gradient(top, #494c56, #42444c);
|
||||
border-top: none;
|
||||
border-left: 1px solid #62646c;
|
||||
border-right: 1px solid #2f3138;
|
||||
border-bottom: none;
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 2px rgba(0,0,0,0.5);
|
||||
text-transform: uppercase;
|
||||
font-size: 9px;
|
||||
line-height: 24px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.navbar-btn:hover {
|
||||
background: #6d6f77;
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-btn:active, .navbar-btn.active {
|
||||
background: #33343b;
|
||||
color: #999a9d;
|
||||
border-right: 1px solid #33343b;
|
||||
border-left: 1px solid #33343b;
|
||||
}
|
||||
.navbar-btn.active:hover {
|
||||
background-image: -moz-linear-gradient(top, #58ade3, #58ade3), -moz-linear-gradient(top, #6d6f77, #6d6f77);
|
||||
background-image: -webkit-linear-gradient(top, #58ade3, #58ade3), -webkit-linear-gradient(top, #6d6f77, #6d6f77);
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-btn.active, .navbar-btn.active:active {
|
||||
background-image: -moz-linear-gradient(top, #58ade3, #58ade3), -moz-linear-gradient(top, #33343b, #33343b);
|
||||
background-image: -webkit-linear-gradient(top, #58ade3, #58ade3), -webkit-linear-gradient(top, #33343b, #33343b);
|
||||
background-size: 72px 3px, 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 63px, 0 0;
|
||||
color: #999a9d;
|
||||
}
|
||||
|
||||
.navbar-btn .notification {
|
||||
display: block;
|
||||
position: absolute;
|
||||
background: #a72424;
|
||||
background-image -moz-linear-gradient(top, #a72424, #8f1f1f);
|
||||
background-image -webkit-linear-gradient(top, #a72424, #8f1f1f);
|
||||
text-shadow: 0 -1px rgba(0,0,0,0.5);
|
||||
border-top: 1px solid #cc7e7e;
|
||||
top: 11px;
|
||||
right: 17px;
|
||||
padding: 1px 4px;
|
||||
font-size: 8px;
|
||||
border-radius: 2px;
|
||||
line-height: 12px;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.navbar-btn i {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
font-size: 32px;
|
||||
line-height: 32px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
}
|
||||
button::-moz-focus-inner, input::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
button:focus, textarea:focus, input:focus {
|
||||
box-shadow: 0 0 4px rgba(88,173,227,0.5) inset;
|
||||
outline: none;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#chat-entry {
|
||||
position: absolute;
|
||||
bottom: 16px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
#chat-entry > textarea {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 16px;
|
||||
font-family: sans-serif;
|
||||
font-size: 12px;
|
||||
width: 197px;
|
||||
height: 56px;
|
||||
resize: none;
|
||||
background: #fff;
|
||||
border: 1px solid #ccc;
|
||||
margin: 0;
|
||||
padding: 3px;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
#chat-entry > button {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 16px;
|
||||
width: 63px;
|
||||
height: 64px;
|
||||
margin: 0;
|
||||
border: 1px solid #ccc;
|
||||
border-left: none;
|
||||
border-radius: 0 4px 4px 0;
|
||||
background: -moz-linear-gradient(top, #fff, #ddd);
|
||||
background: -webkit-linear-gradient(top, #fff, #ddd);
|
||||
}
|
||||
#chat-entry > button:active {
|
||||
background: #ddd;
|
||||
}
|
||||
#chat_messages {
|
||||
position: absolute;
|
||||
overflow: auto;
|
||||
top: 33px;
|
||||
bottom: 96px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #fff;
|
||||
padding: 8px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#users > h3, #chat > h3 {
|
||||
background: -moz-linear-gradient(top, #fff, #ddd);
|
||||
background: -webkit-linear-gradient(top, #fff, #ddd);
|
||||
font-size: 12px;
|
||||
line-height: 32px;
|
||||
font-weight: bold;
|
||||
padding: 0 16px;
|
||||
text-transform: uppercase;
|
||||
color: #666;
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
|
||||
/* ryans stuff */
|
||||
/*
|
||||
#chat_messages {
|
||||
float: right;
|
||||
width: 300px;
|
||||
height: 400px;
|
||||
border: 1px solid red;
|
||||
overflow:scroll;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
*/
|
||||
#chat_input_box {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
#slide {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 805px;
|
||||
height: 610px;
|
||||
overflow:hidden; /* so they don't overlap */
|
||||
}
|
||||
|
||||
.textinput {
|
||||
font-family: Arial;
|
||||
font-size:14px; /* keep in pixels*/
|
||||
resize:none;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.user {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 0 8px;
|
||||
}
|
||||
.user:nth-child(even) {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.user:before {
|
||||
content: "\f007";
|
||||
font-family: FontAwesome;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.presenter:before {
|
||||
content: "\f0d0";
|
||||
}
|
||||
|
||||
.clickable {
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.selected {
|
||||
background: #007fff;
|
||||
color: #FFF;
|
||||
background: -moz-linear-gradient(top, #007fff, #005fdf);
|
||||
background: -webkit-linear-gradient(top, #007fff, #005fdf);
|
||||
}
|
||||
|
||||
#slideAndControls {
|
||||
/*float:left;*/
|
||||
}
|
||||
|
||||
#chat_input {
|
||||
clear: both;
|
||||
display: block;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#uploadcontrols {
|
||||
|
||||
}
|
||||
|
||||
#chat_title {
|
||||
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
#listUsers {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#current_users {
|
||||
position: absolute;
|
||||
top: 33px;
|
||||
bottom: 65px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
#switchPresenter {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 32px;
|
||||
border-top: 1px solid #ccc;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
#switchPresenter > input {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
background: -moz-linear-gradient(top, #fff, #ddd);
|
||||
background: -webkit-linear-gradient(top, #fff, #ddd);
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
#ChatAndControls {
|
||||
float:right;
|
||||
}
|
||||
|
||||
#logout {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#send_chat {
|
||||
float:right;
|
||||
}
|
||||
|
||||
#imagecontrols form {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#thickness {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
#colourText {
|
||||
width: 50px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
#colourView {
|
||||
margin-left: 5px;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.canvas {
|
||||
border: 1px solid blue;
|
||||
position: absolute;
|
||||
}
|
48
labs/html5-embed/public/css/reset.css
Executable file
@ -0,0 +1,48 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
112
labs/html5-embed/public/css/style.css
Executable file
@ -0,0 +1,112 @@
|
||||
body {
|
||||
padding: 10px;
|
||||
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #00B7FF;
|
||||
}
|
||||
|
||||
#chat_messages {
|
||||
float: right;
|
||||
width: 300px;
|
||||
height: 400px;
|
||||
border: 1px solid red;
|
||||
overflow:scroll;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
#chat_input_box {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
#slide {
|
||||
width: 805px;
|
||||
height: 610px;
|
||||
border: 1px solid black;
|
||||
overflow:hidden; /* so they don't overlap */
|
||||
}
|
||||
|
||||
.textinput {
|
||||
font-family: Arial;
|
||||
font-size:14px; /* keep in pixels*/
|
||||
resize:none;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.presenter {
|
||||
border: 3px solid red;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.selected {
|
||||
background-color:#000;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
#slideAndControls {
|
||||
float:left;
|
||||
}
|
||||
|
||||
#chat_input {
|
||||
clear: both;
|
||||
display: block;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#uploadcontrols {
|
||||
|
||||
}
|
||||
|
||||
#chat_title {
|
||||
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
#listUsers {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#current_users {
|
||||
width: 200px;
|
||||
height: 300px;
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
#ChatAndControls {
|
||||
float:right;
|
||||
}
|
||||
|
||||
#logout {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#send_chat {
|
||||
float:right;
|
||||
}
|
||||
|
||||
#imagecontrols form {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#thickness {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
#colourText {
|
||||
width: 50px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
#colourView {
|
||||
margin-left: 5px;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.canvas {
|
||||
border: 1px solid blue;
|
||||
position: absolute;
|
||||
}
|
BIN
labs/html5-embed/public/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
labs/html5-embed/public/font/fontawesome-webfont.eot
Executable file
255
labs/html5-embed/public/font/fontawesome-webfont.svg
Executable file
@ -0,0 +1,255 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata></metadata>
|
||||
<defs>
|
||||
<font id="FontAwesomeRegular" horiz-adv-x="1843" >
|
||||
<font-face units-per-em="2048" ascent="1536" descent="-512" />
|
||||
<missing-glyph horiz-adv-x="512" />
|
||||
<glyph horiz-adv-x="0" />
|
||||
<glyph horiz-adv-x="0" />
|
||||
<glyph unicode="
" horiz-adv-x="512" />
|
||||
<glyph unicode=" " horiz-adv-x="512" />
|
||||
<glyph unicode="	" horiz-adv-x="512" />
|
||||
<glyph unicode=" " horiz-adv-x="512" />
|
||||
<glyph unicode="o" horiz-adv-x="1591" />
|
||||
<glyph unicode="¨" horiz-adv-x="2048" />
|
||||
<glyph unicode="©" horiz-adv-x="2048" />
|
||||
<glyph unicode="®" horiz-adv-x="2048" />
|
||||
<glyph unicode="´" horiz-adv-x="2048" />
|
||||
<glyph unicode="Æ" horiz-adv-x="2048" />
|
||||
<glyph unicode="Í" horiz-adv-x="2048" />
|
||||
<glyph unicode=" " horiz-adv-x="784" />
|
||||
<glyph unicode=" " horiz-adv-x="1569" />
|
||||
<glyph unicode=" " horiz-adv-x="784" />
|
||||
<glyph unicode=" " horiz-adv-x="1569" />
|
||||
<glyph unicode=" " horiz-adv-x="523" />
|
||||
<glyph unicode=" " horiz-adv-x="392" />
|
||||
<glyph unicode=" " horiz-adv-x="261" />
|
||||
<glyph unicode=" " horiz-adv-x="261" />
|
||||
<glyph unicode=" " horiz-adv-x="196" />
|
||||
<glyph unicode=" " horiz-adv-x="313" />
|
||||
<glyph unicode=" " horiz-adv-x="87" />
|
||||
<glyph unicode=" " horiz-adv-x="313" />
|
||||
<glyph unicode="›" horiz-adv-x="2048" />
|
||||
<glyph unicode=" " horiz-adv-x="392" />
|
||||
<glyph unicode="™" horiz-adv-x="2048" />
|
||||
<glyph unicode="∞" horiz-adv-x="2048" />
|
||||
<glyph unicode="" horiz-adv-x="1024" d="M0 0z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M6 1489q20 47 70 47h1382q51 0 72 -47q20 -47 -17 -84l-610 -610v-641h248q33 0 55.5 -22.5t22.5 -53.5q0 -33 -22.5 -55.5t-55.5 -22.5h-768q-31 0 -53.5 22.5t-22.5 55.5q0 31 22.5 53.5t53.5 22.5h250v641l-610 610q-37 37 -17 84z" />
|
||||
<glyph unicode="" horiz-adv-x="1488" d="M0 213q0 57 27.5 103t72.5 77t98.5 47.5t106.5 16.5q25 0 50.5 -4t50.5 -11v779q0 27 16 48t43 29q23 6 99.5 29t178 52.5t215 62.5t211 60.5t164 46t74.5 18.5q35 0 58.5 -23.5t23.5 -58.5v-1028q0 -59 -27.5 -104.5t-73 -76t-99.5 -47t-105 -16.5t-105.5 16.5t-98.5 47 t-71.5 75.5t-27.5 105q0 57 27.5 103t71.5 77t98.5 47t105.5 16q27 0 52.5 -4t49.5 -10v537l-678 -195v-815q0 -59 -27.5 -104.5t-71.5 -76t-98.5 -47t-105.5 -16.5q-53 0 -106.5 16.5t-98.5 47t-72.5 76t-27.5 104.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 901q0 137 52 258t143.5 212t212 143.5t258.5 52.5q137 0 257.5 -52.5t212 -143.5t143.5 -212t52 -258q0 -98 -28.5 -191.5t-81.5 -174.5l358 -359q18 -18 18 -47q0 -16 -18 -43t-45 -53.5t-53.5 -45t-42.5 -18.5q-29 0 -47 19l-359 358q-82 -53 -175 -81.5t-191 -28.5 q-137 0 -258 52t-212.5 143t-143.5 212t-52 258zM266 901q0 -84 32 -156.5t86 -126t127 -85t155 -31.5t154.5 31.5t126.5 85t86 126t32 156.5q0 82 -32 154.5t-86 127t-126.5 86t-154.5 31.5t-155 -31.5t-127 -86t-86 -127t-32 -154.5zM414 901q0 51 19.5 97t54 81t80 54.5 t98.5 19.5q20 0 34.5 -14.5t14.5 -36.5q0 -20 -14.5 -34.5t-34.5 -14.5q-63 0 -107.5 -44t-44.5 -108q0 -20 -14.5 -34.5t-34.5 -14.5q-23 0 -37 14.5t-14 34.5z" />
|
||||
<glyph unicode="" d="M0 115v1306q0 47 34 81t81 34h1614q47 0 80.5 -34t33.5 -81v-1306q0 -47 -33.5 -81t-80.5 -34h-1614q-47 0 -81 34t-34 81zM154 154h1536v852q-31 -31 -58 -50q-106 -80 -212.5 -159.5t-211.5 -163.5q-61 -49 -131.5 -94t-156.5 -45q-82 0 -153 45t-132 94 q-104 84 -211 164t-213 159q-27 18 -57 50v-852zM154 1317q0 -31 14 -65.5t35.5 -66.5t47 -59.5t50.5 -46.5q100 -76 199.5 -150.5t199.5 -152.5q20 -16 48 -37.5t58 -42t59.5 -35t54.5 -14.5h2h2q25 0 54.5 14.5t59 35t57 42t48.5 37.5q100 78 199.5 153t199.5 150 q25 18 50.5 46t47 60t36 66.5t14.5 65.5v65h-1536v-65z" />
|
||||
<glyph unicode="" horiz-adv-x="1802" d="M0 1073q0 113 34 205t97.5 155.5t153.5 98.5t202 35q59 0 117 -18.5t110 -48.5t99 -68.5t88 -77.5q39 39 87 77.5t100.5 68.5t109 48.5t115.5 18.5q113 0 204 -35t154.5 -98.5t97 -155.5t33.5 -205q0 -66 -18.5 -130t-51 -124.5t-74.5 -115t-87 -99.5l-615 -612 q-23 -23 -55 -23q-31 0 -57 23l-615 614q-45 45 -87 99.5t-73.5 114t-50 124t-18.5 129.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1675" d="M1 959.5q9 27.5 54 33.5l506 74l227 459q20 41 49 41t50 -41l227 -459l506 -74q45 -6 54 -33.5t-23 -60.5l-367 -356l86 -504q8 -45 -15.5 -62.5t-64.5 5.5l-452 237l-453 -237q-41 -23 -64.5 -5.5t-15.5 62.5l86 504l-364 356q-35 33 -26 60.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1675" d="M0 948q0 23 18.5 32t36.5 13l506 74l227 459q6 14 20 27.5t30 13.5q18 0 30.5 -13.5t18.5 -27.5l227 -459l506 -74q18 -4 36.5 -13t18.5 -32q0 -14 -7 -26.5t-17 -22.5l-367 -356l86 -504q0 -4 1 -9t1 -12q0 -20 -9 -34.5t-32 -14.5t-41 13l-452 237l-453 -237 q-18 -12 -39 -13q-23 0 -33 14.5t-10 34.5q0 6 1 11.5t1 9.5l86 504l-364 356q-10 10 -18.5 22.5t-8.5 26.5zM289 866l274 -268l-65 -377l340 178l340 -178l-66 377l274 268l-378 56l-170 344l-170 -344z" />
|
||||
<glyph unicode="" horiz-adv-x="1566" d="M0 57v387q0 37 18.5 82t48 86t65.5 74t71 43q18 6 66 13.5t102.5 14.5t104.5 13t77 10q-92 59 -144.5 153.5t-52.5 205.5q0 88 34 165.5t91.5 136t135 92.5t165.5 34t166 -34t136.5 -92.5t92 -136t33.5 -165.5q0 -109 -52 -204.5t-144 -154.5q27 -4 77 -10t104 -13 t101 -14.5t68 -13.5q35 -10 70.5 -42t65.5 -74t48.5 -87t18.5 -82v-387q-10 -4 -22.5 -14t-27 -19.5t-27.5 -16.5t-22 -7h-1370q-35 0 -53 21.5t-45 35.5z" />
|
||||
<glyph unicode="" d="M0 115v1306q0 47 34 81t81 34h1614q47 0 80.5 -34t33.5 -81v-1306q0 -47 -33.5 -81t-80.5 -34h-1614q-47 0 -81 34t-34 81zM115 154q0 -16 11 -27.5t28 -11.5h153q16 0 27.5 11t11.5 28v153q0 16 -11 27.5t-28 11.5h-153q-16 0 -27.5 -11t-11.5 -28v-153zM115 512 q0 -16 11 -27.5t28 -11.5h153q16 0 27.5 11.5t11.5 27.5v154q0 16 -11 27.5t-28 11.5h-153q-16 0 -27.5 -11.5t-11.5 -27.5v-154zM115 870q0 -16 11 -27.5t28 -11.5h153q16 0 27.5 11.5t11.5 27.5v154q0 16 -11 27.5t-28 11.5h-153q-16 0 -27.5 -11.5t-11.5 -27.5v-154z M115 1229q0 -16 11 -27.5t28 -11.5h153q16 0 27.5 11t11.5 28v153q0 16 -11 27.5t-28 11.5h-153q-16 0 -27.5 -11t-11.5 -28v-153zM461 154q0 -16 11 -27.5t28 -11.5h843q16 0 27.5 11t11.5 28v512q0 16 -11 27.5t-28 11.5h-843q-16 0 -27.5 -11.5t-11.5 -27.5v-512z M461 870q0 -16 11 -27.5t28 -11.5h843q16 0 27.5 11.5t11.5 27.5v512q0 16 -11 27.5t-28 11.5h-843q-16 0 -27.5 -11t-11.5 -28v-512zM1497 154q0 -16 11.5 -27.5t27.5 -11.5h154q16 0 27.5 11t11.5 28v153q0 16 -11.5 27.5t-27.5 11.5h-154q-16 0 -27.5 -11t-11.5 -28v-153 zM1497 512q0 -16 11.5 -27.5t27.5 -11.5h154q16 0 27.5 11.5t11.5 27.5v154q0 16 -11.5 27.5t-27.5 11.5h-154q-16 0 -27.5 -11.5t-11.5 -27.5v-154zM1497 870q0 -16 11.5 -27.5t27.5 -11.5h154q16 0 27.5 11.5t11.5 27.5v154q0 16 -11.5 27.5t-27.5 11.5h-154 q-16 0 -27.5 -11.5t-11.5 -27.5v-154zM1497 1229q0 -16 11.5 -27.5t27.5 -11.5h154q16 0 27.5 11t11.5 28v153q0 16 -11.5 27.5t-27.5 11.5h-154q-16 0 -27.5 -11t-11.5 -28v-153z" />
|
||||
<glyph unicode="" d="M0 78v536q0 33 22.5 55.5t55.5 22.5h690q33 0 55.5 -22.5t22.5 -55.5v-536q0 -33 -22.5 -55.5t-55.5 -22.5h-690q-33 0 -55.5 22.5t-22.5 55.5zM0 922v538q0 31 22.5 53.5t55.5 22.5h690q33 0 55.5 -22.5t22.5 -53.5v-538q0 -33 -22.5 -54.5t-55.5 -21.5h-690 q-33 0 -55.5 21.5t-22.5 54.5zM999 78v536q0 33 21.5 55.5t54.5 22.5h692q31 0 53.5 -22.5t22.5 -55.5v-536q0 -33 -22.5 -55.5t-53.5 -22.5h-692q-33 0 -54.5 22.5t-21.5 55.5zM999 922v538q0 31 21.5 53.5t54.5 22.5h692q31 0 53.5 -22.5t22.5 -53.5v-538 q0 -33 -22.5 -54.5t-53.5 -21.5h-692q-33 0 -54.5 21.5t-21.5 54.5z" />
|
||||
<glyph unicode="" d="M0 78v270q0 33 22.5 54.5t55.5 21.5h358q31 0 53.5 -21.5t22.5 -54.5v-270q0 -33 -22.5 -55.5t-53.5 -22.5h-358q-33 0 -55.5 22.5t-22.5 55.5zM0 655v226q0 33 22.5 54t55.5 21h358q31 0 53.5 -21.5t22.5 -53.5v-226q0 -33 -22.5 -55t-53.5 -22h-358q-33 0 -55.5 22.5 t-22.5 54.5zM0 1188v272q0 31 22.5 53.5t55.5 22.5h358q31 0 53.5 -22.5t22.5 -53.5v-272q0 -33 -22.5 -55.5t-53.5 -22.5h-358q-33 0 -55.5 22.5t-22.5 55.5zM666 78v270q0 33 22.5 54.5t54.5 21.5h359q31 0 53.5 -21.5t22.5 -54.5v-270q0 -33 -22.5 -55.5t-53.5 -22.5 h-359q-33 0 -55 22.5t-22 55.5zM666 655v226q0 33 22.5 54t54.5 21h359q31 0 53.5 -21.5t22.5 -53.5v-226q0 -33 -22.5 -55t-53.5 -22h-359q-33 0 -55 22.5t-22 54.5zM666 1188v272q0 31 22.5 53.5t54.5 22.5h359q31 0 53.5 -22.5t22.5 -53.5v-272q0 -33 -22.5 -55.5 t-53.5 -22.5h-359q-33 0 -55 22.5t-22 55.5zM1331 78v270q0 33 22.5 54.5t55.5 21.5h358q31 0 53.5 -21.5t22.5 -54.5v-270q0 -33 -22.5 -55.5t-53.5 -22.5h-358q-33 0 -55.5 22.5t-22.5 55.5zM1331 655v226q0 33 22.5 54t55.5 21h358q31 0 53.5 -21.5t22.5 -53.5v-226 q0 -33 -22.5 -55t-53.5 -22h-358q-33 0 -55.5 22.5t-22.5 54.5zM1331 1188v272q0 31 22.5 53.5t55.5 22.5h358q31 0 53.5 -22.5t22.5 -53.5v-272q0 -33 -22.5 -55.5t-53.5 -22.5h-358q-33 0 -55.5 22.5t-22.5 55.5z" />
|
||||
<glyph unicode="" d="M0 78v270q0 33 22.5 54.5t55.5 21.5h297q31 0 53.5 -21.5t22.5 -54.5v-270q0 -33 -22.5 -55.5t-53.5 -22.5h-297q-33 0 -55.5 22.5t-22.5 55.5zM0 655v226q0 33 22.5 54t55.5 21h297q31 0 53.5 -21.5t22.5 -53.5v-226q0 -33 -22.5 -55t-53.5 -22h-297q-33 0 -55.5 22.5 t-22.5 54.5zM0 1188v272q0 31 22.5 53.5t55.5 22.5h297q31 0 53.5 -22.5t22.5 -53.5v-272q0 -33 -22.5 -55.5t-53.5 -22.5h-297q-33 0 -55.5 22.5t-22.5 55.5zM604 78v270q0 33 22.5 54.5t55.5 21.5h1085q31 0 53.5 -21.5t22.5 -54.5v-270q0 -33 -22.5 -55.5t-53.5 -22.5 h-1085q-33 0 -55.5 22.5t-22.5 55.5zM604 655v226q0 33 22.5 54t55.5 21h1085q31 0 53.5 -21.5t22.5 -53.5v-226q0 -33 -22.5 -55t-53.5 -22h-1085q-33 0 -55.5 22.5t-22.5 54.5zM604 1188v272q0 31 22.5 53.5t55.5 22.5h1085q31 0 53.5 -22.5t22.5 -53.5v-272 q0 -33 -22.5 -55.5t-53.5 -22.5h-1085q-33 0 -55.5 22.5t-22.5 55.5z" />
|
||||
<glyph unicode="" d="M0 732.5q0 33.5 23 55.5l174 175q23 23 56.5 22.5t55.5 -22.5l365 -365q23 -23 56.5 -23t55.5 23l746 745q23 23 56.5 23t56.5 -23l174 -174q23 -23 22.5 -56.5t-22.5 -55.5l-910 -910q-23 -23 -62.5 -39t-72.5 -16h-88q-35 0 -75 16.5t-62 38.5l-526 529 q-23 23 -23 56.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 192.5q0 38.5 29 67.5l508 510l-508 500q-29 29 -29 67.5t29 67.5l100 100q29 29 68 29t67 -29l504 -504l504 504q29 29 67.5 29t67.5 -29l100 -100q29 -29 29 -68t-29 -67l-508 -510l508 -500q29 -29 29 -66.5t-29 -66.5l-100 -102q-29 -29 -68 -29t-67 29l-504 505 l-506 -505q-29 -29 -66.5 -29t-66.5 29l-100 100q-29 29 -29 67.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 901q0 137 52 258t143.5 212t212 143.5t258.5 52.5q137 0 259 -52.5t212 -143.5t142 -212t52 -258q0 -102 -28.5 -195.5t-81.5 -170.5l358 -359q18 -18 18 -46t-18 -48l-94 -94q-20 -18 -48 -18.5t-46 18.5l-359 358q-78 -53 -171 -81.5t-195 -28.5q-137 0 -258 52 t-212.5 142t-143.5 211t-52 260zM266 901q0 -84 32 -156.5t86 -126t127 -85t155 -31.5t155.5 31.5t126.5 85t85 126t32 156.5q0 82 -32 154.5t-85 127t-126.5 86t-155.5 31.5t-155 -31.5t-127 -86t-86 -127t-32 -154.5zM399 868v66q0 33 33 33h168v168q0 33 33 32h65 q14 0 24.5 -9t10.5 -23v-168h166q33 0 33 -33v-66q0 -14 -9.5 -24t-23.5 -10h-166v-166q0 -14 -10 -23.5t-25 -9.5h-65q-33 0 -33 33v166h-168q-14 0 -23.5 10t-9.5 24z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 901q0 137 52 258t143.5 212t212 143.5t258.5 52.5q137 0 259 -52.5t212 -143.5t142 -212t52 -258q0 -102 -28.5 -195.5t-81.5 -170.5l358 -359q18 -18 18 -46t-18 -48l-94 -94q-20 -18 -48 -18.5t-46 18.5l-359 358q-78 -53 -171 -81.5t-195 -28.5q-137 0 -258 52 t-212.5 142t-143.5 211t-52 260zM266 901q0 -84 32 -156.5t86 -126t127 -85t155 -31.5t155.5 31.5t126.5 85t85 126t32 156.5q0 82 -32 154.5t-85 127t-126.5 86t-155.5 31.5t-155 -31.5t-127 -86t-86 -127t-32 -154.5zM399 868v66q0 33 33 33h467q33 0 33 -33v-66 q0 -14 -9.5 -24t-23.5 -10h-467q-14 0 -23.5 10t-9.5 24z" />
|
||||
<glyph unicode="" horiz-adv-x="1488" d="M0 713q0 186 86 349t240 267q12 10 28 6q18 -4 25 -16l90 -131q10 -12 6 -27.5t-16 -25.5q-106 -72 -164.5 -182.5t-58.5 -239.5q0 -104 39.5 -197.5t108.5 -162t162 -108.5t197 -40t197.5 40t163.5 108.5t109.5 161.5t39.5 198q0 129 -59 239.5t-164 182.5 q-14 10 -16 24q-4 16 6 29l88 131q10 12 25.5 15t29.5 -5q154 -104 240 -267t86 -349q0 -154 -58.5 -289t-160 -236.5t-237.5 -160t-290 -58.5t-289 58.5t-236 160t-159.5 236.5t-58.5 289zM627 793v704q0 16 11 27.5t28 11.5h157q16 0 27.5 -11.5t11.5 -27.5v-704 q0 -16 -11 -27.5t-28 -11.5h-157q-16 0 -27.5 11t-11.5 28z" />
|
||||
<glyph unicode="" d="M0 39v260q0 16 11.5 27.5t27.5 11.5h192q16 0 26.5 -11.5t10.5 -27.5v-260q0 -16 -10 -27.5t-27 -11.5h-192q-39 0 -39 39zM393 39v434q0 16 11.5 27.5t27.5 11.5h193q16 0 26.5 -11.5t10.5 -27.5v-434q0 -16 -10.5 -27.5t-26.5 -11.5h-193q-16 0 -27.5 11.5t-11.5 27.5z M786 39v676q0 16 11.5 27.5t27.5 11.5h193q16 0 27.5 -11.5t11.5 -27.5v-676q0 -16 -11.5 -27.5t-27.5 -11.5h-193q-16 0 -27.5 11.5t-11.5 27.5zM1182 39v995q0 16 10 27.5t27 11.5h192q16 0 27.5 -11t11.5 -28v-995q0 -16 -11.5 -27.5t-27.5 -11.5h-192q-16 0 -26.5 11.5 t-10.5 27.5zM1575 39v1458q0 39 39 39h190q39 0 39 -39v-1458q0 -39 -39 -39h-190q-39 0 -39 39z" />
|
||||
<glyph unicode="" horiz-adv-x="1593" d="M0 651v236q0 12 30.5 21.5t68.5 15.5t74 9t48 5q18 61 49 117q-55 82 -120 157l-7 15q0 8 28 38.5t62.5 65.5t66.5 62.5t40 27.5q2 0 26.5 -18.5t54.5 -41t56.5 -43t32.5 -24.5q29 16 58.5 26.5t60.5 20.5q0 12 3 49t9 75t15.5 69t21.5 31h237q14 0 19 -15 q12 -49 17 -103t14 -106q31 -8 59.5 -19t56.5 -28q8 6 34 26.5t55.5 43t53 40t29.5 17.5t37 -27.5t65 -62.5t61.5 -65.5t27.5 -38.5q0 -4 -17.5 -28.5t-39 -53.5t-42 -55.5t-24.5 -32.5q33 -55 51 -123q49 -10 103.5 -13t101.5 -20q16 -4 16 -18v-236q0 -12 -29.5 -21.5 t-68.5 -15.5t-76 -9t-49 -5q-14 -57 -47 -117q55 -82 121 -157l6 -15q0 -8 -27.5 -38.5t-62.5 -65.5t-66.5 -62.5t-40.5 -27.5q-2 0 -26.5 18.5t-54 41t-56 43t-33.5 24.5q-29 -16 -58.5 -27.5t-59.5 -19.5q-2 -12 -5.5 -49.5t-9.5 -76t-14 -69.5t-21 -31h-237q-14 0 -19 17 q-14 49 -19 103t-11 103q-61 18 -117 50q-41 -31 -81 -60.5t-79 -62.5l-12 -4q-6 0 -37 27.5t-64.5 62.5t-61 65.5t-27.5 38.5q0 2 16 26.5t37.5 53.5t42 55.5t26.5 34.5q-33 55 -51 123q-51 10 -104.5 13t-100.5 20q-16 4 -16 18zM557 768q0 -49 18.5 -93t51 -77t77 -52.5 t93.5 -19.5t93 19.5t75.5 52.5t51 77t19.5 93t-19.5 92t-51 76t-75.5 51.5t-93 18.5t-93.5 -18.5t-77 -51.5t-51 -76t-18.5 -92z" />
|
||||
<glyph unicode="" horiz-adv-x="1304" d="M0 1175.5v34.5v36t2 36q25 14 71 23.5t98 15.5t102.5 9t78.5 5q-8 82 11.5 128t59.5 68.5t98.5 29t131.5 6.5q55 0 109.5 -3t97.5 -20.5t68.5 -54.5t25.5 -105v-24t-2 -25q29 -2 79 -5t102.5 -9t99.5 -15.5t72 -23.5v-72v-69q-37 -20 -123 -32.5t-185.5 -19t-193.5 -7.5 t-150 -1q-55 0 -150 1t-194.5 7.5t-184.5 18.5t-122 33q-2 16 -2 34.5zM133 154v837q123 -16 244 -21t244 -5h32q129 2 258 6t258 20v-837q0 -63 -44 -108.5t-107 -45.5h-731q-63 0 -108.5 45t-45.5 109zM303 199q0 -16 10.5 -26.5t26.5 -10.5h39q16 0 27.5 10t11.5 27v614 q0 16 -11.5 27.5t-27.5 11.5h-39q-16 0 -26.5 -11.5t-10.5 -27.5v-614zM504 1384q0 -10 1 -22t3 -23q144 2 291 0q0 12 2 23.5t0 21.5v15q-35 10 -74 11t-74 1q-37 0 -75.5 -1t-73.5 -11v-15zM596 199q0 -16 10 -26.5t27 -10.5h39q16 0 27.5 10t11.5 27v614q0 16 -11.5 27.5 t-27.5 11.5h-39q-16 0 -26.5 -11.5t-10.5 -27.5v-614zM887 199q0 -16 11 -26.5t28 -10.5h39q16 0 27.5 10t11.5 27v614q0 16 -11.5 27.5t-27.5 11.5h-39q-16 0 -27.5 -11.5t-11.5 -27.5v-614z" />
|
||||
<glyph unicode="" horiz-adv-x="1880" d="M0 809.5q2 15.5 14 26.5l867 710q27 20 59 21q33 0 59 -21l240 -196v102q0 16 11.5 27.5t27.5 11.5h223q16 0 26.5 -11.5t10.5 -27.5v-348l328 -268q12 -10 14 -25.5t-8 -28.5l-45 -53q-10 -14 -29 -14h-65q-16 0 -25 8l-743 608q-25 20 -50 0l-743 -608q-8 -8 -25 -8 h-65q-18 0 -29 14l-45 53q-10 12 -8 27.5zM266 76v622l674 553l674 -553v-622q0 -33 -21.5 -54.5t-54.5 -21.5h-422v498h-352v-498h-422q-33 0 -54.5 21.5t-21.5 54.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1228" d="M0 78v1382q0 31 22.5 53.5t55.5 22.5h614q33 0 71 -16.5t60 -38.5l351 -351q23 -23 39 -60.5t16 -70.5v-921q0 -33 -22.5 -55.5t-53.5 -22.5h-1075q-33 0 -55.5 22.5t-22.5 55.5zM154 154h921v692h-459q-31 0 -53 22.5t-22 55.5v458h-387v-1228zM268 326v116h693v-116 h-693zM268 596v115h693v-115h-693zM694 999h381q0 4 -4 13.5t-6 11.5l-350 348q-2 4 -9.5 6t-11.5 4v-383z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 768q0 -117 44 -218t119.5 -177t177 -120t218.5 -44t218 44t177 120t120 177 t44 218t-44 218t-120 177t-177.5 120t-217.5 44q-117 0 -218.5 -44t-177 -120t-119.5 -177t-44 -218zM635 608v465q0 33 23.5 56.5t56.5 23.5h80q35 0 57 -23.5t22 -56.5v-305h201q33 0 56.5 -23.5t23.5 -56.5v-80q0 -33 -23.5 -56.5t-56.5 -23.5h-360q-33 0 -56.5 23.5 t-23.5 56.5z" />
|
||||
<glyph unicode="" d="M2 35l594 1466q6 14 21.5 24.5t31.5 10.5h195l-8 -170h172l-9 170h195q16 0 31.5 -10t21.5 -25l594 -1466q6 -14 -1 -24.5t-23 -10.5h-740l-26 512h-258l-27 -512h-739q-16 0 -23.5 10t-1.5 25zM807 797h229l-20 413h-189z" />
|
||||
<glyph unicode="" d="M0 39v614q0 16 11.5 27.5t27.5 11.5h229q16 0 27.5 -11t11.5 -28v-346h1229v346q0 16 11.5 27.5t27.5 11.5h229q16 0 27.5 -11t11.5 -28v-614q0 -39 -39 -39h-1765q-39 0 -39 39zM345.5 944.5q6.5 16.5 39.5 16.5h307v499q0 31 21.5 53.5t54.5 22.5h307q33 0 55.5 -22.5 t22.5 -53.5v-499h307q31 0 37 -16.5t-16 -39.5l-504 -506q-23 -23 -55.5 -22.5t-55.5 22.5l-504 506q-23 23 -16.5 39.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 768q0 -117 44 -218t119.5 -177t177 -120t218.5 -44t218 44t177 120t120 177 t44 218t-44 218t-120 177t-177.5 120t-217.5 44q-117 0 -218.5 -44t-177 -120t-119.5 -177t-44 -218zM414 743q10 25 37 25h208v358q0 16 11.5 28.5t27.5 12.5h201q16 0 27.5 -12t11.5 -29v-358h209q27 0 37 -25t-10 -43l-347 -346q-14 -10 -28 -10t-29 10l-346 346 q-20 18 -10 43z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 768q0 -117 44 -218t119.5 -177t177 -120t218.5 -44t218 44t177 120t120 177 t44 218t-44 218t-120 177t-177 120t-218 44t-218.5 -44t-177 -120t-119.5 -177t-44 -218zM414 793q-10 25 10 43l346 346q14 10 29 10q14 0 28 -10l347 -346q20 -18 10 -43t-37 -25h-209v-360q0 -16 -11.5 -27.5t-27.5 -11.5h-201q-16 0 -27.5 11t-11.5 28v360h-208 q-27 0 -37 25z" />
|
||||
<glyph unicode="" d="M0 78v577q0 33 9 76t22 72l284 663q12 29 44 49.5t63 20.5h999q31 0 63 -20.5t44 -49.5l284 -663q12 -29 21.5 -72t9.5 -76v-577q0 -33 -22.5 -55.5t-53.5 -22.5h-1689q-33 0 -55.5 22.5t-22.5 55.5zM238 694h387l114 -231h383l117 231h367q-2 4 -2 9.5t-2 9.5l-256 594 h-848l-256 -596q-2 -2 -2 -7.5t-2 -9.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 768q0 -117 44 -218t119.5 -177t177 -120t218.5 -44t218 44t177 120t120 177 t44 218t-44 218t-120 177t-177.5 120t-217.5 44q-117 0 -218.5 -44t-177 -120t-119.5 -177t-44 -218zM582 453v628q0 18 16 29q20 8 31 0l545 -315q16 -6 16 -27q0 -20 -16 -27l-545 -315q-8 -4 -15 -4q-8 0 -16 4q-16 10 -16 27z" />
|
||||
<glyph unicode="" horiz-adv-x="1591" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5q141 0 271 -48.5t239 -140.5l161 162q35 35 58.5 24.5t23.5 -57.5v-463q0 -33 -22 -55q-10 -10 -23.5 -16t-29.5 -6h-463q-47 0 -58.5 23.5t23.5 58.5l160 159q-72 57 -159 88t-181 31q-117 0 -218.5 -44t-177 -120 t-119.5 -177t-44 -218t44 -218t119.5 -177t177 -120t218.5 -44q104 0 198.5 37t169 101.5t123.5 153.5t64 191q0 16 14 27q14 10 31 8l157 -20q16 -4 26.5 -16.5t8.5 -28.5q-20 -147 -89.5 -274.5t-176 -220.5t-242 -145.5t-284.5 -52.5q-166 0 -311.5 62.5t-254 171 t-171 254t-62.5 311.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M6 311l150 437q10 33 39 45t59 4l438 -150q45 -16 46 -40.5t-42 -47.5l-202 -100q53 -78 123.5 -134.5t160.5 -86.5q111 -37 221.5 -28t207 56t170 129t110.5 193q6 16 20.5 22t30.5 2l152 -51q16 -6 23 -20.5t1 -30.5q-53 -158 -159.5 -274.5t-243.5 -184t-296 -81 t-315 39.5q-135 47 -241.5 134t-179.5 208l-205 -100q-43 -23 -63.5 -5.5t-4.5 64.5zM203 1024q53 156 159.5 273.5t243.5 185t295 81t316 -39.5q133 -47 240.5 -134t180.5 -208l205 100q43 23 63.5 5.5t4.5 -62.5l-150 -439q-10 -33 -39 -45t-59 -4l-438 150 q-45 16 -46 40.5t40 47.5l202 100q-51 78 -122.5 134.5t-159.5 86.5q-111 37 -221.5 28t-207 -56t-170 -129t-110.5 -193q-6 -16 -20.5 -22t-30.5 -2l-152 51q-16 6 -23 20.5t-1 30.5z" />
|
||||
<glyph unicode="" d="M0 115v1306q0 47 34 81t81 34h1614q47 0 80.5 -34t33.5 -81v-1306q0 -47 -33.5 -81t-80.5 -34h-1614q-47 0 -81 34t-34 81zM154 154h1536v1075h-1536v-1075zM307 346v76q0 39 39 39h154q16 0 27.5 -11.5t11.5 -27.5v-76q0 -16 -11.5 -27.5t-27.5 -11.5h-154q-39 0 -39 39 zM307 653v76q0 39 39 39h154q16 0 27.5 -11.5t11.5 -27.5v-76q0 -16 -11.5 -27.5t-27.5 -11.5h-154q-39 0 -39 39zM307 961v75q0 39 39 39h154q16 0 27.5 -11t11.5 -28v-75q0 -16 -11.5 -27.5t-27.5 -11.5h-154q-39 0 -39 39zM692 346v76q0 16 10.5 27.5t26.5 11.5h768 q39 0 39 -39v-76q0 -39 -39 -39h-768q-16 0 -26.5 11.5t-10.5 27.5zM692 653v76q0 16 10.5 27.5t26.5 11.5h768q39 0 39 -39v-76q0 -39 -39 -39h-768q-16 0 -26.5 11.5t-10.5 27.5zM692 961v75q0 16 10.5 27.5t26.5 11.5h768q39 0 39 -39v-75q0 -39 -39 -39h-768 q-16 0 -26.5 11t-10.5 28z" />
|
||||
<glyph unicode="" horiz-adv-x="1253" d="M0 117v626q0 39 21.5 69t56.5 42v164q0 113 43 213t117.5 175t175 118t213.5 43t213 -43t175 -118t118 -175.5t43 -212.5v-164q35 -12 56 -42t21 -69v-626q0 -47 -34.5 -82t-81.5 -35h-1020q-47 0 -82 35t-35 82zM313 862h627v156q0 66 -24.5 123t-67.5 99t-100.5 66.5 t-120.5 24.5q-66 0 -122 -24.5t-99.5 -66.5t-68 -99.5t-24.5 -122.5v-156zM494 164h266l-66 285q29 18 47.5 48.5t18.5 65.5q0 55 -39 95t-94 40t-94 -40t-39 -95q0 -35 18 -65.5t47 -46.5z" />
|
||||
<glyph unicode="" d="M0 1382q0 63 45 108.5t109 45.5q63 0 108 -45.5t45 -108.5q0 -41 -20.5 -74.5t-55.5 -56.5v-1212q0 -16 -11 -27.5t-27 -11.5h-78q-16 0 -26.5 11.5t-10.5 27.5v1212q-35 23 -56.5 56.5t-21.5 74.5zM307 416v745q0 33 19.5 66t48.5 49q104 55 188 86t144 45q70 16 124 18 q68 0 124.5 -11t107.5 -29.5t99 -43t100 -51.5q63 -29 145 -33q70 -4 164 15.5t207 87.5q29 16 47 6t18 -43v-748q0 -31 -18.5 -64.5t-46.5 -49.5q-113 -68 -207 -87.5t-164 -15.5q-82 4 -145 33q-51 27 -99.5 51.5t-99.5 43t-107.5 29.5t-124.5 11q-55 -2 -124 -18 q-59 -14 -143.5 -45t-188.5 -88q-29 -16 -48.5 -4t-19.5 45z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 729q0 172 85 324.5t221 266.5t307 180.5t345 66.5t345.5 -66.5t307.5 -180.5t221 -266.5t85 -326.5q0 -182 -78 -350l-27 -60l-174 -26q-27 -104 -110.5 -173t-196.5 -69v-41q0 -16 -12 -27.5t-29 -11.5h-80q-16 0 -27.5 11.5t-11.5 27.5v719q0 16 11.5 28.5 t27.5 12.5h80q16 0 28.5 -12.5t12.5 -28.5v-39q88 0 161 -44t114 -116l39 7q33 90 32 192q0 125 -65.5 233.5t-170 190.5t-232.5 129t-251 47t-250.5 -47t-232 -128t-170 -190.5t-65.5 -232.5q0 -104 32 -194l39 -7q41 72 114 116t161 44v39q0 16 12 28.5t29 12.5h80 q16 0 27 -12.5t11 -28.5v-719q0 -16 -11 -27.5t-27 -11.5h-80q-16 0 -28.5 11.5t-12.5 27.5v41q-55 0 -106.5 18.5t-91.5 50.5t-68.5 76t-40.5 97l-175 26l-26 60q-78 168 -78 352z" />
|
||||
<glyph unicode="" horiz-adv-x="905" d="M0 578v380q0 16 11.5 27.5t27.5 11.5h420l325 326q49 51 84 37t35 -86v-1012q0 -72 -34.5 -86t-84.5 37l-325 326h-420q-16 0 -27.5 11t-11.5 28z" />
|
||||
<glyph unicode="" horiz-adv-x="1277" d="M0 578v380q0 16 11.5 27.5t27.5 11.5h420l325 326q49 51 84 37t35 -86v-1012q0 -72 -34.5 -86t-84.5 37l-325 326h-420q-16 0 -27.5 11t-11.5 28zM1027 406q-9 32 7 61q84 145 84 301t-84 301q-16 29 -7 61t38 48t60.5 8t48.5 -37q104 -182 104 -381q0 -201 -104 -381 q-23 -41 -70 -41q-20 0 -39 12q-29 16 -38 48z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 578v380q0 16 11.5 27.5t27.5 11.5h420l325 326q49 51 84 37t35 -86v-1012q0 -72 -34.5 -86t-84.5 37l-325 326h-420q-16 0 -27.5 11t-11.5 28zM1027 406q-9 32 7 61q84 145 84 301t-84 301q-16 29 -7 61t38 48t60.5 8t48.5 -37q104 -182 104 -381q0 -201 -104 -381 q-23 -41 -70 -41q-20 0 -39 12q-29 16 -38 48zM1285 219q-7 33 11 62q141 225 142 487q0 262 -142 487q-18 29 -11 62t36 49q29 18 61 11t50 -36q82 -131 123.5 -275t41.5 -298q0 -309 -167 -573q-10 -18 -29 -27.5t-37 -9.5q-25 0 -43 12q-29 16 -36 49zM1540 33 q-6 33 12 59q100 154 152.5 325t52.5 351t-52 351t-153 323q-18 29 -12 61.5t35 50.5q29 16 61 10.5t50 -32.5q115 -174 173 -366.5t58 -397.5t-58.5 -397.5t-172.5 -364.5q-10 -18 -29 -27.5t-37 -9.5q-25 0 -45 13q-29 18 -35 51z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 0v698h698v-698h-698zM0 838v698h698v-698h-698zM139 139h420v420h-420v-420zM139 977h420v420h-420v-420zM279 279v141h141v-141h-141zM279 1116v139h141v-139h-141zM838 0v698h417v-139h142v139h139v-419h-420v139h-139v-418h-139zM838 838v698h698v-698h-698z M977 977h420v420h-420v-420zM1116 0v139h139v-139h-139zM1116 1116v139h139v-139h-139zM1397 0v139h139v-139h-139z" />
|
||||
<glyph unicode="" d="M0 0v1536h154v-1536h-154zM227 0v1536h37v-1536h-37zM356 0v1536h117v-1536h-117zM545 0v1536h78v-1536h-78zM715 0v1536h76v-1536h-76zM903 0v1536h37v-1536h-37zM1014 0v1536h153v-1536h-153zM1221 0v1536h77v-1536h-77zM1409 0v1536h39v-1536h-39zM1579 0v1536h37 v-1536h-37zM1690 0v1536h153v-1536h-153z" />
|
||||
<glyph unicode="" horiz-adv-x="1488" d="M0 961v454q0 49 35 85t86 36h454q51 0 113 -24.5t94 -61.5l672 -748q33 -39 34 -88t-34 -84l-526 -526q-35 -35 -86 -36t-86 36l-670 750q-35 37 -60.5 96t-25.5 111zM197 1223q0 -49 33.5 -83t82.5 -34t83 34t34 83t-34 82.5t-83 33.5t-82.5 -33.5t-33.5 -82.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1875" d="M0 961v454q0 49 35 85t86 36h454q25 0 53.5 -6t57.5 -18.5t54.5 -28t41.5 -33.5l670 -748q33 -37 34 -86t-34 -84l-526 -524q-35 -35 -86.5 -37t-83.5 37l-670 746q-35 39 -60.5 98t-25.5 109zM195 1223q0 -47 34.5 -82t83.5 -35q47 0 82 35t35 82q0 49 -35 83.5 t-82 34.5q-49 0 -83.5 -34.5t-34.5 -83.5zM791 1534h174q51 0 112.5 -24.5t93.5 -61.5l670 -748q35 -37 35 -87t-35 -85l-524 -524q-35 -35 -86 -36t-86 36l-12 14l514 514q35 35 34.5 84.5t-34.5 85.5l-670 748q-31 35 -84 56.5t-102 27.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1710" d="M10 311q2 16 4 31.5t4 34.5q0 10 -4 20.5t-2 20.5q2 16 15.5 31.5t25.5 35.5q23 37 45.5 90.5t32.5 92.5q4 16 -1 30.5t-1 26.5q4 16 16.5 27.5t20.5 23.5q10 18 21.5 42t21.5 49.5t16 50t8 40.5t-2 33t0 29q6 16 20.5 26.5t24.5 24.5q10 12 21.5 34.5t23 49.5t19.5 52.5 t10 45.5q2 12 -4 24.5t-2 27.5q4 14 18.5 29.5t26.5 31.5q16 25 28.5 58.5t30 61t46 43t77.5 1.5l-2 -4q31 10 54 10h780q78 0 119 -57q41 -53 18 -129l-283 -906q-18 -63 -77.5 -107t-126.5 -44h-893q-10 0 -20.5 -2t-18.5 -12q-12 -20 0 -56q16 -43 60 -75.5t87 -32.5h946 q29 0 57.5 21.5t37.5 47.5l309 987q4 16 5 29.5t-1 28.5q41 -14 61 -43q41 -53 19 -129l-283 -905q-18 -66 -77.5 -109t-127.5 -43h-946q-41 0 -79.5 14.5t-73.5 39t-61.5 58t-41.5 72.5q-25 68 -2 127zM500 961q-10 -39 26 -39h615q16 0 30.5 11t18.5 28l24 75 q4 16 -3 27.5t-23 11.5h-615q-16 0 -31.5 -11t-19.5 -28zM569 1190q-4 -16 3.5 -26.5t23.5 -10.5h614q16 0 30.5 10.5t21.5 26.5l22 78q4 16 -3 27.5t-24 11.5h-614q-16 0 -30.5 -11.5t-20.5 -27.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1253" d="M0 84v1337q0 47 34 81t81 34h1024q47 0 80.5 -34t33.5 -81v-1337q0 -47 -33.5 -81t-80.5 -34t-80 33l-432 432l-432 -432q-33 -33 -80 -33t-81 34t-34 81z" />
|
||||
<glyph unicode="" d="M0 39v346q0 47 18.5 89t50 73t73.5 49t89 18h1383q47 0 89 -18t72.5 -49t49 -73t18.5 -89v-346q0 -39 -39 -39h-1765q-39 0 -39 39zM268 193q0 -16 11.5 -26.5t27.5 -10.5h1229q16 0 27.5 10t11.5 27v38q0 16 -11.5 27.5t-27.5 11.5h-1229q-16 0 -27.5 -11t-11.5 -28v-38 zM307 729v731q0 31 22.5 53.5t55.5 22.5h651v-383q0 -49 34 -83t81 -34h385v-307h-1229zM1151 1153v383l385 -383h-385z" />
|
||||
<glyph unicode="" d="M0 115v1075q0 47 34 82t81 35h366l58 125q18 43 66 73.5t95 30.5h443q47 0 95 -30.5t67 -73.5l57 -125h367q47 0 80.5 -35t33.5 -82v-1075q0 -47 -33.5 -81t-80.5 -34h-1614q-47 0 -81 34t-34 81zM442 653q0 -100 38 -187t102.5 -152.5t153 -103.5t186.5 -38t186 38 t152.5 103.5t102.5 152.5t38 187q0 98 -38 186.5t-102.5 153t-152.5 102.5t-186 38t-186.5 -38t-153 -102.5t-102.5 -152.5t-38 -187zM596 653q0 68 25.5 127.5t69.5 103.5t103.5 69.5t127.5 25.5t127 -25.5t103 -69.5t69.5 -103.5t25.5 -127.5t-25.5 -127t-69.5 -104 t-103.5 -70.5t-126.5 -25.5q-68 0 -127.5 25.5t-103.5 70.5t-69.5 104.5t-25.5 126.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1644" d="M0 0l2 80q10 4 29.5 8t48.5 8q92 18 108 33q16 10 50 68l233 614l277 725h73h53l11 -20l202 -482q33 -78 64 -151.5t59 -145.5q29 -72 52.5 -130t42.5 -103q12 -29 28.5 -70t36.5 -94q23 -66 64 -150q25 -49 34 -57q20 -18 68 -24q25 -2 49.5 -9.5t52.5 -17.5 q6 -37 7 -55v-10.5t-3 -16.5q-43 0 -90 2t-98 6q-53 4 -99 6t-87 2h-80t-53 -2l-199 -10l-57 -2q0 20 1 39.5t3 38.5l129 26q57 14 67 25q12 8 13 27q0 14 -7 30l-47 115l-90 227l-446 2q-12 -29 -37 -96t-66 -178q-23 -63 -22 -84q0 -27 16 -43q14 -10 40 -17.5t63 -13.5 q14 -4 84 -12v-59q0 -16 -2 -27q-35 0 -121 5t-224 16l-49 -9q-43 -8 -83 -11t-81 -3h-20zM549 655q135 -2 216 -4t105 0l29 2q-18 51 -40.5 111.5t-51.5 130.5t-51.5 122t-38.5 87z" />
|
||||
<glyph unicode="" horiz-adv-x="1419" d="M0 0l2 94q27 6 68 12q39 6 69.5 13.5t55.5 17.5q8 14 13 26.5t7 24.5q6 33 8 81t2 112l-2 498q-2 39 -3 139t-5 266q-4 88 -12 109q-4 8 -13 10q-20 14 -69 16q-23 0 -115 13l-4 84l262 6l383 12h45q8 2 15.5 2h13.5t21.5 -1t39.5 -1h76q92 0 193 -27q18 -4 42.5 -13 t53.5 -26q63 -31 104 -75q45 -47 66 -105q10 -29 15 -58.5t5 -62.5q0 -72 -32 -129q-31 -57 -95 -104q-16 -12 -54 -30.5t-97 -47.5q178 -41 268 -145q92 -104 92 -236q0 -72 -28 -162q-23 -66 -72 -116q-66 -72 -141 -109q-78 -35 -205 -59q-70 -12 -199 -11l-199 5 q-63 2 -138 -2.5t-163 -10.5q-25 -2 -93 -4t-181 -6zM537 1419q0 -12 1 -31.5t3 -44.5q2 -51 4 -119.5t0 -158.5v-98v-78q25 -4 52.5 -6t57.5 -2q176 0 267 65q90 66 90 225q0 113 -86 187q-84 76 -258 76q-53 0 -131 -15zM545 457l4 -271q0 -16 10 -43q74 -33 141 -32 q131 0 220 41q82 39 122 112q18 37 28.5 82t10.5 100q0 113 -43 181q-59 94 -141 125q-80 33 -250 32q-37 0 -61.5 -3t-40.5 -7v-143v-174z" />
|
||||
<glyph unicode="" horiz-adv-x="1054" d="M0 0l18 84q12 4 32 9t46 11q41 10 71 19.5t50 19.5q29 39 41 103l29 137l57 268l12 64q23 119 41.5 178t18.5 63l30 156l17 64l22 135l9 49v39q-45 23 -148 28q-14 0 -23.5 1.5t-17.5 1.5l21 104l325 -14q31 -2 49.5 -2h26.5q35 0 89 2t132 6q41 4 68.5 6t38.5 2 q-2 -10 -3 -19.5t-3 -19.5q-4 -10 -7.5 -22.5t-7.5 -28.5q-49 -16 -110 -31q-66 -16 -105 -31q-12 -33 -24 -88q-6 -25 -9.5 -45t-5.5 -37q-23 -100 -40 -175.5t-27 -129.5l-64 -311l-39 -158l-43 -235l-14 -45v-10.5t2 -16.5q35 -8 64.5 -13t58.5 -9q4 0 21.5 -2.5 l45.5 -6.5q-2 -18 -3 -32.5t-3 -26.5q-2 -6 -4 -16.5t-6 -22.5q-8 0 -14 -1t-10 -1q-18 -2 -28.5 -2h-14.5h-11.5t-17.5 4q-8 0 -45 4t-105 12l-202 2q-61 0 -181 -12q-39 -4 -63.5 -6t-36.5 -2z" />
|
||||
<glyph unicode="" d="M0 1151q14 37 34.5 110.5t45.5 184.5q8 33 13 54.5t9 31.5h58q4 -6 6 -10t4 -9q29 -57 41 -71q16 -4 129 -4q35 0 66.5 1t60.5 1l20 2l113 2l213 -2h289l55 10q10 8 27 53q2 6 4 12.5t6 16.5l43 2h10.5t16.5 -2q2 -39 1 -97.5t1 -138.5v-100v-57q0 -14 -1 -27.5t-3 -23.5 q-20 -8 -37 -11.5t-31 -7.5q-27 51 -53 129q-29 82 -37 92q-12 14 -27 21q-10 4 -60 4h-138h-31t-35 -4q-6 -43 -6 -72l2 -151v-334l2 -359v-147q0 -72 10 -117q8 -4 21.5 -8t34.5 -8q4 0 21 -4t50 -13q27 -10 49 -18q4 -20 4 -33.5v-17.5v-11.5t-2 -17.5h-34q-47 0 -88 2 t-76 6t-95.5 6t-148.5 2q-16 0 -57 -4t-109 -10q-29 -2 -45 -3t-24 -1q0 10 -1.5 16.5t-1.5 10.5l-2 24v10q18 31 80 50q94 27 135 49q4 10 6.5 25.5t4.5 31.5q4 68 6 176.5t0 255.5l-4 428q-2 90 -2 142.5t-4 72.5q0 8 -7 15q-4 6 -12 6q-16 4 -63 4h-127q-90 0 -119 -21 q-41 -29 -121 -153q-23 -35 -35 -35q-23 12 -36 23.5t-19 19.5zM1383 1305.5q-5 13.5 14 33.5l184 185q14 12 33 12q14 0 31 -12l184 -185q18 -20 13 -33.5t-34 -13.5h-118v-1048h118q29 0 34 -13.5t-13 -31.5l-184 -187q-16 -12 -33 -12q-16 0 -31 12l-184 187 q-18 18 -13 31.5t31 13.5h121v1048h-121q-27 0 -32 13.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 233q0 18 12 31l187 185q18 20 31.5 14t13.5 -33v-121h1048v121q0 27 13.5 33t33.5 -14l185 -185q12 -12 12 -31q0 -18 -12 -30l-185 -187q-20 -18 -33.5 -13t-13.5 34v119h-1048v-119q0 -29 -13.5 -34t-31.5 13l-187 187q-12 12 -12 30zM0 1233q14 29 33.5 87 t44.5 146q6 27 11 43.5t9 26.5h56q8 -12 10 -14q27 -47 37 -58q2 0 35.5 -1t77.5 -1h90.5h74.5h123l19 2h108h203h416l53 6q12 10 24 46l4.5 9l6.5 13h39h28v-188v-80v-45q0 -12 -1 -21.5t-3 -19.5q-33 -10 -63 -15q-25 37 -52 103q-27 59 -34 74q-12 10 -27 14q-6 2 -42 3 t-85 1h-103.5h-97.5h-28.5t-34.5 -2q-2 -18 -3 -32.5t-1 -24.5l4 -445l-2 -119q0 -61 12 -92q12 -6 53 -12q4 0 20.5 -4t45.5 -10q14 -4 26.5 -7.5t22.5 -7.5q2 -16 3 -25.5t1 -13.5t-1 -10t-1 -14h-33q-94 0 -157 6q-66 6 -236 6q-14 0 -53 -3t-105 -7q-27 -2 -43 -3 t-24 -1q0 16 -2 20v21v8q20 27 73 39q90 20 132 41q4 8 6 19t4 26q0 18 1 70.5t1 120t-1 142t-2 139t-2 107.5t-1 47q0 8 -6 13q-2 2 -13 6q-14 2 -59 2h-123q-20 0 -62 -1t-85 -2t-78 -4t-41 -7q-41 -25 -117 -123q-20 -29 -33 -29q-23 10 -35 19.5t-18 15.5z" />
|
||||
<glyph unicode="" d="M0 78v115q0 31 22.5 53t55.5 22h1689q31 0 53.5 -22.5t22.5 -52.5v-115q0 -33 -22.5 -55.5t-53.5 -22.5h-1689q-33 0 -55.5 22.5t-22.5 55.5zM0 500v114q0 33 22.5 55.5t55.5 22.5h1075q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -55.5t-53.5 -22.5h-1075 q-33 0 -55.5 22.5t-22.5 55.5zM0 922v114q0 33 22.5 55.5t55.5 22.5h1536q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -54.5t-53.5 -21.5h-1536q-33 0 -55.5 21.5t-22.5 54.5zM0 1343v117q0 31 22.5 53.5t55.5 22.5h921q31 0 53.5 -22.5t22.5 -53.5v-117q0 -31 -22.5 -53 t-53.5 -22h-921q-33 0 -55.5 22.5t-22.5 52.5z" />
|
||||
<glyph unicode="" d="M0 78v115q0 31 22.5 53t55.5 22h1689q31 0 53.5 -22.5t22.5 -52.5v-115q0 -33 -22.5 -55.5t-53.5 -22.5h-1689q-33 0 -55.5 22.5t-22.5 55.5zM78 922v114q0 33 21.5 55.5t54.5 22.5h1536q33 0 55 -22.5t22 -55.5v-114q0 -33 -22.5 -54.5t-54.5 -21.5h-1536 q-33 0 -54.5 21.5t-21.5 54.5zM307 500v114q0 33 22.5 55.5t55.5 22.5h1075q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -55.5t-53.5 -22.5h-1075q-33 0 -55.5 22.5t-22.5 55.5zM385 1343v117q0 31 21.5 53.5t54.5 22.5h921q33 0 55.5 -22.5t22.5 -53.5v-117 q0 -31 -22.5 -53t-55.5 -22h-921q-33 0 -54.5 22.5t-21.5 52.5z" />
|
||||
<glyph unicode="" d="M0 78v115q0 31 22.5 53t55.5 22h1689q31 0 53.5 -22.5t22.5 -52.5v-115q0 -33 -22.5 -55.5t-53.5 -22.5h-1689q-33 0 -55.5 22.5t-22.5 55.5zM154 922v114q0 33 22.5 55.5t54.5 22.5h1536q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -54.5t-53.5 -21.5h-1536 q-33 0 -55 21.5t-22 54.5zM614 500v114q0 33 22.5 55.5t55.5 22.5h1075q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -55.5t-53.5 -22.5h-1075q-33 0 -55.5 22.5t-22.5 55.5zM768 1343v117q0 31 22.5 53.5t55.5 22.5h921q31 0 53.5 -22.5t22.5 -53.5v-117q0 -31 -22.5 -53 t-53.5 -22h-921q-33 0 -55.5 22.5t-22.5 52.5z" />
|
||||
<glyph unicode="" d="M0 78v115q0 31 22.5 53t55.5 22h1689q31 0 53.5 -22.5t22.5 -52.5v-115q0 -33 -22.5 -55.5t-53.5 -22.5h-1689q-33 0 -55.5 22.5t-22.5 55.5zM0 500v114q0 33 22.5 55.5t55.5 22.5h1689q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -55.5t-53.5 -22.5h-1689 q-33 0 -55.5 22.5t-22.5 55.5zM0 922v114q0 33 22.5 55.5t55.5 22.5h1689q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -54.5t-53.5 -21.5h-1689q-33 0 -55.5 21.5t-22.5 54.5zM0 1343v117q0 31 22.5 53.5t55.5 22.5h1689q31 0 53.5 -22.5t22.5 -53.5v-117 q0 -31 -22.5 -53t-53.5 -22h-1689q-33 0 -55.5 22.5t-22.5 52.5z" />
|
||||
<glyph unicode="" d="M0 78v115q0 31 22.5 53t55.5 22h153q31 0 53.5 -22.5t22.5 -52.5v-115q0 -33 -22.5 -55.5t-53.5 -22.5h-153q-33 0 -55.5 22.5t-22.5 55.5zM0 500v114q0 33 22.5 55.5t55.5 22.5h153q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -55.5t-53.5 -22.5h-153 q-33 0 -55.5 22.5t-22.5 55.5zM0 922v114q0 33 22.5 55.5t55.5 22.5h153q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -54.5t-53.5 -21.5h-153q-33 0 -55.5 21.5t-22.5 54.5zM0 1343v117q0 31 22.5 53.5t55.5 22.5h153q31 0 53.5 -22.5t22.5 -53.5v-117q0 -31 -22.5 -53 t-53.5 -22h-153q-33 0 -55.5 22.5t-22.5 52.5zM461 78v115q0 31 22.5 53t55.5 22h1228q31 0 53.5 -22.5t22.5 -52.5v-115q0 -33 -22.5 -55.5t-53.5 -22.5h-1228q-33 0 -55.5 22.5t-22.5 55.5zM461 500v114q0 33 22.5 55.5t55.5 22.5h1228q31 0 53.5 -22.5t22.5 -55.5v-114 q0 -33 -22.5 -55.5t-53.5 -22.5h-1228q-33 0 -55.5 22.5t-22.5 55.5zM461 922v114q0 33 22.5 55.5t55.5 22.5h1228q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -54.5t-53.5 -21.5h-1228q-33 0 -55.5 21.5t-22.5 54.5zM461 1343v117q0 31 22.5 53.5t55.5 22.5h1228 q31 0 53.5 -22.5t22.5 -53.5v-117q0 -31 -22.5 -53t-53.5 -22h-1228q-33 0 -55.5 22.5t-22.5 52.5z" />
|
||||
<glyph unicode="" d="M0 756v75q0 39 39 39h213v154q0 31 16.5 37t38.5 -17l215 -215q16 -16 17 -36q0 -18 -17 -35l-215 -215q-23 -23 -39 -17t-16 39v152h-213q-39 0 -39 39zM614 39v1458q0 39 39 39h76q39 0 39 -39v-1458q0 -39 -39 -39h-76q-39 0 -39 39zM922 78v115q0 31 22.5 53t54.5 22 h768q31 0 53.5 -22.5t22.5 -52.5v-115q0 -33 -22.5 -55.5t-53.5 -22.5h-768q-33 0 -55 22.5t-22 55.5zM922 500v114q0 33 22.5 55.5t54.5 22.5h615q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -55.5t-53.5 -22.5h-615q-33 0 -55 22.5t-22 55.5zM922 922v114 q0 33 22.5 55.5t54.5 22.5h691q33 0 55 -22.5t22 -55.5v-114q0 -33 -22.5 -54.5t-54.5 -21.5h-691q-33 0 -55 21.5t-22 54.5zM922 1343v117q0 31 22.5 53.5t54.5 22.5h537q33 0 55.5 -22.5t22.5 -53.5v-117q0 -31 -22.5 -53t-55.5 -22h-537q-33 0 -55 22.5t-22 52.5z" />
|
||||
<glyph unicode="" d="M0 78v115q0 31 22.5 53t53.5 22h768q33 0 55.5 -22.5t22.5 -52.5v-115q0 -33 -22.5 -55.5t-55.5 -22.5h-768q-31 0 -53.5 22.5t-22.5 55.5zM0 500v114q0 33 22.5 55.5t53.5 22.5h614q33 0 55.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -55.5t-55.5 -22.5h-614 q-31 0 -53.5 22.5t-22.5 55.5zM0 922v114q0 33 22.5 55.5t53.5 22.5h692q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -54.5t-53.5 -21.5h-692q-31 0 -53.5 21.5t-22.5 54.5zM0 1343v117q0 31 22.5 53.5t53.5 22.5h538q31 0 53.5 -22.5t22.5 -53.5v-117q0 -31 -22.5 -53 t-53.5 -22h-538q-31 0 -53.5 22.5t-22.5 52.5zM1075 39v1458q0 39 39 39h76q16 0 27.5 -11.5t11.5 -27.5v-1458q0 -16 -11.5 -27.5t-27.5 -11.5h-76q-39 0 -39 39zM1305 743q0 16 14 35l217 215q23 23 38 17t15 -39v-152h215q16 0 27.5 -11t11.5 -28v-75q0 -16 -11 -27.5 t-28 -11.5h-215v-154q0 -31 -15 -38t-38 15l-217 218q-14 18 -14 36z" />
|
||||
<glyph unicode="" d="M0 324v768q0 47 18.5 89t50 72.5t73.5 49t89 18.5h768q47 0 89 -18.5t73 -49t49.5 -72.5t18.5 -89v-240l483 471q23 23 55 23q13 -1 29 -7q47 -20 47 -69v-1127q0 -49 -47 -69q-16 -6 -29 -6q-33 0 -55 22l-483 471v-237q0 -47 -18.5 -89t-49.5 -74t-72.5 -50.5 t-89.5 -18.5h-768q-47 0 -89 18.5t-73.5 50.5t-50 73.5t-18.5 89.5z" />
|
||||
<glyph unicode="" d="M0 115v1306q0 47 34 81t81 34h1614q47 0 80.5 -34t33.5 -81v-1306q0 -47 -33.5 -81t-80.5 -34h-1614q-47 0 -81 34t-34 81zM154 154h1536v1228h-1536v-1228zM307 307v105l277 360l188 -156l354 537l410 -424v-422h-1229zM307 1073q0 66 45 111t111 45q63 0 108 -45 t45 -111q0 -63 -45 -108t-108 -45q-66 0 -111 45t-45 108z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 0l137 418l867 866l280 -280l-866 -867zM287 407.5q0 -12.5 10 -22.5q8 -8 22 -8q12 0 21 8l690 690q20 20 0 43q-10 10 -22.5 10t-20.5 -10l-690 -688q-10 -10 -10 -22.5zM1102 1382l119 119q35 35 84 35t84 -35l57 -55l55 -57q35 -35 35 -84.5t-35 -83.5l-119 -119z " />
|
||||
<glyph unicode="" horiz-adv-x="1128" d="M0 1001q0 117 44 220.5t121 180.5t180.5 121t219.5 44q117 0 219.5 -44t179 -121t120.5 -180.5t44 -220.5q0 -84 -24.5 -159.5t-65.5 -143.5l-379 -661q-41 -68 -95 -68t-93 68l-381 663q-41 68 -65.5 143t-24.5 158zM285 1001q0 -57 21.5 -108t60.5 -89t89 -59.5 t109 -21.5q57 0 108.5 21.5t89.5 59.5t59.5 89t21.5 108t-21.5 108.5t-59.5 90.5t-89 60.5t-109 21.5q-59 0 -109 -21.5t-89 -60.5t-60.5 -90t-21.5 -109z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 768q0 -117 44 -218t119.5 -177t177 -120t218.5 -44v1118q-117 0 -218.5 -44 t-177 -120t-119.5 -177t-44 -218z" />
|
||||
<glyph unicode="" horiz-adv-x="1130" d="M0 535q0 86 23.5 161.5t66.5 141.5q20 33 69.5 99.5t108 154.5t113.5 193.5t90 217.5q10 35 37 51.5t57 12.5q31 4 57.5 -12.5t36.5 -51.5q33 -113 89.5 -218t115 -193t107.5 -154.5t69 -99.5q43 -66 66.5 -141.5t23.5 -161.5q0 -117 -44 -220.5t-120.5 -180.5t-180 -121 t-220.5 -44t-220 44t-180 121t-121 180.5t-44 220.5zM248 410q0 -59 41 -100.5t100 -41.5t100 41t41 101q0 43 -22 75q-6 8 -18.5 24.5t-26.5 39t-28.5 48.5t-22.5 54q-4 20 -23 17q-18 4 -24 -17q-8 -29 -21.5 -54.5t-28 -48t-27 -38.5t-18.5 -25q-23 -33 -22 -75z" />
|
||||
<glyph unicode="" d="M0 307v922q0 63 24.5 119.5t65.5 97.5t97.5 65.5t119.5 24.5h1075q4 0 10.5 -1t10.5 -1l-191 -191h-905q-47 0 -80.5 -33.5t-33.5 -80.5v-922q0 -47 33.5 -80.5t80.5 -33.5h1075q47 0 81 33.5t34 80.5v445l193 192v-637q0 -63 -25 -118.5t-67 -97.5t-97 -66.5t-119 -24.5 h-1075q-63 0 -119.5 24.5t-97.5 66.5t-65.5 97.5t-24.5 118.5zM631 324l108 329l652 652l221 -222l-651 -651zM866 629q6 -8 17 -8q10 0 16 8l512 510q18 18 0 35q-18 16 -35 0l-510 -510q-18 -18 0 -35zM1501 1415l92 94q29 29 68 29t65 -29l46 -45l45 -45 q27 -29 27.5 -66.5t-27.5 -66.5l-95 -92z" />
|
||||
<glyph unicode="" d="M0 307v922q0 63 24.5 119.5t65.5 97.5t97.5 65.5t119.5 24.5h836q-6 -31 -6 -63v-52q-164 -20 -310 -78h-520q-47 0 -80.5 -33.5t-33.5 -80.5v-922q0 -47 33.5 -80.5t80.5 -33.5h1075q47 0 81 33.5t34 80.5v111q16 10 31.5 21.5t32.5 27.5l129 127v-287q0 -63 -25 -118.5 t-67 -97.5t-97 -66.5t-119 -24.5h-1075q-63 0 -119.5 24.5t-97.5 66.5t-65.5 97.5t-24.5 118.5zM385 388.5v37.5q0 166 56.5 312.5t173 256t293.5 173t419 65.5v231q0 57 28.5 69.5t69.5 -28.5l392 -391q27 -25 26 -65q0 -39 -26 -64l-392 -391q-41 -41 -69.5 -28.5 t-28.5 69.5v260q-207 0 -364.5 -43t-266 -116.5t-170 -174t-77.5 -215.5q-4 -27 -31 -27q-25 0 -29 27q-4 23 -4 42.5z" />
|
||||
<glyph unicode="" d="M0 307v922q0 63 24.5 119.5t65.5 97.5t97.5 65.5t119.5 24.5h1075q27 0 52 -6l-187 -187h-940q-47 0 -80.5 -33.5t-33.5 -80.5v-922q0 -47 33.5 -80.5t80.5 -33.5h1075q47 0 81 33.5t34 80.5v326l193 192v-518q0 -63 -25 -118.5t-67 -97.5t-97 -66.5t-119 -24.5h-1075 q-63 0 -119.5 24.5t-97.5 66.5t-65.5 97.5t-24.5 118.5zM385 966.5q0 32.5 23 55.5l98 98q23 23 55.5 23t54.5 -23l340 -340l654 656q23 23 56.5 22.5t55.5 -22.5l99 -99q23 -23 22.5 -55.5t-22.5 -54.5l-711 -711l-98 -98q-23 -23 -55.5 -23t-55.5 23l-100 98l-393 395 q-23 23 -23 55.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 25 18 43l256 256q27 27 45.5 19.5t18.5 -46.5v-170h360v359h-172q-37 0 -45 18.5t19 44.5l256 256q18 18 43 19q25 0 43 -19l256 -256q27 -27 19.5 -45t-46.5 -18h-172v-359h361v170q0 39 18 46.5t45 -19.5l256 -256q18 -18 18 -43t-18 -43l-256 -256 q-27 -27 -45 -19.5t-18 46.5v176h-361v-365h172q39 0 47 -18.5t-20 -44.5l-256 -256q-18 -18 -43 -19q-25 0 -43 19l-256 256q-27 27 -20 45t46 18h172v365h-360v-176q0 -39 -18.5 -46.5t-45.5 19.5l-256 256q-18 18 -18 43z" />
|
||||
<glyph unicode="" horiz-adv-x="1075" d="M0 76q0 -31 22.5 -53.5t53.5 -22.5h153q33 0 55.5 22.5t22.5 53.5v1382q0 33 -22.5 55.5t-55.5 22.5h-153q-31 0 -53.5 -22.5t-22.5 -55.5v-1382zM307.5 768q-0.5 27 16.5 43l653 707q14 18 41 18q6 0 22 -4q35 -18 35 -59v-1412q0 -41 -35 -57q-39 -14 -63 14l-653 705 q-16 18 -16.5 45z" />
|
||||
<glyph unicode="" d="M0 76q0 -31 22.5 -53.5t53.5 -22.5h153q33 0 55.5 22.5t22.5 53.5v1382q0 33 -22.5 55.5t-55.5 22.5h-153q-31 0 -53.5 -22.5t-22.5 -55.5v-1382zM307.5 768q-0.5 27 16.5 43l653 707q14 18 41 18q6 0 22 -4q35 -18 35 -59v-1412q0 -41 -35 -57q-39 -14 -63 14l-653 705 q-16 18 -16.5 45zM1075.5 768q-0.5 27 16.5 43l653 707q14 18 41 18q6 0 22 -4q35 -18 35 -59v-1412q0 -41 -35 -57q-39 -14 -63 14l-653 705q-16 18 -16.5 45z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 767q0 26 16 44l654 707q14 18 41 18q10 0 22 -6q35 -14 35 -57v-1412q0 -41 -35 -57q-37 -16 -63 14l-654 705q-16 18 -16 44zM768 767q0 26 16 44l654 707q14 18 41 18q10 0 22 -6q35 -14 35 -57v-1412q0 -41 -35 -57q-37 -16 -63 14l-654 705q-16 18 -16 44z" />
|
||||
<glyph unicode="" horiz-adv-x="1349" d="M0 70v1396q0 39 35 60q37 23 69 0l1211 -697q35 -25 35 -61q0 -37 -35 -61l-1211 -697q-16 -10 -34 -10t-35 10q-35 20 -35 60z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 70v1396q0 29 20.5 49.5t49.5 20.5h489q29 0 49.5 -20.5t20.5 -49.5v-1396q0 -29 -20.5 -49.5t-49.5 -20.5h-489q-29 0 -49.5 20.5t-20.5 49.5zM907 70v1396q0 29 20.5 49.5t49.5 20.5h489q29 0 49.5 -20.5t20.5 -49.5v-1396q0 -29 -20.5 -49.5t-49.5 -20.5h-489 q-29 0 -49.5 20.5t-20.5 49.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 70v1396q0 29 20.5 49.5t49.5 20.5h1396q29 0 49.5 -20.5t20.5 -49.5v-1396q0 -29 -20.5 -49.5t-49.5 -20.5h-1396q-29 0 -49.5 20.5t-20.5 49.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 61v1414q0 39 35 57q39 14 63 -14l654 -705q16 -18 16 -45t-16 -45l-654 -705q-16 -18 -41 -18q-6 0 -22 4q-35 16 -35 57zM768 61v1414q0 39 35 57q39 14 63 -14l654 -705q16 -18 16 -45t-16 -45l-654 -705q-16 -18 -41 -18q-6 0 -22 4q-35 16 -35 57z" />
|
||||
<glyph unicode="" d="M0 61v1414q0 39 35 57q39 14 63 -14l654 -705q16 -18 16 -45t-16 -45l-654 -705q-16 -18 -41 -18q-6 0 -22 4q-35 16 -35 57zM768 61v1414q0 39 35 57q39 14 63 -14l654 -705q16 -18 16 -45t-16 -45l-654 -705q-16 -18 -41 -18q-6 0 -22 4q-35 16 -35 57zM1536 76 q0 -31 22.5 -53.5t53.5 -22.5h153q33 0 55.5 22.5t22.5 53.5v1382q0 33 -22.5 55.5t-55.5 22.5h-153q-31 0 -53.5 -22.5t-22.5 -55.5v-1382z" />
|
||||
<glyph unicode="" horiz-adv-x="1075" d="M0 61v1414q0 39 35 57q39 14 63 -14l654 -705q16 -18 16 -45t-16 -45l-654 -705q-16 -18 -41 -18q-6 0 -22 4q-35 16 -35 57zM768 76q0 -31 22.5 -53.5t53.5 -22.5h153q33 0 55.5 22.5t22.5 53.5v1382q0 33 -22.5 55.5t-55.5 22.5h-153q-31 0 -53.5 -22.5t-22.5 -55.5 v-1382z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 70v198q0 29 20.5 49.5t49.5 20.5h1396q29 0 49.5 -20.5t20.5 -49.5v-198q0 -29 -20.5 -49.5t-49.5 -20.5h-1396q-29 0 -49.5 20.5t-20.5 49.5zM6 594q-18 43 14 76l699 698q20 20 49 20.5t49 -20.5l699 -698q33 -33 14 -76q-16 -43 -64 -43h-1396q-47 0 -64 43z" />
|
||||
<glyph unicode="" horiz-adv-x="964" d="M0 765q0 38 29 66l671 674q29 29 68 29t68 -29l100 -100q29 -29 29 -68t-29 -67l-508 -510l508 -500q29 -29 29 -66.5t-29 -66.5l-100 -102q-29 -29 -68 -29t-68 29l-671 673q-29 29 -29 67z" />
|
||||
<glyph unicode="" horiz-adv-x="964" d="M0 194.5q0 38.5 29 67.5l508 508l-508 502q-29 29 -29 66.5t29 66.5l100 102q29 29 68 29t67 -29l672 -673q29 -29 29 -68t-29 -68l-672 -671q-29 -29 -67.5 -29t-67.5 29l-100 100q-29 29 -29 67.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM338 688q0 -33 33 -33h313v-344q0 -33 33 -32h164q33 0 32 32v344h314 q12 0 22.5 9.5t10.5 23.5v158q0 14 -10.5 23.5t-22.5 9.5h-314v346q0 33 -32 32h-164q-33 0 -33 -32v-346h-313q-33 0 -33 -33v-158z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM338 688q0 -33 33 -33h856q12 0 22.5 9.5t10.5 23.5v158q0 14 -10.5 23.5 t-22.5 9.5h-856q-33 0 -33 -33v-158z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 770q0 154 58.5 301.5t174.5 263.5q117 117 264.5 175.5t301 58.5t301 -58.5t264.5 -175.5t175 -264t58 -301t-58 -301t-175 -264t-264.5 -175.5t-301 -58.5t-301 58.5t-264.5 175.5t-175 264t-58 301zM385 505q0 -13 10 -24l115 -116q10 -10 23.5 -10.5t23.5 10.5 l244 243l219 -221q10 -10 23.5 -10t23.5 10l113 113q23 23 0 47l-222 219l246 246q23 23 0 47l-117 115q-25 25 -47 0l-243 -244l-222 221q-10 10 -23 10t-24 -10l-110 -113q-25 -23 0 -47l219 -219l-242 -244q-10 -10 -10 -23z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 718q0 -20 14 -34l319 -319q14 -14 38 -24.5t44 -10.5h56q20 0 43.5 10 t38.5 25l550 550q14 14 14.5 34t-14.5 34l-104 107q-16 14 -35.5 14t-34.5 -14l-452 -453q-14 -14 -33.5 -14t-34.5 14l-221 221q-14 14 -33.5 14t-36.5 -14l-104 -106q-14 -14 -14 -34z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM532 1100l95 -115q4 -8 20 -12q12 0 23 6l10 8t27.5 17.5t39 16.5t46.5 7 q41 0 69.5 -22.5t28.5 -57.5q0 -37 -24.5 -64.5t-61.5 -60.5q-23 -18 -46.5 -40.5t-43 -51.5t-31.5 -63.5t-12 -79.5v-64q0 -12 9 -21t21 -9h164q12 0 20.5 9t8.5 21v51q0 39 25.5 66.5t62.5 60.5q25 20 49.5 46t46 57t34.5 69.5t13 90.5q0 68 -27.5 121t-73.5 87.5 t-103.5 53t-114.5 18.5q-63 0 -113.5 -16.5t-85.5 -35.5t-53 -35.5t-20 -18.5q-16 -16 -3 -39zM672 252q0 -12 9 -21.5t21 -9.5h164q12 0 20.5 9.5t8.5 21.5v156q0 12 -8 21t-21 9h-164q-12 0 -21 -9t-9 -21v-156z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM573 858q0 -29 29 -29h86v-409h-78q-12 0 -21 -8.5t-9 -20.5v-139q0 -12 9 -21.5 t21 -9.5h402q12 0 20 9.5t8 21.5v139q0 29 -28 29h-78v577q0 12 -8 21.5t-21 9.5h-303q-12 0 -20.5 -9t-8.5 -22v-139zM686 1151q0 -12 9.5 -21.5t21.5 -9.5h188q12 0 20.5 9.5t8.5 21.5v166q0 29 -29 29h-188q-12 0 -21.5 -8.5t-9.5 -20.5v-166z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 692v154q0 16 11.5 26.5t27.5 10.5h164q18 84 59 158.5t99.5 133t133 99.5t158.5 59v164q0 39 39 39h154q16 0 26.5 -11.5t10.5 -27.5v-164q84 -18 158.5 -59t133 -99.5t99.5 -133t59 -158.5h164q16 0 27.5 -10.5t11.5 -26.5v-154q0 -39 -39 -39h-164 q-18 -84 -59 -158.5t-99.5 -133t-133 -99.5t-158.5 -59v-164q0 -16 -10.5 -27.5t-26.5 -11.5h-154q-39 0 -39 39v164q-84 18 -158.5 59t-133 99.5t-99.5 133t-59 158.5h-164q-39 0 -39 39zM365 653q29 -106 105.5 -183t182.5 -105v174q0 16 11.5 26t27.5 10h154 q16 0 26.5 -10t10.5 -26v-174q106 29 183 105.5t105 182.5h-172q-39 0 -38 39v154q0 16 11 26.5t27 10.5h172q-29 106 -105.5 183t-182.5 105v-172q0 -16 -10.5 -27t-26.5 -11h-154q-39 0 -39 38v172q-106 -29 -183 -105.5t-105 -182.5h174q16 0 26 -10.5t10 -26.5v-154 q0 -16 -10 -27.5t-26 -11.5h-174z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 768q0 -117 44 -218t119.5 -177t177 -120t218.5 -44t218 44t177 120t120 177 t44 218t-44 218t-120 177t-177.5 120t-217.5 44q-117 0 -218.5 -44t-177 -120t-119.5 -177t-44 -218zM451 573.5q0 16.5 12 28.5l166 166l-166 166q-12 12 -12 28.5t12 28.5l112 113q29 29 58 0l166 -166l166 166q29 29 57 0l113 -113q29 -29 0 -57l-166 -166l166 -166 q29 -29 0 -57l-113 -113q-12 -12 -28.5 -12t-28.5 12l-166 166l-166 -166q-12 -12 -28.5 -12t-29.5 12l-112 113q-12 12 -12 28.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 768q0 -117 44 -218t119.5 -177t177 -120t218.5 -44t218 44t177 120t120 177 t44 218t-44 218t-120 177t-177.5 120t-217.5 44q-117 0 -218.5 -44t-177 -120t-119.5 -177t-44 -218zM332 717.5q0 17.5 10 27.5l115 115q10 10 27.5 10t27.5 -10l178 -180q29 -25 58 0l337 340q10 10 27.5 10t28.5 -10l114 -115q10 -10 10.5 -27.5t-10.5 -27.5l-409 -410 q-12 -12 -32.5 -20t-37.5 -8h-114q-16 0 -37 8t-33 20l-250 250q-10 10 -10 27.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 768q0 -84 23.5 -160t66.5 -141l770 770q-66 43 -141.5 66.5t-159.5 23.5 q-117 0 -218.5 -44t-177 -120t-119.5 -177t-44 -218zM498 297q66 -41 141.5 -64.5t159.5 -23.5q117 0 218 44t177 120t120 177t44 218q0 84 -23.5 160t-64.5 141z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 768q0 39 29 68l671 673q29 29 68 29t68 -29l100 -100q29 -29 29 -67.5t-29 -67.5l-338 -338h842q41 0 68.5 -27.5t27.5 -68.5v-144q0 -39 -27.5 -66.5t-66.5 -27.5h-844l338 -338q29 -29 29 -67.5t-29 -67.5l-100 -100q-29 -29 -68 -29t-68 29l-671 671q-29 29 -29 68 z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 698v144q0 39 27.5 66.5t66.5 27.5h844l-338 338q-29 29 -29 67.5t29 67.5l100 100q29 29 68 29t68 -29l671 -673q29 -29 29 -67t-29 -67l-671 -673q-29 -29 -68 -29t-68 29l-100 100q-29 29 -29 68t29 67l338 338h-844q-39 0 -66.5 27.5t-27.5 68.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M-1 768q-1 39 28 68l673 671q29 29 68 29t68 -29l671 -671q29 -29 29 -68t-29 -68l-100 -100q-29 -29 -66.5 -29t-66.5 29l-340 338v-844q0 -39 -27.5 -66.5t-66.5 -27.5h-144q-41 0 -67.5 27.5t-26.5 66.5v844l-338 -338q-29 -29 -67.5 -29t-67.5 29l-100 100 q-29 29 -30 68z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 766q0 39 29 68l100 100q29 29 68 29t67 -29l338 -338v844q0 39 27.5 66.5t66.5 27.5h144q41 0 67.5 -27.5t26.5 -66.5v-844l340 338q29 29 66.5 29t66.5 -29l102 -100q29 -29 29 -68t-29 -68l-673 -671q-29 -29 -68 -29t-68 29l-671 671q-29 29 -29 68z" />
|
||||
<glyph unicode="" d="M0 135q0 209 71.5 393.5t218 322.5t371 219t531.5 83v293q0 72 36 87t89 -36l491 -493q35 -33 35 -82q0 -47 -35 -82l-491 -494q-51 -51 -88 -35.5t-37 86.5v330q-262 -2 -461 -56.5t-336 -147.5t-215 -219t-98 -271q-4 -33 -37 -33h-2q-33 0 -37 33q-6 51 -6 102z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 86v522q0 53 26.5 64.5t65.5 -25.5l166 -166l274 275q12 12 31 12t33 -12l160 -160q12 -14 12 -32.5t-12 -31.5l-275 -274l166 -166q39 -39 27 -65.5t-66 -26.5h-520q-37 0 -61 25q-27 27 -27 61zM768 972.5q0 18.5 12 31.5l275 274l-166 166q-39 39 -27 65.5t66 26.5 h520q37 0 61 -25q27 -27 27 -61v-522q0 -53 -26.5 -64.5t-65.5 25.5l-166 166l-274 -273q-12 -14 -31 -14t-33 14l-160 158q-12 14 -12 32.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 202.5q0 18.5 12 33.5l275 272l-166 166q-39 39 -27 65.5t66 26.5h520q38 0 61 -25q27 -27 27 -61v-522q0 -53 -26.5 -64.5t-65.5 27.5l-166 166l-274 -275q-12 -14 -31 -14t-33 14l-160 160q-12 12 -12 30.5zM768 854v522q0 53 26.5 64.5t65.5 -27.5l166 -166l274 275 q12 14 31 14t33 -14l160 -160q12 -12 12 -30.5t-12 -33.5l-275 -272l166 -166q39 -39 27 -65.5t-66 -26.5h-520q-41 0 -61 25q-27 27 -27 61z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 696v144q0 39 27.5 66.5t66.5 27.5h508v506q0 41 26.5 68.5t67.5 27.5h144q39 0 66.5 -27.5t27.5 -66.5v-508h508q39 0 66.5 -27.5t27.5 -66.5v-144q0 -39 -27.5 -66.5t-66.5 -27.5h-508v-506q0 -41 -27.5 -68.5t-66.5 -27.5h-144q-39 0 -66.5 27.5t-27.5 66.5v508 h-506q-41 0 -68.5 26.5t-27.5 67.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 696v144q0 39 27.5 66.5t66.5 27.5h1348q39 0 66.5 -27.5t27.5 -66.5v-144q0 -39 -27.5 -66.5t-66.5 -27.5h-1346q-41 0 -68.5 26.5t-27.5 67.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1427" d="M2 1018q-10 37 10 72l72 124q20 35 58 44.5t73 -9.5l332 -192v383q0 41 27.5 68.5t68.5 27.5h141q41 0 69 -27.5t28 -66.5v-385l331 192q35 18 73 9t58 -44l70 -124q20 -35 11 -72t-44 -57l-333 -193l333 -193q35 -20 44.5 -57t-9.5 -72l-72 -124q-20 -35 -58 -44.5 t-73 9.5l-331 192v-383q0 -41 -28 -68.5t-69 -27.5h-141q-41 0 -68.5 27.5t-27.5 66.5v385l-332 -192q-35 -20 -73 -10t-58 45l-72 124q-18 35 -9 72t44 57l334 193l-334 193q-35 20 -45 57z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM672 1274l14 -739q4 -29 31 -29h162q12 0 21 8t9 21l17 739q0 10 -8 22q-8 8 -23 9 h-193q-14 0 -22 -9q-8 -12 -8 -22zM680 236q0 -12 8 -21.5t21 -9.5h180q12 0 21.5 9t9.5 22v174q0 12 -9.5 21t-21.5 9h-180q-12 0 -20.5 -9t-8.5 -21v-174z" />
|
||||
<glyph unicode="" horiz-adv-x="1880" d="M0 588v391q0 16 11.5 27.5t27.5 11.5h539q-57 0 -107.5 21.5t-87.5 58.5t-58.5 87t-21.5 107t21.5 107.5t58.5 87.5t87 58.5t108 21.5q61 0 115.5 -24.5t88.5 -69.5l158 -203l158 203q35 45 89 69.5t116 24.5q57 0 107 -21.5t87 -58.5t58.5 -87t21.5 -108 q0 -57 -21.5 -107t-58.5 -87t-87 -58.5t-107 -21.5h538q16 0 27.5 -11.5t11.5 -27.5v-391q0 -16 -11 -27.5t-28 -11.5h-117v-432q0 -47 -34.5 -82t-83.5 -35h-1332q-49 0 -82.5 35t-33.5 82v432h-119q-16 0 -27.5 11t-11.5 28zM461 1292q0 -49 33.5 -82.5t83.5 -33.5h237 l-151 196q-10 10 -32 24.5t-54 14.5q-49 0 -83 -35t-34 -84zM743 221q0 -33 24 -56.5t56 -23.5h234q33 0 56.5 23.5t23.5 56.5v797h-394v-797zM1065 1176h238q49 0 82.5 33.5t33.5 82.5t-33.5 84t-82.5 35q-33 0 -54.5 -14.5t-31.5 -24.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M6 135q20 53 56 89t71 65q29 23 50.5 43t27.5 43q2 6 0 12t-10 25q-6 12 -11.5 27.5t-9.5 35.5q-25 160 13 295t120 242.5t195 185.5t235 121q82 29 179.5 34t203.5 7q61 0 127 2t127.5 11t113.5 28.5t85 54.5q20 20 38.5 41t38 36t43 24.5t58.5 9.5q23 0 42.5 -11.5 t29.5 -31.5q66 -133 83 -281.5t-18 -322.5q-90 -487 -579 -740q-231 -123 -467 -123q-154 0 -307 54q-23 8 -45.5 20t-44.5 25q-29 16 -57.5 30.5t-49.5 14.5q-10 -2 -23.5 -17.5t-27.5 -35t-26.5 -41t-20.5 -33.5q-14 -23 -26.5 -41.5t-22.5 -32.5q-25 -31 -64 -31h-4 q-29 2 -49.5 12.5t-33.5 24.5t-20.5 28.5t-9.5 22.5q-27 37 -10 78zM401 507.5q2 -32.5 29 -54.5q20 -18 51 -19q37 0 62 27q90 102 181 175t191.5 117t212 62t242.5 14q33 -4 57.5 19.5t26.5 56.5q2 35 -20.5 58.5t-57.5 25.5q-147 6 -277 -16.5t-247 -73.5t-223.5 -133 t-206.5 -199q-23 -27 -21 -59.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1445" d="M0 442q0 123 63.5 254t174.5 238q10 16 33.5 13t31.5 -21q4 -16 0 -29q-8 -35 -14 -84t-4 -101.5t13 -101.5t38 -84q31 -37 78 -49q-49 154 -40 293t49 259t101.5 217t118.5 167t98 106.5t43 39.5q25 18 47 0q10 -8 13.5 -21.5t-0.5 -24.5q0 -2 -15.5 -42.5t-21.5 -102 t7 -134.5t71 -136q37 -43 67.5 -85t52 -93.5t34 -120t12.5 -162.5q0 -33 -31 -39q-12 -2 -24.5 4t-16.5 19q-14 31 -42 49t-63 18q-47 0 -79.5 -33.5t-32.5 -81.5q0 -121 156 -120q98 0 153 63q37 43 53.5 101.5t20.5 114.5t2 102.5t-4 62.5q-6 12 0 29q8 18 31.5 21 t35.5 -13q111 -106 173.5 -237.5t62.5 -254.5q0 -109 -51.5 -195.5t-145.5 -148t-228 -95.5t-298 -34t-298 34t-228.5 95.5t-145.5 148.5t-51 195z" />
|
||||
<glyph unicode="" d="M0 722q0 44 25 83q78 125 178 224t216 168t242.5 104.5t260.5 35.5q135 0 262 -35.5t241.5 -103.5t215 -167t180.5 -226q23 -39 22.5 -83t-22.5 -81q-80 -127 -180.5 -226.5t-215 -167t-241.5 -103t-262 -35.5q-133 0 -260 35.5t-243 104t-216.5 168t-177.5 224.5 q-25 37 -25 81zM154 723q66 -104 149.5 -190.5t182 -145.5t208 -92t228.5 -33t228.5 33t207.5 92t182 145t150 191q-80 129 -187.5 226.5t-236.5 156.5q51 -59 79.5 -133t28.5 -160q0 -96 -35.5 -179t-99 -146.5t-147.5 -99.5t-179 -36q-96 0 -179 36t-146.5 99.5t-99 146.5 t-35.5 179q0 78 25.5 148.5t68.5 128.5q-117 -59 -217.5 -152.5t-175.5 -214.5zM614 813q0 -23 16.5 -40t41.5 -17t41 17.5t16 39.5q0 78 53.5 131t130.5 53q25 0 41.5 17.5t16.5 40.5q0 25 -16.5 41t-41.5 16q-61 0 -116.5 -23.5t-95 -63.5t-63.5 -95.5t-24 -116.5z" />
|
||||
<glyph unicode="" d="M0 767q0 44 25 83q78 125 178 224.5t216 168t242.5 104t260.5 35.5q53 0 105 -7t103 -17l89 158q8 14 24 18q12 6 29 -2l133 -76q14 -8 19.5 -23.5t-3.5 -29.5l-774 -1383q-6 -14 -22 -18q-4 -2 -11 -2q-6 0 -18 4l-135 76q-14 8 -18.5 23.5t3.5 29.5l66 115 q-145 68 -269 178.5t-218 259.5q-25 37 -25 81zM154 768q82 -131 191.5 -229.5t240.5 -157.5l57 104q-86 63 -138 159.5t-52 213.5q0 78 25.5 148.5t68.5 130.5q-117 -61 -217.5 -153.5t-175.5 -215.5zM614 858q0 -23 16.5 -40t41.5 -17t41 17.5t16 39.5q0 78 53.5 131 t130.5 53q25 0 41.5 17.5t16.5 40.5q0 25 -16.5 41t-41.5 16q-61 0 -116.5 -23.5t-95 -63.5t-63.5 -95.5t-24 -116.5zM928 154l88 159q209 25 382 145t292 310q-109 170 -263 283l76 137q92 -66 172 -150t146 -188q23 -39 22.5 -83t-22.5 -81q-160 -254 -392.5 -392 t-500.5 -140zM1081 430l285 510q4 -20 6 -39.5t2 -42.5q0 -74 -21.5 -140.5t-60.5 -121.5t-93 -98t-118 -68z" />
|
||||
<glyph unicode="" horiz-adv-x="1775" d="M0 92q0 20 6 39t17 35l768 1331q16 27 39.5 48.5t56.5 21.5t56.5 -21.5t39.5 -48.5l770 -1331q10 -16 16.5 -34.5t6.5 -39.5q0 -49 -38 -70.5t-81 -21.5h-1538q-43 0 -81 21.5t-38 70.5zM770 1114l12 -633q0 -14 10.5 -24.5t24.5 -10.5h139q14 0 24.5 10.5t10.5 24.5 l15 633q0 14 -10.5 24.5t-24.5 10.5h-166q-16 0 -25.5 -10.5t-9.5 -24.5zM776 168q0 -16 10.5 -25.5t24.5 -9.5h154q35 0 34 35v147q0 16 -9 26.5t-25 10.5h-154q-14 0 -24.5 -10t-10.5 -27v-147z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 541v4q0 31 23 57l30 29q20 25 56 24q8 0 10 -2l280 -32q39 63 93.5 134.5t125.5 151.5l-583 457q-31 25 -31 59v4q0 31 23 58l57 57q27 23 57 23h13.5t13.5 -4l803 -293l151 149q70 70 161 110t167 40q72 0 109 -37q20 -18 28 -46t8 -63q0 -76 -38.5 -167t-110.5 -160 l-150 -152l293 -803q6 -12 6 -26q0 -33 -24 -58l-58 -57q-23 -25 -57 -25h-4q-35 4 -59 31l-455 586q-82 -72 -153.5 -126t-135.5 -93l35 -281v-10q0 -33 -22 -55l-31 -31q-23 -23 -58 -23h-4q-39 4 -59 31l-205 272l-274 207q-29 25 -31 60z" />
|
||||
<glyph unicode="" horiz-adv-x="1566" d="M0 117v1147q0 47 35 81.5t82 34.5h39v13q0 31 10 62.5t32.5 56t59.5 40t90 15.5t90 -15.5t59.5 -40t33 -56.5t10.5 -62v-13h49v13q0 31 10 62.5t32.5 56t59.5 40t90 15.5t90 -15.5t60.5 -40t34 -56.5t10.5 -62v-13h49v13q0 31 10.5 62.5t33 56t59 40t90.5 15.5 q53 0 90 -15.5t59.5 -40t32.5 -56.5t10 -62v-13h39q47 0 82 -34.5t35 -81.5v-1147q0 -47 -35 -82t-82 -35h-1333q-47 0 -82 35t-35 82zM158 158h282v250h-282v-250zM158 446h282v252h-282v-252zM158 737h282v252h-282v-252zM272 1165q0 -57 76 -57t76 57v228q0 57 -76 57 t-76 -57v-228zM479 158h285v250h-285v-250zM479 446h285v252h-285v-252zM479 737h285v252h-285v-252zM709 1165q0 -31 16 -44t57 -13t58.5 13.5t17.5 43.5v228q0 29 -17.5 43t-58.5 14t-57 -14.5t-16 -42.5v-228zM803 158h284v250h-284v-250zM803 446h284v252h-284v-252z M803 737h284v252h-284v-252zM1126 158h283v250h-283v-250zM1126 446h283v252h-283v-252zM1126 737h283v252h-283v-252zM1143 1165q0 -57 76 -57t75 57v228q0 57 -75 57q-76 0 -76 -57v-228z" />
|
||||
<glyph unicode="" d="M0 252v154q0 16 11.5 27t27.5 11h219q51 0 99.5 31t93.5 83t90 119.5t90 139.5q55 88 114.5 175t127 156t147.5 110.5t180 41.5h203v185q0 41 24.5 49t59.5 -21l334 -278q23 -18 22 -45q0 -29 -22 -47l-334 -277q-35 -29 -59.5 -20.5t-24.5 49.5v174h-203 q-53 0 -100 -31.5t-93 -84t-91.5 -120t-90.5 -139.5q-55 -88 -113.5 -174t-126 -154.5t-148.5 -110.5t-179 -42h-219q-16 0 -27.5 11.5t-11.5 27.5zM0 1108v154q0 39 39 38h219q68 0 127 -20t111.5 -56t97.5 -84t88 -104q-61 -90 -117 -178q-4 -8 -9 -14t-9 -15 q-70 102 -139.5 172t-149.5 70h-219q-16 0 -27.5 10.5t-11.5 26.5zM778 481q29 41 56.5 85t56.5 87q4 10 10 17.5t10 17.5q70 -102 139.5 -170.5t149.5 -68.5h203v190q0 41 24.5 49t59.5 -20l334 -277q23 -18 22 -47q0 -27 -22 -45l-334 -279q-35 -29 -59.5 -20.5 t-24.5 49.5v168h-203q-68 0 -127 20.5t-110.5 56.5t-97.5 84t-87 103z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 866q0 145 76 272.5t206 222.5t303.5 150.5t372.5 55.5t373 -55.5t304 -150.5t206 -222t76 -273q0 -145 -76 -272t-206 -222.5t-304 -150.5t-373 -55q-92 0 -180 12q-176 -139 -411 -192q-25 -4 -50.5 -8.5t-54.5 -8.5q-16 -2 -27.5 6.5t-15.5 24.5t5 26.5t20 20.5 q23 23 43 44.5t36.5 51t30 69.5t23.5 97q-174 98 -275.5 241.5t-101.5 315.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1566" d="M0 621v288q0 16 11.5 27.5t27.5 11.5h391q16 0 28.5 -11t12.5 -28v-288q0 -29 22.5 -60t63.5 -58.5t98.5 -45t128.5 -17.5q70 0 128.5 17.5t99.5 45t63.5 58.5t22.5 60v288q0 39 39 39h391q16 0 27.5 -11t11.5 -28v-288q0 -135 -61.5 -254t-168 -207t-249 -139.5 t-304.5 -51.5q-164 0 -306 51.5t-248.5 139.5t-168 206.5t-61.5 254.5zM0 1106v391q0 16 11.5 27.5t27.5 11.5h391q16 0 28.5 -11.5t12.5 -27.5v-391q0 -16 -12.5 -27.5t-28.5 -11.5h-391q-16 0 -27.5 11.5t-11.5 27.5zM1098 1106v391q0 16 11 27.5t28 11.5h391 q16 0 27.5 -11.5t11.5 -27.5v-391q0 -16 -11.5 -27.5t-27.5 -11.5h-391q-39 0 -39 39z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M-1 355.5q-1 37.5 28 66.5l673 674q29 29 68 28.5t68 -28.5l671 -674q29 -29 29 -67t-29 -66l-100 -103q-29 -29 -68 -28.5t-67 28.5l-508 510l-500 -510q-29 -29 -67.5 -28.5t-67.5 28.5l-100 103q-29 29 -30 66.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 918.5q0 37.5 29 66.5l100 102q29 29 68 29t67 -29l508 -509l500 509q29 29 67.5 29t67.5 -29l100 -102q29 -29 30 -66.5t-28 -66.5l-673 -674q-29 -29 -68 -28.5t-68 28.5l-671 674q-29 29 -29 66.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M2.5 1038.5q-12.5 30.5 28.5 75.5l385 424q25 29 63 29q39 0 64 -29l385 -424q41 -45 28.5 -75.5t-67.5 -30.5h-250v-680h174q6 -10 12 -19.5t17 -19.5l252 -281h-695q-33 0 -56.5 23.5t-23.5 56.5v920h-249q-55 0 -67.5 30.5zM823 1526h695q33 0 56 -22.5t23 -57.5v-918 h250q55 0 67.5 -30.5t-28.5 -75.5l-385 -424q-25 -29 -63 -29q-39 0 -64 29l-385 424q-41 45 -28.5 75.5t67.5 30.5h250v678h-174q-6 10 -12.5 20.5t-14.5 20.5z" />
|
||||
<glyph unicode="" d="M0 1421v76q0 39 39 39h231q16 0 38 -4t36 -8q6 -4 14.5 -14.5t15.5 -23.5t12 -26.5t7 -21.5l27 -125h1347q35 0 58 -27t16 -59l-108 -578q-6 -25 -26.5 -42t-49.5 -17h-1084l35 -168q4 -16 17.5 -26.5t29.5 -10.5h856q16 0 27.5 -11.5t11.5 -27.5v-78q0 -16 -11 -26.5 t-28 -10.5h-163h-652h-104q-16 0 -36.5 3.5t-35.5 9.5q-6 2 -14 13t-15.5 24.5t-12.5 27t-7 21.5l-215 1016q-4 16 -17.5 26t-29.5 10h-170q-39 0 -39 39zM582 115q0 47 33.5 81.5t80.5 34.5q49 0 83 -34.5t34 -81.5t-34 -81t-83 -34q-47 0 -80.5 34t-33.5 81zM1233 115 q0 47 33.5 81.5t81.5 34.5q47 0 80.5 -34.5t33.5 -81.5t-33.5 -81t-80.5 -34t-81 34t-34 81z" />
|
||||
<glyph unicode="" d="M0 115v1306q0 47 34 81t81 34h692q47 0 81 -34t34 -81t33.5 -80.5t80.5 -33.5h693q47 0 80.5 -35t33.5 -82v-1075q0 -47 -33.5 -81t-80.5 -34h-1614q-47 0 -81 34t-34 81z" />
|
||||
<glyph unicode="" d="M0 379v1042q0 47 34 81t81 34h692q47 0 81 -34t34 -81t33.5 -80.5t80.5 -33.5h443q47 0 80.5 -35t33.5 -82v-221h-1228q-37 0 -72 -12.5t-65.5 -34t-53 -51t-35.5 -64.5zM43 0l246 760q6 23 30.5 39t47.5 16h1476l-260 -758q-6 -23 -30.5 -40t-47.5 -17h-1462z" />
|
||||
<glyph unicode="" horiz-adv-x="798" d="M2 368.5q10 22.5 57 22.5h203v754h-203q-47 0 -57 22.5t25 57.5l319 319q23 23 53 23q31 0 54 -23l321 -319q33 -35 22.5 -57.5t-57.5 -22.5h-202v-754h202q47 0 57.5 -22.5t-24.5 -57.5l-319 -319q-23 -23 -54 -23t-53 23l-321 319q-33 35 -23 57.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 729q0 31 23 53l319 322q35 33 57.5 23.5t22.5 -56.5v-205h754v203q0 47 22.5 57.5t56.5 -22.5l320 -322q23 -23 22 -53q0 -31 -22 -53l-320 -322q-35 -33 -57 -22.5t-22 57.5v203h-754v-203q0 -47 -22.5 -57t-57.5 24l-319 320q-23 23 -23 53z" />
|
||||
<glyph unicode="" d="M0 115v1306q0 47 35 81t82 34h1612q47 0 80.5 -34t33.5 -81v-1306q0 -47 -33.5 -81t-80.5 -34h-1612q-47 0 -82 34t-35 81zM154 154h1536v1228h-1536v-1228zM307 264v363h203v-363h-203zM649 264v776h201v-776h-201zM993 264v592h203v-592h-203zM1333 264v922h203v-922 h-203z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 193v1150q0 39 15.5 75t41 61.5t60.5 41t73 15.5h1153q80 0 136.5 -56.5t56.5 -136.5v-1150q0 -41 -15.5 -76t-41 -60.5t-61.5 -41t-75 -15.5h-1153q-39 0 -73.5 15.5t-60 41t-41 60.5t-15.5 76zM201 559q80 -111 198.5 -169t259.5 -58q96 0 184.5 26.5t160 73.5 t124 112.5t76.5 143.5q82 6 129 57q14 14 4 33q-8 18 -30 15h-4q23 23 30 45q8 20 -8 32q-14 14 -33 2q-8 -4 -29.5 -10t-45.5 -6q-4 0 -7.5 1t-7.5 1q0 2 -1 4t-1 4q-16 61 -57 110.5t-94 72.5q4 4 6 8t6 8q6 16 0 33q-2 6 -12.5 16t-34.5 8q-2 4 -6 8q-12 12 -25 9 q-25 -4 -49 -13l-2 2q-14 8 -31 -2q-59 -37 -98 -100t-68 -135q-35 31 -57 41q-61 35 -129 63.5t-154 61.5q-14 4 -24 -4q-10 -6 -15 -21q-2 -27 8.5 -58.5t38.5 -62.5q-25 -6 -20 -32q12 -68 68 -101l-13 -12q-14 -14 -4 -33q4 -12 26.5 -37.5t65.5 -38.5q-6 -12 -6 -22 t2 -14q6 -33 39 -50q-37 -25 -79 -34t-85 -5.5t-83 20.5t-70 46q-8 8 -19.5 8t-19.5 -8q-23 -18 -4 -39z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M2 193v1150q0 39 15.5 75t41 61.5t60.5 41t74 15.5h1153q80 0 136 -56.5t56 -136.5v-1150q0 -41 -15.5 -76t-41 -60.5t-61.5 -41t-74 -15.5h-486v643h172q12 0 21.5 8t9.5 21l12 168q0 14 -8 24q-10 10 -23 10h-184v74q0 41 10.5 54.5t53.5 13.5q25 0 55.5 -4t58.5 -11 q6 0 13.5 1.5t11.5 5.5q10 6 14 22l23 162q4 29 -25 35q-90 25 -188 24q-301 0 -301 -293v-84h-103q-33 0 -32 -32v-168q0 -12 9 -21.5t23 -9.5h103v-643h-393q-39 0 -74 15.5t-60.5 41t-41 60.5t-15.5 76z" />
|
||||
<glyph unicode="" d="M0 115v1306q0 47 34 81t81 34h1614q47 0 80.5 -34t33.5 -81v-1306q0 -47 -33.5 -81t-80.5 -34h-1614q-47 0 -81 34t-34 81zM154 160h1536v114h-1536v-114zM154 1145h1536v231h-957l-14 -92h-565v-139zM266 1341h316v93h-316v-93zM557 709q0 -76 28.5 -142.5t78 -116 t116 -78t142.5 -28.5t142 28.5t115.5 78t78 116t28.5 142.5t-28.5 142.5t-78 115.5t-116 77.5t-141.5 28.5q-76 0 -142.5 -28.5t-116 -77.5t-78 -115.5t-28.5 -142.5zM672 709q0 51 19.5 97t53 80t79.5 53t98 19q51 0 97 -19t80 -53t53 -80t19 -97t-19 -97.5t-53 -80 t-80 -53t-97 -19.5t-97.5 19.5t-80 53t-53 79.5t-19.5 98zM743 709q0 -16 12.5 -28.5t28.5 -12.5q18 0 30.5 12.5t12.5 28.5q0 41 28 67.5t67 26.5v2q18 0 30.5 12t12.5 29q0 18 -12.5 30.5t-30.5 12.5q-74 0 -126.5 -53.5t-52.5 -126.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 803.5q-6 111.5 30 230.5t113 228q78 109 179.5 180t209 102t213 17.5t191.5 -74.5q76 -53 121 -134t59 -176.5t-4 -199t-68 -203.5l414 -297l101 139l-105 74q-14 10 -17 27.5t7 32.5l51 69q10 14 26.5 17.5t32.5 -7.5l344 -247q16 -10 18.5 -27.5t-7.5 -32.5l-49 -69 q-10 -14 -27.5 -17.5t-32.5 6.5l-102 76l-101 -139l248 -178q43 -31 52.5 -83t-21.5 -95q-33 -43 -84 -51.5t-94 22.5l-803 573q-78 -80 -170 -130t-186.5 -68.5t-185.5 -2t-167 71.5q-86 61 -133 157.5t-53 208zM230.5 766q7.5 -41 30 -78t58.5 -63q37 -27 79 -36t83 -2 t78 29.5t64 59.5q39 53 41 114.5t-27 114.5q59 -10 116.5 11.5t96.5 74.5q27 37 36 79t2 84t-29.5 79t-59.5 63q-37 27 -79 36t-84 2t-79 -29.5t-63 -59.5q-37 -53 -39 -114.5t26 -114.5q-59 10 -116.5 -12.5t-96.5 -75.5q-27 -37 -36 -79t-1.5 -83z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 801v180q0 8 22.5 15.5t52 11.5t56.5 7t37 3q12 49 37 88q-23 31 -45.5 61.5t-46.5 59.5l-4 10q0 6 20.5 29.5t47 50t50 47t29.5 20.5q2 0 20.5 -13t41 -30.5t43 -34t24.5 -20.5q43 25 90 37q0 8 3 37t7 57.5t10.5 52t16.5 23.5h178q8 0 15.5 -23.5t11.5 -52t7 -57.5 t5 -37q45 -12 86 -35q31 23 62.5 45.5t60.5 46.5l8 4q4 0 27.5 -21.5t49.5 -47t47.5 -49t21.5 -29.5q0 -4 -13.5 -22.5t-30 -40t-32 -41t-19.5 -25.5q23 -39 39 -92q10 -2 37 -5t55.5 -8.5t51 -11.5t22.5 -14v-178q0 -10 -22.5 -16.5t-51 -11.5t-56.5 -7t-36 -4 q-14 -43 -37 -88q23 -31 44.5 -60.5t48.5 -58.5l2 -10q0 -6 -20.5 -30t-47.5 -50.5t-50.5 -47t-29.5 -20.5q-2 0 -20.5 13.5t-41 31t-42 32.5t-25.5 20q-45 -23 -88 -37q0 -10 -3 -37t-8 -56.5t-12.5 -52t-15.5 -22.5h-178q-8 0 -15.5 22.5t-11.5 52t-7 56t-3 37.5 q-45 12 -88 37q-31 -23 -61.5 -46.5t-59.5 -48.5l-10 -2q-4 0 -27.5 20.5t-49 47t-46 50.5t-20.5 30q0 2 13 20.5t29.5 40t31 41t18.5 25.5q-23 43 -39 94q-10 2 -37 5t-55.5 7t-51 10.5t-22.5 14.5zM420 889q0 -37 14.5 -70t39 -57.5t58 -38.5t70.5 -14t70 14t57.5 38.5 t38.5 57.5t14 70t-14 70.5t-38.5 58t-57.5 39t-70 14.5q-76 0 -129 -53t-53 -129zM1114 373q0 6 13.5 13t31 14.5t33.5 12.5t22 7q4 23 9.5 39t15.5 37q-4 4 -13 17t-18.5 27.5t-16.5 28t-7 17.5t18.5 23.5t43 41t47 40t28.5 24.5l8 4q4 0 16.5 -8.5t25.5 -19.5t25.5 -21.5 t16.5 -14.5q35 12 76 19q2 6 9 21.5t16.5 30.5t17.5 27.5t14 12.5q4 0 34 -7t63.5 -18.5t60.5 -23.5t27 -23q0 -23 -5.5 -47t-9.5 -47q16 -12 28.5 -26.5t22.5 -30.5q25 2 49.5 3t47.5 1q8 0 18 -26.5t17.5 -60.5t12.5 -64.5t5 -39.5q0 -6 -13.5 -13t-29.5 -13t-32.5 -12.5 t-22.5 -8.5q-9 -38 -23 -71q2 -6 11.5 -18.5t18.5 -27t16 -27.5t7 -18q0 -4 -18.5 -23.5t-43 -41t-47 -40.5t-28.5 -26l-8 -4q-4 0 -16.5 8.5t-25.5 19.5t-25.5 21.5t-16.5 14.5q-37 -12 -78 -19q-2 -6 -9 -21.5t-15.5 -30.5t-16.5 -27.5t-14 -12.5t-35 7.5t-62.5 18.5 t-60 23.5t-26.5 22.5q0 23 5 47.5t9 46.5q-16 12 -28.5 26.5t-22.5 30.5q-23 -2 -45.5 -3t-44.5 -1h-14.5t-8.5 11q-2 8 -8 35.5t-13.5 58t-12.5 55.5t-5 29zM1192 1264q0 6 12.5 12t29.5 10t33.5 6t22.5 4q10 33 31 64q-2 4 -8 17.5t-12.5 27.5t-11.5 25.5t-5 15.5 q0 6 21.5 22.5t49 35t51.5 32.5t28 14t13 -9t20.5 -21.5t20.5 -23.5t13 -15q14 4 28.5 6t29.5 0h14q2 4 11 16.5t18.5 25.5t17.5 23.5t12 10.5t30 -11.5t55.5 -26t53 -28.5t23.5 -20q0 -4 -4 -15.5t-8 -26t-8.5 -27.5t-6.5 -17q20 -25 39 -60q51 -4 74 -7t29 -18.5t5 -52 t3 -106.5q0 -6 -12.5 -12.5t-28.5 -10.5t-32.5 -6t-22.5 -4q-13 -36 -31 -63q2 -4 8 -16.5t13.5 -27t12.5 -26.5t5 -14q0 -6 -22.5 -23.5t-50 -36t-51.5 -33t-26 -14.5q-4 0 -14 9.5t-21.5 21.5t-20.5 23.5t-13 15.5q-14 -4 -28.5 -6t-29.5 0h-14q-4 -4 -12 -16.5t-17.5 -26 t-18.5 -23.5t-13 -10t-30 11t-54.5 25.5t-52 29t-23.5 20.5q0 2 3 14.5t8 26.5t9 27.5t6 17.5q-23 23 -38 59q-53 2 -75 5t-29 18.5t-5 52.5t-4 109zM1397 367q0 -49 34.5 -85t84.5 -36q49 0 84.5 34.5t35.5 86.5q0 49 -34.5 83.5t-85.5 34.5q-49 0 -84 -34.5t-35 -83.5z M1446 1206q0 -47 31.5 -78.5t76.5 -31.5q47 0 79 31.5t32 76.5q0 47 -31.5 79t-77.5 32q-47 0 -78.5 -32t-31.5 -77z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 997q0 119 61.5 222.5t167 180.5t246.5 122t303 45t303.5 -45t247 -122t166.5 -180.5t61 -222.5q0 -117 -61 -221t-166.5 -181t-247 -122t-303.5 -45q-37 0 -73.5 3t-71.5 7q-147 -113 -336 -155q-20 -4 -40.5 -7.5t-43.5 -7.5q-12 -2 -21.5 6.5t-13.5 18.5v2 q-4 12 3 19.5t18 17.5q18 18 34.5 36.5t29.5 42t24.5 55.5t19.5 79q-141 78 -224 195.5t-83 256.5zM649 258q6 4 13.5 8t13.5 8q51 -6 102 -6q197 0 369 56.5t298 155t198.5 231.5t72.5 286q0 41 -6 84q96 -78 151.5 -175t55.5 -208q0 -139 -83 -256.5t-224 -195.5 q8 -47 19 -79t25.5 -55.5t30 -42t33.5 -36.5q10 -10 17.5 -18.5t3.5 -18.5v-2q-2 -12 -12.5 -19.5t-22.5 -5.5q-23 4 -43.5 7.5t-40.5 7.5q-96 20 -180 60t-156 95q-35 -4 -71.5 -7t-73.5 -3q-141 0 -265 35t-225 94z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 193v643q0 49 35 83.5t84 34.5h348q27 14 43 30.5t35 39.5q16 20 32.5 38.5t34.5 37.5q33 35 76 68.5t66 74.5q16 29 23 64.5t12.5 71.5t12.5 70t23.5 60.5t47 42t81.5 15.5q61 0 111.5 -25.5t85.5 -68.5t54.5 -98.5t19.5 -112.5q0 -59 -17.5 -112.5t-42.5 -107.5 q35 2 70 4.5t70 2.5q55 0 107 -10.5t93 -35t66.5 -67.5t25.5 -109q0 -29 -5 -57t-15 -57q18 -43 18 -90q0 -78 -41 -142q10 -59 -7 -118.5t-58 -104.5q-4 -84 -45 -139.5t-102.5 -89t-135 -47t-143.5 -13.5q-72 0 -144.5 10.5t-142.5 28.5q-70 20 -139.5 43t-142.5 23h-375 q-49 0 -84 34.5t-35 84.5zM236 276q0 -35 22 -57t57 -22q33 0 56.5 22.5t23.5 56.5q0 33 -23.5 56.5t-56.5 23.5q-35 0 -57 -23.5t-22 -56.5zM492 193q70 0 136 -16.5t133.5 -35t141.5 -35t160 -16.5q45 0 98 6t99.5 26.5t78 56.5t31.5 95q0 10 -1 18.5t-3 18.5 q35 16 53.5 53t18.5 74q0 39 -21 68q60 49 60 123q0 23 -12.5 43t-26.5 35q16 29 28.5 57.5t12.5 62.5q0 35 -17.5 55.5t-43 31t-56.5 12.5t-57 2q-45 0 -90.5 -3t-90.5 -3q-31 0 -61.5 3t-58.5 15q0 41 16 78t35.5 74.5t35 78.5t15.5 91q0 33 -10.5 65.5t-29.5 59t-47 44 t-65 17.5h-11t-11 -2q-8 -4 -9 -8t-3 -13q-12 -59 -22.5 -123.5t-39.5 -117.5q-29 -51 -74 -88t-86 -78q-29 -31 -49 -56.5t-41.5 -48t-48.5 -42t-65 -35.5h-2v-643z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 309q0 29 5 57.5t15 57.5q-18 43 -18 90q0 78 41 141q-10 59 7.5 119t58.5 105q4 84 45 139t102 89t135 47t144 13q72 0 144.5 -10t141.5 -29q70 -20 139.5 -42.5t143.5 -22.5h375q49 0 83.5 -35t34.5 -84v-643q0 -49 -34.5 -84t-83.5 -35h-349q-27 -14 -43 -30.5 t-34 -38.5q-16 -20 -32.5 -39t-35.5 -37q-33 -35 -76 -69t-65 -74q-25 -43 -31 -99.5t-18.5 -106.5t-44 -84t-107.5 -34q-61 0 -111.5 25.5t-85 68.5t-54 98.5t-19.5 112.5q0 59 17.5 112.5t41.5 106.5q-35 -2 -69.5 -4t-69.5 -2q-55 0 -107.5 10.5t-93.5 35t-66.5 67.5 t-25.5 108zM119 309q0 -35 17.5 -55.5t43 -30.5t56 -12t57.5 -2q47 0 91 3t89 3q31 0 61.5 -3t59.5 -15q0 -41 -16.5 -78t-36 -75t-34.5 -79t-15 -90q0 -33 10 -65.5t29.5 -59t47 -43t64.5 -16.5q4 0 11.5 -1t11.5 1q8 4 9 8l3 12q12 59 22.5 124t38.5 118q29 51 74 88 t86 78q29 31 49.5 56.5t42 48t47 42t66.5 35.5h2v643q-72 0 -137.5 16.5t-133 36t-141 36t-159.5 16.5q-45 0 -98.5 -7.5t-99.5 -27t-78 -56t-32 -96.5q0 -10 1 -18t3 -19q-35 -16 -53 -53t-18 -74q0 -39 20 -67q-59 -49 -59 -123q0 -23 12 -43.5t27 -34.5 q-16 -29 -28.5 -57.5t-12.5 -63.5zM1202 860q0 -33 23.5 -56.5t56.5 -23.5q35 0 57.5 23.5t22.5 56.5q0 35 -22.5 57.5t-57.5 22.5q-33 0 -56.5 -22.5t-23.5 -57.5z" />
|
||||
<glyph unicode="" horiz-adv-x="837" d="M1 959.5q9 27.5 54 33.5l506 74l227 459q23 41 50 41v-1348l-453 -237q-41 -23 -64.5 -6.5t-15.5 63.5l86 504l-364 356q-35 33 -26 60.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1802" d="M0 1073q0 137 43 231.5t112.5 153t156.5 84t177 25.5q63 0 125 -21.5t115 -53.5t97 -70t75 -68q31 31 76 68.5t98 69.5t113.5 53.5t126.5 21.5q88 0 175 -25.5t156.5 -84t112.5 -153t43 -231.5q0 -94 -34.5 -177t-76.5 -146.5t-79 -102.5t-39 -43l-615 -612 q-26 -23 -57 -23q-33 0 -55 23l-617 614q-4 2 -39.5 41t-77.5 102.5t-77 146.5t-35 177zM160 1073q0 -68 27.5 -131t61.5 -112.5t63 -79.5l28 -29l561 -559l561 559l29 29q29 30 62.5 79.5t61 113t27.5 130.5q0 104 -29.5 169t-77.5 101.5t-106.5 50t-113.5 13.5 q-53 0 -107.5 -25.5t-102.5 -61.5t-86 -74t-56 -60q-25 -31 -62 -31t-61 31q-18 23 -56.5 60.5t-86.5 73.5t-102.5 61.5t-105.5 25.5q-57 0 -115.5 -13.5t-106.5 -50t-77.5 -101t-29.5 -169.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1689" d="M0 307v922q0 63 24.5 118.5t66.5 97.5t97.5 66.5t118.5 24.5h461v-193h-461q-47 0 -80.5 -33.5t-33.5 -80.5v-922q0 -47 33.5 -80.5t80.5 -33.5h461v-193h-461q-63 0 -118.5 24.5t-97.5 66.5t-66.5 97.5t-24.5 118.5zM508 584v368q0 33 22.5 54.5t55.5 21.5h428v293 q0 41 39 57q39 14 65 -14l553 -553q18 -18 18.5 -44t-18.5 -42l-553 -553q-18 -18 -43 -18q-10 0 -22 4q-39 16 -39 57v291h-428q-33 0 -55.5 22.5t-22.5 55.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 193v1150q0 39 15.5 75t41 61.5t60.5 41t76 15.5h1150q80 0 136.5 -56.5t56.5 -136.5v-1150q0 -41 -15.5 -76t-41 -60.5t-61.5 -41t-75 -15.5h-1150q-80 0 -136.5 56.5t-56.5 136.5zM207 1192q0 -57 40 -97t95 -40q57 0 97 40t40 97q0 55 -40 95t-97 40q-55 0 -95 -40 t-40 -95zM213 240q0 -10 9 -19.5t20 -9.5h200q12 0 20.5 9t8.5 20v706q0 29 -29 29h-200q-10 0 -19.5 -8.5t-9.5 -20.5v-706zM580 240q0 -10 9 -19.5t19 -9.5h201q12 0 20.5 9t8.5 20v383q0 68 26.5 113.5t102.5 45.5q59 0 79.5 -28.5t20.5 -81.5v-432q0 -10 8 -19.5 t21 -9.5h204q10 0 19.5 9t9.5 20v477q0 141 -81 208.5t-216 67.5q-55 0 -107.5 -15t-93.5 -56q0 16 -3 34.5t-25 18.5h-195q-10 0 -19 -8.5t-9 -20.5v-706z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M2 950q8 82 45 172t100 176t139 147.5t152 92.5t145.5 30t121.5 -40q53 -41 73.5 -107.5t12.5 -148.5l301 -225q111 63 215 73t180 -47q55 -41 80.5 -108.5t23.5 -150.5t-30.5 -177t-83.5 -188l428 -410q25 -25 4 -53q-12 -16 -33 -17q-10 0 -18 6l-517 293 q-74 -80 -155.5 -135t-161.5 -80.5t-151.5 -19.5t-127.5 47q-76 55 -95 158.5t9 228.5l-303 223q-76 -33 -145.5 -32t-122.5 40q-51 39 -72.5 104.5t-13.5 147.5zM171 858.5q3 -16.5 15 -27.5q21 -14 50 -14q31 0 65.5 17.5t71.5 46t72.5 66.5t66.5 79q10 14 7 30.5 t-15 26.5q-14 10 -30.5 8.5t-27.5 -16.5q-78 -104 -138 -143t-72 -35q-14 10 -31 7t-27 -15q-10 -14 -7 -30.5zM465 754l364 -271q8 -8 23 -8q20 0 33 17q10 14 8 29.5t-16 25.5l-347 258q-16 -14 -32.5 -27.5t-32.5 -23.5zM829.5 239.5q1.5 -16.5 16.5 -26.5q29 -23 69 -23 q41 0 88.5 21.5t95.5 57.5t94 84.5t87 101.5q10 12 8 28.5t-16 26.5q-12 10 -28.5 8t-26.5 -16q-51 -68 -102.5 -116t-95.5 -75.5t-78 -36t-48 4.5q-14 10 -29.5 7t-25.5 -18q-10 -12 -8.5 -28.5z" />
|
||||
<glyph unicode="" d="M0 307v922q0 63 24.5 119.5t65.5 97.5t97.5 65.5t119.5 24.5h582q-2 -14 -4 -27.5t-2 -29.5v-88q0 -23 6 -48h-582q-47 0 -80.5 -33.5t-33.5 -80.5v-922q0 -47 33.5 -80.5t80.5 -33.5h1075q47 0 81 33.5t34 80.5v340q41 -31 90 -49t103 -20v-271q0 -63 -25 -118.5 t-67 -97.5t-97 -66.5t-119 -24.5h-1075q-63 0 -119.5 24.5t-97.5 66.5t-65.5 97.5t-24.5 118.5zM692.5 522q-0.5 25 16.5 41l770 772h-269q-25 0 -41 16.5t-16 41.5v86q-2 23 15.5 40t41.5 17h576q23 0 40 -17.5t17 -39.5v-86v-490q0 -25 -17.5 -42t-39.5 -15h-86 q-25 0 -41.5 16.5t-16.5 40.5v268l-772 -770q-16 -16 -40.5 -16t-41.5 16l-79 80q-16 16 -16.5 41z" />
|
||||
<glyph unicode="" horiz-adv-x="1689" d="M0 584v368q0 33 22.5 54.5t55.5 21.5h428v293q0 41 37 57q39 14 67 -14l553 -553q16 -18 16.5 -44t-16.5 -42l-553 -553q-18 -18 -43 -18q-8 0 -24 4q-37 16 -37 57v291h-428q-33 0 -55.5 22.5t-22.5 55.5zM922 0v193h460q47 0 81 33.5t34 80.5v922q0 47 -33.5 80.5 t-81.5 33.5h-460v193h460q63 0 118.5 -24.5t97.5 -65.5t67 -97.5t25 -119.5v-922q0 -63 -25 -118.5t-67 -97.5t-97 -66.5t-119 -24.5h-460z" />
|
||||
<glyph unicode="" horiz-adv-x="1689" d="M0 1042v187q0 33 22.5 54.5t55.5 21.5h323q-2 12 -2 25v24v4q0 53 4.5 88t15.5 54.5t31.5 27.5t55.5 8h678q33 0 54.5 -8t32.5 -27.5t15 -54.5t4 -88v-25.5t-2 -27.5h324q33 0 55.5 -21.5t22.5 -54.5v-187q0 -63 -45.5 -130.5t-122 -128t-180 -106.5t-222.5 -65 q-51 -10 -91 -41.5t-40 -70.5q0 -35 17.5 -51.5t39 -31t40 -31.5t22.5 -52q4 -23 -2 -47q-4 -14 23.5 -23.5t67.5 -18.5t82 -22.5t64 -34.5q12 -10 19.5 -39.5t9.5 -64.5q2 -33 -6 -58.5t-29 -25.5h-985q-20 0 -28.5 25.5t-6.5 58.5q2 35 9.5 64.5t19.5 39.5q23 20 64 34 t80.5 23t68.5 18t25 24q-4 14 -4 25.5v21.5q2 35 21.5 52t42 31.5t39.5 31t17 51.5q0 39 -39.5 70.5t-93.5 41.5q-117 20 -220 66.5t-180 106t-122 127t-45 130.5zM154 1042q0 -20 23.5 -54t67.5 -70.5t106.5 -71.5t140.5 -60q-25 80 -44.5 175.5t-33.5 189.5h-260v-109z M1198 786q78 25 140.5 60t106.5 71.5t67.5 70.5t23.5 54v109h-262q-12 -94 -31.5 -189.5t-44.5 -175.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 193v1150q0 39 15.5 75t41 61.5t60.5 41t76 15.5h1150q80 0 136.5 -56.5t56.5 -136.5v-1150q0 -41 -15.5 -76t-41 -60.5t-61.5 -41t-75 -15.5h-337v25q0 39 2 97t-3.5 115.5t-24.5 104.5t-65 66q188 20 290 110t102 287q0 66 -22.5 128t-67.5 114q6 23 8 45t2 45 q0 41 -9.5 91t-31.5 85h-12q-43 2 -79 -8.5t-68 -27.5t-62.5 -37.5t-65.5 -39.5q-33 4 -65.5 6t-65.5 2t-65.5 -2t-65.5 -6q-35 18 -65.5 39t-62.5 38t-67.5 27.5t-79.5 8.5h-12q-23 -35 -32 -85t-9 -91q0 -23 2 -45.5t8 -44.5q-45 -51 -66.5 -114t-21.5 -128 q0 -193 95.5 -283t281.5 -112q-39 -16 -59.5 -50t-32.5 -75q-27 -8 -49.5 -15.5t-50.5 -7.5q-55 0 -88 28.5t-59.5 62.5t-56.5 62.5t-79 28.5q-4 0 -20.5 -2t-16.5 -12q0 -23 19.5 -32t31.5 -19q39 -31 56.5 -71t39 -76.5t62.5 -62.5t127 -26q35 0 80 11q0 -10 -1 -18.5 t-1 -16.5q0 -29 2 -59.5t-2 -59.5h-317q-80 0 -136.5 56.5t-56.5 136.5z" />
|
||||
<glyph unicode="" d="M0 39v614q0 16 11.5 27.5t27.5 11.5h229q16 0 27.5 -11t11.5 -28v-346h1229v346q0 16 11.5 27.5t27.5 11.5h229q16 0 27.5 -11t11.5 -28v-614q0 -39 -39 -39h-1765q-39 0 -39 39zM346 969.5q-6 15.5 16 38.5l504 505q23 23 55.5 23t55.5 -23l506 -505q23 -23 15.5 -38.5 t-38.5 -15.5h-307v-499q0 -33 -22.5 -55.5t-55.5 -22.5h-307q-33 0 -54.5 22.5t-21.5 55.5v499h-307q-33 0 -39 15.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1609" d="M2 514q-2 35 1 68.5t7 74.5q4 35 7 72t10 66q14 66 30.5 128t44.5 117q20 41 45 81t54 79q10 14 21 24.5t24 20.5q23 23 45 45.5t49 42.5t57.5 36.5t65.5 33.5q33 16 67.5 29.5t71.5 27.5q70 29 156 51l2 2q45 12 85 17.5t79 5.5q59 0 112.5 -9t106.5 -20q41 -8 85 -15 t93 -7h2q29 0 62.5 5t66.5 5q25 0 45.5 -6t32.5 -25q23 -31 26 -71.5t-2 -75.5q-4 -35 -8 -71t2 -72q4 -23 11.5 -39.5t15.5 -36.5q8 -18 11 -40t7 -42q18 -104 15.5 -195.5t-23 -170.5t-56.5 -148.5t-81 -132.5q-37 -49 -79 -97.5t-92 -91.5t-110.5 -77.5t-134.5 -59.5 q-76 -27 -158.5 -34t-158.5 -11h-31q-104 0 -194.5 16.5t-192.5 16.5h-4q-35 0 -77 -10.5t-83 -12.5h-2q-37 0 -65.5 17.5t-42.5 42.5q-20 35 -17.5 72.5t12.5 68.5t10.5 66.5t-5 75.5t-12.5 81t-9 82z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 1169q0 55 14.5 114.5t43 114t68.5 98.5t93 69q12 -2 26.5 0t26.5 2q10 0 30 -1l40 -2t38.5 -4.5t27.5 -7.5q8 -6 15 -18t12 -26.5t9.5 -30t8.5 -25.5q6 -18 23.5 -65.5t35.5 -97.5t32.5 -93t14.5 -53q0 -37 -24.5 -68t-54 -57.5t-54.5 -50t-25 -45.5q0 -20 16.5 -49 t26.5 -46q84 -145 188.5 -248.5t252.5 -187.5q18 -10 45.5 -27.5t50.5 -17.5t52.5 32t60 70.5t62 70.5t58.5 32q10 0 51.5 -22.5t89.5 -50t93 -55.5t61 -36q16 -10 46 -25.5t40 -35.5q2 -6 2 -23q0 -16 -3 -36.5t-8 -43t-12 -43t-13 -35.5q-18 -39 -59.5 -71.5t-92.5 -55 t-104.5 -36t-92.5 -13.5q-80 0 -153.5 25.5t-145.5 54.5q-123 45 -232.5 118t-203.5 164t-175 196.5t-144 215.5q-25 41 -52.5 95.5t-51 112t-39 113.5t-15.5 105z" />
|
||||
<glyph unicode="" d="M0 307v922q0 63 24.5 118.5t66.5 97.5t97.5 66.5t118.5 24.5h1075q63 0 118.5 -24.5t97.5 -66.5t67 -97.5t25 -118.5v-922q0 -63 -25 -118.5t-67 -97.5t-97 -66.5t-119 -24.5h-1075q-63 0 -118.5 24.5t-97.5 66.5t-66.5 97.5t-24.5 118.5zM193 307q0 -47 33.5 -80.5 t80.5 -33.5h1075q47 0 81 33.5t34 80.5v922q0 47 -34 80.5t-81 33.5h-1075q-47 0 -80.5 -33.5t-33.5 -80.5v-922z" />
|
||||
<glyph unicode="" horiz-adv-x="1253" d="M0 84v1337q0 47 34 81t81 34h1024q47 0 80.5 -34t33.5 -81v-1337q0 -47 -33.5 -81t-80.5 -34t-80 33l-432 432l-432 -432q-33 -33 -80 -33t-81 34t-34 81zM158 186l469 471l469 -471v1194h-938v-1194z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 193v1150q0 39 15.5 75t41 61.5t60.5 41t76 15.5h1150q80 0 136.5 -56.5t56.5 -136.5v-1150q0 -41 -15.5 -76t-41 -60.5t-61.5 -41t-75 -15.5h-1150q-80 0 -136.5 56.5t-56.5 136.5zM193 1040q2 -35 15 -76.5t30 -78.5q16 -37 33.5 -72t33.5 -63q74 -129 176.5 -241 t225.5 -190q31 -18 67.5 -36.5t75.5 -32.5q41 -16 83 -31.5t81 -21.5q63 -10 112.5 2t90.5 34q27 12 57.5 33.5t44.5 52.5q4 8 9 27t9 38t6.5 37.5t-2.5 29.5q-4 12 -24.5 22t-36.5 21q-43 25 -71.5 41t-67.5 38q-16 10 -36 23.5t-38 13.5q-23 0 -46.5 -27.5t-37.5 -43.5 q-12 -14 -36.5 -43t-47.5 -31q-14 -2 -32.5 10t-37.5 23q-106 59 -182 136t-135 177q-10 16 -21.5 37.5t-7.5 38.5q2 18 24.5 33.5t35.5 29.5q14 16 31.5 37t19.5 43q4 16 -5 38t-16 42q-16 43 -28.5 76t-26.5 76q-6 16 -12 40.5t-21 30.5q-8 4 -26.5 7t-39 4.5t-37.5 0 t-24 -1.5h-8q-33 -16 -62.5 -45.5t-51 -69.5t-34 -88t-9.5 -100z" />
|
||||
<glyph unicode="" d="M0 399q0 20 13.5 33.5t33.5 13.5q14 0 31 -12q123 -109 287 -108q59 0 117.5 15t107.5 48q-29 16 -47.5 42t-18.5 58q0 23 8 39q-18 6 -44.5 20.5t-51 34t-41 43t-16.5 46.5q0 16 10 28.5t25 22.5q-41 25 -76 74t-35 98q0 33 33 43q-35 35 -55.5 81t-20.5 95 q0 23 9.5 41.5t37.5 18.5q18 0 84 -27t142.5 -60.5t146.5 -67.5t98 -48q25 -14 47.5 -31.5t44.5 -36.5q20 51 47 106.5t60 106.5t73 96t89 74q8 6 24 6q18 0 27 -8q16 6 41.5 13.5t42.5 7.5q29 0 43 -27q31 0 56.5 -15.5t25.5 -50.5q0 -31 -27 -53q96 -43 159.5 -125 t90.5 -182q6 -2 23 -2q47 0 88 16.5t57 16.5q18 0 31.5 -14.5t13.5 -32.5q0 -23 -19.5 -48.5t-33.5 -39.5q23 4 42 -7.5t19 -38.5q0 -29 -26.5 -50t-61.5 -37.5t-72.5 -25.5t-58.5 -11q-43 -139 -133 -246t-210 -178.5t-258 -109.5t-275 -38q-219 0 -415 93.5t-325 273.5 q-8 16 -8 26z" />
|
||||
<glyph unicode="" horiz-adv-x="790" d="M0 862v203q0 16 11.5 28.5t27.5 12.5h125v102q0 358 366 359q123 0 232 -31q33 -10 29 -43l-27 -199q-4 -16 -16 -26q-16 -10 -31 -6q-35 8 -72.5 12t-66.5 4q-53 0 -65.5 -16.5t-12.5 -67.5v-88h223q14 0 29 -14q10 -10 10 -29l-17 -205q0 -16 -11 -25.5t-27 -9.5h-207 v-784q0 -16 -11.5 -27.5t-27.5 -11.5h-258q-16 0 -27.5 11.5t-11.5 27.5v784h-125q-16 0 -27.5 11.5t-11.5 27.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1847" d="M0 743q0 115 37 222.5t113 193.5l-3 4l3 2q-16 39 -21.5 81t-5.5 85q0 25 2 56.5t8 65.5t15.5 63.5t23.5 50.5h8q61 0 110.5 -12.5t94.5 -35t87 -52t91 -60.5q86 25 178.5 33t182.5 8t182 -8t180 -33q47 31 90 60.5t87 52t93.5 35t110.5 12.5h10q12 -20 21.5 -50 t15.5 -64t9 -65.5t3 -56.5q0 -43 -6 -85t-20 -81v-2l-2 -4q76 -86 112.5 -193.5t36.5 -222.5q0 -233 -66.5 -383.5t-188.5 -236.5t-292 -120t-376 -34q-207 0 -378 34t-292 120t-187.5 236.5t-66.5 383.5zM250 483q0 -145 64.5 -224t165 -116t219 -43t227.5 -6q74 0 152.5 2 t153.5 12.5t142.5 34t117.5 67.5t80 111.5t30 165.5q0 84 -27 147.5t-75 106.5t-114.5 64.5t-146.5 21.5q-78 0 -156.5 -7t-156.5 -7t-157 7t-157 7q-162 0 -262 -87t-100 -257zM494 524q0 66 26.5 113t65.5 47t66.5 -47t27.5 -113t-27.5 -112.5t-66.5 -46.5t-65.5 46.5 t-26.5 112.5zM795 258q-6 16 12 25q16 6 24 -13q27 -76 93 -75q31 0 56.5 20.5t35.5 54.5q8 20 26 13q16 -6 13 -25q-16 -47 -51 -75.5t-80 -28.5q-43 0 -78 28.5t-51 75.5zM864 369q0 -12 17.5 -21.5t42.5 -9.5t42 9.5t17 21.5t-17.5 21t-41.5 9q-25 0 -42.5 -9t-17.5 -21z M1167 524q0 -66 28 -112.5t67 -46.5t65.5 46.5t26.5 112.5t-27 113t-65 47q-39 0 -67 -47t-28 -113z" />
|
||||
<glyph unicode="" horiz-adv-x="1880" d="M0 117v626q0 49 35 84t82 35h665v156q0 113 43 213t118 175t175 118t213 43t213.5 -43t175 -118t117.5 -175.5t43 -212.5v-152q0 -33 -22.5 -55.5t-55.5 -22.5h-80q-33 0 -55 23t-22 55v152q0 66 -25 123t-67 99t-99 66.5t-123 24.5t-122 -24.5t-99 -66.5t-67.5 -99.5 t-24.5 -122.5v-156h119q47 0 81.5 -34.5t34.5 -84.5v-626q0 -47 -34.5 -82t-81.5 -35h-1020q-47 0 -82 35t-35 82zM494 164h266l-66 285q29 18 47.5 48.5t18.5 65.5q0 55 -39 95t-94 40t-94 -40t-39 -95q0 -35 18 -65.5t47 -46.5z" />
|
||||
<glyph unicode="" d="M0 154v1228q0 63 45 108.5t109 45.5h1536q63 0 108 -45t45 -109v-1228q0 -63 -45 -108.5t-108 -45.5h-1536q-63 0 -108.5 45t-45.5 109zM154 154h1536v575h-1536v-575zM154 1114h1536v268h-1536v-268zM260 250v115h307v-115h-307zM676 250v115h446v-115h-446z" />
|
||||
<glyph unicode="" horiz-adv-x="1566" d="M0 236q0 49 18.5 91t50 74.5t75 51t92.5 18.5t91 -18.5t74.5 -51t51 -74.5t18.5 -91t-18.5 -92.5t-51 -75t-74.5 -50t-91 -18.5t-92.5 18.5t-75 50t-50 74.5t-18.5 93zM0 819v158q0 35 25 57q23 23 53 23q2 0 3 -1t3 -1q193 -14 362.5 -95t301 -212.5t212 -301.5 t95.5 -362q4 -35 -21 -59q-23 -25 -57 -25h-158q-29 0 -51.5 20.5t-26.5 51.5q-12 133 -68.5 249.5t-145.5 205.5t-205.5 145.5t-249.5 68.5q-31 4 -51.5 27t-20.5 51zM0 1331v158q0 33 25 55q23 23 53 23h4q301 -16 565 -137t463 -320t319.5 -463t137.5 -565q4 -31 -23 -57 q-23 -25 -55 -25h-158q-31 0 -53.5 21.5t-24.5 52.5q-14 238 -110 446.5t-255 367.5t-368 255t-446 110q-31 2 -52.5 24.5t-21.5 53.5z" />
|
||||
<glyph unicode="" d="M0 193v382q0 23 6 45.5t12 45.5l238 727q20 63 75.5 103t121.5 40h938q66 0 121 -40t75 -103l238 -727q6 -23 12 -45.5t6 -45.5v-382q0 -41 -15.5 -76t-41 -60.5t-61 -41t-74.5 -15.5h-1458q-80 0 -136.5 56.5t-56.5 136.5zM154 193q0 -16 11 -27.5t28 -11.5h1458 q16 0 27.5 11t11.5 28v382q0 16 -11.5 27.5t-27.5 11.5h-1458q-16 0 -27.5 -11t-11.5 -28v-382zM213 768h1417l-188 578q-4 16 -19.5 26t-31.5 10h-938q-16 0 -31.5 -10t-20.5 -26zM1057 385q0 39 27.5 66.5t68.5 27.5q39 0 66.5 -27.5t27.5 -66.5q0 -41 -27.5 -68.5 t-66.5 -27.5q-41 0 -68.5 27.5t-27.5 68.5zM1364 385q0 39 27.5 66.5t68.5 27.5q39 0 66.5 -27.5t27.5 -66.5q0 -41 -27.5 -68.5t-66.5 -27.5q-41 0 -68.5 27.5t-27.5 68.5z" />
|
||||
<glyph unicode="" d="M0 754v229q0 63 45 108.5t109 45.5h499q115 0 245 33.5t255 90t235.5 128t186.5 147.5q63 0 108.5 -45t45.5 -109v-368q49 -12 81.5 -52.5t32.5 -93.5t-32.5 -93t-81.5 -52v-369q0 -63 -45.5 -108t-108.5 -45q-68 68 -164 132t-206.5 117.5t-227.5 91.5t-227 50 q-43 -12 -70 -40t-37 -62.5t-2 -70.5t37 -65q-25 -41 -23 -75.5t20.5 -66.5t49.5 -61.5t66 -58.5q-20 -43 -69.5 -65.5t-106 -25.5t-110.5 10.5t-85 43.5q-18 61 -40 125t-36 130.5t-14 138t24 151.5h-200q-63 0 -108.5 45t-45.5 109zM807 741q102 -16 206.5 -49t205 -78 t191.5 -99t165 -112v930q-76 -59 -166 -113.5t-190.5 -98.5t-205 -77.5t-206.5 -48.5v-254z" />
|
||||
<glyph unicode="" horiz-adv-x="1759" d="M0 317q104 78 172 172.5t109 201t60 224t28 240.5q6 84 56 159t126 131t163 89t167 33q74 0 163 -33t165.5 -88t129 -129t52.5 -158q6 -121 27.5 -239.5t63.5 -227t109.5 -204t167.5 -171.5q-4 -70 -56 -114.5t-120 -44.5h-469q-18 -82 -82.5 -135.5t-150.5 -53.5 t-151.5 53.5t-84.5 135.5h-469q-68 0 -120 45t-56 114zM238 317h1284q-78 86 -129.5 183.5t-84 202t-50 214t-25.5 222.5q-4 55 -41 104t-89 86t-111.5 57.5t-110.5 20.5q-47 0 -107.5 -21.5t-114 -56.5t-91.5 -83t-40 -99q-6 -111 -23.5 -222.5t-51 -218t-87 -205 t-128.5 -184.5zM713 209q0 -70 49 -119t119 -49q18 0 18 20t-18 21q-53 0 -91 37t-38 90q0 20 -19 20q-20 0 -20 -20z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 573q0 33 23 56l143 139l-143 139q-23 23 -23 56q0 25 16.5 45t40.5 26l195 49q-6 18 -15.5 48t-18.5 61t-16 59.5t-7 46.5q0 31 21.5 52.5t51.5 21.5q18 0 47 -7t60 -16.5t60.5 -18.5t47.5 -15l49 194q6 25 27 41.5t45 16.5q35 0 53 -23l142 -143l139 143q23 23 53 23 q27 0 47.5 -15.5t26.5 -42.5l49 -194q18 6 48 15t60.5 18.5t59.5 16.5t47 7q29 0 51.5 -21.5t22.5 -52.5q0 -18 -7 -46.5t-16.5 -59.5t-18.5 -60.5t-15 -48.5l194 -49q25 -6 41 -26.5t16 -44.5q0 -33 -22 -56l-145 -139l145 -139q23 -23 22 -56q0 -25 -16 -45t-41 -26 l-194 -49q6 -18 15 -48t18.5 -61t16.5 -59.5t7 -46.5q0 -29 -21.5 -51.5t-52.5 -22.5q-18 0 -47 7t-59.5 16.5t-60 18.5t-48.5 15l-49 -194q-6 -25 -26.5 -41.5t-45.5 -16.5q-33 0 -55 23l-139 143l-142 -143q-18 -23 -53 -23q-25 0 -45 16.5t-27 41.5l-49 194 q-18 -6 -47.5 -15t-60.5 -18.5t-59.5 -16.5t-47.5 -7q-31 0 -52 22.5t-21 51.5q0 18 7 46.5t16 59.5t18.5 60.5t15.5 48.5l-195 49q-25 6 -41 26.5t-16 44.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 193v643q0 49 35 83.5t84 34.5h348q27 14 42 30.5t34 39.5q16 20 33.5 38.5t33.5 37.5q35 35 77 68.5t65 74.5q25 43 29.5 99.5t17 106.5t44 84t109.5 34q61 0 111.5 -25.5t85.5 -68.5t54.5 -98.5t19.5 -112.5q0 -53 -15.5 -104.5t-38.5 -98.5h134l376 -2 q49 0 93.5 -17.5t76 -49.5t50 -75t18.5 -94q0 -49 -18.5 -92t-50 -74.5t-75.5 -49t-94 -17.5h-200q-10 -59 -39 -107q10 -59 -7.5 -117.5t-56.5 -103.5q0 -76 -28.5 -131t-75.5 -90t-109.5 -52.5t-132.5 -17.5q-78 0 -148.5 16.5t-136 36t-128 36t-123.5 16.5h-375 q-49 0 -84 34.5t-35 84.5zM233 276q0 -35 22.5 -57t57.5 -22q33 0 56.5 22.5t23.5 56.5q0 33 -23.5 56.5t-56.5 23.5q-35 0 -57.5 -23.5t-22.5 -56.5zM489 193q70 0 136.5 -16.5t133 -35t133 -35t138.5 -16.5q43 0 84 8t72 27.5t50 52.5t19 82q0 14 -1 26.5t-3 24.5 q35 16 53.5 53t18.5 74q0 39 -20 68q59 49 59 123q0 23 -12.5 43.5t-26.5 34.5q90 0 178 1t178 1q51 0 84 30.5t33 81.5q0 53 -32.5 85t-84.5 32q-172 0 -340 1t-338 1q0 41 16.5 78t35 74.5t34 78.5t15.5 91q0 33 -10.5 65.5t-29 59t-46 44t-64.5 17.5h-11t-11 -2 q-8 -4 -9 -8t-3 -13q-12 -59 -22.5 -123.5t-39.5 -117.5q-29 -51 -73 -88t-85 -78q-29 -31 -49 -56.5t-41.5 -48t-48.5 -42t-65 -35.5h-5v-643z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 821q0 51 18.5 94t50 75t75.5 49.5t94 17.5l376 2h134q-23 47 -38.5 98t-15.5 105q0 57 19.5 112.5t54.5 98.5t85 68.5t112 25.5q78 0 109.5 -34t43.5 -84t17.5 -106.5t29.5 -99.5q23 -41 65 -74.5t77 -68.5q16 -18 33.5 -37t33.5 -39q18 -23 33.5 -39t42.5 -31h348 q49 0 84 -34.5t35 -83.5v-643q0 -49 -35 -84t-84 -35h-375q-61 0 -123.5 -16.5t-128 -36t-136 -36t-148.5 -16.5q-70 0 -132.5 17.5t-109.5 52.5t-75.5 90t-28.5 131q-39 45 -56.5 103.5t-7.5 117.5q-29 47 -39 107h-200q-49 0 -93.5 17.5t-76 49t-50 74.5t-18.5 92z M121 821q0 -51 32.5 -81.5t84.5 -30.5q90 0 178 -1t178 -1q-14 -14 -26.5 -35t-12.5 -43q0 -74 59 -123q-20 -29 -20 -68q0 -37 18.5 -73.5t53.5 -53.5q-2 -12 -3 -24.5t-1 -26.5q0 -49 19 -82t50 -52.5t72 -27.5t84 -8q70 0 137.5 16.5t134 35t133 35t135.5 16.5v643h-4 q-41 16 -66.5 35.5t-47 42t-42 48t-48.5 56.5q-41 41 -85 78t-73 88q-29 53 -39 117.5t-23 123.5q-2 8 -3 12.5t-9 8.5q-4 2 -11 2h-11q-37 0 -65 -17.5t-46 -44t-28.5 -59.5t-10.5 -65q0 -49 15.5 -90.5t34 -79t34.5 -74.5t16 -78q-170 0 -337.5 -1t-339.5 -1 q-51 0 -84 -32t-33 -85zM1524 276q0 -35 23.5 -57t56.5 -22q35 0 57 22.5t22 56.5q0 33 -22.5 56.5t-56.5 23.5q-33 0 -56.5 -23.5t-23.5 -56.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 602q0 61 25.5 111.5t68.5 85.5t98.5 54t112.5 19q53 0 104.5 -15t98.5 -38v133l2 377q0 49 17.5 93t49 76t74.5 50.5t94 18.5q49 0 92.5 -18.5t75 -50.5t49 -76t17.5 -93v-201q59 -10 106 -38q59 10 118 -7.5t104 -56.5q76 0 131 -28.5t90 -76t52 -109.5t17 -132 q0 -78 -16 -148.5t-35.5 -136t-36 -128t-16.5 -124.5v-374q0 -49 -35 -84t-84 -35h-643q-49 0 -84 34.5t-35 84.5v348q-14 27 -30.5 42t-38.5 34q-20 16 -39 33.5t-37 33.5q-35 35 -68.5 77t-74.5 64q-43 25 -99.5 30t-106.5 17.5t-84 44t-34 109.5zM120 591q-1 -7 1 -11 q4 -8 8 -9.5t12 -3.5q59 -12 124 -22t118 -39q51 -29 88 -73t78 -85q31 -29 56.5 -49t48 -41.5t42 -48.5t35.5 -66v-4h643q0 70 16.5 136.5t35 133t35 133t16.5 138.5q0 43 -8.5 84t-28 71.5t-52 50t-81.5 19.5q-14 0 -26.5 -1t-25.5 -3q-16 35 -53 53.5t-74 18.5 q-39 0 -67 -21q-49 59 -123 60q-23 0 -43.5 -12.5t-34.5 -26.5q0 90 -1 178t-1 178q0 51 -30.5 84t-82.5 33q-53 0 -84.5 -33t-31.5 -84q0 -172 -1 -340t-1 -338q-41 0 -78 16.5t-75 35t-79 34t-90 15.5q-33 0 -65.5 -10.5t-59 -29t-43 -46t-16.5 -64.5q0 -4 -1 -11z M1210 -37q0 -35 23.5 -57.5t56.5 -22.5q35 0 57.5 22.5t22.5 57.5q0 33 -22.5 56.5t-57.5 23.5q-33 0 -56.5 -23.5t-23.5 -56.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 584q0 78 34 109.5t84 44t106.5 17.5t99.5 29q41 23 74.5 65t68.5 77q18 16 36.5 33.5t39.5 33.5q23 18 39 33.5t30 42.5v348q0 49 35 84t84 35h643q49 0 84 -35t35 -84v-375q0 -61 16.5 -123.5t36 -128t35.5 -136t16 -148.5q0 -70 -17 -132.5t-52 -109.5t-90.5 -75.5 t-130.5 -28.5q-45 -39 -103.5 -56.5t-118.5 -7.5q-47 -29 -106 -39v-200q0 -49 -17.5 -93.5t-49 -76t-74.5 -50t-93 -18.5q-51 0 -94 18.5t-74.5 50t-49 75.5t-17.5 94l-2 376v134q-47 -23 -98.5 -38.5t-104.5 -15.5q-57 0 -112.5 19.5t-98.5 54.5t-68.5 85t-25.5 112z M120 595q1 -7 1 -11q0 -37 16.5 -64.5t43 -46t59 -29t65.5 -10.5q49 0 90 15.5t79 34t75 35t78 16.5q0 -170 1 -338t1 -340q0 -51 31.5 -84t84.5 -33q51 0 82 32.5t31 84.5q0 90 1 178t1 178q14 -14 34.5 -26.5t43.5 -12.5q74 0 123 59q29 -20 67 -20q37 0 74 18.5t53 53.5 q12 -2 24.5 -3t27.5 -1q49 0 81.5 19t52 50t28 72t8.5 84q0 70 -16.5 137.5t-35 134t-35 133t-16.5 136.5h-643v-5q-16 -41 -35.5 -66.5t-42 -47t-48 -42t-56.5 -48.5q-41 -41 -78 -85t-88 -73q-53 -29 -117.5 -39t-124.5 -23l-12 -3t-8 -9q-2 -4 -1 -11zM1210 1223 q0 -33 23.5 -56.5t56.5 -23.5q35 0 57.5 23.5t22.5 56.5q0 35 -22.5 57.5t-57.5 22.5q-33 0 -56.5 -23t-23.5 -57z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 768q0 -29 20 -49l490 -490q20 -20 48.5 -20t49.5 20l74 74q20 20 20 48 t-20 50l-246 246h612q29 0 49.5 19.5t20.5 48.5v104q0 29 -20.5 49.5t-49.5 20.5h-612l246 246q20 20 20 48.5t-20 49.5l-74 74q-20 20 -48 20t-50 -20l-490 -490q-20 -20 -20 -49z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 717q0 -29 20.5 -49.5t48.5 -20.5h613l-246 -246q-20 -20 -20.5 -48.5 t20.5 -49.5l74 -74q20 -20 47.5 -20t50.5 20l489 490q20 20 20.5 49t-20.5 49l-489 490q-20 20 -49 20t-49 -20l-74 -74q-20 -20 -20.5 -48t20.5 -50l246 -246h-613q-29 0 -49 -19.5t-20 -48.5v-104z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 768q0 -29 20 -49l74 -74q20 -20 48 -20t50 20l246 246v-612q0 -29 19.5 -49.5 t47.5 -20.5h105q29 0 49.5 20.5t20.5 49.5v612l245 -246q20 -20 49 -20t50 20l73 74q20 20 20.5 48t-20.5 50l-489 490q-20 20 -49 20t-49 -20l-490 -490q-20 -20 -20 -49z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5t-311.5 62.5t-254 171t-171 254t-62.5 311.5zM240 769q0 -28 20 -50l490 -490q20 -20 48.5 -20t49.5 20l489 490q20 20 20.5 49 t-20.5 49l-73 74q-20 20 -48 20t-51 -20l-245 -246v612q0 29 -19.5 49.5t-48.5 20.5h-104q-29 0 -49.5 -20.5t-20.5 -49.5v-612l-246 246q-20 20 -49 20t-49 -20l-74 -74q-20 -20 -20 -48z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 162 63.5 307.5t173 255t254 173t308.5 63.5q162 0 307 -63.5t254.5 -173t173 -255t63.5 -307.5q0 -164 -63.5 -308.5t-173 -254t-254.5 -173t-307 -63.5q-164 0 -308.5 63.5t-254 173t-173 254t-63.5 308.5zM186 1141h4q4 0 12.5 3t8.5 -9q0 -4 -3 -10.5 t11 -6.5q4 0 5 6t3 0l4 -16v-2q0 -4 -5 -6t-3 -6q4 -4 9.5 -4h9.5l4 2l2 2q0 -6 6 -8.5t10 -2.5h2q0 -2 -4 -4t0 -6l23 -4v-2l14 -29q0 -4 -3 -10t-7 -6t-3 3t1 7t-2 7t-15 3q-2 0 -5 -1t-1 -5l12 -26l3 -2l2 -2q-10 0 -13.5 -24t-3.5 -34l4 -18l2 -6v-4l-4 -19l29 -43h6 q2 -4 -2 -8t-2 -8l8 -8q0 -10 4 -14.5t13 -12.5q-2 -12 20.5 -22.5t28.5 -14.5q8 -23 20 -45.5t29 -38.5l2 -14q0 -2 -5 -4t-1 -6l16 -7q4 4 10.5 -8t10.5 -16l-2 -6l12 -17l6 -2l4 8q-4 10 -14 26.5t-20.5 32t-17.5 28t-7 14.5t-2 16t-4 17q6 -4 15 -7.5t15 -7.5 q4 -25 19.5 -40t27.5 -34q-4 -4 0 -5t7 -1q4 -4 4 -14q14 -16 36.5 -44t22.5 -44v-2l-4 -14q6 -16 20.5 -25.5t28.5 -15.5h4q20 -10 41 -21.5t43 -19.5l23 14q8 -2 17 -10t20.5 -18.5t27 -19.5t35.5 -11q14 10 14 -5v-4l25 -30l4 -15q10 -6 20.5 -15t16.5 -20h4 q10 0 16.5 -9t16.5 -9q6 0 6 6q0 14 2 18.5t5 5.5t6 1t3 4l-4 6q-4 0 -6 -5t-6 -1l-14 -8l-17 4l-24 41l8 57q2 4 -7.5 9t-5.5 10q-14 8 -34 8q-4 0 -20.5 -3t-16.5 3t3 16t7 21.5t6 19.5t2 10l13 27l-3 4l-16 4q-4 0 -13 -6t-17.5 -14.5t-14.5 -16.5t-6 -14l-45 -10 q-14 0 -23 12q-4 16 -17 35.5t-13 34.5q0 23 8 43t-6 43q2 0 5 2t1 6l12 14l2 2l2 -2q14 10 37 7t29 14l16 -13q4 -2 9 4.5t5 10.5l-8 4l39 10l2 -6l19 2l22 -14q4 0 8 5t9 1l20 -21q-4 -8 -1 -12t3 -8q0 -6 10.5 -27.5t18.5 -21.5q10 0 9 13t-1 17q0 20 -8 39t-15 39v6 q0 10 12.5 17.5t12.5 9.5q10 8 22.5 16t18.5 19l8 16v10h6t4 6q0 2 -3 3.5t-7 5.5q-4 2 -8 6l6 4q4 6 6 15t-2 16l15 8q-2 -6 4 -8t10 0l10 16q-4 10 -5 7t5 7q10 4 19.5 9.5t19.5 5.5q2 -2 4 -2q6 0 6 2q0 10 -4 12l12 25q14 0 21 12l18 2q6 2 6 8v2l35 10l4 11l-10 14 q2 0 2 4t-4 6t-7 4t-7 4l-4 -2l4 2h6h13t9 9q0 12 -14 12q-18 0 -41.5 -8.5t-32.5 -28.5l-14 -8l18 18l3 6q0 4 -9.5 5.5t-5.5 1.5q18 0 27.5 4t15.5 9t12.5 10t18.5 9q23 -4 44 -2t44 2q6 4 12 8.5t8 10.5l23 4q4 -4 12 2t8 10q0 10 -11 13t-11 14q0 2 1 6t-3 4 q-6 0 -19.5 -6t-19.5 -10q-4 -2 -5 1t-1 7l2 -2l8 4l23 8l4 4q0 6 -7.5 8t-11.5 2t-12 -3t-8 3l2 4q-12 10 -21.5 22.5t-9.5 16.5t1 8.5t-5 4.5q-4 0 -7 -1t-3 5q0 4 -5 17t-14 13l-8 -8q0 -6 -6 -9t-6 -7h-4l-21 -12q-2 4 -5 2t-7 -2h-2l-2 -2q8 0 7 9t-7 9l-16 -4 q-4 0 -4.5 1t2 4t4.5 7t0 8t-6.5 1t-4.5 1h6l5 5q2 2 -1.5 7t-5.5 7l-22 4l-14 12q-2 -2 -7.5 3t-9.5 7l-16 -6l-39 9q-4 0 -8 -2.5t-4 -6.5t4 -6t4 -6t3 -21.5t-5 -13.5l-10 -14q2 -4 7 -7t10 -7.5t9 -10.5t2 -18l-45 -31v-4q0 -8 4 -15t8 -18q10 -4 9.5 -7t-7 -6t-12.5 -6 t-6 -5t-4 -2h-8h-4q0 2 2 3t2 5l-19 12v-2l-8 16q4 10 1 14.5t-3 10.5q0 16 -14.5 16t-30.5 -4q4 2 -1 6.5t-7 4.5q-16 0 -38 14t-36 14q-6 0 -14 -2t-15 -4q4 2 5 10l-13 23l-2 2q-6 0 -14 -5t-8 9q0 2 2 4t0 4q-2 12 5 20.5t11 18.5q4 4 4 8t4 4q8 0 15.5 4.5t17.5 6.5 l2 6q0 4 -21.5 7t-21.5 7l2 2q20 -6 30.5 -7t17.5 2t16.5 8t29.5 14q0 4 -21.5 8t-27.5 8h12q4 0 10.5 -2t10.5 -4q0 -4 6 -5t10 -1l15 10v6l-4 6l22 4q-2 2 1 4t5 2q6 0 12.5 -6t8.5 -6l20 8q-2 2 5.5 3t4.5 6l-14 16q-2 0 -3 3t1 3q10 0 6 10q-8 4 -17 9.5t-20 5.5 q-4 0 -9 -2t-5 -7q0 -4 5 -4t7 -4q4 -4 -2 -4t-6 -2q-8 0 -15 -12t-18 -17q-4 0 -3 2.5t-1 4.5q-2 4 -7 5t-5 5t5 13t-13 9q-8 0 -11.5 -6t-7.5 -12l-22 25l-17 2q0 8 3.5 14t-9.5 16q-6 4 -11 7.5t-11 3.5q-2 0 -9.5 -4.5t-13.5 -8.5t-6 -8t10 -4h-2q-6 0 -6 -8 q0 -2 9.5 -5t13.5 -3q4 2 6 -1.5t6 -3.5l8 3v-5q-2 -2 -2 -4l2 -8l-20 -10q-2 -2 -4 -2t-5 -2q0 -6 5.5 -12.5t-11.5 -6.5l-6 4q0 8 -16.5 13.5t-40 7.5t-47 3t-35.5 1l-33 -10l8 -19q-4 0 -5 -3t3 -5q-4 4 -15 14.5t-15 10.5l-17 4q-35 -2 -78 -33t-84 -72t-75.5 -84 t-53.5 -71zM471 674h2h-2zM487 1413q14 2 25.5 8t24.5 6l6 -4q6 -2 11 -2t9 -4q8 2 17 -2l6 4v8l-2 5l6 -2q6 0 12 10l-2 4q-4 2 -10 4t-10 2t-16.5 -5t-28 -11.5t-29.5 -12.5t-19 -8zM918 86q0 -4 3 -9t3 -9q0 -5 -2 -7q115 20 217 74.5t182 140.5h-2q-8 -4 -14 0l-5 -4 l-12 4h-4l-4 -8l2 8q-6 8 -14 15l-4 2q-4 0 -4 -8q2 16 -8.5 27.5t-26.5 11.5q0 -2 -2 -2h-4l-5 4h7l4 12l-11 8l-2 -2q-14 2 -20 16l-4 2l-2 -2l-4 -2q-12 -4 -21 -8q-12 4 -18 10l-27 -2q0 6 -4 12.5t-12 6.5q-10 0 -20.5 -2t-14.5 -13q0 -4 2 -8t4 -6v-8l-2 -6l-4 -2h-2 l-6 16l6 10q-2 4 -2 10.5t-2 10.5l-2 4h-6l-15 -10h-8l-4 -4q-2 -2 -2 -4t-2 -3l-2 3h-8q-8 -8 -9 -19l3 -4l-9 -6l-2 -4l-6 -4q0 -2 -1 -2t-1 -2v-2v-9l-2 -2v4l-2 2q-2 12 -23 21h-6v-4q2 -6 8.5 -10.5t10.5 -8.5q-2 2 -5 1t-3 -3v-4l14 -20v-39l4 -10q-4 -16 -16 -27v2 l-4 -2l-3 -2l-2 -10l2 -2v-2l-4 4l-2 -13l-12 -4q-6 -4 -5 -11t-5 -11l2 -4l-6 -6q0 -4 -1 -6.5t-1 -6.5l2 -14l6 -4l4 4l2 6l2 -12q0 -4 -4 -8q-6 -4 -12 -9.5t-6 -15.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1593" d="M8 242q0 33 12.5 62.5t34.5 51.5l609 609q-16 66 -17 122q0 98 38 186.5t102.5 153t151.5 102.5t185 38q94 0 181.5 -36t154.5 -101l-442 -162l-43 -236l184 -153l443 159q-10 -92 -50.5 -171t-104 -137t-145 -91t-174.5 -33q-61 0 -127 17l-606 -607q-47 -47 -112 -47 q-68 0 -115 47q-23 23 -50.5 47.5t-52 52t-41 58.5t-16.5 68zM203 242q0 -33 22.5 -56.5t57.5 -23.5q33 0 56 23.5t23 56.5q0 35 -23.5 57.5t-55.5 22.5q-35 0 -57.5 -23t-22.5 -57z" />
|
||||
<glyph unicode="" d="M0 76v217q0 31 22.5 53.5t53.5 22.5h1689q33 0 55.5 -22.5t22.5 -53.5v-217q0 -31 -22.5 -53.5t-55.5 -22.5h-1689q-31 0 -53.5 22.5t-22.5 53.5zM0 662v215q0 31 22.5 53t53.5 22h1689q33 0 55.5 -22.5t22.5 -52.5v-215q0 -33 -22.5 -55.5t-55.5 -22.5h-1689 q-31 0 -53.5 22.5t-22.5 55.5zM0 1243v217q0 31 22.5 53.5t53.5 22.5h1689q33 0 55.5 -22.5t22.5 -53.5v-217q0 -31 -22.5 -53.5t-55.5 -22.5h-1689q-31 0 -53.5 22.5t-22.5 53.5zM752 692h999v154h-999v-154zM1059 109h692v153h-692v-153zM1366 1274h385v153h-385v-153z " />
|
||||
<glyph unicode="" horiz-adv-x="1566" d="M0 1458q0 33 22.5 55.5t55.5 22.5h1411q33 0 55.5 -22.5t22.5 -55.5t-23 -55l-565 -565v-791q0 -33 -22.5 -55.5t-55.5 -22.5t-55 23l-236 235q-23 23 -22 56v555l-565 565q-23 23 -23 55z" />
|
||||
<glyph unicode="" d="M0 115v512h713q-2 -6 -2 -19v-153q0 -55 38.5 -95.5t96.5 -40.5h153q55 0 94.5 40t39.5 96v153q0 12 -3 19h713v-512q0 -47 -33.5 -81t-80.5 -34h-1614q-47 0 -81 34t-34 81zM0 743v371q0 47 34 81t81 34h424v231q0 31 21.5 53.5t53.5 22.5h615q33 0 55.5 -22.5 t22.5 -53.5v-231h422q47 0 80.5 -34t33.5 -81v-371h-1843zM692 1229h461v153h-461v-153zM825 455v153q0 18 21 19h153q18 0 19 -19v-153q0 -18 -19 -19h-153q-20 0 -21 19z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 80v477q0 51 24.5 61.5t59.5 -24.5l162 -162l340 338l-338 338l-164 -164q-35 -35 -59.5 -25.5t-24.5 60.5v477q0 31 23 57q27 23 57 23h477q51 0 61.5 -24.5t-24.5 -59.5l-160 -158l338 -338l332 334l-162 162q-35 35 -24.5 59.5t61.5 24.5h477q33 0 55 -23 q25 -25 25 -57v-477q0 -51 -24.5 -61.5t-59.5 24.5l-162 162l-334 -334l338 -336l158 160q35 35 59.5 24.5t24.5 -61.5v-477q0 -35 -25 -55q-23 -25 -55 -25h-477q-51 0 -61.5 24.5t24.5 59.5l166 166l-336 336l-340 -340l162 -162q35 -35 24.5 -59.5t-61.5 -24.5h-477 q-31 0 -55 25q-25 20 -25 55z" />
|
||||
<glyph unicode="" horiz-adv-x="1880" d="M0 852v152q0 18 1 47.5t10 56.5t29.5 46.5t57.5 19.5q-45 29 -71.5 75.5t-26.5 104.5q0 43 16.5 82t46 68.5t68.5 46t82 16.5q45 0 84 -16.5t67.5 -46t46 -68.5t17.5 -82q0 -57 -27.5 -104t-72.5 -76q37 0 57.5 -19.5t29.5 -46.5t11 -56.5t2 -47.5v-152 q-14 -8 -23.5 -18.5t-27.5 -10.5h-328q-16 0 -26.5 10.5t-22.5 18.5zM158 57v387q0 78 45 138.5t98 109.5q10 10 25.5 21.5t33.5 15.5q18 6 41 7t45 5q61 10 130 19.5t135 19.5q-90 57 -144.5 151.5t-54.5 207.5q0 88 34 166.5t92 136t136 91.5t166 34t166 -34t136 -91.5 t92 -136t34 -166.5q0 -113 -54 -207t-145 -152q66 -10 134.5 -19t130.5 -20q23 -4 45 -5t41 -7q18 -4 33.5 -15.5t27.5 -21.5q66 -59 103.5 -116.5t37.5 -131.5v-387q-12 -6 -20 -13t-18.5 -14t-23.5 -14.5t-36 -15.5h-1368q-35 0 -54.5 22.5t-43.5 34.5zM1452 852v152 q0 18 2 47.5t11.5 56.5t30 46.5t56.5 19.5q-45 29 -72.5 75.5t-27.5 104.5q0 43 16.5 82t46 68.5t68.5 46t84 16.5q43 0 82 -16.5t68.5 -46t46 -68.5t16.5 -82q0 -57 -26.5 -104t-71.5 -76q37 0 56.5 -19.5t28.5 -46.5t11 -56.5t2 -47.5v-152q-12 -8 -22.5 -18.5 t-26.5 -10.5h-328q-18 0 -27.5 10.5t-23.5 18.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 1137q0 88 34 166.5t92 137t136 92.5t168 34q86 0 166 -33t139 -92q8 -8 21.5 -20.5t26 -25t21.5 -25.5t9 -25q0 -18 -12 -31q-6 -8 -25 -12q-47 -10 -88 -22.5t-86 -31.5q-4 -4 -16 -4t-25.5 10.5t-31 21.5t-42 21.5t-57.5 10.5q-35 0 -66.5 -13.5t-54 -37t-36 -54 t-13.5 -67.5q0 -41 17.5 -75t43 -63.5t56.5 -56.5t57 -53l180 -178q23 -25 54.5 -37t66.5 -12q43 0 73 16t46 16q12 0 39 -21.5t55.5 -49t50 -55t21.5 -42.5q0 -29 -36 -51t-83 -38.5t-94 -26t-72 -9.5q-86 0 -164.5 33t-140.5 92l-303 305q-61 59 -94 139.5t-33 166.5z M578 1010q0 29 35.5 51t82.5 38.5t94 26t72 9.5q86 0 166 -33t139 -92l303 -305q61 -59 94 -139.5t33 -166.5q0 -90 -33.5 -167.5t-92 -136t-137.5 -92.5t-167 -34q-86 0 -165.5 34t-139.5 93q-8 8 -21.5 19.5t-25.5 25t-21.5 26.5t-9.5 26q0 18 13 28q6 8 24 12 q47 10 88 22.5t86 33.5q12 4 17 4q12 0 25.5 -10.5t30.5 -21.5t41 -21.5t58 -10.5q72 0 121 49.5t49 120.5q0 41 -17 76t-44 63.5t-56.5 55.5t-56.5 53l-178 180q-53 49 -123 50q-43 0 -72.5 -17.5t-46.5 -17.5q-12 0 -38.5 21.5t-55 49t-50 56t-21.5 41.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1880" d="M0 391q0 70 23.5 132.5t64.5 113.5t96.5 86t120.5 51q-33 41 -51 90t-18 105q0 66 24.5 123t66.5 99t99 66.5t123 24.5q113 0 196 -72q18 76 61.5 141.5t103 113.5t133 75t157.5 27q96 0 182 -37t149.5 -100.5t100.5 -149.5t37 -182q0 -57 -13 -109.5t-36 -99.5 q117 -59 188.5 -170t71.5 -248q0 -98 -37 -183t-101.5 -149.5t-149.5 -101.5t-183 -37h-1018q-80 0 -151.5 30.5t-125 84t-84 125t-30.5 151.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M16 72q-39 72 7 141l516 803v366h-78q-33 0 -54.5 22.5t-21.5 55.5q0 31 21.5 53.5t54.5 22.5h614q33 0 55.5 -22.5t22.5 -53.5q0 -33 -22.5 -55.5t-55.5 -22.5h-76v-368l514 -801q45 -70 7 -141q-18 -35 -51 -53.5t-70 -18.5h-1262q-37 0 -69.5 18.5t-51.5 53.5z M377 479h782l-313 490v413h-154v-411z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 180q0 86 44 168t113.5 146.5t154.5 103.5t169 39h13q18 25 57 60.5t63 58.5v12v12q-12 12 -28.5 27.5t-35 32t-33.5 32t-23 27.5q-84 -6 -172.5 33t-160 105.5t-116.5 150.5t-45 168q0 98 62.5 154.5t160.5 56.5q82 0 168 -39t155.5 -103.5t114 -146.5t44.5 -168 q0 -10 -1.5 -21.5t-3.5 -21.5l86 -76l34 17q34 18 90.5 46.5t129 65.5t148.5 76t150.5 77t135 69.5t102.5 52t52 26.5q16 8 37 9q14 0 39 -4.5t52.5 -9.5t53 -11t41.5 -8q29 -4 47.5 -26.5t18.5 -51.5q0 -43 -35 -66l-700 -485l700 -485q35 -23 35 -66q0 -29 -18.5 -51.5 t-47.5 -26.5q-16 -4 -41.5 -9t-53 -10t-52.5 -9.5t-39 -4.5q-10 0 -18.5 2.5t-18.5 6.5l-842 430l-86 -76q2 -10 3.5 -21.5t1.5 -21.5q0 -86 -44.5 -168t-114 -146.5t-155.5 -103.5t-168 -39q-98 0 -160.5 56.5t-62.5 154.5zM197 1358q0 -23 11 -49.5t27.5 -51t35 -45 t34.5 -34.5q35 -29 82 -54.5t94 -25.5q10 0 27 4v6q0 23 -11.5 48.5t-27.5 50t-34.5 46t-35.5 35.5q-35 29 -82 54.5t-94 25.5q-14 0 -26 -4v-6zM199 180q0 -6 2 -10q6 0 11 -1t11 -1q41 0 90 24.5t92.5 61.5t72 83t28.5 89q0 4 -1 5t-1 5q-8 2 -23 2q-41 0 -90 -24.5 t-92 -61.5t-71.5 -83t-28.5 -89zM586 616q53 -25 82 -69l108 96l45 -27l1016 703l-172 31l-975 -498l6 -127zM586 920l35 -35q12 29 36.5 41t53.5 26l-43 37q-29 -45 -82 -69zM741 768q0 35 23.5 57.5t58.5 22.5q33 0 55.5 -22.5t22.5 -57.5q0 -33 -22.5 -56.5t-57.5 -23.5 q-33 0 -56.5 23.5t-23.5 56.5zM903 575l762 -389l172 31l-727 502z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 385v707q0 33 16.5 70.5t38.5 60.5l258 258q23 23 61 39t70 16h463q31 0 53.5 -22.5t22.5 -53.5v-250q16 8 35.5 13.5t40.5 5.5h463q31 0 53 -22.5t22 -53.5v-1075q0 -33 -22.5 -55.5t-52.5 -22.5h-830q-33 0 -55.5 22.5t-22.5 55.5v229h-536q-33 0 -55.5 22.5 t-22.5 55.5zM154 461h460v293q0 45 10.5 87t45.5 74l159 162v305h-278v-321q0 -31 -22.5 -53.5t-53.5 -22.5h-321v-524zM186 1139h211v211zM768 154h676v921h-279v-321q0 -31 -22.5 -53.5t-52.5 -22.5h-322v-524zM801 831h211v211z" />
|
||||
<glyph unicode="" horiz-adv-x="1470" d="M0 1128q0 90 35 170t94 139.5t139 94.5t170 35q88 0 169 -34t143 -95l655 -656q12 -12 12 -28q0 -10 -11 -26.5t-26.5 -32t-32 -27t-26.5 -11.5q-16 0 -29 13l-655 655q-41 41 -92 61.5t-107 20.5q-57 0 -108 -21.5t-89 -59.5t-59.5 -89t-21.5 -109q0 -55 20.5 -106 t61.5 -92l745 -746q55 -55 133 -55q39 0 74 15.5t60.5 41t41 60.5t15.5 73q0 78 -56 134l-563 563q-29 29 -69 28q-41 0 -71 -29.5t-30 -70.5t29 -70l475 -475q12 -12 12 -28q0 -10 -11 -26.5t-26.5 -32t-32 -27t-26.5 -11.5q-16 0 -29 13l-475 473q-35 37 -55.5 85 t-20.5 99q0 53 20.5 100.5t55.5 83t83.5 56t101.5 20.5q51 0 99 -20.5t85 -55.5l561 -563q102 -102 102 -246q0 -74 -27.5 -137t-74.5 -110t-110.5 -75t-137.5 -28q-143 0 -246 103l-745 745q-61 61 -95 142t-34 169z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 154v1228q0 63 45 108.5t109 45.5h1075q63 0 108 -45l154 -154q45 -45 45 -108v-1075q0 -63 -45 -108.5t-109 -45.5h-1228q-63 0 -108.5 45t-45.5 109zM154 846h1075v536h-1075v-536zM846 922v385h190v-385h-190z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 193v1150q0 39 15.5 75t41 61.5t60.5 41t76 15.5h1150q80 0 136.5 -56.5t56.5 -136.5v-1150q0 -41 -15.5 -76t-41 -60.5t-61.5 -41t-75 -15.5h-1150q-80 0 -136.5 56.5t-56.5 136.5z" />
|
||||
<glyph unicode="" d="M0 78v215q0 31 22.5 53.5t55.5 22.5h1689q31 0 53.5 -22.5t22.5 -53.5v-215q0 -33 -22.5 -55.5t-53.5 -22.5h-1689q-33 0 -55.5 22.5t-22.5 55.5zM0 659v218q0 31 22.5 53t55.5 22h1689q31 0 53.5 -22.5t22.5 -52.5v-218q0 -31 -22.5 -53t-53.5 -22h-1689 q-33 0 -55.5 22.5t-22.5 52.5zM0 1243v217q0 31 22.5 53.5t55.5 22.5h1689q31 0 53.5 -22.5t22.5 -53.5v-217q0 -31 -22.5 -53.5t-53.5 -22.5h-1689q-33 0 -55.5 22.5t-22.5 53.5z" />
|
||||
<glyph unicode="" d="M0 211q0 39 15.5 75t41 61.5t60.5 40.5t76 15q39 0 73.5 -15t61 -40.5t42 -61.5t15.5 -75q0 -41 -15.5 -76t-42 -60.5t-61.5 -41t-73 -15.5q-80 0 -136.5 56.5t-56.5 136.5zM0 768q0 39 15.5 75t41 61.5t60.5 41t76 15.5q39 0 73.5 -15.5t61 -41t42 -61.5t15.5 -75 q0 -41 -15.5 -76t-42 -60.5t-61.5 -41t-73 -15.5q-41 0 -76 15.5t-60.5 41t-41 60.5t-15.5 76zM0 1325q0 39 15.5 75t41 61.5t60.5 41t76 15.5q39 0 73.5 -15.5t61 -41t42 -61.5t15.5 -75q0 -41 -15.5 -76t-42 -60.5t-61.5 -40.5t-73 -15q-41 0 -76 15t-60.5 40.5t-41 60.5 t-15.5 76zM522 154v114q0 33 22.5 55.5t55.5 22.5h1167q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -54.5t-53.5 -21.5h-1167q-33 0 -55.5 21.5t-22.5 54.5zM522 711v114q0 33 22.5 55.5t55.5 22.5h1167q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -55.5t-53.5 -22.5 h-1167q-33 0 -55.5 22.5t-22.5 55.5zM522 1268v114q0 33 22.5 55.5t55.5 22.5h1167q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -55.5t-53.5 -22.5h-1167q-33 0 -55.5 22.5t-22.5 55.5z" />
|
||||
<glyph unicode="" d="M0 594q0 55 30.5 90t68.5 61.5t69 50t31 56.5q0 29 -17.5 44t-46.5 15q-25 0 -44 -15t-34 -36l-53 37q23 39 58.5 60.5t78.5 21.5q55 0 96.5 -32t41.5 -91q0 -49 -30 -80t-67 -55.5t-67.5 -47t-30.5 -55.5h143v54h66v-115h-289q-2 10 -3 18.5t-1 18.5zM4 55l37 54 q6 -4 12 -10.5t15 -10.5q12 -8 29.5 -14t37.5 -6q35 0 55.5 18t20.5 47q0 31 -23.5 48.5t-58.5 17.5h-23l-16 37l90 108l6 6t7 6l4 6h-9q-4 -2 -14 -2h-92v-49h-66v111h263v-53l-97 -115q41 -6 74 -35t33 -82t-38 -95t-110 -42q-35 0 -60.5 9t-41.5 20q-25 14 -35 26z M14 1434l105 102h67v-360h93v-62h-259v62h93v258v8h-2q-10 -16 -22.5 -28.5t-29.5 -27.5zM522 154v114q0 33 22.5 55.5t55.5 22.5h1167q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -54.5t-53.5 -21.5h-1167q-33 0 -55.5 21.5t-22.5 54.5zM522 711v114q0 33 22.5 55.5 t55.5 22.5h1167q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -55.5t-53.5 -22.5h-1167q-33 0 -55.5 22.5t-22.5 55.5zM522 1268v114q0 33 22.5 55.5t55.5 22.5h1167q31 0 53.5 -22.5t22.5 -55.5v-114q0 -33 -22.5 -55.5t-53.5 -22.5h-1167q-33 0 -55.5 22.5t-22.5 55.5z " />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 692v152h1536v-152h-1536zM268 1114q0 117 44 202t118 141t170 83t203 27q88 0 176 -20.5t172 -49.5q20 -72 27.5 -156t7.5 -157q0 -10 -1 -22.5t-3 -24.5l-13 -2q-23 2 -50 2t-50 6q-18 59 -44 114.5t-62.5 98.5t-88 68.5t-122.5 25.5q-49 0 -94.5 -13.5t-80 -40 t-56 -66.5t-21.5 -93q0 -59 28.5 -102t75.5 -75t105.5 -54.5t118 -42t113.5 -39t93 -41.5h-696q-33 53 -51.5 110.5t-18.5 120.5zM285 310v63v45l110 2q31 -72 64 -134.5t76 -108.5t104 -71.5t152 -25.5q55 0 110 16.5t100.5 48t74 78.5t28.5 109q0 76 -49 128t-119 88 t-146.5 59.5t-132.5 45.5h617q8 -16 15 -38.5t10.5 -48t5.5 -50t2 -43.5q0 -131 -47.5 -226t-127 -156.5t-186 -91.5t-225.5 -30q-53 0 -93 4t-78 12.5t-78 20.5t-93 29q-12 4 -38 12t-36 16q-8 6 -12 50.5t-6 96.5t-2 100z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 0v154h1536v-154h-1536zM0 1532q10 2 19.5 2h19.5q72 0 140.5 -5t137.5 -5q100 0 200.5 2t199.5 6q-4 -16 -1 -36.5t3 -37.5v-8q-66 -10 -108 -7t-65.5 -5t-32.5 -39t-9 -109q0 -137 4 -272t10 -273q8 -147 88 -237t238 -90q125 0 207 29.5t131 88t69.5 146.5t20.5 203 q0 20 -2 65t-5 102.5t-8.5 119t-11.5 113.5t-13 89t-15 45q-33 33 -78 33q-6 0 -23.5 -1t-36 -1t-34 1t-21.5 3l2 82q82 4 163 -3t165 -7q39 0 77.5 5t79.5 5q4 0 9.5 -1t9.5 -1q2 -12 4 -24.5t2 -24.5t-4 -29q-23 -6 -52.5 -8t-58 -7t-48 -16.5t-19.5 -38.5q0 -14 1 -27 t3 -28q2 -6 5 -38.5t5 -79t4 -101.5t4 -103t3 -85t1 -50q0 -37 -2 -80.5t-8 -89t-17.5 -87.5t-29.5 -74q-41 -68 -104.5 -114t-137 -72.5t-153.5 -38t-154 -11.5q-72 0 -144.5 9.5t-140.5 35.5q-96 35 -151 88.5t-84 121t-36 148.5t-7 173v321v42t-1 62.5t-5 60.5t-10 38 q-12 16 -37 23.5t-53.5 10.5t-56.5 3t-44 4z" />
|
||||
<glyph unicode="" d="M0 115v1306q0 47 34 81t81 34h1614q47 0 80.5 -34t33.5 -81v-1306q0 -47 -33.5 -81t-80.5 -34h-1614q-47 0 -81 34t-34 81zM154 154h460v335h-460v-335zM154 565h460v332h-460v-332zM154 975h460v332h-460v-332zM692 154h461v335h-461v-335zM692 565h461v332h-461v-332z M692 975h461v332h-461v-332zM1229 154h461v335h-461v-335zM1229 565h461v332h-461v-332zM1229 975h461v332h-461v-332z" />
|
||||
<glyph unicode="" d="M0 197q0 39 29 61l1579 1247q20 17 47 17q35 0 59 -29q10 -12 29.5 -33.5t38 -44t32 -47.5t13.5 -43q0 -39 -29 -61l-1579 -1248q-20 -16 -47 -16q-37 0 -59 29q-10 12 -30 33.5t-38 44t-31.5 47t-13.5 43.5zM256 922l117 36l37 117l34 -117l119 -36l-119 -37l-34 -117 l-37 117zM373 1229l235 71l72 236l72 -236l235 -71l-235 -72l-72 -235l-72 235zM942 1382l117 37l37 117l37 -117l116 -37l-116 -36l-37 -117l-37 117zM1286 1153l94 -121l369 291l-94 121zM1536 885l117 35l37 118l36 -118l117 -35l-117 -37l-36 -117l-37 117z" />
|
||||
<glyph unicode="" d="M0 358v404q0 25 6 51.5t17.5 53t27 51t31.5 40.5l223 222q16 16 41 31.5t51.5 26.5t53 17.5t51.5 6.5h80v198q0 31 22.5 53.5t52.5 22.5h1108q33 0 55.5 -22.5t22.5 -53.5v-1102q0 -31 -22.5 -53t-55.5 -22h-75v-7q0 -63 -25 -119.5t-65.5 -97.5t-97 -65.5t-120.5 -24.5 q-63 0 -119.5 24.5t-97.5 65.5t-65.5 97.5t-24.5 119.5v7h-307v-7q0 -63 -24.5 -119.5t-65.5 -97.5t-97.5 -65.5t-119.5 -24.5t-119.5 24.5t-97.5 65.5t-65.5 97.5t-24.5 119.5v7h-78q-31 0 -53.5 22.5t-22.5 52.5zM193 700h387v369h-78q-10 0 -31.5 -8t-30.5 -17l-223 -221 q-8 -8 -16 -29.5t-8 -31.5v-62zM346 276q0 -47 34 -80.5t81 -33.5t80.5 33.5t33.5 80.5t-33.5 81t-80.5 34t-81 -33.5t-34 -81.5zM1268 276q0 -47 33.5 -80.5t80.5 -33.5t81 33.5t34 80.5t-33.5 81t-81.5 34q-47 0 -80.5 -33.5t-33.5 -81.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 768q0 166 62.5 311.5t171 254t254 171t311.5 62.5t311 -62.5t254 -171t171 -254t62 -311.5t-62 -311.5t-171 -254t-254 -171t-311 -62.5q-59 0 -115.5 8.5t-112.5 24.5q23 35 46.5 80t35.5 92l11 41q6 23 16 66t29 112q23 -41 76 -70.5t118 -29.5q96 0 176 41 t136.5 114.5t88 174t31.5 217.5q0 88 -35.5 171t-102.5 147.5t-160 102t-208 37.5q-141 0 -248.5 -46t-179 -118.5t-107.5 -160.5t-36 -174q0 -104 40 -187.5t124 -117.5q31 -10 41 20q2 10 7 31.5t9 32.5q4 16 1 23t-13 22q-53 59 -53 155q0 76 27.5 145.5t78.5 122t124 84 t163 31.5q80 0 142.5 -23.5t105.5 -64.5t64.5 -96t21.5 -121q0 -86 -18.5 -164t-52.5 -136t-80 -92t-103 -34q-31 0 -57.5 12.5t-45 34t-25.5 49t1 60.5q18 76 44.5 151.5t26.5 130.5q0 49 -26.5 84t-81.5 35q-66 0 -110 -58.5t-44 -146.5q-2 -23 2 -45q2 -18 7.5 -40.5 t15.5 -41.5q-33 -141 -53.5 -225t-30.5 -131q-12 -55 -18 -80q-10 -45 -13.5 -93t-1.5 -89q-104 45 -192 119.5t-151.5 169t-98.5 207t-35 235.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 193v1150q0 39 15.5 75t41 61.5t60.5 41t76 15.5h1150q80 0 136.5 -56.5t56.5 -136.5v-1150q0 -41 -15.5 -76t-41 -60.5t-61.5 -41t-75 -15.5h-829q27 39 59.5 95.5t49.5 117.5l10 41q6 25 17.5 68t29.5 112q20 -41 75.5 -70.5t121.5 -29.5q96 0 176 42t137 115.5 t89 175t32 220.5q0 90 -37 173t-103.5 147.5t-161 102.5t-208.5 38q-143 0 -251 -46.5t-180.5 -120t-108.5 -162.5t-36 -175q0 -104 40 -188.5t124 -118.5q14 -6 25.5 -1t15.5 21q4 10 8 31.5t8 34.5q8 23 -12 43q-23 29 -37 67.5t-14 91.5q0 76 27.5 145.5t79 123t124 85 t164.5 31.5q82 0 144.5 -23.5t105.5 -64.5t64.5 -97t21.5 -124q0 -86 -18.5 -164t-52 -136t-81 -93t-104.5 -35q-31 0 -57.5 12.5t-45 34t-25.5 49t1 60.5q18 78 45 154.5t27 131.5q0 49 -26.5 85t-82.5 36q-66 0 -110.5 -59t-44.5 -150q-2 -23 2 -45q4 -43 22 -84 q-35 -141 -54.5 -226t-29.5 -132q-12 -55 -18 -80q-16 -70 -14 -142.5t6 -117.5h-260q-80 0 -136.5 56.5t-56.5 136.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 342v438q55 -68 120.5 -96.5t153.5 -28.5h36t34 4q-8 -23 -14 -42t-6 -42q0 -41 18 -77.5t43 -67.5q-104 -4 -198.5 -22.5t-186.5 -65.5zM0 1214v129q0 39 15.5 75t41 61.5t60.5 41t76 15.5h1150q80 0 136.5 -56.5t56.5 -136.5v-1150q0 -41 -15.5 -76t-41 -60.5 t-61.5 -41t-75 -15.5h-583q23 39 36 81t13 89q0 70 -21.5 121t-54.5 90t-70.5 69.5t-70.5 57.5t-54.5 53.5t-21.5 59.5q0 49 34 81.5t76 72.5t75.5 99.5t33.5 163.5q0 78 -39 157t-106 122h131l133 76h-428q-129 0 -237.5 -36t-188.5 -143zM2 170q14 57 55 96t96.5 61.5 t115 33t110.5 10.5h31.5t31.5 -2q37 -27 78 -54.5t75 -61.5t55.5 -75t21.5 -92q0 -47 -19 -86h-460q-72 0 -126.5 49t-64.5 121zM102 1094q0 43 11.5 85t35 73.5t59.5 51t85 19.5q68 0 118 -41t81.5 -100.5t47 -128t15.5 -123.5q0 -45 -9 -84t-30.5 -68.5t-56.5 -47 t-84 -17.5q-66 0 -116 39t-85 96t-53.5 123.5t-18.5 122.5zM854 1051h223v-224h109v224h223v108h-223v225h-109v-225h-223v-108z" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 262q0 100 56.5 166t139.5 105.5t179 56t174 18.5q-23 29 -41.5 64t-18.5 76q0 23 6.5 41t14.5 40q-16 -4 -33.5 -4h-34.5q-68 0 -130 23.5t-108 66.5t-74 101.5t-28 130.5q0 68 25 128t67 109.5t98 84t120 49.5q88 18 176 18h411l-127 -74h-127q72 -43 107 -120.5 t35 -157.5q0 -94 -33 -149.5t-73 -94.5t-72.5 -70.5t-32.5 -78.5q0 -45 44 -82t97 -82t97 -107.5t44 -161.5q0 -102 -50 -175.5t-126.5 -121t-170 -70t-181.5 -22.5q-66 0 -141.5 15.5t-140 50.5t-106.5 90t-42 137zM174 307q0 -68 35 -116t87 -78.5t114.5 -44t117.5 -13.5 q51 0 104.5 11.5t96.5 38t69.5 68.5t26.5 103q0 49 -21.5 89.5t-53 72t-70.5 59t-76 52.5q-14 2 -29.5 3t-29.5 1q-57 0 -123 -12.5t-121 -41t-91 -75.5t-36 -117zM276 1247q0 -53 17.5 -117.5t51.5 -120t82.5 -92t111.5 -36.5q96 0 134 61.5t38 147.5q0 53 -14.5 118.5 t-45 124t-78 97t-112.5 38.5q-47 0 -82 -18t-57.5 -49t-34 -71t-11.5 -83zM999 1206h215v-215h107v215h215v105h-215v217h-107v-217h-215v-105z" />
|
||||
<glyph unicode="" d="M0 78v1382q0 31 22.5 53.5t55.5 22.5h1689q31 0 53.5 -22.5t22.5 -53.5v-1382q0 -33 -22.5 -55.5t-53.5 -22.5h-1689q-33 0 -55.5 22.5t-22.5 55.5zM154 461q63 0 119.5 -24.5t97.5 -65.5t65.5 -97.5t24.5 -119.5h921q0 63 25 119.5t65.5 97.5t97 65.5t120.5 24.5v614 q-63 0 -120 24.5t-97.5 65.5t-65.5 97.5t-25 119.5h-921q0 -63 -24.5 -119.5t-65.5 -97.5t-97.5 -65.5t-119.5 -24.5v-614zM539 768q0 104 29.5 195.5t81.5 159t122 106.5t150 39t149.5 -39t121.5 -106.5t83 -159t31 -195.5t-31 -195.5t-83 -159t-122 -106.5t-149 -39 q-80 0 -150 39t-122 106.5t-81.5 159t-29.5 195.5zM692 969l94 -99l39 35q8 6 11.5 13.5t7.5 11.5q4 2 8 10h2v-16q0 -8 -1 -16.5t-1 -18.5v-283h-139v-129h438v129h-141v529h-140z" />
|
||||
<glyph unicode="" horiz-adv-x="1228" d="M6 967q20 47 72 47h1075q50 0 70 -47t-17 -84l-536 -537q-27 -23 -56 -22q-29 0 -55 22l-536 537q-37 37 -17 84z" />
|
||||
<glyph unicode="" horiz-adv-x="1228" d="M6 371q-20 47 17 84l536 536q23 23 55 23q31 0 54 -23l538 -536q37 -37 17 -84t-70 -47h-1077q-50 0 -70 47z" />
|
||||
<glyph unicode="" horiz-adv-x="692" d="M0 768q0 33 23 55l538 537q16 16 38 21t44 -5q23 -8 36 -27.5t13 -41.5v-1076q0 -25 -13 -43t-36 -28t-44 -5t-38 21l-538 539q-23 23 -23 53z" />
|
||||
<glyph unicode="" horiz-adv-x="692" d="M0 231v1076q0 49 47 69t84 -16l539 -537q23 -23 22 -55q0 -31 -22 -53l-539 -539q-37 -37 -84 -16q-47 20 -47 71z" />
|
||||
<glyph unicode="" d="M0 115v1306q0 47 34 81t81 34h1614q47 0 80.5 -34t33.5 -81v-1306q0 -47 -33.5 -81t-80.5 -34h-1614q-47 0 -81 34t-34 81zM154 154h692v1153h-692v-1153zM999 154h691v1153h-691v-1153z" />
|
||||
<glyph unicode="" horiz-adv-x="1228" d="M0 584q0 31 22.5 54.5t53.5 23.5h1075q33 0 55.5 -23t22.5 -55q0 -33 -23 -56l-536 -536q-23 -23 -56 -23t-55 23l-536 536q-23 23 -23 56zM0 952q0 33 23 56l536 536q23 23 55 23q33 0 56 -23l536 -536q23 -23 23 -56q0 -31 -22.5 -54.5t-55.5 -23.5h-1075 q-31 0 -53.5 23t-22.5 55z" />
|
||||
<glyph unicode="" horiz-adv-x="1228" d="M0 584q0 31 22.5 54.5t53.5 23.5h1077q31 0 53.5 -23t22.5 -55q0 -33 -23 -56l-536 -536q-23 -23 -56 -23q-35 0 -53 23l-538 536q-23 23 -23 56z" />
|
||||
<glyph unicode="" horiz-adv-x="1228" d="M0 952q0 33 23 56l536 536q23 23 55 23q33 0 56 -23l536 -536q23 -23 23 -56q0 -31 -22.5 -54.5t-53.5 -23.5h-1077q-31 0 -53.5 23t-22.5 55z" />
|
||||
<glyph unicode="" d="M0 115v905q10 -10 20.5 -17.5t20.5 -15.5q129 -96 256 -191.5t252 -195.5q39 -31 82 -62.5t89 -57t96.5 -41t103.5 -15.5q55 0 105 15.5t96 40t89 56t84 64.5q125 100 252 195.5t256 191.5q10 8 20.5 15.5t20.5 17.5v-905q0 -47 -33.5 -81t-80.5 -34h-1614q-47 0 -81 34 t-34 81zM2 1434q0 41 36 71.5t77 30.5h1614q41 0 76.5 -30.5t35.5 -71.5q0 -31 -18.5 -69t-45 -75t-57 -67.5t-53.5 -48.5q-123 -92 -241.5 -182.5t-239.5 -182.5q-25 -18 -57.5 -45t-67.5 -51.5t-71 -42t-66 -17.5h-2h-2q-31 0 -67 17.5t-70.5 42t-67.5 51.5t-58 45 q-121 92 -239.5 182t-241.5 183q-23 18 -53.5 48.5t-57 67.5t-45 75t-18.5 69z" />
|
||||
<glyph unicode="" horiz-adv-x="1576" d="M0 1376q0 39 15.5 74t41 60.5t60 41t73.5 15.5t74 -15.5t61.5 -41t41 -60.5t14.5 -74t-14.5 -73.5t-41 -60t-61.5 -41t-74 -15.5t-73.5 15.5t-60 41t-41 60t-15.5 73.5zM10 41v991q0 16 12.5 28.5t28.5 12.5h281q16 0 28.5 -12t12.5 -29v-991q0 -16 -12.5 -28.5 t-28.5 -12.5h-281q-16 0 -28.5 12.5t-12.5 28.5zM524 41v991q0 16 12.5 28.5t28.5 12.5h273q33 0 37 -25.5t4 -48.5q57 53 129.5 76t150.5 23q190 0 304 -95.5t114 -293.5v-668q0 -16 -12.5 -28.5t-28.5 -12.5h-289q-16 0 -27.5 12.5t-11.5 28.5v604q0 76 -27.5 116 t-111.5 40q-53 0 -89 -17.5t-56.5 -47t-28.5 -70.5t-8 -88v-537q0 -16 -12.5 -28.5t-28.5 -12.5h-281q-16 0 -28.5 12.5t-12.5 28.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1591" d="M0 662q-4 39 35 45l158 20q12 2 30 -8q12 -8 15 -27q14 -102 63 -191t123 -153.5t169 -101.5t200 -37q115 0 217 44t178 120t120 177t44 218t-44 218t-120 177t-178.5 120t-216.5 44q-94 0 -181.5 -30.5t-158.5 -88.5l159 -159q35 -35 24 -58.5t-58 -23.5h-463 q-16 0 -29.5 6t-24.5 16q-25 25 -24 55v463q0 47 24.5 57.5t59.5 -24.5l162 -162q109 92 238.5 140.5t271.5 48.5q166 0 311 -62.5t253.5 -171t171 -254t62.5 -311.5t-62.5 -311.5t-171 -254t-254 -171t-310.5 -62.5q-150 0 -285 52.5t-241.5 145.5t-176.5 220t-90 275z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 651q0 49 37 91t88 42q35 0 68 -22q-20 14 -21 37q0 8 8 24l334 502q14 20 37 21q16 0 24 -9q-25 18 -40 43t-15 56q0 49 38 90t87 41q33 0 62 -19l514 -342q23 -16 36 -40.5t13 -53.5q0 -25 -10.5 -48.5t-26.5 -41.5t-40 -29.5t-48 -11.5q-33 0 -68 23q20 -14 21 -37 q0 -14 -8 -25l-105 -158l227 -151q14 4 28 6t28 2q53 0 94 -29l475 -315q37 -27 58.5 -65.5t21.5 -84.5q0 -74 -52.5 -126t-125.5 -52q-55 0 -99 31l-475 315q-70 47 -75 131l-228 152l-106 -158q-14 -20 -37 -20q-14 0 -25 8q55 -39 56 -100q0 -25 -10.5 -47.5t-28 -41 t-40 -29.5t-46.5 -11q-35 0 -62 18l-514 342q-49 33 -49 92z" />
|
||||
<glyph unicode="" horiz-adv-x="1880" d="M0 627q0 195 73.5 365.5t201.5 298.5t299 202t366 74t366 -74t299 -202t201.5 -299t73.5 -365q0 -78 -14.5 -159t-42 -159t-68.5 -149.5t-92 -130.5q-23 -29 -59 -29h-1328q-37 0 -59 29q-53 59 -93 130.5t-67.5 149.5t-42 159t-14.5 159zM158 627q0 -49 33.5 -83 t82.5 -34t83 34t34 83t-34.5 82.5t-82.5 33.5q-49 0 -82.5 -33.5t-33.5 -82.5zM352 1098q0 -49 35 -84t82 -35q49 0 84 35t35 84t-35 82.5t-84 33.5q-47 0 -82 -33.5t-35 -82.5zM743 313q0 -82 57.5 -139t139.5 -57t139.5 57t57.5 139q0 49 -26 91t-67 71q4 14 15.5 55 t27 95.5t33 114t30.5 110.5t22.5 88t9.5 43q0 23 -17.5 40t-40.5 17q-20 0 -35.5 -12t-21.5 -31l-135 -487q-39 -2 -74 -17.5t-60.5 -42t-40 -61.5t-14.5 -74zM823 1292q0 -49 34 -82.5t83 -33.5t83 33.5t34 82.5t-34 83t-83 34t-83 -34t-34 -83zM1292 1098q0 -49 35 -83 t84 -34t83 34t34 83t-34 82.5t-83 33.5t-84 -33.5t-35 -82.5zM1489 627q0 -49 34 -83t83 -34t82.5 34t33.5 83t-33.5 82.5t-82.5 33.5t-83 -33.5t-34 -82.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 866q0 123 49 225.5t130 183.5t184.5 139.5t209.5 92.5q94 31 190.5 45.5t194.5 14.5t194.5 -14.5t190.5 -45.5q106 -35 210 -93t185 -139t130 -183.5t49 -225.5t-49 -225t-130 -183t-184.5 -140.5t-210.5 -92.5q-94 -31 -190 -45t-195 -14q-92 0 -180 12 q-92 -72 -195.5 -119t-215.5 -73q-27 -4 -55.5 -10.5t-53.5 -6.5q-16 0 -27.5 11.5t-11.5 27.5q0 12 8.5 21.5t16.5 17.5q31 33 53 60.5t37.5 57.5t25 64.5t17.5 79.5q-78 43 -145.5 100.5t-120 128t-82 153.5t-29.5 175zM160 866q0 -72 24.5 -133t65.5 -113.5t94 -95.5 t111 -75q27 -14 51 -27.5t49 -28.5q-10 -47 -17.5 -94t-19.5 -94q59 29 111.5 64.5t105.5 76.5q55 -8 110.5 -14t112.5 -6q156 0 308 43q84 25 171 68.5t158.5 107t116.5 143.5t45 178t-45 178t-116.5 143.5t-158.5 107.5t-171 69q-152 43 -308 43q-158 0 -307 -43 q-84 -25 -171 -69t-158.5 -107.5t-116.5 -143t-45 -178.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1916" d="M0 997q0 98 40 182.5t106.5 151t150.5 113.5t170 76q76 25 154.5 36t156.5 11q80 0 159 -11.5t155 -35.5q86 -29 170 -76t149.5 -113.5t105 -150.5t39.5 -183q0 -98 -39.5 -182t-105 -149.5t-149.5 -113.5t-170 -77q-154 -47 -314 -47q-37 0 -72.5 3t-72.5 7 q-150 -115 -336 -155q-20 -4 -43 -9.5t-45 -5.5q-12 0 -21.5 9.5t-9.5 23.5q0 10 7.5 17.5l13.5 13.5q51 51 72.5 96t35.5 117q-63 35 -118.5 82t-97.5 104t-66.5 124t-24.5 142zM160 997q0 -72 30.5 -127t77.5 -99t104.5 -78t112.5 -64l-20 -111q33 18 63.5 42t59.5 46 q47 -6 95 -12t95 -6q135 0 264 41q61 18 124 52t114 81t84 105.5t33 129.5q0 72 -33 131.5t-84 105.5t-113.5 80t-124.5 52q-63 23 -129.5 32t-134.5 9q-66 0 -132 -9t-132 -32q-59 -18 -122.5 -52t-115 -80t-84 -105.5t-32.5 -131.5zM649 258l27 16q51 -6 102 -6 q197 0 381 62q111 37 211 99.5t177 147.5t123 190t46 230q0 41 -6 84q90 -72 148.5 -169t58.5 -214q0 -76 -24.5 -142.5t-66.5 -123.5t-97.5 -104t-118.5 -82q14 -72 35.5 -117t72.5 -96q6 -6 13.5 -14.5t7.5 -18.5q0 -16 -10.5 -23.5t-24.5 -7.5q-20 0 -43 5.5t-41 9.5 q-186 41 -336 155q-37 -4 -72.5 -7t-72.5 -3q-129 0 -254 32t-236 97z" />
|
||||
<glyph unicode="" horiz-adv-x="933" d="M0 557q0 8 2 10l209 932q4 16 16.5 26.5t28.5 10.5h344q18 0 31.5 -13.5t13.5 -33.5q0 -6 -1 -10t-3 -11l-180 -524q12 4 47 13.5t81 21.5t95 26.5t93 25.5t75 18.5t37 7.5q18 0 31.5 -13.5t13.5 -33.5q0 -12 -2 -19l-565 -1306q-10 -29 -43 -29q-18 0 -33 13.5t-15 33.5 q0 6 3 10l204 914q-12 -4 -48 -14.5t-82 -22.5t-97 -26.5t-95 -27t-76 -19.5t-38 -7q-20 0 -33.5 14.5t-13.5 32.5z" />
|
||||
<glyph unicode="" d="M0 78v383q0 33 22.5 55.5t55.5 22.5h133v153q0 55 40 94t95 39h518v174h-135q-31 0 -53.5 21.5t-22.5 54.5v385q0 31 22.5 53.5t53.5 22.5h385q31 0 53.5 -22.5t22.5 -53.5v-385q0 -33 -22.5 -54.5t-53.5 -21.5h-135v-174h518q55 0 95 -38.5t40 -94.5v-153h135 q31 0 53.5 -22.5t22.5 -55.5v-383q0 -33 -22.5 -55.5t-53.5 -22.5h-385q-33 0 -54 22.5t-21 55.5v383q0 33 21.5 55.5t53.5 22.5h136v153q0 18 -21 19h-518v-172h135q31 0 53.5 -22.5t22.5 -55.5v-383q0 -33 -22.5 -55.5t-53.5 -22.5h-385q-31 0 -53.5 22.5t-22.5 55.5v383 q0 33 22.5 55.5t53.5 22.5h135v172h-518q-20 0 -20 -19v-153h135q33 0 55.5 -22.5t22.5 -55.5v-383q0 -33 -22.5 -55.5t-55.5 -22.5h-383q-33 0 -55.5 22.5t-22.5 55.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1884" d="M0 770q31 137 109.5 253t193.5 204t257 141t302 66v53q0 35 23.5 57.5t56.5 22.5q35 0 57.5 -22.5t22.5 -57.5v-53q160 -12 303 -65.5t258 -141.5t192.5 -204t108.5 -253q6 -29 -20 -43q-10 -6 -19 -6q-20 0 -28 12q-98 102 -218 103q-86 0 -163.5 -54.5t-130.5 -152.5 q-10 -23 -35 -23t-35 23q-82 150 -213 194v-526q0 -68 -23.5 -127t-63.5 -104.5t-93.5 -71t-114.5 -25.5t-115.5 25.5t-94.5 71t-63.5 104.5t-23.5 127q0 35 23.5 57.5t56.5 22.5q35 0 57.5 -22.5t22.5 -57.5q0 -70 40 -119t97 -49q55 0 95 49t40 119v526 q-131 -45 -213 -194q-10 -23 -35 -23t-34 23q-53 98 -130 152.5t-163 54.5q-121 0 -217 -103q-12 -12 -31 -12q-10 0 -19 6q-25 14 -20 43z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" d="M0 385v1075q0 31 22.5 53.5t55.5 22.5h921q31 0 53.5 -22.5t22.5 -53.5v-231h33h61q25 0 55.5 -13.5t49.5 -29.5l280 -281q18 -18 30.5 -49t12.5 -55v-62v-678q0 -27 -17 -44t-44 -17h-860q-27 0 -44.5 17.5t-17.5 43.5v246h-536q-33 0 -55.5 22.5t-22.5 55.5zM276 1321 q0 -12 9.5 -21.5t21.5 -9.5h461q12 0 21.5 9.5t9.5 21.5v61q0 12 -9.5 21.5t-21.5 9.5h-461q-12 0 -21.5 -9t-9.5 -22v-61zM737 123h738v555h-367q-27 0 -44 17.5t-17 43.5v367h-310v-983zM1169 801h306q0 2 -3.5 8t-5.5 10l-280 279q0 4 -6 4q-2 0 -2 1t-2 1t-3.5 1t-3.5 1 v-305z" />
|
||||
<glyph unicode="" horiz-adv-x="2048" />
|
||||
<glyph unicode="" horiz-adv-x="1536" d="M0 57v379q0 39 20.5 87t54.5 90t74.5 73t81.5 35q-35 -59 -34 -129q0 -59 16 -124t59 -106q-18 -37 -18 -75q0 -72 50 -122t122 -50q37 0 68.5 13t55 36.5t37 55.5t13.5 67t-13.5 66.5t-37 55t-55 38t-68.5 14.5q-18 0 -36.5 -5t-35.5 -14q-12 12 -20 31t-13.5 40.5 t-7.5 41.5t-2 37q0 47 28 86t62 67l142 21q-92 57 -142.5 150.5t-50.5 201.5q0 86 33 162t90 133t133 90t162 33t162 -33t133 -90t90 -133t33 -162q0 -109 -50.5 -202t-142.5 -150l158 -23q18 -16 34.5 -36.5t16.5 -47.5q0 -45 -18 -77q-59 33 -121 32q-45 0 -87 -17 t-77 -46q-6 2 -11 3t-11 1q-47 0 -82 -34t-35 -81t34.5 -80.5t82.5 -33.5q47 0 80.5 33.5t33.5 80.5q0 8 -2 15.5t-4 13.5q16 12 35.5 20.5t42.5 8.5q55 0 95 -39t40 -94q0 -23 -8 -41.5t-19 -34.5q-25 10 -45 10q-47 0 -81.5 -34t-34.5 -81t34.5 -80.5t81.5 -33.5t81 33.5 t34 80.5l-2 4q74 74 74 177q0 74 -41 137q45 70 45 157q0 31 -12 62q41 -4 83 -34t74.5 -72t53 -90t20.5 -89v-379q-10 -6 -22.5 -15t-25.5 -18.5t-26.5 -16.5t-21.5 -7h-1344q-35 0 -52 20.5t-44 36.5zM369 287q0 25 17 41t40 16q25 0 41 -16t16 -41q0 -23 -16 -40.5 t-41 -17.5q-23 0 -40 17.5t-17 40.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1597" />
|
||||
<glyph unicode="" horiz-adv-x="1597" />
|
||||
<glyph unicode="" horiz-adv-x="1597" />
|
||||
<glyph unicode="" horiz-adv-x="1597" />
|
||||
</font>
|
||||
</defs></svg>
|
After Width: | Height: | Size: 127 KiB |
BIN
labs/html5-embed/public/font/fontawesome-webfont.ttf
Executable file
BIN
labs/html5-embed/public/font/fontawesome-webfont.woff
Executable file
0
labs/html5-embed/public/images/.gitkeep
Normal file
1
labs/html5-embed/public/images/README
Normal file
@ -0,0 +1 @@
|
||||
this directory is used to hold the presentations for meetings
|
46
labs/html5-embed/public/index.html
Executable file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>BigBlueButton</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/reset.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/font-awesome.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/layout.css">
|
||||
<script src="js/lib/jquery-1.7.2.min.js">
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="layout">
|
||||
<div id="presentation">
|
||||
<object data="FreshFlower.jpg"></object>
|
||||
</div>
|
||||
<div id="users">
|
||||
<h3>Users</h3>
|
||||
</div>
|
||||
<div id="chat">
|
||||
<h3>Chat</h3>
|
||||
<div id="chat-text">
|
||||
<p>Chat messages go here</p>
|
||||
</div>
|
||||
<div id="chat-entry">
|
||||
<textarea placeholder="Enter a chat message."></textarea><button>Post</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="navbar">
|
||||
<div class="navbar-btngroup">
|
||||
<button id="prev-slide-btn" class="navbar-btn"><i class="icon-arrow-left"></i>Prev</button>
|
||||
<button id="next-slide-btn" class="navbar-btn"><i class="icon-arrow-right"></i>Next</button>
|
||||
<button id="tool-pan-btn" class="navbar-btn"><i class="icon-move"></i>Pan</button>
|
||||
<button id="tool-draw-btn" class="navbar-btn"><i class="icon-pencil"></i>Draw</button>
|
||||
</div>
|
||||
<div class="navbar-btngroup pull-right">
|
||||
<button id="users-btn" class="navbar-btn"><i class="icon-group"></i>Users</button>
|
||||
<button id="video-btn" class="navbar-btn"><i class="icon-facetime-video"></i>Video</button>
|
||||
<button id="chat-btn" class="navbar-btn"><i class="icon-comments"></i>Chat<div id="chat-notifications" class="notification">12</div></button>
|
||||
<button id="logout-btn" class="navbar-btn"><i class="icon-signout"></i>Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
<script src="js/chat/behaviour.js"></script>
|
||||
</body>
|
||||
</html>
|
36
labs/html5-embed/public/js/chat/behaviour.js
Executable file
@ -0,0 +1,36 @@
|
||||
var layout = $("#layout");
|
||||
var chat = $("#chat-btn");
|
||||
var users = $("#users-btn");
|
||||
var logoutBtn = $("#logout-btn");
|
||||
var userclick, chatclick;
|
||||
|
||||
/* Ensure the status is set right at page load. */
|
||||
chat.toggleClass("active", layout.hasClass("chat-enabled"));
|
||||
users.toggleClass("active", layout.hasClass("chat-enabled"));
|
||||
|
||||
chat.click(function() {
|
||||
if(chatclick) clearTimeout(chatclick);
|
||||
layout.toggleClass("chat-enabled");
|
||||
chat.toggleClass("active", layout.hasClass("chat-enabled"));
|
||||
chatclick = setTimeout(function(){
|
||||
windowResized();
|
||||
}, 1100);
|
||||
});
|
||||
|
||||
users.click(function() {
|
||||
if(userclick) clearTimeout(userclick);
|
||||
layout.toggleClass("users-enabled");
|
||||
users.toggleClass("active", layout.hasClass("users-enabled"));
|
||||
userclick = setTimeout(function() {
|
||||
windowResized('users');
|
||||
}, 1100);
|
||||
});
|
||||
|
||||
logoutBtn.click(function() { logout() });
|
||||
|
||||
$("#prev-slide-btn").click(function() { prevImg(); });
|
||||
$("#next-slide-btn").click(function() { nextImg(); });
|
||||
$("#tool-pan-btn").click(function() { changeTool('panzoom'); });
|
||||
$("#tool-line-btn").click(function() { changeTool('line'); });
|
||||
$("#tool-rect-btn").click(function() { changeTool('rect'); });
|
||||
$("#tool-ellipse-btn").click(function() { changeTool('ellipse'); });
|
522
labs/html5-embed/public/js/chat/chat.js
Executable file
@ -0,0 +1,522 @@
|
||||
// Documented
|
||||
|
||||
// Object references
|
||||
var chcount = document.getElementById('charcount');
|
||||
var msgbox = document.getElementById("chat_messages");
|
||||
var chatbox = document.getElementById('chat_input_box');
|
||||
|
||||
var PORT = 3000; //port that SocketIO will connect on
|
||||
var SERVER_IP = window.location.hostname;
|
||||
|
||||
// Connect to the websocket via SocketIO
|
||||
var socket = io.connect('http://'+SERVER_IP+':'+PORT);
|
||||
|
||||
/**
|
||||
* If the socket is connected
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('connect', function () {
|
||||
|
||||
// Immediately say we are connected
|
||||
socket.emit('user connect');
|
||||
|
||||
/**
|
||||
* Received event for a new public chat message
|
||||
* @param {string} name name of user
|
||||
* @param {string} msg message to be displayed
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('msg', function (name, msg) {
|
||||
msgbox.innerHTML += '<div>' + name + ': ' + msg + '</div>';
|
||||
msgbox.scrollTop = msgbox.scrollHeight;
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to logout yourself
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('logout', function () {
|
||||
post_to_url('logout');
|
||||
window.location.replace("./");
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update the user list
|
||||
* @param {Array} names Array of names and publicIDs of connected users
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('user list change', function (names) {
|
||||
var clickFunc = '$(\'.selected\').removeClass(\'selected\');$(this).addClass(\'selected\');';
|
||||
var currusers = document.getElementById('current_users');
|
||||
currusers.innerHTML = ''; //clear it first
|
||||
for (var i = names.length - 1; i >= 0; i--) {
|
||||
currusers.innerHTML += '<div class="user clickable" onclick="'+clickFunc+'" id= "'+names[i].id+'"><b>' + names[i].name + '</b></div>';
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update all the messages in the chat box
|
||||
* @param {Array} messages Array of messages in public chat box
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('all_messages', function (messages) {
|
||||
//msgbox.innerHTML = '';
|
||||
for (var i = messages.length - 1; i >= 0; i--){
|
||||
msgbox.innerHTML += '<div>' + messages[i].username + ": " + messages[i].message + '</div>';
|
||||
};
|
||||
msgbox.scrollTop = msgbox.scrollHeight;
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update all the shapes in the whiteboard
|
||||
* @param {Array} shapes Array of shapes to be drawn
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('all_shapes', function (shapes) {
|
||||
clearPaper();
|
||||
drawListOfShapes(shapes);
|
||||
});
|
||||
|
||||
/**
|
||||
* If the server is reconnected to the client
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('reconnect', function () {
|
||||
msgbox.innerHTML += '<div><b> RECONNECTED! </b></div>';
|
||||
});
|
||||
|
||||
/**
|
||||
* If the client is attempting to reconnect to the server
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('reconnecting', function () {
|
||||
msgbox.innerHTML += '<div><b> Reconnecting... </b></div>';
|
||||
});
|
||||
|
||||
/**
|
||||
* If the client cannot reconnect to the server
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('reconnect_failed', function () {
|
||||
msgbox.innerHTML += '<div><b> Reconnect FAILED! </b></div>';
|
||||
});
|
||||
|
||||
/**
|
||||
* If the server disconnects from the client or vice-versa
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('disconnect', function() {
|
||||
window.location.replace("./");
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to clear the whiteboard shapes
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('clrPaper', function () {
|
||||
clearPaper();
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update the viewBox value
|
||||
* @param {string} xperc Percentage of x-offset from top left corner
|
||||
* @param {string} yperc Percentage of y-offset from top left corner
|
||||
* @param {string} wperc Percentage of full width of image to be displayed
|
||||
* @param {string} hperc Percentage of full height of image to be displayed
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('viewBox', function(xperc, yperc, wperc, hperc) {
|
||||
xperc = parseFloat(xperc, 10);
|
||||
yperc = parseFloat(yperc, 10);
|
||||
wperc = parseFloat(wperc, 10);
|
||||
hperc = parseFloat(hperc, 10);
|
||||
updatePaperFromServer(xperc, yperc, wperc, hperc);
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update the cursor coordinates
|
||||
* @param {number} x x-coord of the cursor as a percentage of page width
|
||||
* @param {number} y y-coord of the cursor as a percentage of page height
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('mvCur', function(x, y) {
|
||||
mvCur(x, y);
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update the slide image
|
||||
* @param {string} url URL of image to show
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('changeslide', function(url) {
|
||||
showImageFromPaper(url);
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update the whiteboard between fit to width and fit to page
|
||||
* @param {boolean} fit choice of fit: true for fit to page, false for fit to width
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('fitToPage', function(fit) {
|
||||
setFitToPage(fit);
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update the zoom level of the whiteboard.
|
||||
* @param {number} delta amount of change in scroll wheel
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('zoom', function(delta) {
|
||||
setZoom(delta);
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event when the panning action finishes
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('panStop', function() {
|
||||
panDone();
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to create a shape on the whiteboard
|
||||
* @param {string} shape type of shape being made
|
||||
* @param {Array} data all information to make the shape
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('makeShape', function(shape, data) {
|
||||
switch(shape) {
|
||||
case 'line':
|
||||
makeLine.apply(makeLine, data);
|
||||
break;
|
||||
|
||||
case 'rect':
|
||||
makeRect.apply(makeRect, data);
|
||||
break;
|
||||
|
||||
case 'ellipse':
|
||||
makeEllipse.apply(makeEllipse, data);
|
||||
break;
|
||||
|
||||
default:
|
||||
//no other shapes allowed
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update a shape being created
|
||||
* @param {string} shape type of shape being updated
|
||||
* @param {Array} data all information to update the shape
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('updShape', function(shape, data) {
|
||||
switch(shape) {
|
||||
case 'line':
|
||||
updateLine.apply(updateLine, data);
|
||||
break;
|
||||
|
||||
case 'rect':
|
||||
updateRect.apply(updateRect, data);
|
||||
break;
|
||||
|
||||
case 'ellipse':
|
||||
updateEllipse.apply(updateEllipse, data);
|
||||
break;
|
||||
|
||||
case 'text':
|
||||
updateText.apply(updateText, data);
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log('shape not recognized');
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to denote when the text has been created
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('textDone', function() {
|
||||
textDone();
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to change the current tool
|
||||
* @param {string} tool tool to be turned on
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('toolChanged', function(tool) {
|
||||
turnOn(tool);
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update the whiteboard size and position
|
||||
* @param {number} cx x-offset from top left corner as percentage of original width of paper
|
||||
* @param {number} cy y-offset from top left corner as percentage of original height of paper
|
||||
* @param {number} sw slide width as percentage of original width of paper
|
||||
* @param {number} sh slide height as a percentage of original height of paper
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('paper', function(cx, cy, sw, sh) {
|
||||
updatePaperFromServer(cx, cy, sw, sh);
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to set the presenter to a user
|
||||
* @param {string} publicID publicID of the user that is being set as the current presenter
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('setPresenter', function(publicID) {
|
||||
$('.presenter').removeClass('presenter');
|
||||
$('#' + publicID).addClass('presenter');
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update the status of the upload progress
|
||||
* @param {string} message update message of status of upload progress
|
||||
* @param {boolean} fade true if you wish the message to automatically disappear after 3 seconds
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('uploadStatus', function(message, fade) {
|
||||
$('#uploadStatus').text(message);
|
||||
// if a true is passed for fade, it will only stay for
|
||||
// a period of time before disappearing automatically
|
||||
if(fade) {
|
||||
setTimeout(function() {
|
||||
$('#uploadStatus').text('');
|
||||
}, 3000);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Received event to update all the slide images
|
||||
* @param {Array} urls list of URLs to be added to the paper (after old images are removed)
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('all_slides', function(urls) {
|
||||
$('#uploadStatus').text(""); //upload finished
|
||||
removeAllImagesFromPaper();
|
||||
var count = 0;
|
||||
var numOfSlides = urls.length;
|
||||
for (var i = 0; i < numOfSlides; i++) {
|
||||
var array = urls[i];
|
||||
var img = addImageToPaper(array[0], array[1], array[2]);
|
||||
//TODO: temporary solution for remove :3000
|
||||
var custom_src = img.attr('src');
|
||||
custom_src = custom_src.replace(':3000', "");
|
||||
console.log(custom_src);
|
||||
$('#slide').append('<img id="preload'+img.id+'"src="'+custom_src+'" style="display:none;" alt=""/>'); //preload images
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* If an error occurs while not connected
|
||||
* @param {string} reason Reason for the error.
|
||||
* @return {undefined}
|
||||
*/
|
||||
socket.on('error', function (reason) {
|
||||
console.error('Unable to connect Socket.IO', reason);
|
||||
});
|
||||
|
||||
/**
|
||||
* POST request using javascript
|
||||
* @param {string} path path of submission
|
||||
* @param {string} params parameters to submit
|
||||
* @param {string} method method of submission ("post" is default)
|
||||
* @return {undefined}
|
||||
*/
|
||||
function post_to_url(path, params, method) {
|
||||
method = method || "post"; // Set method to post by default, if not specified.
|
||||
// The rest of this code assumes you are not using a library.
|
||||
// It can be made less wordy if you use one.
|
||||
var form = document.createElement("form");
|
||||
form.setAttribute("method", method);
|
||||
form.setAttribute("action", path);
|
||||
for(var key in params) {
|
||||
if(params.hasOwnProperty(key)) {
|
||||
var hiddenField = document.createElement("input");
|
||||
hiddenField.setAttribute("type", "hidden");
|
||||
hiddenField.setAttribute("name", key);
|
||||
hiddenField.setAttribute("value", params[key]);
|
||||
form.appendChild(hiddenField);
|
||||
}
|
||||
}
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sending a public chat message to users
|
||||
* @return {undefined}
|
||||
*/
|
||||
function sendMessage() {
|
||||
var msg = chatbox.value;
|
||||
if (msg != '') {
|
||||
socket.emit('msg', msg);
|
||||
chatbox.value = '';
|
||||
}
|
||||
chatbox.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clearing the canvas drawings
|
||||
* @return {undefined}
|
||||
*/
|
||||
function clearCanvas() {
|
||||
socket.emit("clrPaper");
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the shapes from the server.
|
||||
* @return {undefined}
|
||||
*/
|
||||
function getShapesFromServer() {
|
||||
socket.emit('all_shapes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an update in a fit of the whiteboard
|
||||
* @param {boolean} true for fitToPage, false for fitToWidth
|
||||
* @return {undefined}
|
||||
*/
|
||||
function sendFitToPage(fit) {
|
||||
socket.emit('fitToPage', fit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit the finish of a text shape
|
||||
* @return {undefined}
|
||||
*/
|
||||
function emitDoneText() {
|
||||
socket.emit('textDone');
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit the creation of a shape
|
||||
* @param {string} shape type of shape
|
||||
* @param {Array} data all the data required to draw the shape on the client whiteboard
|
||||
* @return {undefined}
|
||||
*/
|
||||
function emitMakeShape(shape, data) {
|
||||
socket.emit('makeShape', shape, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit the update of a shape
|
||||
* @param {string} shape type of shape
|
||||
* @param {Array} data all the data required to update the shape on the client whiteboard
|
||||
* @return {undefined}
|
||||
*/
|
||||
function emitUpdateShape(shape, data) {
|
||||
socket.emit('updShape', shape, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an update in the whiteboard position/size values
|
||||
* @param {number} cx x-offset from top left corner as percentage of original width of paper
|
||||
* @param {number} cy y-offset from top left corner as percentage of original height of paper
|
||||
* @param {number} sw slide width as percentage of original width of paper
|
||||
* @param {number} sh slide height as a percentage of original height of paper
|
||||
* @return {undefined}
|
||||
*/
|
||||
function sendPaperUpdate(cx, cy, sw, sh) {
|
||||
socket.emit('paper', cx, cy, sw, sh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an update to move the cursor around the canvas
|
||||
* @param {number} x x-coord of the cursor as a percentage of page width
|
||||
* @param {number} y y-coord of the cursor as a percentage of page height
|
||||
* @return {undefined}
|
||||
*/
|
||||
function emMvCur(x, y) {
|
||||
socket.emit('mvCur', x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the zoom level for the clients
|
||||
* @param {number} delta amount of change in scroll wheel
|
||||
* @return {undefined}
|
||||
*/
|
||||
function emZoom(delta) {
|
||||
socket.emit('zoom', delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the next slide
|
||||
* @return {undefined}
|
||||
*/
|
||||
function nextImg() {
|
||||
socket.emit('nextslide');
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the previous slide
|
||||
* @return {undefined}
|
||||
*/
|
||||
function prevImg() {
|
||||
socket.emit('prevslide');
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout of the meeting
|
||||
* @return {undefined}
|
||||
*/
|
||||
function logout() {
|
||||
socket.emit('logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit panning has stopped
|
||||
* @return {undefined}
|
||||
*/
|
||||
function emPanStop() {
|
||||
socket.emit('panStop');
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a shape to the server to be saved
|
||||
* @param {string} shape type of shape to be saved
|
||||
* @param {Array} data information about shape so that it can be recreated later
|
||||
* @return {undefined}
|
||||
*/
|
||||
function emitPublishShape(shape, data) {
|
||||
socket.emit('saveShape', shape, JSON.stringify(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit a change in the current tool
|
||||
* @param {string} tool [description]
|
||||
* @return {undefined}
|
||||
*/
|
||||
function changeTool(tool) {
|
||||
socket.emit('changeTool', tool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the server to undo the last shape
|
||||
* @return {undefined}
|
||||
*/
|
||||
function undoShape() {
|
||||
socket.emit('undo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit a change in the presenter
|
||||
* @return {undefined}
|
||||
*/
|
||||
function switchPresenter() {
|
||||
socket.emit('setPresenter', $('.selected').attr('id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the character count remaining in the chat box
|
||||
* @param {number} max maximum number of allowed characters
|
||||
* @return {undefined}
|
||||
*/
|
||||
function countchars(max) {
|
||||
chcount.innerHTML = max - chatbox.value.length;
|
||||
}
|
1022
labs/html5-embed/public/js/chat/whiteboard.js
Executable file
19
labs/html5-embed/public/js/index/index.js
Normal file
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Validates form and input for data
|
||||
* @param {[type]} form [description]
|
||||
* @param {[type]} input1 [description]
|
||||
* @param {[type]} input2 [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
function validateForm(form, input1, input2) {
|
||||
var x = document.forms[form][input].value;
|
||||
var y = document.forms[form][input2].value;
|
||||
if (x == null || x == "") {
|
||||
alert("Please enter a username");
|
||||
return false;
|
||||
}
|
||||
if (y == null || y == "") {
|
||||
alert("Please enter a meeting ID");
|
||||
return false;
|
||||
}
|
||||
}
|
171
labs/html5-embed/public/js/lib/colorwheel.js
Normal file
@ -0,0 +1,171 @@
|
||||
(function (Raphael) {
|
||||
Raphael.colorwheel = function (x, y, size, initcolor, element) {
|
||||
return new ColorWheel(x, y, size, initcolor, element);
|
||||
};
|
||||
var pi = Math.PI,
|
||||
doc = document,
|
||||
win = window,
|
||||
ColorWheel = function (x, y, size, initcolor, element) {
|
||||
size = size || 200;
|
||||
var w3 = 3 * size / 200,
|
||||
w1 = size / 200,
|
||||
fi = 1.6180339887,
|
||||
segments = pi * size / 5,
|
||||
size20 = size / 20,
|
||||
size2 = size / 2,
|
||||
padding = 2 * size / 200,
|
||||
t = this;
|
||||
|
||||
var H = 1, S = 1, B = 1, s = size - (size20 * 4);
|
||||
var r = element ? Raphael(element, size, size) : Raphael(x, y, size, size),
|
||||
xy = s / 6 + size20 * 2 + padding,
|
||||
wh = s * 2 / 3 - padding * 2;
|
||||
w1 < 1 && (w1 = 1);
|
||||
w3 < 1 && (w3 = 1);
|
||||
|
||||
|
||||
// ring drawing
|
||||
var a = pi / 2 - pi * 2 / segments * 1.3,
|
||||
R = size2 - padding,
|
||||
R2 = size2 - padding - size20 * 2,
|
||||
path = ["M", size2, padding, "A", R, R, 0, 0, 1, R * Math.cos(a) + R + padding, R - R * Math.sin(a) + padding, "L", R2 * Math.cos(a) + R + padding, R - R2 * Math.sin(a) + padding, "A", R2, R2, 0, 0, 0, size2, padding + size20 * 2, "z"].join();
|
||||
for (var i = 0; i < segments; i++) {
|
||||
r.path(path).attr({
|
||||
stroke: "none",
|
||||
fill: "hsb(" + i * (255 / segments) / 255 + ", 1, 0.78)",
|
||||
transform: "r" + [(360 / segments) * i, size2, size2]
|
||||
});
|
||||
}
|
||||
r.path(["M", size2, padding, "A", R, R, 0, 1, 1, size2 - 1, padding, "l1,0", "M", size2, padding + size20 * 2, "A", R2, R2, 0, 1, 1, size2 - 1, padding + size20 * 2, "l1,0"]).attr({
|
||||
"stroke-width": w3,
|
||||
stroke: "#fff"
|
||||
});
|
||||
t.cursorhsb = r.set();
|
||||
var h = size20 * 2 + 2;
|
||||
t.cursorhsb.push(r.rect(size2 - h / fi / 2, padding - 1, h / fi, h, 3 * size / 200).attr({
|
||||
stroke: "#000",
|
||||
opacity: .5,
|
||||
"stroke-width": w3
|
||||
}));
|
||||
t.cursorhsb.push(t.cursorhsb[0].clone().attr({
|
||||
stroke: "#fff",
|
||||
opacity: 1,
|
||||
"stroke-width": w1
|
||||
}));
|
||||
t.ring = r.path(["M", size2, padding, "A", R, R, 0, 1, 1, size2 - 1, padding, "l1,0M", size2, padding + size20 * 2, "A", R2, R2, 0, 1, 1, size2 - 1, padding + size20 * 2, "l1,0"]).attr({
|
||||
fill: "#000",
|
||||
opacity: 0,
|
||||
stroke: "none"
|
||||
});
|
||||
|
||||
// rect drawing
|
||||
t.main = r.rect(xy, xy, wh, wh).attr({
|
||||
stroke: "none",
|
||||
fill: "#f00",
|
||||
opacity: 1
|
||||
});
|
||||
t.main.clone().attr({
|
||||
stroke: "none",
|
||||
fill: "0-#fff-#fff",
|
||||
opacity: 0
|
||||
});
|
||||
t.square = r.rect(xy - 1, xy - 1, wh + 2, wh + 2).attr({
|
||||
r: 2,
|
||||
stroke: "#fff",
|
||||
"stroke-width": w3,
|
||||
fill: "90-#000-#000",
|
||||
opacity: 0,
|
||||
cursor: "crosshair"
|
||||
});
|
||||
t.cursor = r.set();
|
||||
t.cursor.push(r.circle(size2, size2, size20 / 2).attr({
|
||||
stroke: "#000",
|
||||
opacity: .5,
|
||||
"stroke-width": w3
|
||||
}));
|
||||
t.cursor.push(t.cursor[0].clone().attr({
|
||||
stroke: "#fff",
|
||||
opacity: 1,
|
||||
"stroke-width": w1
|
||||
}));
|
||||
t.H = t.S = t.B = 1;
|
||||
t.raphael = r;
|
||||
t.size2 = size2;
|
||||
t.wh = wh;
|
||||
t.x = x;
|
||||
t.xy = xy;
|
||||
t.y = y;
|
||||
|
||||
// events
|
||||
t.ring.drag(function (dx, dy, x, y) {
|
||||
t.docOnMove(dx, dy, x, y);
|
||||
}, function (x, y) {
|
||||
t.hsbOnTheMove = true;
|
||||
t.setH(x - t.x - t.size2, y - t.y - t.size2);
|
||||
}, function () {
|
||||
t.hsbOnTheMove = false;
|
||||
});
|
||||
t.square.drag(function (dx, dy, x, y) {
|
||||
t.docOnMove(dx, dy, x, y);
|
||||
}, function (x, y) {
|
||||
t.clrOnTheMove = true;
|
||||
t.setSB(x - t.x, y - t.y);
|
||||
}, function () {
|
||||
t.clrOnTheMove = false;
|
||||
});
|
||||
|
||||
t.color(initcolor || "#f00");
|
||||
this.onchanged && this.onchanged(this.color());
|
||||
},
|
||||
proto = ColorWheel.prototype;
|
||||
proto.setH = function (x, y) {
|
||||
var d = Raphael.angle(x, y, 0, 0),
|
||||
rd = Raphael.rad(d);
|
||||
this.cursorhsb.attr({transform: "r" + [d + 90, this.size2, this.size2]});
|
||||
this.H = (d + 90) / 360;
|
||||
this.main.attr({fill: "hsb(" + this.H + ",1,1)"});
|
||||
this.onchange && this.onchange(this.color());
|
||||
};
|
||||
proto.setSB = function (x, y) {
|
||||
var me = this;
|
||||
x < me.size2 - me.wh / 2 && (x = me.size2 - me.wh / 2);
|
||||
x > me.size2 + me.wh / 2 && (x = me.size2 + me.wh / 2);
|
||||
y < me.size2 - me.wh / 2 && (y = me.size2 - me.wh / 2);
|
||||
y > me.size2 + me.wh / 2 && (y = me.size2 + me.wh / 2);
|
||||
me.cursor.attr({cx: x, cy: y});
|
||||
me.B = 1 - (y - me.xy) / me.wh;
|
||||
me.S = (x - me.xy) / me.wh;
|
||||
me.onchange && me.onchange(me.color());
|
||||
};
|
||||
proto.docOnMove = function (dx, dy, x, y) {
|
||||
if (this.hsbOnTheMove) {
|
||||
this.setH(x - this.x - this.size2, y - this.y - this.size2);
|
||||
}
|
||||
if (this.clrOnTheMove) {
|
||||
this.setSB(x - this.x, y - this.y);
|
||||
}
|
||||
};
|
||||
proto.remove = function () {
|
||||
this.raphael.remove();
|
||||
this.color = function () {
|
||||
return false;
|
||||
};
|
||||
};
|
||||
proto.color = function (color) {
|
||||
if (color) {
|
||||
color = Raphael.color(color);
|
||||
var d = color.h * 360;
|
||||
this.H = color.h;
|
||||
this.S = color.s;
|
||||
this.B = color.v;
|
||||
this.cursorhsb.attr({transform: "r" + [d, this.size2, this.size2]});
|
||||
this.main.attr({fill: "hsb(" + this.H + ",1,1)"});
|
||||
var x = this.S * this.wh + this.xy,
|
||||
y = (1 - this.B) * this.wh + this.xy;
|
||||
this.cursor.attr({cx: x, cy: y});
|
||||
return this;
|
||||
} else {
|
||||
return Raphael.hsb2rgb(this.H, this.S, this.B).hex;
|
||||
}
|
||||
};
|
||||
})(window.Raphael);
|
125
labs/html5-embed/public/js/lib/jq-ui.js
Normal file
4
labs/html5-embed/public/js/lib/jquery-1.7.2.min.js
vendored
Normal file
4
labs/html5-embed/public/js/lib/jquery.autosize-min.js
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
// Autosize 1.11 - jQuery plugin for textareas
|
||||
// (c) 2012 Jack Moore - jacklmoore.com
|
||||
// license: www.opensource.org/licenses/mit-license.php
|
||||
(function(e){var t="hidden",n="border-box",r="lineHeight",i='<textarea tabindex="-1" style="position:absolute; top:-9999px; left:-9999px; right:auto; bottom:auto; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden;">',s=["fontFamily","fontSize","fontWeight","fontStyle","letterSpacing","textTransform","wordSpacing","textIndent"],o="oninput",u="onpropertychange",a=e(i)[0];a.setAttribute(o,"return"),e.isFunction(a[o])||u in a?(e(a).css(r,"99px"),e(a).css(r)==="99px"&&s.push(r),e.fn.autosize=function(r){return this.each(function(){function g(){var e,n;p||(p=!0,l.value=a.value,l.style.overflowY=a.style.overflowY,l.style.width=f.css("width"),l.scrollTop=0,l.scrollTop=9e4,e=l.scrollTop,n=t,e>h?(e=h,n="scroll"):e<c&&(e=c),a.style.overflowY=n,a.style.height=e+16+m+"px",setTimeout(function(){p=!1},1))}var a=this,f=e(a),l,c=f.height(),h=parseInt(f.css("maxHeight"),10),p,d=s.length,v,m=0;if(f.css("box-sizing")===n||f.css("-moz-box-sizing")===n||f.css("-webkit-box-sizing")===n)m=f.outerHeight()-f.height();if(f.data("mirror")||f.data("ismirror"))return;l=e(i).data("ismirror",!0).addClass(r||"autosizejs")[0],v=f.css("resize")==="none"?"none":"horizontal",f.data("mirror",e(l)).css({overflow:t,overflowY:t,wordWrap:"break-word",resize:v}),h=h&&h>0?h:9e4;while(d--)l.style[s[d]]=f.css(s[d]);e("body").append(l),u in a?o in a?a[o]=a.onkeyup=g:a[u]=g:a[o]=g,e(window).resize(g),f.bind("autosize",g),f.text(f.text()),g()})}):e.fn.autosize=function(){return this}})(jQuery);
|
1089
labs/html5-embed/public/js/lib/jquery.form.js
Normal file
12
labs/html5-embed/public/js/lib/jquery.mousewheel.min.js
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
|
||||
* Licensed under the MIT License (LICENSE.txt).
|
||||
*
|
||||
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
||||
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
||||
* Thanks to: Seamus Leahy for adding deltaX and deltaY
|
||||
*
|
||||
* Version: 3.0.6
|
||||
*
|
||||
* Requires: 1.2.2+
|
||||
*/
|
||||
(function(a){function d(b){var c=b||window.event,d=[].slice.call(arguments,1),e=0,f=!0,g=0,h=0;return b=a.event.fix(c),b.type="mousewheel",c.wheelDelta&&(e=c.wheelDelta/120),c.detail&&(e=-c.detail/3),h=e,c.axis!==undefined&&c.axis===c.HORIZONTAL_AXIS&&(h=0,g=-1*e),c.wheelDeltaY!==undefined&&(h=c.wheelDeltaY/120),c.wheelDeltaX!==undefined&&(g=-1*c.wheelDeltaX/120),d.unshift(b,e,g,h),(a.event.dispatch||a.event.handle).apply(this,d)}var b=["DOMMouseScroll","mousewheel"];if(a.event.fixHooks)for(var c=b.length;c;)a.event.fixHooks[b[--c]]=a.event.mouseHooks;a.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=b.length;a;)this.addEventListener(b[--a],d,!1);else this.onmousewheel=d},teardown:function(){if(this.removeEventListener)for(var a=b.length;a;)this.removeEventListener(b[--a],d,!1);else this.onmousewheel=null}},a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery)
|
10
labs/html5-embed/public/js/lib/raphael-min.js
vendored
Normal file
821
labs/html5-embed/public/js/lib/textflow-helper.js
Normal file
@ -0,0 +1,821 @@
|
||||
/**
|
||||
* @fileoverview
|
||||
*
|
||||
* ECMAScript <a href="http://www.carto.net/papers/svg/resources/helper_functions.html">helper functions</a>, main purpose is to serve in SVG mapping or other SVG based web applications
|
||||
*
|
||||
* This ECMA script library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library (http://www.carto.net/papers/svg/resources/lesser_gpl.txt); if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Please report bugs and send improvements to neumann@karto.baug.ethz.ch
|
||||
* If you use these scripts, please link to the original (http://www.carto.net/papers/svg/resources/helper_functions.html)
|
||||
* somewhere in the source-code-comment or the "about" of your project and give credits, thanks!
|
||||
*
|
||||
* See <a href="js_docs_out/overview-summary-helper_functions.js.html">documentation</a>.
|
||||
*
|
||||
* @author Andreas Neumann a.neumann@carto.net
|
||||
* @copyright LGPL 2.1 <a href="http://www.gnu.org/copyleft/lesser.txt">Gnu LGPL 2.1</a>
|
||||
* @credits Bruce Rindahl, numerous people on svgdevelopers@yahoogroups.com
|
||||
*/
|
||||
|
||||
//global variables necessary to create elements in these namespaces, do not delete them!!!!
|
||||
|
||||
/**
|
||||
* This variable is a shortcut to the full URL of the SVG namespace
|
||||
* @final
|
||||
* @type String
|
||||
*/
|
||||
var svgNS = "http://www.w3.org/2000/svg";
|
||||
|
||||
/**
|
||||
* This variable is a shortcut to the full URL of the XLink namespace
|
||||
* @final
|
||||
* @type String
|
||||
*/
|
||||
var xlinkNS = "http://www.w3.org/1999/xlink";
|
||||
|
||||
/**
|
||||
* This variable is a shortcut to the full URL of the attrib namespace
|
||||
* @final
|
||||
* @type String
|
||||
*/
|
||||
var cartoNS = "http://www.carto.net/attrib";
|
||||
|
||||
/**
|
||||
* This variable is a alias to the full URL of the attrib namespace
|
||||
* @final
|
||||
* @type String
|
||||
*/
|
||||
var attribNS = "http://www.carto.net/attrib";
|
||||
|
||||
/**
|
||||
* This variable is a alias to the full URL of the Batik extension namespace
|
||||
* @final
|
||||
* @type String
|
||||
*/
|
||||
var batikNS = "http://xml.apache.org/batik/ext";
|
||||
|
||||
/**
|
||||
* Returns the polar direction from a given vector
|
||||
* @param {Number} xdiff the x-part of the vector
|
||||
* @param {Number} ydiff the y-part of the vector
|
||||
* @return direction the direction in radians
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @see #toPolarDist
|
||||
* @see #toRectX
|
||||
* @see #toRectY
|
||||
*/
|
||||
function toPolarDir(xdiff,ydiff) {
|
||||
var direction = (Math.atan2(ydiff,xdiff));
|
||||
return(direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the polar distance from a given vector
|
||||
* @param {Number} xdiff the x-part of the vector
|
||||
* @param {Number} ydiff the y-part of the vector
|
||||
* @return distance the distance
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @see #toPolarDir
|
||||
* @see #toRectX
|
||||
* @see #toRectY
|
||||
*/
|
||||
function toPolarDist(xdiff,ydiff) {
|
||||
var distance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
|
||||
return(distance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the x-part of a vector from a given direction and distance
|
||||
* @param {Number} direction the direction (in radians)
|
||||
* @param {Number} distance the distance
|
||||
* @return x the x-part of the vector
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @see #toPolarDist
|
||||
* @see #toPolarDir
|
||||
* @see #toRectY
|
||||
*/
|
||||
function toRectX(direction,distance) {
|
||||
var x = distance * Math.cos(direction);
|
||||
return(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the y-part of the vector from a given direction and distance
|
||||
* @param {Number} direction the direction (in radians)
|
||||
* @param {Number} distance the distance
|
||||
* @return y the y-part of the vector
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @see #toPolarDist
|
||||
* @see #toPolarDir
|
||||
* @see #toRectX
|
||||
*/
|
||||
function toRectY(direction,distance) {
|
||||
y = distance * Math.sin(direction);
|
||||
return(y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts degrees to radians
|
||||
* @param {Number} deg the degree value
|
||||
* @return rad the radians value
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @see #RadToDeg
|
||||
*/
|
||||
function DegToRad(deg) {
|
||||
return (deg / 180.0 * Math.PI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts radians to degrees
|
||||
* @param {Number} rad the radians value
|
||||
* @return deg the degree value
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @see #DegToRad
|
||||
*/
|
||||
function RadToDeg(rad) {
|
||||
return (rad / Math.PI * 180.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts decimal degrees to degrees, minutes, seconds
|
||||
* @param {Number} dd the decimal degree value
|
||||
* @return degrees the degree values in the following notation: {deg:degrees,min:minutes,sec:seconds}
|
||||
* @type literal
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @see #dms2dd
|
||||
*/
|
||||
function dd2dms(dd) {
|
||||
var minutes = (Math.abs(dd) - Math.floor(Math.abs(dd))) * 60;
|
||||
var seconds = (minutes - Math.floor(minutes)) * 60;
|
||||
var minutes = Math.floor(minutes);
|
||||
if (dd >= 0) {
|
||||
var degrees = Math.floor(dd);
|
||||
}
|
||||
else {
|
||||
var degrees = Math.ceil(dd);
|
||||
}
|
||||
return {deg:degrees,min:minutes,sec:seconds};
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts degrees, minutes and seconds to decimal degrees
|
||||
* @param {Number} deg the degree value
|
||||
* @param {Number} min the minute value
|
||||
* @param {Number} sec the second value
|
||||
* @return deg the decimal degree values
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @see #dd2dms
|
||||
*/
|
||||
function dms2dd(deg,min,sec) {
|
||||
if (deg < 0) {
|
||||
return deg - (min / 60) - (sec / 3600);
|
||||
}
|
||||
else {
|
||||
return deg + (min / 60) + (sec / 3600);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* log function, missing in the standard Math object
|
||||
* @param {Number} x the value where the log function should be applied to
|
||||
* @param {Number} b the base value for the log function
|
||||
* @return logResult the result of the log function
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
*/
|
||||
function log(x,b) {
|
||||
if(b==null) b=Math.E;
|
||||
return Math.log(x)/Math.log(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* interpolates a value (e.g. elevation) bilinearly based on the position within a cell with 4 corner values
|
||||
* @param {Number} za the value at the upper left corner of the cell
|
||||
* @param {Number} zb the value at the upper right corner of the cell
|
||||
* @param {Number} zc the value at the lower right corner of the cell
|
||||
* @param {Number} zd the value at the lower left corner of the cell
|
||||
* @param {Number} xpos the x position of the point where a new value should be interpolated
|
||||
* @param {Number} ypos the y position of the point where a new value should be interpolated
|
||||
* @param {Number} ax the x position of the lower left corner of the cell
|
||||
* @param {Number} ay the y position of the lower left corner of the cell
|
||||
* @param {Number} cellsize the size of the cell
|
||||
* @return interpol_value the result of the bilinear interpolation function
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
*/
|
||||
function intBilinear(za,zb,zc,zd,xpos,ypos,ax,ay,cellsize) { //bilinear interpolation function
|
||||
var e = (xpos - ax) / cellsize;
|
||||
var f = (ypos - ay) / cellsize;
|
||||
|
||||
//calculation of weights
|
||||
var wa = (1 - e) * (1 - f);
|
||||
var wb = e * (1 - f);
|
||||
var wc = e * f;
|
||||
var wd = f * (1 - e);
|
||||
|
||||
var interpol_value = wa * zc + wb * zd + wc * za + wd * zb;
|
||||
return interpol_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* tests if a given point is left or right of a given line
|
||||
* @param {Number} pointx the x position of the given point
|
||||
* @param {Number} pointy the y position of the given point
|
||||
* @param {Number} linex1 the x position of line's start point
|
||||
* @param {Number} liney1 the y position of line's start point
|
||||
* @param {Number} linex2 the x position of line's end point
|
||||
* @param {Number} liney2 the y position of line's end point
|
||||
* @return leftof the result of the leftOfTest, 1 means leftOf, 0 means rightOf
|
||||
* @type Number (integer, 0|1)
|
||||
* @version 1.0 (2007-04-30)
|
||||
*/
|
||||
function leftOfTest(pointx,pointy,linex1,liney1,linex2,liney2) {
|
||||
var result = (liney1 - pointy) * (linex2 - linex1) - (linex1 - pointx) * (liney2 - liney1);
|
||||
if (result < 0) {
|
||||
var leftof = 1; //case left of
|
||||
}
|
||||
else {
|
||||
var leftof = 0; //case left of
|
||||
}
|
||||
return leftof;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the distance between a given point and a given line
|
||||
* @param {Number} pointx the x position of the given point
|
||||
* @param {Number} pointy the y position of the given point
|
||||
* @param {Number} linex1 the x position of line's start point
|
||||
* @param {Number} liney1 the y position of line's start point
|
||||
* @param {Number} linex2 the x position of line's end point
|
||||
* @param {Number} liney2 the y position of line's end point
|
||||
* @return distance the result of the leftOfTest, 1 means leftOf, 0 means rightOf
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
*/
|
||||
function distFromLine(xpoint,ypoint,linex1,liney1,linex2,liney2) {
|
||||
var dx = linex2 - linex1;
|
||||
var dy = liney2 - liney1;
|
||||
var distance = (dy * (xpoint - linex1) - dx * (ypoint - liney1)) / Math.sqrt(Math.pow(dx,2) + Math.pow(dy,2));
|
||||
return distance;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the angle between two vectors (lines)
|
||||
* @param {Number} ax the x part of vector a
|
||||
* @param {Number} ay the y part of vector a
|
||||
* @param {Number} bx the x part of vector b
|
||||
* @param {Number} by the y part of vector b
|
||||
* @return angle the angle in radians
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @credits <a href="http://www.mathe-online.at/mathint/vect2/i.html#Winkel">Mathe Online (Winkel)</a>
|
||||
*/
|
||||
function angleBetwTwoLines(ax,ay,bx,by) {
|
||||
var angle = Math.acos((ax * bx + ay * by) / (Math.sqrt(Math.pow(ax,2) + Math.pow(ay,2)) * Math.sqrt(Math.pow(bx,2) + Math.pow(by,2))));
|
||||
return angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the bisector vector for two given vectors
|
||||
* @param {Number} ax the x part of vector a
|
||||
* @param {Number} ay the y part of vector a
|
||||
* @param {Number} bx the x part of vector b
|
||||
* @param {Number} by the y part of vector b
|
||||
* @return c the resulting vector as an Array, c[0] is the x part of the vector, c[1] is the y part
|
||||
* @type Array
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @credits <a href="http://www.mathe-online.at/mathint/vect1/i.html#Winkelsymmetrale">Mathe Online (Winkelsymmetrale)</a>
|
||||
* see #calcBisectorAngle
|
||||
* */
|
||||
function calcBisectorVector(ax,ay,bx,by) {
|
||||
var betraga = Math.sqrt(Math.pow(ax,2) + Math.pow(ay,2));
|
||||
var betragb = Math.sqrt(Math.pow(bx,2) + Math.pow(by,2));
|
||||
var c = new Array();
|
||||
c[0] = ax / betraga + bx / betragb;
|
||||
c[1] = ay / betraga + by / betragb;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the bisector angle for two given vectors
|
||||
* @param {Number} ax the x part of vector a
|
||||
* @param {Number} ay the y part of vector a
|
||||
* @param {Number} bx the x part of vector b
|
||||
* @param {Number} by the y part of vector b
|
||||
* @return angle the bisector angle in radians
|
||||
* @type Number
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @credits <a href="http://www.mathe-online.at/mathint/vect1/i.html#Winkelsymmetrale">Mathe Online (Winkelsymmetrale)</a>
|
||||
* see #calcBisectorVector
|
||||
* */
|
||||
function calcBisectorAngle(ax,ay,bx,by) {
|
||||
var betraga = Math.sqrt(Math.pow(ax,2) + Math.pow(ay,2));
|
||||
var betragb = Math.sqrt(Math.pow(bx,2) + Math.pow(by,2));
|
||||
var c1 = ax / betraga + bx / betragb;
|
||||
var c2 = ay / betraga + by / betragb;
|
||||
var angle = toPolarDir(c1,c2);
|
||||
return angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the intersection point of two given lines
|
||||
* @param {Number} line1x1 the x the start point of line 1
|
||||
* @param {Number} line1y1 the y the start point of line 1
|
||||
* @param {Number} line1x2 the x the end point of line 1
|
||||
* @param {Number} line1y2 the y the end point of line 1
|
||||
* @return interSectPoint the intersection point, interSectPoint.x contains x-part, interSectPoint.y the y-part of the resulting coordinate
|
||||
* @type Object
|
||||
* @version 1.0 (2007-04-30)
|
||||
* @credits <a href="http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/">P. Bourke</a>
|
||||
*/
|
||||
function intersect2lines(line1x1,line1y1,line1x2,line1y2,line2x1,line2y1,line2x2,line2y2) {
|
||||
var interSectPoint = new Object();
|
||||
var denominator = (line2y2 - line2y1)*(line1x2 - line1x1) - (line2x2 - line2x1)*(line1y2 - line1y1);
|
||||
if (denominator == 0) {
|
||||
alert("lines are parallel");
|
||||
}
|
||||
else {
|
||||
var ua = ((line2x2 - line2x1)*(line1y1 - line2y1) - (line2y2 - line2y1)*(line1x1 - line2x1)) / denominator;
|
||||
var ub = ((line1x2 - line1x1)*(line1y1 - line2y1) - (line1y2 - line1y1)*(line1x1 - line2x1)) / denominator;
|
||||
}
|
||||
interSectPoint["x"] = line1x1 + ua * (line1x2 - line1x1);
|
||||
interSectPoint["y"] = line1y1 + ua * (line1y2 - line1y1);
|
||||
return interSectPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* reformats a given number to a string by adding separators at every third digit
|
||||
* @param {String|Number} inputNumber the input number, can be of type number or string
|
||||
* @param {String} separator the separator, e.g. ' or ,
|
||||
* @return newString the intersection point, interSectPoint.x contains x-part, interSectPoint.y the y-part of the resulting coordinate
|
||||
* @type String
|
||||
* @version 1.0.1 (2011-10-02)
|
||||
*/
|
||||
function formatNumberString(inputNumber,separator) {
|
||||
//check if of type string, if number, convert it to string
|
||||
if (typeof(inputNumber) == "number") {
|
||||
var myTempString = inputNumber.toString();
|
||||
}
|
||||
else {
|
||||
var myTempString = inputNumber;
|
||||
}
|
||||
var newString="";
|
||||
//if it contains a comma, it will be split
|
||||
var splitResults = myTempString.split(".");
|
||||
var myCounter = splitResults[0].length;
|
||||
if (myCounter > 3) {
|
||||
while(myCounter > 0) {
|
||||
if (myCounter > 3) {
|
||||
newString = separator + splitResults[0].substr(myCounter - 3,3) + newString;
|
||||
}
|
||||
else {
|
||||
newString = splitResults[0].substr(0,myCounter) + newString;
|
||||
}
|
||||
myCounter -= 3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
newString = splitResults[0];
|
||||
}
|
||||
//concatenate if it contains a comma
|
||||
if (splitResults[1]) {
|
||||
newString = newString + "." + splitResults[1];
|
||||
}
|
||||
return newString;
|
||||
}
|
||||
|
||||
/**
|
||||
* writes a status text message out to a SVG text element's first child
|
||||
* @param {String} statusText the text message to be displayed
|
||||
* @version 1.0 (2007-04-30)
|
||||
*/
|
||||
function statusChange(statusText) {
|
||||
document.getElementById("statusText").firstChild.nodeValue = "Statusbar: " + statusText;
|
||||
}
|
||||
|
||||
/**
|
||||
* scales an SVG element, requires that the element has an x and y attribute (e.g. circle, ellipse, use element, etc.)
|
||||
* @param {dom::Event} evt the evt object that triggered the scaling
|
||||
* @param {Number} factor the scaling factor
|
||||
* @version 1.0 (2007-04-30)
|
||||
*/
|
||||
function scaleObject(evt,factor) {
|
||||
//reference to the currently selected object
|
||||
var element = evt.currentTarget;
|
||||
var myX = element.getAttributeNS(null,"x");
|
||||
var myY = element.getAttributeNS(null,"y");
|
||||
var newtransform = "scale(" + factor + ") translate(" + (myX * 1 / factor - myX) + " " + (myY * 1 / factor - myY) +")";
|
||||
element.setAttributeNS(null,'transform', newtransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the transformation matrix (ctm) for the given node up to the root element
|
||||
* the basic use case is to provide a wrapper function for the missing SVGLocatable.getTransformToElement method (missing in ASV3)
|
||||
* @param {svg::SVGTransformable} node the node reference for the SVGElement the ctm is queried
|
||||
* @return CTM the current transformation matrix from the given node to the root element
|
||||
* @type svg::SVGMatrix
|
||||
* @version 1.0 (2007-05-01)
|
||||
* @credits <a href="http://www.kevlindev.com/tutorials/basics/transformations/toUserSpace/index.htm">Kevin Lindsey (toUserSpace)</a>
|
||||
* @see #getTransformToElement
|
||||
*/
|
||||
function getTransformToRootElement(node) {
|
||||
try {
|
||||
//this part is for fully conformant players (like Opera, Batik, Firefox, Safari ...)
|
||||
var CTM = node.getTransformToElement(document.documentElement);
|
||||
}
|
||||
catch (ex) {
|
||||
//this part is for ASV3 or other non-conformant players
|
||||
// Initialize our CTM the node's Current Transformation Matrix
|
||||
var CTM = node.getCTM();
|
||||
// Work our way through the ancestor nodes stopping at the SVG Document
|
||||
while ( ( node = node.parentNode ) != document ) {
|
||||
// Multiply the new CTM to the one with what we have accumulated so far
|
||||
CTM = node.getCTM().multiply(CTM);
|
||||
}
|
||||
}
|
||||
return CTM;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the transformation matrix (ctm) for the given dom::Node up to a different dom::Node
|
||||
* the basic use case is to provide a wrapper function for the missing SVGLocatable.getTransformToElement method (missing in ASV3)
|
||||
* @param {svg::SVGTransformable} node the node reference for the element the where the ctm should be calculated from
|
||||
* @param {svg::SVGTransformable} targetNode the target node reference for the element the ctm should be calculated to
|
||||
* @return CTM the current transformation matrix from the given node to the target element
|
||||
* @type svg::SVGMatrix
|
||||
* @version 1.0 (2007-05-01)
|
||||
* @credits <a href="http://www.kevlindev.com/tutorials/basics/transformations/toUserSpace/index.htm">Kevin Lindsey (toUserSpace)</a>
|
||||
* @see #getTransformToRootElement
|
||||
*/
|
||||
function getTransformToElement(node,targetNode) {
|
||||
try {
|
||||
//this part is for fully conformant players
|
||||
var CTM = node.getTransformToElement(targetNode);
|
||||
}
|
||||
catch (ex) {
|
||||
//this part is for ASV3 or other non-conformant players
|
||||
// Initialize our CTM the node's Current Transformation Matrix
|
||||
var CTM = node.getCTM();
|
||||
// Work our way through the ancestor nodes stopping at the SVG Document
|
||||
while ( ( node = node.parentNode ) != targetNode ) {
|
||||
// Multiply the new CTM to the one with what we have accumulated so far
|
||||
CTM = node.getCTM().multiply(CTM);
|
||||
}
|
||||
}
|
||||
return CTM;
|
||||
}
|
||||
|
||||
/**
|
||||
* converts HSV to RGB values
|
||||
* @param {Number} hue the hue value (between 0 and 360)
|
||||
* @param {Number} sat the saturation value (between 0 and 1)
|
||||
* @param {Number} val the value value (between 0 and 1)
|
||||
* @return rgbArr the rgb values (associative array or object, the keys are: red,green,blue), all values are scaled between 0 and 255
|
||||
* @type Object
|
||||
* @version 1.0 (2007-05-01)
|
||||
* @see #rgb2hsv
|
||||
*/
|
||||
function hsv2rgb(hue,sat,val) {
|
||||
var rgbArr = new Object();
|
||||
if ( sat == 0) {
|
||||
rgbArr["red"] = Math.round(val * 255);
|
||||
rgbArr["green"] = Math.round(val * 255);
|
||||
rgbArr["blue"] = Math.round(val * 255);
|
||||
}
|
||||
else {
|
||||
var h = hue / 60;
|
||||
var i = Math.floor(h);
|
||||
var f = h - i;
|
||||
if (i % 2 == 0) {
|
||||
f = 1 - f;
|
||||
}
|
||||
var m = val * (1 - sat);
|
||||
var n = val * (1 - sat * f);
|
||||
switch(i) {
|
||||
case 0:
|
||||
rgbArr["red"] = val;
|
||||
rgbArr["green"] = n;
|
||||
rgbArr["blue"] = m;
|
||||
break;
|
||||
case 1:
|
||||
rgbArr["red"] = n;
|
||||
rgbArr["green"] = val;
|
||||
rgbArr["blue"] = m;
|
||||
break;
|
||||
case 2:
|
||||
rgbArr["red"] = m;
|
||||
rgbArr["green"] = val;
|
||||
rgbArr["blue"] = n;
|
||||
break;
|
||||
case 3:
|
||||
rgbArr["red"] = m;
|
||||
rgbArr["green"] = n;
|
||||
rgbArr["blue"] = val;
|
||||
break;
|
||||
case 4:
|
||||
rgbArr["red"] = n;
|
||||
rgbArr["green"] = m;
|
||||
rgbArr["blue"] = val;
|
||||
break;
|
||||
case 5:
|
||||
rgbArr["red"] = val;
|
||||
rgbArr["green"] = m;
|
||||
rgbArr["blue"] = n;
|
||||
break;
|
||||
case 6:
|
||||
rgbArr["red"] = val;
|
||||
rgbArr["green"] = n;
|
||||
rgbArr["blue"] = m;
|
||||
break;
|
||||
}
|
||||
rgbArr["red"] = Math.round(rgbArr["red"] * 255);
|
||||
rgbArr["green"] = Math.round(rgbArr["green"] * 255);
|
||||
rgbArr["blue"] = Math.round(rgbArr["blue"] * 255);
|
||||
}
|
||||
return rgbArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* converts RGB to HSV values
|
||||
* @param {Number} red the hue value (between 0 and 255)
|
||||
* @param {Number} green the saturation value (between 0 and 255)
|
||||
* @param {Number} blue the value value (between 0 and 255)
|
||||
* @return hsvArr the hsv values (associative array or object, the keys are: hue (0-360),sat (0-1),val (0-1))
|
||||
* @type Object
|
||||
* @version 1.0 (2007-05-01)
|
||||
* @see #hsv2rgb
|
||||
*/
|
||||
function rgb2hsv(red,green,blue) {
|
||||
var hsvArr = new Object();
|
||||
red = red / 255;
|
||||
green = green / 255;
|
||||
blue = blue / 255;
|
||||
myMax = Math.max(red, Math.max(green,blue));
|
||||
myMin = Math.min(red, Math.min(green,blue));
|
||||
v = myMax;
|
||||
if (myMax > 0) {
|
||||
s = (myMax - myMin) / myMax;
|
||||
}
|
||||
else {
|
||||
s = 0;
|
||||
}
|
||||
if (s > 0) {
|
||||
myDiff = myMax - myMin;
|
||||
rc = (myMax - red) / myDiff;
|
||||
gc = (myMax - green) / myDiff;
|
||||
bc = (myMax - blue) / myDiff;
|
||||
if (red == myMax) {
|
||||
h = (bc - gc) / 6;
|
||||
}
|
||||
if (green == myMax) {
|
||||
h = (2 + rc - bc) / 6;
|
||||
}
|
||||
if (blue == myMax) {
|
||||
h = (4 + gc - rc) / 6;
|
||||
}
|
||||
}
|
||||
else {
|
||||
h = 0;
|
||||
}
|
||||
if (h < 0) {
|
||||
h += 1;
|
||||
}
|
||||
hsvArr["hue"] = Math.round(h * 360);
|
||||
hsvArr["sat"] = s;
|
||||
hsvArr["val"] = v;
|
||||
return hsvArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* populates an array such that it can be addressed by both a key or an index nr,
|
||||
* note that both Arrays need to be of the same length
|
||||
* @param {Array} arrayKeys the array containing the keys
|
||||
* @param {Array} arrayValues the array containing the values
|
||||
* @return returnArray the resulting array containing both associative values and also a regular indexed array
|
||||
* @type Array
|
||||
* @version 1.0 (2007-05-01)
|
||||
*/
|
||||
function arrayPopulate(arrayKeys,arrayValues) {
|
||||
var returnArray = new Array();
|
||||
if (arrayKeys.length != arrayValues.length) {
|
||||
alert("error: arrays do not have the same length!");
|
||||
}
|
||||
else {
|
||||
for (i=0;i<arrayKeys.length;i++) {
|
||||
returnArray[arrayKeys[i]] = arrayValues[i];
|
||||
}
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper object for network requests, uses getURL or XMLHttpRequest depending on availability
|
||||
* The callBackFunction receives a XML or text node representing the rootElement
|
||||
* of the fragment received or the return text, depending on the returnFormat.
|
||||
* See also the following <a href="http://www.carto.net/papers/svg/network_requests/">documentation</a>.
|
||||
* @class this is a wrapper object to provide network request functionality (get|post)
|
||||
* @param {String} url the URL/IRI of the network resource to be called
|
||||
* @param {Function|Object} callBackFunction the callBack function or object that is called after the data was received, in case of an object, the method 'receiveData' is called; both the function and the object's 'receiveData' method get 2 return parameters: 'node.firstChild'|text (the root element of the XML or text resource), this.additionalParams (if defined)
|
||||
* @param {String} returnFormat the return format, either 'xml' or 'json' (or text)
|
||||
* @param {String} method the method of the network request, either 'get' or 'post'
|
||||
* @param {String|Undefined} postText the String containing the post text (optional) or Undefined (if not a 'post' request)
|
||||
* @param {Object|Array|String|Number|Undefined} additionalParams additional parameters that will be passed to the callBackFunction or object (optional) or Undefined
|
||||
* @return a new getData instance
|
||||
* @type getData
|
||||
* @constructor
|
||||
* @version 1.0 (2007-02-23)
|
||||
*/
|
||||
function getData(url,callBackFunction,returnFormat,method,postText,additionalParams) {
|
||||
this.url = url;
|
||||
this.callBackFunction = callBackFunction;
|
||||
this.returnFormat = returnFormat;
|
||||
this.method = method;
|
||||
this.additionalParams = additionalParams;
|
||||
if (method != "get" && method != "post") {
|
||||
alert("Error in network request: parameter 'method' must be 'get' or 'post'");
|
||||
}
|
||||
this.postText = postText;
|
||||
this.xmlRequest = null; //@private reference to the XMLHttpRequest object
|
||||
}
|
||||
|
||||
/**
|
||||
* triggers the network request defined in the constructor
|
||||
*/
|
||||
getData.prototype.getData = function() {
|
||||
//call getURL() if available
|
||||
if (window.getURL) {
|
||||
if (this.method == "get") {
|
||||
getURL(this.url,this);
|
||||
}
|
||||
if (this.method == "post") {
|
||||
postURL(this.url,this.postText,this);
|
||||
}
|
||||
}
|
||||
//or call XMLHttpRequest() if available
|
||||
else if (window.XMLHttpRequest) {
|
||||
var _this = this;
|
||||
this.xmlRequest = new XMLHttpRequest();
|
||||
if (this.method == "get") {
|
||||
if (this.returnFormat == "xml") {
|
||||
if (this.xmlRequest.overrideMimeType) {
|
||||
this.xmlRequest.overrideMimeType("text/xml");
|
||||
}
|
||||
}
|
||||
this.xmlRequest.open("GET",this.url,true);
|
||||
}
|
||||
if (this.method == "post") {
|
||||
this.xmlRequest.open("POST",this.url,true);
|
||||
}
|
||||
this.xmlRequest.onreadystatechange = function() {_this.handleEvent()};
|
||||
if (this.method == "get") {
|
||||
this.xmlRequest.send(null);
|
||||
}
|
||||
if (this.method == "post") {
|
||||
//test if postText exists and is of type string
|
||||
var reallyPost = true;
|
||||
if (!this.postText) {
|
||||
reallyPost = false;
|
||||
alert("Error in network post request: missing parameter 'postText'!");
|
||||
}
|
||||
if (typeof(this.postText) != "string") {
|
||||
reallyPost = false;
|
||||
alert("Error in network post request: parameter 'postText' has to be of type 'string')");
|
||||
}
|
||||
if (reallyPost) {
|
||||
this.xmlRequest.send(this.postText);
|
||||
}
|
||||
}
|
||||
}
|
||||
//write an error message if neither method is available
|
||||
else {
|
||||
alert("your browser/svg viewer neither supports window.getURL nor window.XMLHttpRequest!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* this is the callback method for the getURL() or postURL() case
|
||||
* @private
|
||||
*/
|
||||
getData.prototype.operationComplete = function(data) {
|
||||
//check if data has a success property
|
||||
if (data.success) {
|
||||
//parse content of the XML format to the variable "node"
|
||||
if (this.returnFormat == "xml") {
|
||||
//convert the text information to an XML node and get the first child
|
||||
var node = parseXML(data.content,document);
|
||||
//distinguish between a callback function and an object
|
||||
if (typeof(this.callBackFunction) == "function") {
|
||||
this.callBackFunction(node.firstChild,this.additionalParams);
|
||||
}
|
||||
if (typeof(this.callBackFunction) == "object") {
|
||||
this.callBackFunction.receiveData(node.firstChild,this.additionalParams);
|
||||
}
|
||||
}
|
||||
if (this.returnFormat == "json") {
|
||||
if (typeof(this.callBackFunction) == "function") {
|
||||
this.callBackFunction(data.content,this.additionalParams);
|
||||
}
|
||||
if (typeof(this.callBackFunction) == "object") {
|
||||
this.callBackFunction.receiveData(data.content,this.additionalParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
alert("something went wrong with dynamic loading of geometry!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* this is the callback method for the XMLHttpRequest case
|
||||
* @private
|
||||
*/
|
||||
getData.prototype.handleEvent = function() {
|
||||
if (this.xmlRequest.readyState == 4) {
|
||||
if (this.returnFormat == "xml") {
|
||||
//we need to import the XML node first
|
||||
var parser = new DOMParser();
|
||||
var doc = parser.parseFromString(this.xmlRequest.responseText,"text/xml");
|
||||
var importedNode = document.importNode(doc.documentElement,true);
|
||||
if (typeof(this.callBackFunction) == "function") {
|
||||
this.callBackFunction(importedNode,this.additionalParams);
|
||||
}
|
||||
if (typeof(this.callBackFunction) == "object") {
|
||||
this.callBackFunction.receiveData(importedNode,this.additionalParams);
|
||||
}
|
||||
}
|
||||
if (this.returnFormat == "json") {
|
||||
if (typeof(this.callBackFunction) == "function") {
|
||||
this.callBackFunction(this.xmlRequest.responseText,this.additionalParams);
|
||||
}
|
||||
if (typeof(this.callBackFunction) == "object") {
|
||||
this.callBackFunction.receiveData(this.xmlRequest.responseText,this.additionalParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes an XML node and returns a string representation. Wrapper function to hide implementation differences.
|
||||
* This can be used for debugging purposes or to post data to a server or network resource.
|
||||
* @param {dom::Node} node the DOM node reference
|
||||
* @return textRepresentation the String representation of the XML node
|
||||
* @type String
|
||||
* @version 1.0 (2007-05-01)
|
||||
* @see getData
|
||||
*/
|
||||
function serializeNode(node) {
|
||||
if (typeof XMLSerializer != 'undefined') {
|
||||
return new XMLSerializer().serializeToString(node);
|
||||
}
|
||||
else if (typeof node.xml != 'undefined') {
|
||||
return node.xml;
|
||||
}
|
||||
else if (typeof printNode != 'undefined') {
|
||||
return printNode(node);
|
||||
}
|
||||
else if (typeof Packages != 'undefined') {
|
||||
try {
|
||||
var stringWriter = new java.io.StringWriter();
|
||||
Packages.org.apache.batik.dom.util.DOMUtilities.writeNode(node,stringWriter);
|
||||
return stringWriter.toString();
|
||||
}
|
||||
catch (e) {
|
||||
alert("Sorry, your SVG viewer does not support the printNode/serialize function.");
|
||||
return '';
|
||||
}
|
||||
}
|
||||
else {
|
||||
alert("Sorry, your SVG viewer does not support the printNode/serialize function.");
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a SMIL animation element with the given id by triggering the '.beginElement()' method.
|
||||
* This is a convenience (shortcut) function.
|
||||
* @param {String} id a valid id of a valid SMIL animation element
|
||||
* @version 1.0 (2007-05-01)
|
||||
*/
|
||||
//starts an animtion with the given id
|
||||
//this function is useful in combination with window.setTimeout()
|
||||
function startAnimation(id) {
|
||||
document.getElementById(id).beginElement();
|
||||
}
|
152
labs/html5-embed/public/js/lib/textflow.js
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
Scripts to create flowText (rectangular) in SVG 1.1 UAs
|
||||
Copyright (C) <2007> <Andreas Neumann>
|
||||
Version 1.0, 2007-02-26
|
||||
neumann@karto.baug.ethz.ch
|
||||
http://www.carto.net/
|
||||
http://www.carto.net/neumann/
|
||||
|
||||
----
|
||||
|
||||
Documentation: http://www.carto.net/papers/svg/textFlow/
|
||||
|
||||
----
|
||||
|
||||
current version: 1.0.
|
||||
|
||||
1.0 (2007-02-26)
|
||||
initial release
|
||||
|
||||
-------
|
||||
|
||||
This ECMA script library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library (lesser_gpl.txt); if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
----
|
||||
|
||||
original document site: http://www.carto.net/papers/svg/textFlow/
|
||||
Please contact the author in case you want to use code or ideas commercially.
|
||||
If you use this code, please include this copyright header, the included full
|
||||
LGPL 2.1 text and read the terms provided in the LGPL 2.1 license
|
||||
(http://www.gnu.org/copyleft/lesser.txt)
|
||||
|
||||
-------------------------------
|
||||
|
||||
Please report bugs and send improvements to neumann@karto.baug.ethz.ch
|
||||
If you use this control, please link to the original (http://www.carto.net/papers/svg/textFlow/)
|
||||
somewhere in the source-code-comment or the "about" of your project and give credits, thanks!
|
||||
|
||||
*/
|
||||
|
||||
//main function
|
||||
function textFlow(myText,textToAppend,maxWidth,x,ddy,justified) {
|
||||
//extract and add line breaks for start
|
||||
var dashArray = new Array();
|
||||
var dashFound = true;
|
||||
var indexPos = 0;
|
||||
var cumulY = 0;
|
||||
while (dashFound == true) {
|
||||
var result = myText.indexOf("-",indexPos);
|
||||
if (result == -1) {
|
||||
//could not find a dash
|
||||
dashFound = false;
|
||||
}
|
||||
else {
|
||||
dashArray.push(result);
|
||||
indexPos = result + 1;
|
||||
}
|
||||
}
|
||||
//split the text at all spaces and dashes
|
||||
var words = myText.split(/[\s-]/);
|
||||
var line = "";
|
||||
var dy = 0;
|
||||
var curNumChars = 0;
|
||||
var computedTextLength = 0;
|
||||
var myTextNode;
|
||||
var tspanEl;
|
||||
var lastLineBreak = 0;
|
||||
|
||||
for (i=0;i<words.length;i++) {
|
||||
var word = words[i];
|
||||
curNumChars += word.length + 1;
|
||||
if (computedTextLength > maxWidth || i == 0) {
|
||||
if (computedTextLength > maxWidth) {
|
||||
var tempText = tspanEl.firstChild.nodeValue;
|
||||
tempText = tempText.slice(0,(tempText.length - words[i-1].length - 2)); //the -2 is because we also strip off white space
|
||||
tspanEl.firstChild.nodeValue = tempText;
|
||||
if (justified) {
|
||||
//determine the number of words in this line
|
||||
var nrWords = tempText.split(/\s/).length;
|
||||
computedTextLength = tspanEl.getComputedTextLength();
|
||||
var additionalWordSpacing = (maxWidth - computedTextLength) / (nrWords - 1);
|
||||
tspanEl.setAttributeNS(null,"word-spacing",additionalWordSpacing);
|
||||
//alternatively one could use textLength and lengthAdjust, however, currently this is not too well supported in SVG UA's
|
||||
}
|
||||
}
|
||||
tspanEl = document.createElementNS(svgNS,"tspan");
|
||||
tspanEl.setAttributeNS(null,"x",x);
|
||||
tspanEl.setAttributeNS(null,"dy",dy);
|
||||
myTextNode = document.createTextNode(line);
|
||||
tspanEl.appendChild(myTextNode);
|
||||
textToAppend.appendChild(tspanEl);
|
||||
|
||||
if(checkDashPosition(dashArray,curNumChars-1)) {
|
||||
line = word + "-";
|
||||
}
|
||||
else {
|
||||
line = word + " ";
|
||||
}
|
||||
if (i != 0) {
|
||||
line = words[i-1] + " " + line;
|
||||
}
|
||||
dy = ddy;
|
||||
cumulY += dy;
|
||||
}
|
||||
else {
|
||||
if(checkDashPosition(dashArray,curNumChars-1)) {
|
||||
line += word + "-";
|
||||
}
|
||||
else {
|
||||
line += word + " ";
|
||||
}
|
||||
}
|
||||
tspanEl.firstChild.nodeValue = line;
|
||||
computedTextLength = tspanEl.getComputedTextLength();
|
||||
if (i == words.length - 1) {
|
||||
if (computedTextLength > maxWidth) {
|
||||
var tempText = tspanEl.firstChild.nodeValue;
|
||||
tspanEl.firstChild.nodeValue = tempText.slice(0,(tempText.length - words[i].length - 1));
|
||||
tspanEl = document.createElementNS(svgNS,"tspan");
|
||||
tspanEl.setAttributeNS(null,"x",x);
|
||||
tspanEl.setAttributeNS(null,"dy",dy);
|
||||
myTextNode = document.createTextNode(words[i]);
|
||||
tspanEl.appendChild(myTextNode);
|
||||
textToAppend.appendChild(tspanEl);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return cumulY;
|
||||
}
|
||||
|
||||
//this function checks if there should be a dash at the given position, instead of a blank
|
||||
function checkDashPosition(dashArray,pos) {
|
||||
var result = false;
|
||||
for (var i=0;i<dashArray.length;i++) {
|
||||
if (dashArray[i] == pos) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
@ -34,17 +34,23 @@ module BigBlueButton
|
||||
|
||||
class MatterhornProcessor
|
||||
def self.create_manifest_xml(webcam, deskshare, manifest)
|
||||
vpresenter = FFMPEG::Movie.new(webcam)
|
||||
vpresentation = FFMPEG::Movie.new(deskshare)
|
||||
|
||||
vpresenter = FFMPEG::Movie.new(webcam) if File.exists?(webcam)
|
||||
vpresentation = FFMPEG::Movie.new(deskshare) if File.exists?(deskshare)
|
||||
|
||||
duration = vpresenter ? vpresenter.duration.round : vpresentation.duration.round
|
||||
|
||||
|
||||
xml = Builder::XmlMarkup.new( :indent => 2 )
|
||||
result = xml.instruct! :xml, :version => "1.0"
|
||||
|
||||
timestamp = (Time::now).utc.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
xml.tag!("ns2:mediapackage", "duration" => vpresenter.duration.round.to_s.split(".")[0] + "000",
|
||||
xml.tag!("ns2:mediapackage", "duration" => duration.to_s.split(".")[0] + "000",
|
||||
"start" => timestamp, "xmlns:ns2" => "http://mediapackage.opencastproject.org") {
|
||||
|
||||
xml.media{
|
||||
|
||||
if vpresenter
|
||||
xml.track("id" => "track-1", "type" => "presenter/source") {
|
||||
xml.mimetype(MIME::Types.type_for(vpresenter.path).first.content_type)
|
||||
xml.tags
|
||||
@ -59,7 +65,9 @@ module BigBlueButton
|
||||
xml.resolution(vpresenter.width.to_s + "x" + vpresenter.height.to_s)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
if vpresentation
|
||||
xml.track("id" => "track-2", "type" => "presentation/source") {
|
||||
xml.mimetype(MIME::Types.type_for(vpresentation.path).first.content_type)
|
||||
xml.tags
|
||||
@ -74,6 +82,8 @@ module BigBlueButton
|
||||
xml.resolution(vpresentation.width.to_s + "x" + vpresentation.height.to_s)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
xml.metadata {
|
||||
@ -128,9 +138,8 @@ module BigBlueButton
|
||||
aFile.close
|
||||
end
|
||||
|
||||
def self.zip_artifacts(webcam, deskshare, dublincore, manifest, zipped_file)
|
||||
BigBlueButton.logger.info("Task: Zipping package... #{zipped_file} #{webcam} #{deskshare} #{dublincore} #{manifest}")
|
||||
files = [webcam, deskshare, dublincore, manifest]
|
||||
def self.zip_artifacts(files, zipped_file)
|
||||
BigBlueButton.logger.info("Task: Zipping package... #{zipped_file} #{files}")
|
||||
Zip::ZipFile.open(zipped_file, Zip::ZipFile::CREATE) do |zipfile|
|
||||
files.each { |f|
|
||||
BigBlueButton.logger.info("Zipping #{f} into #{zipped_file}")
|
||||
|
@ -126,10 +126,10 @@ module BigBlueButton
|
||||
target_dir = File.dirname("#{video_out}")
|
||||
|
||||
#Concatenate mpg files
|
||||
BigBlueButton.concatenate_mpg_files(mpgs,"#{target_dir}/webcam.mpg")
|
||||
BigBlueButton.concatenate_mpg_files(mpgs,"#{target_dir}/concatenated.mpg")
|
||||
|
||||
#Convert mpg to flv
|
||||
BigBlueButton.convert_mpg_to_flv("#{target_dir}/webcam.mpg", video_out)
|
||||
BigBlueButton.convert_mpg_to_flv("#{target_dir}/concatenated.mpg", video_out)
|
||||
|
||||
end
|
||||
|
||||
@ -642,6 +642,17 @@ module BigBlueButton
|
||||
BigBlueButton.execute(command)
|
||||
end
|
||||
|
||||
|
||||
# Muxes audio with deskshare video
|
||||
# audio_file : Audio of the recording
|
||||
# deskshare_file : Video of shared desktop of the recording
|
||||
|
||||
def self.mux_audio_deskshare(target_dir, audio_file, deskshare_file)
|
||||
command = "ffmpeg -i #{audio_file} -i #{deskshare_file} -loglevel fatal -v -10 -vcodec flv -b 1000k -threads 0 -map 1:0 -map 0:0 -ar 22050 #{target_dir}/muxed_audio_deskshare.flv"
|
||||
BigBlueButton.execute(command)
|
||||
FileUtils.mv("#{target_dir}/muxed_audio_deskshare.flv","#{target_dir}/deskshare.flv")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
@ -42,29 +42,30 @@ raw_archive_dir = "#{recording_dir}/raw/#{meeting_id}"
|
||||
target_dir = "#{recording_dir}/process/matterhorn/#{meeting_id}"
|
||||
|
||||
if not FileTest.directory?(target_dir)
|
||||
FileUtils.mkdir_p target_dir
|
||||
FileUtils.mkdir_p target_dir
|
||||
|
||||
#Verify media absence before trying to process
|
||||
media_absence = Hash.new
|
||||
media_absence["audio"] = !Dir["#{raw_archive_dir}/audio/*"].empty?
|
||||
media_absence["video"] = !Dir["#{raw_archive_dir}/video/*"].empty?
|
||||
media_absence["deskshare"] = !Dir["#{raw_archive_dir}/deskshare/*"].empty?
|
||||
|
||||
if not media_absence.values.join("_").include? "false"
|
||||
if !Dir["#{raw_archive_dir}/video/*"].empty? or !Dir["#{raw_archive_dir}/deskshare/*"].empty?
|
||||
# Create a copy of the raw archives
|
||||
temp_dir = "#{target_dir}/temp"
|
||||
FileUtils.mkdir_p temp_dir
|
||||
FileUtils.cp_r(raw_archive_dir, temp_dir)
|
||||
|
||||
# Process webcam recording
|
||||
BigBlueButton.process_webcam(target_dir, temp_dir, meeting_id)
|
||||
BigBlueButton.process_webcam(target_dir, temp_dir, meeting_id) if !Dir["#{raw_archive_dir}/video/*"].empty?
|
||||
|
||||
# Process desktop sharing
|
||||
BigBlueButton.process_deskstop_sharing(target_dir, temp_dir, meeting_id)
|
||||
|
||||
BigBlueButton.process_deskstop_sharing(target_dir, temp_dir, meeting_id) if !Dir["#{raw_archive_dir}/deskshare/*"].empty?
|
||||
|
||||
# Mux audio and deskshare if webcam was not processed
|
||||
if !File.exists?("#{target_dir}/muxed-audio-webcam.flv")
|
||||
BigBlueButton::AudioProcessor.process("#{temp_dir}/#{meeting_id}", "#{target_dir}/audio.ogg")
|
||||
BigBlueButton.mux_audio_deskshare( target_dir, "#{target_dir}/audio.ogg", "#{target_dir}/deskshare.flv")
|
||||
end
|
||||
|
||||
#Create xml files with metadata
|
||||
BigBlueButton::MatterhornProcessor.create_manifest_xml("#{target_dir}/muxed-audio-webcam.flv", "#{target_dir}/deskshare.flv", "#{target_dir}/manifest.xml")
|
||||
|
||||
BigBlueButton::MatterhornProcessor.create_manifest_xml("#{target_dir}/muxed-audio-webcam.flv", "#{target_dir}/deskshare.flv", "#{target_dir}/manifest.xml")
|
||||
|
||||
metadata = BigBlueButton::Events.get_meeting_metadata("#{temp_dir}/#{meeting_id}/events.xml")
|
||||
|
||||
dublincore_data = { :title => metadata[:title.to_s].nil? ? meeting_id : metadata[:title.to_s],
|
||||
@ -76,10 +77,10 @@ if not FileTest.directory?(target_dir)
|
||||
:identifier => metadata[:identifier.to_s]
|
||||
}
|
||||
BigBlueButton::MatterhornProcessor.create_dublincore_xml("#{target_dir}/dublincore.xml", dublincore_data)
|
||||
|
||||
else
|
||||
logger.error "Failed Matterhorn process for meeting #{meeting_id}. Absence of media #{media_absence.to_s}"
|
||||
end
|
||||
|
||||
logger.error "Failed Matterhorn process for meeting #{meeting_id}. Absence of video (webcam or deskshare)."
|
||||
end
|
||||
process_done = File.new("#{recording_dir}/status/processed/#{meeting_id}-matterhorn.done", "w")
|
||||
process_done.write("Processed #{meeting_id}")
|
||||
process_done.close
|
||||
|
@ -47,20 +47,26 @@ done_files.each do |df|
|
||||
MANIFEST = "manifest.xml"
|
||||
DUBLIN = "dublincore.xml"
|
||||
|
||||
[WEBCAM, DESKSHARE, MANIFEST, DUBLIN].each { |file| FileUtils.cp("#{process_dir}/#{file}", target_dir)}
|
||||
|
||||
files = [WEBCAM, DESKSHARE, MANIFEST, DUBLIN]
|
||||
files.select! do |file|
|
||||
if File.exist?("#{process_dir}/#{file}")
|
||||
FileUtils.cp("#{process_dir}/#{file}", target_dir)
|
||||
file
|
||||
end
|
||||
end
|
||||
BigBlueButton.logger.info files
|
||||
Dir.chdir(target_dir) do
|
||||
BigBlueButton::MatterhornProcessor.zip_artifacts(WEBCAM, DESKSHARE, DUBLIN, MANIFEST, "#{meeting_id}.zip")
|
||||
BigBlueButton::MatterhornProcessor.zip_artifacts(files, "#{meeting_id}.zip")
|
||||
end
|
||||
|
||||
command = "scp -i #{scp_key} -o StrictHostKeyChecking=no -o CheckHostIP=no #{target_dir}/#{meeting_id}.zip #{scp_user}@#{scp_server}:#{scp_inbox}"
|
||||
BigBlueButton.logger.info(command)
|
||||
Open3.popen3(command) do | stdin, stdout, stderr|
|
||||
BigBlueButton.logger.info("scp result=#{$?.exitstatus}")
|
||||
end
|
||||
BigBlueButton.execute(command)
|
||||
|
||||
BigBlueButton.logger.info("Removing processed files.")
|
||||
FileUtils.rm_r(Dir.glob("#{$process_dir}/*"))
|
||||
FileUtils.rm_r(Dir.glob("#{process_dir}/*"))
|
||||
|
||||
BigBlueButton.logger.info("Removing published files.")
|
||||
FileUtils.rm_r(Dir.glob("#{target_dir}/*"))
|
||||
|
||||
end
|
||||
end
|
||||
|