oauth client

This commit is contained in:
Bill Burke 2013-11-26 15:39:57 -05:00
parent f933ffba3f
commit f79739f73e
90 changed files with 992 additions and 3826 deletions

View file

@ -43,6 +43,7 @@
<script src="js/app.js"></script>
<script src="js/controllers/realm.js"></script>
<script src="js/controllers/applications.js"></script>
<script src="js/controllers/oauth-clients.js"></script>
<script src="js/controllers/users.js"></script>
<script src="js/loaders.js"></script>
<script src="js/services.js"></script>

View file

@ -296,6 +296,77 @@ module.config([ '$routeProvider', function($routeProvider) {
},
controller : 'ApplicationListCtrl'
})
// OAUTH Client
.when('/realms/:realm/oauth-clients/:oauth/credentials', {
templateUrl : 'partials/oauth-client-credentials.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(OAuthClientLoader) {
return OAuthClientLoader();
}
},
controller : 'OAuthClientCredentialsCtrl'
})
.when('/realms/:realm/oauth-clients/:oauth/scope-mappings', {
templateUrl : 'partials/oauth-client-scope-mappings.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
oauth : function(OAuthClientLoader) {
return OAuthClientLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
},
roles : function(RoleListLoader) {
return RoleListLoader();
}
},
controller : 'OAuthClientScopeMappingCtrl'
})
.when('/create/oauth-client/:realm', {
templateUrl : 'partials/oauth-client-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
oauth : function() {
return {};
}
},
controller : 'OAuthClientDetailCtrl'
})
.when('/realms/:realm/oauth-clients/:oauth', {
templateUrl : 'partials/oauth-client-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
oauth : function(OAuthClientLoader) {
return OAuthClientLoader();
}
},
controller : 'OAuthClientDetailCtrl'
})
.when('/realms/:realm/oauth-clients', {
templateUrl : 'partials/oauth-client-list.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
oauthClients : function(OAuthClientListLoader) {
return OAuthClientListLoader();
}
},
controller : 'OAuthClientListCtrl'
})
.when('/', {
templateUrl : 'partials/home.html',
controller : 'HomeCtrl'

View file

@ -188,6 +188,8 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application,
$scope.application= angular.copy(application);
} else {
$scope.application = {};
$scope.application.webOrigins = [];
$scope.application.redirectUris = [];
}
$scope.$watch(function() {

View file

@ -0,0 +1,296 @@
module.controller('OAuthClientCredentialsCtrl', function($scope, $location, realm, oauth, OAuthClientCredentials, Notifications) {
$scope.realm = realm;
$scope.oauth = oauth;
var required = realm.requiredOAuthClientCredentials;
for (var i = 0; i < required.length; i++) {
if (required[i] == 'password') {
$scope.passwordRequired = true;
} else if (required[i] == 'totp') {
$scope.totpRequired = true;
} else if (required[i] == 'cert') {
$scope.certRequired = true;
}
}
function randomString(len) {
var charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var randomString = '';
for (var i = 0; i < len; i++) {
var randomPoz = Math.floor(Math.random() * charSet.length);
randomString += charSet.substring(randomPoz,randomPoz+1);
}
return randomString;
}
$scope.generateTotp = function() {
$scope.totp = randomString(5) + '-' + randomString(5) + '-' + randomString(5);
}
$scope.changePassword = function() {
if ($scope.password != $scope.confirmPassword) {
Notifications.error("Password and confirmation does not match.");
$scope.password = "";
$scope.confirmPassword = "";
return;
}
var creds = [
{
type : "password",
value : $scope.password
}
];
OAuthClientCredentials.update({ realm : realm.id, oauth : oauth.id }, creds,
function() {
Notifications.success('The password has been changed.');
$scope.password = null;
$scope.confirmPassword = null;
},
function() {
Notifications.error("The password was not changed due to a problem.");
$scope.password = null;
$scope.confirmPassword = null;
}
);
};
$scope.changeTotp = function() {
var creds = [
{
type : "totp",
value : $scope.totp
}
];
OAuthClientCredentials.update({ realm : realm.id, oauth : oauth.id }, creds,
function() {
Notifications.success('The totp was changed.');
$scope.totp = null;
},
function() {
Notifications.error("The totp was not changed due to a problem.");
$scope.totp = null;
}
);
};
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
});
module.controller('OAuthClientListCtrl', function($scope, realm, oauthClients, OAuthClient, $location) {
$scope.realm = realm;
$scope.oauthClients = oauthClients;
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
});
module.controller('OAuthClientDetailCtrl', function($scope, realm, oauth, OAuthClient, $location, Dialog, Notifications) {
$scope.realm = realm;
$scope.create = !oauth.id;
if (!$scope.create) {
$scope.oauth= angular.copy(oauth);
} else {
$scope.oauth = {};
$scope.oauth.webOrigins = [];
$scope.oauth.redirectUris = [];
}
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
$scope.$watch('oauth', function() {
if (!angular.equals($scope.oauth, oauth)) {
$scope.changed = true;
}
}, true);
$scope.deleteWebOrigin = function(index) {
$scope.oauth.webOrigins.splice(index, 1);
}
$scope.addWebOrigin = function() {
$scope.oauth.webOrigins.push($scope.newWebOrigin);
$scope.newWebOrigin = "";
}
$scope.deleteRedirectUri = function(index) {
$scope.oauth.redirectUris.splice(index, 1);
}
$scope.addRedirectUri = function() {
$scope.oauth.redirectUris.push($scope.newRedirectUri);
$scope.newRedirectUri = "";
}
$scope.save = function() {
if ($scope.create) {
OAuthClient.save({
realm: realm.id
}, $scope.oauth, function (data, headers) {
$scope.changed = false;
var l = headers().location;
var id = l.substring(l.lastIndexOf("/") + 1);
$location.url("/realms/" + realm.id + "/oauth-clients/" + id);
Notifications.success("The oauth client has been created.");
});
} else {
OAuthClient.update({
realm : realm.id,
id : oauth.id
}, $scope.oauth, function() {
$scope.changed = false;
oauth = angular.copy($scope.oauth);
Notifications.success("Your changes have been saved to the oauth client.");
});
}
};
$scope.reset = function() {
$scope.oauth = angular.copy(oauth);
$scope.changed = false;
};
$scope.cancel = function() {
$location.url("/realms/" + realm.id + "/oauth-clients");
};
$scope.remove = function() {
Dialog.confirmDelete($scope.oauth.name, 'oauth', function() {
$scope.oauth.$remove({
realm : realm.id,
id : $scope.oauth.id
}, function() {
$location.url("/realms/" + realm.id + "/oauth-clients");
Notifications.success("The oauth client has been deleted.");
});
});
};
});
module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, oauth, roles, applications, OAuthClientRealmScopeMapping, OAuthClientApplicationScopeMapping, ApplicationRole) {
$scope.realm = realm;
$scope.oauth = oauth;
$scope.realmRoles = angular.copy(roles);
$scope.selectedRealmRoles = [];
$scope.selectedRealmMappings = [];
$scope.realmMappings = [];
$scope.applications = applications;
$scope.applicationRoles = [];
$scope.selectedApplicationRoles = [];
$scope.selectedApplicationMappings = [];
$scope.applicationMappings = [];
$scope.realmMappings = OAuthClientRealmScopeMapping.query({realm : realm.id, oauth : oauth.id}, function(){
for (var i = 0; i < $scope.realmMappings.length; i++) {
var role = $scope.realmMappings[i];
for (var j = 0; j < $scope.realmRoles.length; j++) {
var realmRole = $scope.realmRoles[j];
if (realmRole.id == role.id) {
var idx = $scope.realmRoles.indexOf(realmRole);
if (idx != -1) {
$scope.realmRoles.splice(idx, 1);
break;
}
}
}
}
});
$scope.addRealmRole = function() {
$http.post('/auth-server/rest/saas/admin/realms/' + realm.id + '/oauth-clients/' + oauth.id + '/scope-mappings/realm',
$scope.selectedRealmRoles).success(function() {
for (var i = 0; i < $scope.selectedRealmRoles.length; i++) {
var role = $scope.selectedRealmRoles[i];
var idx = $scope.realmRoles.indexOf($scope.selectedRealmRoles[i]);
if (idx != -1) {
$scope.realmRoles.splice(idx, 1);
$scope.realmMappings.push(role);
}
}
$scope.selectRealmRoles = [];
});
};
$scope.deleteRealmRole = function() {
$http.delete('/auth-server/rest/saas/admin/realms/' + realm.id + '/oauth-clients/' + oauth.id + '/scope-mappings/realm',
{data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).success(function() {
for (var i = 0; i < $scope.selectedRealmMappings.length; i++) {
var role = $scope.selectedRealmMappings[i];
var idx = $scope.realmMappings.indexOf($scope.selectedRealmMappings[i]);
if (idx != -1) {
$scope.realmMappings.splice(idx, 1);
$scope.realmRoles.push(role);
}
}
$scope.selectedRealmMappings = [];
});
};
$scope.addApplicationRole = function() {
$http.post('/auth-server/rest/saas/admin/realms/' + realm.id + '/oauth-clients/' + oauth.id + '/scope-mappings/applications/' + $scope.targetApp.id,
$scope.selectedApplicationRoles).success(function() {
for (var i = 0; i < $scope.selectedApplicationRoles.length; i++) {
var role = $scope.selectedApplicationRoles[i];
var idx = $scope.applicationRoles.indexOf($scope.selectedApplicationRoles[i]);
if (idx != -1) {
$scope.applicationRoles.splice(idx, 1);
$scope.applicationMappings.push(role);
}
}
$scope.selectedApplicationRoles = [];
});
};
$scope.deleteApplicationRole = function() {
$http.delete('/auth-server/rest/saas/admin/realms/' + realm.id + '/oauth-clients/' + oauth.id + '/scope-mappings/applications/' + $scope.targetApp.id,
{data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function() {
for (var i = 0; i < $scope.selectedApplicationMappings.length; i++) {
var role = $scope.selectedApplicationMappings[i];
var idx = $scope.applicationMappings.indexOf($scope.selectedApplicationMappings[i]);
if (idx != -1) {
$scope.applicationMappings.splice(idx, 1);
$scope.applicationRoles.push(role);
}
}
$scope.selectedApplicationMappings = [];
});
};
$scope.changeApplication = function() {
$scope.applicationRoles = ApplicationRole.query({realm : realm.id, application : $scope.targetApp.id}, function() {
$scope.applicationMappings = OAuthClientApplicationScopeMapping.query({realm : realm.id, oauth : oauth.id, targetApp : $scope.targetApp.id}, function(){
for (var i = 0; i < $scope.applicationMappings.length; i++) {
var role = $scope.applicationMappings[i];
for (var j = 0; j < $scope.applicationRoles.length; j++) {
var realmRole = $scope.applicationRoles[j];
if (realmRole.id == role.id) {
var idx = $scope.applicationRoles.indexOf(realmRole);
if (idx != -1) {
$scope.applicationRoles.splice(idx, 1);
break;
}
}
}
}
});
}
);
};
});

View file

@ -125,4 +125,21 @@ module.factory('RoleMappingLoader', function(Loader, RoleMapping, $route, $q) {
role : $route.current.params.role
}
});
});
});
module.factory('OAuthClientLoader', function(Loader, OAuthClient, $route, $q) {
return Loader.get(OAuthClient, function() {
return {
realm : $route.current.params.realm,
id : $route.current.params.oauth
}
});
});
module.factory('OAuthClientListLoader', function(Loader, OAuthClient, $route, $q) {
return Loader.query(OAuthClient, function() {
return {
realm : $route.current.params.realm
}
});
});

View file

@ -226,6 +226,45 @@ module.factory('ApplicationOrigins', function($resource) {
});
});
module.factory('OAuthClient', function($resource) {
return $resource('/auth-server/rest/saas/admin/realms/:realm/oauth-clients/:id', {
realm : '@realm',
id : '@id'
}, {
update : {
method : 'PUT'
}
});
});
module.factory('OAuthClientCredentials', function($resource) {
return $resource('/auth-server/rest/saas/admin/realms/:realm/oauth-clients/:oauth/credentials', {
realm : '@realm',
oauth : '@oauth'
}, {
update : {
method : 'PUT',
isArray : true
}
});
});
module.factory('OAuthClientRealmScopeMapping', function($resource) {
return $resource('/auth-server/rest/saas/admin/realms/:realm/oauth-clients/:oauth/scope-mappings/realm', {
realm : '@realm',
oauth : '@oauth'
});
});
module.factory('OAuthClientApplicationScopeMapping', function($resource) {
return $resource('/auth-server/rest/saas/admin/realms/:realm/oauth-clients/:oauth/scope-mappings/applications/:targetApp', {
realm : '@realm',
oauth : '@oauth',
targetApp : '@targetApp'
});
});
module.factory('Current', function(Realm, $route) {
var current = {};

View file

@ -46,14 +46,6 @@
<label for="enabled" class="control-label">Enabled</label>
<input ng-model="application.enabled" name="enabled" id="enabled" onoffswitch />
</div>
<div class="form-group">
<label for="baseUrl" class="control-label">Base URL</label>
<div class="controls">
<input class="input-small" type="text" name="baseUrl" id="baseUrl"
data-ng-model="application.baseUrl">
</div>
</div>
<div class="form-group">
<label for="adminUrl" class="control-label">Admin URL</label>

View file

@ -1,23 +0,0 @@
<div data-ng-hide="create">
<div data-ng-show="selection.applications.length > 0"><span class="divider-vertical-right">Application </span>
<select ng-change="changeApplication()" ng-model="selection.application" ng-options="a.name for a in selection.applications">
<option value="">-- chose an application --</option>
</select>
</div>
<ul data-ng-show="selection.application">
<li data-ng-class="path[4] == 'roles' && 'active'"><a
href="#/realms/{{realm.id}}/applications/{{selection.application.id}}/roles">Application Roles</a>
<ul class="sub-items">
<li data-ng-class="path[0] == 'create' && path[1] == 'role' && 'active'"><a
href="#/create/role/realms/{{realm.id}}/applications/{{selection.application.id}}">Add Role</a></li>
</ul>
</li>
</ul>
<hr/>
<div>
<a href="#/create/application/{{realm.id}}">New Application...</a>
</div>
<div>
<a href="#/realms/{{realm.id}}">Back to realm management...</a>
</div>
</div>

View file

@ -0,0 +1,64 @@
<div id="wrapper" class="container">
<div class="row">
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<div class="top-nav">
<ul class="rcue-tabs">
<li><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}">Settings</a></li>
<li class="active"><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}/credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}/scope-mappings">Scope</a></li>
</ul>
</div>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.id}}">{{realm.realm}}</a></li>
<li><a href="#/realms/{{realm.id}}/oauth-clients">OAuth Clients</a></li>
<li><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}">{{oauth.name}}</a></li>
<li class="active">Credentials</li>
</ol>
<h2 data-ng-hide="create"><span>{{oauth.name}}</span> Credentials</h2>
<form name="credentialForm" novalidate >
<fieldset data-ng-show="passwordRequired">
<legend uncollapsed><span class="text">Change Password</span></legend>
<div class="form-group">
<label for="password">New Password</label>
<div class="controls">
<input type="password" id="password" name="password" data-ng-model="password" autofocus
required>
</div>
</div>
<div class="form-group">
<label class="two-lines" for="password">New Password Confirmation</label>
<div class="controls">
<input type="password" id="confirmPassword" name="confirmPassword" data-ng-model="confirmPassword"
required>
</div>
</div>
<div class="form-actions">
<button type="submit" data-ng-click="changePassword()" class="primary" ng-show="password != null">Save
</button>
</div>
</fieldset>
<fieldset data-ng-show="totpRequired">
<legend uncollapsed><span class="text">Change TOTP Key</span></legend>
<div class="form-group">
<label for="totp">New Key</label>
<div class="controls">
<input type="text" id="totp" name="totp" data-ng-model="totp" autofocus
required>
<button type="submit" data-ng-click="generateTotp()">Generate
</button>
</div>
</div>
<div class="form-actions">
<label></label>
<button type="submit" data-ng-click="changeTotp()" class="primary" ng-show="totp != null">Save
</button>
</div>
</fieldset>
</form>
</div>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -0,0 +1,99 @@
<div id="wrapper" class="container">
<div class="row">
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<div class="top-nav" data-ng-show="!create">
<ul class="rcue-tabs">
<li class="active"><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}">Settings</a></li>
<li><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}/credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}/scope-mappings">Scope</a></li>
</ul>
</div>
<div class="top-nav" data-ng-show="create">
<ul class="rcue-tabs">
<li></li>
</ul>
</div>
<div id="content">
<ol class="breadcrumb" data-ng-show="create">
<li><a href="#/realms/{{realm.id}}">{{realm.realm}}</a></li>
<li><a href="#/realms/{{realm.id}}/oauth-clients">OAuth Clients</a></li>
<li class="active">Add OAuth Client</li>
</ol>
<h2 class="pull-left" data-ng-show="create"><span>{{realm.realm}}</span> Add OAuth Client</h2>
<p class="subtitle" data-ng-show="create"><span class="required">*</span> Required fields</p>
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.id}}">{{realm.realm}}</a></li>
<li><a href="#/realms/{{realm.id}}/oauth-clients">OAuth Clients</a></li>
<li><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}">{{oauth.name}}</a></li>
<li class="active">Settings</li>
</ol>
<h2 data-ng-hide="create"><span>{{oauth.name}}</span> Settings</h2>
<form name="oauthForm" novalidate>
<fieldset class="border-top">
<div class="form-group">
<label for="name">Name <span class="required" data-ng-show="create">*</span></label>
<div class="controls">
<input type="text" id="name" name="name" data-ng-model="oauth.name" autofocus
required>
</div>
</div>
<div class="form-group clearfix block">
<label for="enabled" class="control-label">Enabled</label>
<input ng-model="oauth.enabled" name="enabled" id="enabled" onoffswitch />
</div>
<div class="form-group">
<label for="newWebOrigin" class="control-label">Web Origin</label>
<div class="controls">
<div ng-repeat="webOrigin in oauth.webOrigins" class="item-deletable">
<input class="input-small" type="text" data-ng-class="{'input-below':!$first}"
name="webOrigin" id="webOrigin" data-ng-model="webOrigin" readonly />
<button type="button" data-ng-click="deleteWebOrigin($index)" class="btn-delete">
Delete</button>
</div>
<input class="input-small" type="text" name="newWebOrigin" id="newWebOrigin"
placeholder="New Web Origin..." data-ng-model="newWebOrigin"
data-ng-class="{'input-below':oauth.webOrigins.length}" />
<button data-ng-click="addWebOrigin()" ng-show="newWebOrigin.length > 0">Add</button>
</div>
</div>
<div class="form-group">
<label for="newRedirectUri" class="control-label">Redirect URI</label>
<div class="controls">
<div ng-repeat="redirectUri in oauth.redirectUris" class="item-deletable">
<input class="input-small" type="text" data-ng-class="{'input-below':!$first}"
name="redirectUri" id="redirectUri" data-ng-model="redirectUri" readonly />
<button type="button" data-ng-click="deleteRedirectUri($index)" class="btn-delete">
Delete</button>
</div>
<input class="input-small" type="text" name="newRedirectUri" id="newRedirectUri"
placeholder="New Redirect URI..." data-ng-model="newRedirectUri"
data-ng-class="{'input-below':oauth.redirectUris.length}" />
<button data-ng-click="addRedirectUri()" ng-show="newRedirectUri.length > 0">Add</button>
</div>
</div>
</fieldset>
<div class="form-actions" data-ng-show="create">
<button type="submit" kc-save data-ng-show="changed" class="primary">Save
</button>
<button type="submit" data-ng-click="cancel()">Cancel
</button>
</div>
<div class="form-actions" data-ng-show="!create">
<button type="submit" kc-save class="primary" data-ng-show="changed">Save
</button>
<button type="submit" kc-reset data-ng-show="changed">Clear changes
</button>
<button type="submit" data-ng-click="remove()" class="destructive" data-ng-hide="changed">
Delete
</button>
</div>
</form>
</div>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -0,0 +1,67 @@
<div id="wrapper" class="container">
<div class="row">
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<div class="top-nav">
<ul class="rcue-tabs">
<li></li>
</ul>
</div>
<div id="content">
<ol class="breadcrumb">
<li><a href="#/realms/{{realm.id}}">{{realm.realm}}</a></li>
<li class="active">OAuth Clients</li>
</ol>
<h2><span>{{realm.realm}}</span> OAuth Clients</h2>
<div class="feedback info inline" data-ng-show="!oauthClients || oauthClients.length == 0">
<p><strong>You have not configured oauth clients.</strong> <a class="button" href="#/create/oauth-client/{{realm.id}}">Add OAuth Client</a></p>
</div>
<table data-ng-hide="oauthClients.length == 0">
<thead>
<tr>
<th class="rcue-table-actions" colspan="3">
<div class="search-comp clearfix">
<input type="text" placeholder="Search..." class="search"
onkeyup="if(event.keyCode == 13){$(this).next('button').click();}">
<button class="icon-search" tooltip-placement="right"
tooltip="Search by oauth client name.">
Icon: search
</button>
</div>
<div class="actions">
<a class="button" href="#/create/oauth-client/{{realm.id}}">Add OAuth Client</a>
</div>
</th>
</tr>
<tr data-ng-show="oauthClients.length > 0">
<th>OAuth Client Name</th>
<th>Enabled</th>
</tr>
</thead>
<tfoot data-ng-show="oauthClients && oauthClients.length > 5"> <!-- todo -->
<tr>
<td colspan="2">
<div class="table-nav">
<a href="#" class="first disabled">First page</a><a href="#" class="prev disabled">Previous
page</a><span><strong>1-8</strong> of <strong>10</strong></span><a href="#"
class="next">Next
page</a><a href="#" class="last">Last page</a>
</div>
</td>
</tr>
</tfoot>
<tbody>
<tr ng-repeat="client in oauthClients">
<td><a href="#/realms/{{realm.id}}/oauth-clients/{{client.id}}">{{client.name}}</a></td>
<td>{{client.enabled}}</td>
</tr>
</tbody>
</table>
<div class="feedback warning inline" data-ng-show="search && oauthClients.length == 0">
<p><strong>Your search returned no results.</strong><br>Try modifying the query and try again.</p>
</div>
</div>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -0,0 +1,92 @@
<div id="wrapper" class="container">
<div class="row">
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<div class="top-nav">
<ul class="rcue-tabs">
<li><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}">Settings</a></li>
<li><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}/credentials">Credentials</a></li>
<li class="active"><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}/scope-mappings">Scope</a></li>
</ul>
</div>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.id}}">{{realm.realm}}</a></li>
<li><a href="#/realms/{{realm.id}}/oauth-clients">OAuth Clients</a></li>
<li><a href="#/realms/{{realm.id}}/oauth-clients/{{oauth.id}}">{{oauth.name}}</a></li>
<li class="active">Scope</li>
</ol>
<h2 class="pull-left"><span>{{oauth.name}}</span> Scope Mappings</h2>
<p class="subtitle"></p>
<form name="realmForm" novalidate>
<fieldset>
<legend uncollapsed><span class="text">Realm Roles</span></legend>
<div class="form-group">
<div class="controls changing-selectors">
<div class="select-title">
<label for="available">Available Roles</label>
<select id="available" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedRealmRoles"
ng-options="r.name for r in realmRoles">
</select>
</div>
<div class="middle-buttons">
<button type="submit" ng-click="addRealmRole()" tooltip="Move right" tooltip-placement="right"><span class="icon-arrow-right">Move right</span></button>
<button type="submit" ng-click="deleteRealmRole()" tooltip="Move left" tooltip-placement="right"><span class="icon-arrow-left">Move left</span></button>
</div>
<div class="select-title">
<label for="assigned">Assigned Roles</label>
<select id="assigned" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedRealmMappings"
ng-options="r.name for r in realmMappings">
</select>
</div>
</div>
</div>
</fieldset>
<fieldset ng-show="applications.length > 0">
<legend collapsed><span class="text">Application Roles</span> </legend>
<div class="form-group input-select">
<label for="applications">Application</label>
<div class="input-group">
<div class="select-rcue">
<select id="applications" name="applications" ng-change="changeApplication()" ng-model="targetApp" ng-options="a.name for a in (applications)">
<option value="" selected> Select an Application </option>
</select>
</div>
</div>
</div>
<div class="form-group" ng-show="targetApp">
<div class="controls changing-selectors application">
<div class="select-title">
<label for="app-available">Available Roles</label>
<select id="app-available" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedApplicationRoles"
ng-options="r.name for r in applicationRoles">
</select>
</div>
<div class="middle-buttons">
<button type="submit" ng-click="addApplicationRole()" tooltip="Move right" tooltip-placement="right"><span class="icon-arrow-right">Move right</span></button>
<button type="submit" ng-click="deleteApplicationRole()" tooltip="Move left" tooltip-placement="right"><span class="icon-arrow-left">Move left</span></button>
</div>
<div class="select-title">
<label for="app-assigned">Assigned Roles</label>
<select id="app-assigned" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedApplicationMappings"
ng-options="r.name for r in applicationMappings">
</select>
</div>
</div>
</div>
</fieldset>
</form>
</div>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -3,5 +3,6 @@
<li data-ng-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.id}}/users">Users</a>
</li>
<li data-ng-class="(path[2] == 'applications' || path[1] == 'application') && 'active'"><a href="#/realms/{{realm.id}}/applications">Applications</a></li>
<li data-ng-class="(path[2] == 'oauth-clients' || path[1] == 'oauth-client') && 'active'"><a href="#/realms/{{realm.id}}/oauth-clients">OAuth Clients</a></li>
</ul>

View file

@ -12,7 +12,6 @@ public class ApplicationRepresentation {
protected String id;
protected String name;
protected String adminUrl;
protected String baseUrl;
protected boolean surrogateAuthRequired;
protected boolean enabled;
protected List<CredentialRepresentation> credentials;
@ -116,14 +115,6 @@ public class ApplicationRepresentation {
this.adminUrl = adminUrl;
}
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public List<CredentialRepresentation> getCredentials() {
return credentials;
}

View file

@ -10,9 +10,10 @@ import java.util.List;
public class OAuthClientRepresentation {
protected String id;
protected String name;
protected String baseUrl;
protected List<String> redirectUris;
protected List<String> webOrigins;
protected boolean enabled;
protected List<ScopeMappingRepresentation> scopeMappings;
protected List<CredentialRepresentation> credentials;
public String getId() {
return id;
@ -38,23 +39,27 @@ public class OAuthClientRepresentation {
this.enabled = enabled;
}
public List<ScopeMappingRepresentation> getScopeMappings() {
return scopeMappings;
public List<String> getRedirectUris() {
return redirectUris;
}
public ScopeMappingRepresentation scopeMapping(String username) {
ScopeMappingRepresentation mapping = new ScopeMappingRepresentation();
mapping.setUsername(username);
if (scopeMappings == null) scopeMappings = new ArrayList<ScopeMappingRepresentation>();
scopeMappings.add(mapping);
return mapping;
public void setRedirectUris(List<String> redirectUris) {
this.redirectUris = redirectUris;
}
public String getBaseUrl() {
return baseUrl;
public List<String> getWebOrigins() {
return webOrigins;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
public void setWebOrigins(List<String> webOrigins) {
this.webOrigins = webOrigins;
}
public List<CredentialRepresentation> getCredentials() {
return credentials;
}
public void setCredentials(List<CredentialRepresentation> credentials) {
this.credentials = credentials;
}
}

View file

@ -33,11 +33,11 @@ public class RealmRepresentation {
protected Set<String> requiredApplicationCredentials;
protected Set<String> requiredOAuthClientCredentials;
protected List<UserRepresentation> users;
protected List<UserRepresentation> clients;
protected List<UserRoleMappingRepresentation> roleMappings;
protected List<ScopeMappingRepresentation> scopeMappings;
protected List<SocialMappingRepresentation> socialMappings;
protected List<ApplicationRepresentation> applications;
protected List<OAuthClientRepresentation> oauthClients;
protected Map<String, String> socialProviders;
protected Map<String, String> smtpServer;
@ -69,10 +69,6 @@ public class RealmRepresentation {
return users;
}
public List<UserRepresentation> getClients() {
return clients;
}
public List<ApplicationRepresentation> getApplications() {
return applications;
}
@ -89,10 +85,6 @@ public class RealmRepresentation {
this.users = users;
}
public void setClients(List<UserRepresentation> clients) {
this.clients = clients;
}
public UserRepresentation user(String username) {
UserRepresentation user = new UserRepresentation();
user.setUsername(username);
@ -308,4 +300,12 @@ public class RealmRepresentation {
public void setSmtpServer(Map<String, String> smtpServer) {
this.smtpServer = smtpServer;
}
public List<OAuthClientRepresentation> getOauthClients() {
return oauthClients;
}
public void setOauthClients(List<OAuthClientRepresentation> oauthClients) {
this.oauthClients = oauthClients;
}
}

View file

@ -0,0 +1,36 @@
package org.jboss.resteasy.example.oauth;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.keycloak.SkeletonKeySession;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ProductDatabaseClient
{
public static List<String> getProducts(HttpServletRequest request)
{
SkeletonKeySession session = (SkeletonKeySession)request.getAttribute(SkeletonKeySession.class.getName());
ResteasyClient client = new ResteasyClientBuilder()
.trustStore(session.getMetadata().getTruststore())
.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY).build();
try
{
Response response = client.target("http://localhost:8080/database/products").request()
.header(HttpHeaders.AUTHORIZATION, "Bearer " + session.getTokenString()).get();
return response.readEntity(new GenericType<List<String>>(){});
}
finally
{
client.close();
}
}
}

View file

@ -35,6 +35,11 @@
<artifactId>keycloak-model-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-jpa</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-social-core</artifactId>

View file

@ -28,16 +28,6 @@
]
}
],
"clients" : [
{
"username" : "third-party",
"enabled": true,
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
}
],
"roles": [
{
"name": "user",
@ -58,7 +48,16 @@
{
"username": "third-party",
"roles": ["user"]
},
{
"username": "customer-portal",
"roles": ["user"]
},
{
"username": "product-portal",
"roles": ["user"]
}
],
"applications": [
{
@ -83,5 +82,18 @@
}
]
}
],
"oauthClients": [
{
"name": "third-party",
"enabled": true,
"credentials": [
{
"type": "password",
"value": "password"
}
]
}
]
}

View file

@ -1,79 +0,0 @@
Login, Distributed SSO, Distributed Logout, and Oauth Token Grant AS7 Examples
===================================
The following examples requires JBoss AS7 or EAP 6.1, and Resteasy 3.0.2 and has been tested on version EAP 6.1. Here's the highlights of the examples
* Delegating authentication of a web app to the remote authentication server via OAuth 2 protocols
* Distributed Single-Sign-On and Single-Logout
* Transferring identity and role mappings via a special bearer token (Skeleton Key Token).
* Bearer token authentication and authorization of JAX-RS services
* Obtaining bearer tokens via the OAuth2 protocol
There are 5 WAR projects. These all will run on the same jboss instance, but pretend each one is running on a different
machine on the network or Internet.
* **auth-server**: This is the keycloak SSO auth server
* **customer-app** A WAR applications that does remote login using OAUTH2 browser redirects with the auth server
* **product-app** A WAR applications that does remote login using OAUTH2 browser redirects with the auth server
* **database-service** JAX-RS services authenticated by bearer tokens only. The customer and product app invoke on it
to get data
* **third-party** Simple WAR that obtain a bearer token using OAuth2 using browser redirects to the auth-server.
The UI of each of these applications is very crude and exists just to show our OAuth2 implementation in action.
Step 1: Make sure you've upgraded Resteasy
--------------------------------------
The first thing you is upgrade Resteasy to 3.0.4 within JBoss as described [here](http://docs.jboss.org/resteasy/docs/3.0.4.Final/userguide/html/Installation_Configuration.html#upgrading-as7)
Step 2: Boot JBoss
---------------------------------------
Boot JBoss in 'standalone' mode.
Step 3: Build and deploy
---------------------------------------
next you must build and deploy
1. cd as7-eap-demo
2. mvn clean install
3. mvn jboss-as:deploy
Step 4: Login and Observe Apps
---------------------------------------
Try going to the customer app and viewing customer data:
[http://localhost:8080/customer-portal/customers/view.jsp](http://localhost:8080/customer-portal/customers/view.jsp)
This should take you to the auth-server login screen. Enter username: bburke@redhat.com and password: password.
If you click on the products link, you'll be take to the products app and show a product listing. The redirects
are still happening, but the auth-server knows you are already logged in so the login is bypassed.
If you click on the logout link of either of the product or customer app, you'll be logged out of all the applications.
Step 5: Traditional OAuth2 Example
----------------------------------
The customer and product apps are logins. The third-party app is the traditional OAuth2 usecase of a client wanting
to get permission to access a user's data. To run this example
[http://localhost:8080/oauth-client](http://localhost:8080/oauth-client)
If you area already logged in, you will not be asked for a username and password, but you will be redirected to
an oauth grant page. This page asks you if you want to grant certain permissions to the third-part app.
Admin Console
==========================
1. Register or login
You'll have to first register and create an account
Login:
[http://localhost:8080/auth-server/rest/saas/login](http://localhost:8080/auth-server/rest/saas/login)
Register:
[http://localhost:8080/auth-server/rest/saas/registrations](http://localhost:8080/auth-server/rest/saas/registrations)
2. Next you'll be brought to the admin console. Click "New Realm" button and start doing stuff.

View file

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-alpha-1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak.example.as7.demo</groupId>
<artifactId>customer-portal-example</artifactId>
<packaging>war</packaging>
<name>Customer Portal - Secured via Valve</name>
<description/>
<repositories>
<repository>
<id>jboss</id>
<name>jboss repo</name>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-adapter</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<finalName>customer-portal</finalName>
<plugins>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.4.Final</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -1,11 +0,0 @@
<jboss-deployment-structure>
<deployment>
<!-- This allows you to define additional dependencies, it is the same as using the Dependencies: manifest attribute -->
<dependencies>
<module name="org.bouncycastle"/>
<module name="org.jboss.resteasy.resteasy-jaxrs" services="import"/>
<module name="org.jboss.resteasy.resteasy-jackson-provider" services="import"/>
<module name="org.jboss.resteasy.jose-jwt" />
</dependencies>
</deployment>
</jboss-deployment-structure>

View file

@ -1,5 +0,0 @@
<jboss-web>
<valve>
<class-name>org.keycloak.adapters.as7.OAuthManagedResourceValve</class-name>
</valve>
</jboss-web>

View file

@ -1,12 +0,0 @@
{
"realm" : "demo",
"resource" : "customer-portal",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/login",
"code-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes",
"ssl-not-required" : true,
"expose-token" : true,
"credentials" : {
"password" : "password"
}
}

View file

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<module-name>customer-portal</module-name>
<security-constraint>
<web-resource-collection>
<web-resource-name>Admins</web-resource-name>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Customers</web-resource-name>
<url-pattern>/customers/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<!--
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint> -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>commerce</realm-name>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
</web-app>

View file

@ -1,11 +0,0 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
<head>
<title>Customer Admin Iterface</title>
</head>
<body bgcolor="#E3F6CE">
<h1>Customer Admin Interface</h1>
User <b><%=request.getUserPrincipal().getName()%></b> made this request.
</body>
</html>

View file

@ -1,38 +0,0 @@
<!doctype html>
<html lang="en">
<body>
<script type="text/javascript">
console.log('here!!!!!');
var xhr1 = new XMLHttpRequest();
xhr1.open('GET', '/customer-portal/K_QUERY_BEARER_TOKEN');
xhr1.onreadystatechange = function () {
console.log('got here');
if (this.status == 200 && this.readyState == 4) {
var token = this.responseText;
console.log('Access token: ' + token);
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8080/database/customers');
xhr.withCredentials = true;
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.onreadystatechange = function () {
console.log('got auth success');
if (this.status == 200 && this.readyState == 4) {
console.log('db response: ' + this.responseText);
} else if (this.status != 200) {
console.log('there was an error:' + this.status);
}
};
xhr.send();
} else if (this.status != 200) {
console.log('there was an error on get bearer token:' + this.status);
}
};
xhr1.send();
</script>
</body>
</html>

View file

@ -1,27 +0,0 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
<head>
<title>Customer View Page</title>
</head>
<body bgcolor="#E3F6CE">
<%
String logoutUri = UriBuilder.fromUri("http://localhost:8080/auth-server/rest/realms/demo/tokens/logout")
.queryParam("redirect_uri", "http://localhost:8080/customer-portal").build().toString();
%>
<p>Goto: <a href="http://localhost:8080/product-portal">products</a> | <a href="<%=logoutUri%>">logout</a></p>
User <b><%=request.getUserPrincipal().getName()%></b> made this request.
<h2>Customer Listing</h2>
<%
java.util.List<String> list = org.jboss.resteasy.example.oauth.CustomerDatabaseClient.getCustomers(request);
for (String cust : list)
{
out.print("<p>");
out.print(cust);
out.println("</p>");
}
%>
<br><br>
</body>
</html>

View file

@ -1,14 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
</head>
<body bgcolor="#E3F6CE">
<h1>Customer Portal</h1>
<p><a href="customers/view.jsp">Customer Listing</a></p>
<p><a href="admin/admin.html">Customer Admin Interface</a></p>
</body>
</html>

View file

@ -1,62 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-alpha-1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak.example.as7.demo</groupId>
<artifactId>database-service</artifactId>
<packaging>war</packaging>
<name>JAX-RS Database Service Using OAuth Bearer Tokens</name>
<description/>
<url>http://maven.apache.org</url>
<repositories>
<repository>
<id>jboss</id>
<name>jboss repo</name>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-adapter</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<finalName>database</finalName>
<plugins>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.4.Final</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -1,26 +0,0 @@
package org.jboss.resteasy.example.oauth;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.util.ArrayList;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
@Path("customers")
public class CustomerService
{
@GET
@Produces("application/json")
public List<String> getCustomers()
{
ArrayList<String> rtn = new ArrayList<String>();
rtn.add("Bill Burke");
rtn.add("Ron Sigal");
rtn.add("Weinan Li");
return rtn;
}
}

View file

@ -1,13 +0,0 @@
package org.jboss.resteasy.example.oauth;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
@ApplicationPath("/")
public class DataApplication extends Application
{
}

View file

@ -1,26 +0,0 @@
package org.jboss.resteasy.example.oauth;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.util.ArrayList;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
@Path("products")
public class ProductService
{
@GET
@Produces("application/json")
public List<String> getProducts()
{
ArrayList<String> rtn = new ArrayList<String>();
rtn.add("iphone");
rtn.add("ipad");
rtn.add("ipod");
return rtn;
}
}

View file

@ -1,9 +0,0 @@
<jboss-deployment-structure>
<deployment>
<!-- This allows you to define additional dependencies, it is the same as using the Dependencies: manifest attribute -->
<dependencies>
<module name="org.bouncycastle"/>
<module name="org.jboss.resteasy.jose-jwt" />
</dependencies>
</deployment>
</jboss-deployment-structure>

View file

@ -1,5 +0,0 @@
<jboss-web>
<valve>
<class-name>org.keycloak.adapters.as7.BearerTokenAuthenticatorValve</class-name>
</valve>
</jboss-web>

View file

@ -1,7 +0,0 @@
{
"realm" : "demo",
"resource" : "database-service",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"enable-cors" : true
}

View file

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<module-name>database</module-name>
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<!-- <user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint> -->
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>commerce</realm-name>
</login-config>
<security-role>
<role-name>user</role-name>
</security-role>
</web-app>

View file

@ -1,44 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-alpha-1</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Examples</name>
<description/>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak</groupId>
<artifactId>as7-eap-dev-pom</artifactId>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.1.1.Final</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<modules>
<module>server</module>
<!--
<module>customer-app</module>
<module>product-app</module>
<module>database-service</module>
<module>third-party</module> -->
</modules>
</project>

View file

@ -1,20 +0,0 @@
@echo off
if not DEFINED JBOSS_HOME (
exit /b
)
setlocal
set KEYCLOAK_HOME=%CD%\..\..\..
mkdir %JBOSS_HOME%\standalone\deployments\auth-server.war
echo>>%JBOSS_HOME%\standalone\deployments\auth-server.war.dodeploy
set CURDIR=%CD%
cd %JBOSS_HOME%\standalone\deployments\auth-server.war
mklink /D admin-ui %KEYCLOAK_HOME%\admin-ui-styles\src\main\resources\META-INF\resources\admin-ui
mklink /D admin %KEYCLOAK_HOME%\admin-ui\src\main\resources\META-INF\resources\admin
mklink /D WEB-INF %CURDIR%\target\auth-server\WEB-INF
cd %CURDIR%

View file

@ -1,16 +0,0 @@
#!/bin/bash
# dev setup
if [ -z "$JBOSS_HOME"]; then
echo "Need toset JBOSS_HOME"
exit 1
fi
KEYCLOAK_HOME=`pwd`/../../..
mkdir $JBOSS_HOME/standalone/deployments/auth-server.war
touch $JBOSS_HOME/standalone/deployments/auth-server.war.dodeploy
ln -s $KEYCLOAK_HOME/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui $JBOSS_HOME/standalone/deployments/auth-server.war/admin-ui
ln -s $KEYCLOAK_HOME/admin-ui/src/main/resources/META-INF/resources/admin $JBOSS_HOME/standalone/deployments/auth-server.war/admin
ln -s `pwd`/target/auth-server/WEB-INF $JBOSS_HOME/standalone/deployments/auth-server.war/WEB-INF

View file

@ -1,133 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-alpha-1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak.example.as7.demo</groupId>
<artifactId>keycloak-dev-server</artifactId>
<packaging>war</packaging>
<name>Keycloak Demo</name>
<description/>
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jose-jwt</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-social-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-social-google</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-social-twitter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-social-facebook</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-forms</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.161</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>auth-server</finalName>
<plugins>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.1.1.Final</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -1,60 +0,0 @@
package org.keycloak.example.demo;
import org.jboss.resteasy.jwt.JsonSerialization;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.ApplianceBootstrap;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.resources.KeycloakApplication;
import javax.servlet.ServletContext;
import javax.ws.rs.core.Context;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class DemoApplication extends KeycloakApplication {
public DemoApplication(@Context ServletContext servletContext) {
super(servletContext);
KeycloakSession session = factory.createSession();
session.getTransaction().begin();
ApplianceBootstrap bootstrap = new ApplianceBootstrap();
bootstrap.bootstrap(session);
install(new RealmManager(session));
session.getTransaction().commit();
}
public void install(RealmManager manager) {
RealmRepresentation rep = loadJson("META-INF/testrealm.json");
RealmModel realm = manager.createRealm("demo", rep.getRealm());
manager.importRealm(rep, realm);
}
public static RealmRepresentation loadJson(String path)
{
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
ByteArrayOutputStream os = new ByteArrayOutputStream();
int c;
try {
while ( (c = is.read()) != -1)
{
os.write(c);
}
byte[] bytes = os.toByteArray();
//System.out.println(new String(bytes));
return JsonSerialization.fromBytes(RealmRepresentation.class, bytes);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View file

@ -1,32 +0,0 @@
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="jpa-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
<class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
<class>org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity</class>
<class>org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity</class>
<class>org.keycloak.models.jpa.entities.CredentialEntity</class>
<class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
<class>org.keycloak.models.jpa.entities.RealmEntity</class>
<class>org.keycloak.models.jpa.entities.RealmScopeMappingEntity</class>
<class>org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity</class>
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
<class>org.keycloak.models.jpa.entities.RoleEntity</class>
<class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
<class>org.keycloak.models.jpa.entities.UserEntity</class>
<class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
</properties>
</persistence-unit>
</persistence>

View file

@ -1,88 +0,0 @@
{
"realm": "demo",
"enabled": true,
"tokenLifespan": 300,
"accessCodeLifespan": 10,
"accessCodeLifespanUserAction": 600,
"sslNotRequired": true,
"cookieLoginAllowed": true,
"registrationAllowed": true,
"social": true,
"automaticRegistrationAfterSocialLogin": false,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"requiredCredentials": [ "password" ],
"requiredApplicationCredentials": [ "password" ],
"requiredOAuthClientCredentials": [ "password" ],
"defaultRoles": [ "user" ],
"users" : [
{
"username" : "bburke@redhat.com",
"enabled": true,
"attributes" : {
"email" : "bburke@redhat.com"
},
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
}
],
"clients" : [
{
"username" : "third-party",
"enabled": true,
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
}
],
"roles": [
{
"name": "user",
"description": "Have User privileges"
},
{
"name": "admin",
"description": "Have Administrator privileges"
}
],
"roleMappings": [
{
"username": "bburke@redhat.com",
"roles": ["user"]
}
],
"scopeMappings": [
{
"username": "third-party",
"roles": ["user"]
}
],
"applications": [
{
"name": "customer-portal",
"enabled": true,
"adminUrl": "http://localhost:8080/customer-portal/j_admin_request",
"webOrigins" : [ "http://localhost1:8080"],
"credentials": [
{
"type": "password",
"value": "password"
}
]
},
{
"name": "product-portal",
"enabled": true,
"adminUrl": "http://localhost:8080/product-portal/j_admin_request",
"credentials": [
{
"type": "password",
"value": "password"
}
]
}
]
}

View file

@ -1,10 +0,0 @@
<jboss-deployment-structure>
<deployment>
<!-- This allows you to define additional dependencies, it is the same as using the Dependencies: manifest attribute -->
<dependencies>
<module name="org.jboss.resteasy.jose-jwt"/>
<module name="org.jboss.resteasy.resteasy-crypto"/>
<module name="org.bouncycastle"/>
</dependencies>
</deployment>
</jboss-deployment-structure>

View file

@ -1,3 +0,0 @@
<jboss-web>
<symbolic-linking-enabled>true</symbolic-linking-enabled>
</jboss-web>

View file

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<module-name>auth-server</module-name>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.keycloak.example.demo.DemoApplication</param-value>
</init-param>
<init-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<filter>
<filter-name>Keycloak Session Management</filter-name>
<filter-class>org.keycloak.services.filters.KeycloakSessionServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Keycloak Session Management</filter-name>
<url-pattern>/rest/*</url-pattern>
</filter-mapping>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<!--
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint> -->
</web-app>

View file

@ -1,35 +0,0 @@
* {
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: "Open Sans", sans-serif;
}
body {
min-width: 120em;
height: 100%;
width: 100%;
font-family: "Open Sans", sans-serif;
}
body {
font-size: 62.5%;
}
h1, h2, h3, h4, h5, h6 {
letter-spacing: -0.1em;
font-weight: normal;
font-family: "Overpass", sans-serif;
}
a {
color: #0099d3;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}

View file

@ -1,321 +0,0 @@
/* General styles */
.btn-pressed {
box-shadow: none;
margin-top: 0.1em;
margin-left: 0;
margin-bottom: -0.1em;
margin-right: 0.1em;
}
a {
color: #07a1a3;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
input[type="submit"] {
cursor: pointer;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
strong {
font-weight: bold;
}
span.required {
color: #cb2915;
}
.hidden-element {
display: none;
}
/* */
.register-login {
background: url(images/register-login-bg.png) repeat left top;
margin: 0 auto;
font-size: 62.5%;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #777777;
}
.register-login .container {
width: 68em;
margin: 0 auto;
}
.register-login .header {
margin-top: 7.5em;
margin-left: 4em;
margin-right: 4em;
margin-bottom: 2.5em;
width: 60em;
}
.register-login h1 {
font-size: 4em;
font-weight: normal;
color: #c4c4c4;
letter-spacing: -0.02em;
float: left;
}
.register-login .back {
float: right;
font-size: 1.4em;
margin-top: 1.42857142857143em;
}
.feedback {
width: 60em;
margin-left: 2em;
padding: 1.5em 2em;
clear: both;
}
.feedback p {
font-size: 1.6em;
}
.feedback-error {
background-color: #ffe7e3;
border-left: 5px solid #cb2915;
margin-bottom: -15px;
z-index: 10;
position: relative;
}
.feedback-error p {
color: #cb2915;
}
.register-login-container {
background-color: #fff;
width: 100%;
}
.register-login-container form {
padding: 5em 4em 2.2em;
}
p.subtitle {
float: right;
margin-top: -2.14285714285714em;
font-size: 1.4em;
color: #b7b7b7;
}
label {
font-size: 1.8em;
width: 8.88888888888889em;
text-align: right;
display: inline-block;
position: relative;
}
label .required {
position: absolute;
right: -0.94444444444444em;
}
input[type="text"],
input[type="email"],
input[type="password"],
select,
textarea {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
border: 1px solid #dddddd;
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.1);
transition: border 0.5s linear 0s, box-shadow 0.5s linear 0s;
color: #333333;
}
input[type="text"]:focus,
input[type="email"]:focus,
input[type="password"]:focus,
select:focus,
textarea:focus {
border-color: #07a1a3;
box-shadow: 0 0 5px rgba(7, 161, 163, 0.5);
}
input[type="text"].error,
input[type="email"].error,
input[type="password"].error,
select.error,
textarea.error {
border-color: #cb2915;
box-shadow: 0 0 5px rgba(203, 41, 21, 0.5);
background-color: rgba(203, 41, 21, 0.05);
}
label + input {
font-size: 2em;
height: 2em;
margin-left: 1.35em;
padding: 0 0.5em;
}
.register-login label + input {
width: 14em;
}
.register-login form > div {
margin-bottom: 2.5em;
}
.register-login .form-actions {
margin-left: 19em;
}
.form-actions .btn {
float: left;
}
.form-actions a {
font-size: 1.4em;
float: left;
margin-left: 1.07142857142857em;
color: #999999;
margin-top: 1em;
}
.btn {
font-size: 2em;
text-transform: uppercase;
letter-spacing: -0.05em;
padding: 0 1.1em;
height: 2em;
line-height: 2em;
border: none;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.btn-primary {
background-color: #07a1a3;
color: #fff;
box-shadow: -2px 2px 0 #077576;
margin-left: 0.1em;
}
.btn-primary:hover,
.btn-primary:focus {
background-color: #068e90;
}
.btn-primary:active {
box-shadow: none;
margin-top: 0.1em;
margin-left: 0;
margin-bottom: -0.1em;
margin-right: 0.1em;
background-color: #077576;
}
.bottom-actions {
background-color: rgba(221, 221, 221, 0.7);
padding: 2em 4em;
}
.bottom-actions p {
font-size: 1.4em;
}
/* Log in: social */
.social .login-container {
float: left;
width: 34em;
border-right: 1px solid rgba(221, 221, 221, 0.7);
}
.social form,
.social .bottom-actions {
clear: both;
}
.social form {
padding: 4em 4em 1.8em;
}
.social label {
display: block;
width: auto;
text-align: left;
margin-bottom: 0.55555555555556em;
line-height: 1em;
}
.social label + input {
margin-left: 0;
width: auto;
width: 11.8em;
}
.social .form-actions {
margin-left: 0;
}
.social-container {
width: 26em;
float: left;
margin-right: 4em;
margin-top: 4em;
padding-top: 2.8em;
padding-left: 3.9em;
}
.btn-social {
color: #fff;
display: block;
padding: 0;
line-height: 2em;
height: 2em;
margin-left: 0.1em;
letter-spacing: -0.025em;
}
.btn-social .icon {
display: block;
width: 2em;
border-right-width: 1px;
border-right-style: solid;
text-indent: -9999em;
float: left;
}
.btn-social .text {
font-size: 0.8em;
text-align: center;
display: block;
}
.btn-social:hover {
text-decoration: none;
}
.btn-social.facebook {
background-color: #3c5a99;
box-shadow: -2px 2px 0 #293e6b;
}
.btn-social.facebook:hover,
.btn-social.facebook:focus {
background-color: #36518a;
}
.btn-social.facebook:active {
box-shadow: none;
margin-top: 0.1em;
margin-left: 0;
margin-bottom: -0.1em;
margin-right: 0.1em;
background-color: #293e6b;
margin-top: 0;
border-top: 2px solid #fff;
}
.btn-social.facebook .icon {
border-color: #293e6b;
background-image: url(images/btn-social-fb.svg);
background-size: 2em;
background-repeat: no-repeat;
background-position: center 0.1em;
}
/* Specific social logins */
.social-two-three li {
margin-bottom: 5.5em;
}
.social-four {
padding-top: 1em;
}
.social-four li {
margin-bottom: 3.5em;
}
.social-five-nine {
padding-top: 0;
}
.social-five-nine h2 {
font-size: 1.8em;
margin-bottom: 1.11111111111112em;
}
.social-five-nine li {
margin-right: 2.5em;
margin-bottom: 2.5em;
float: left;
}
.social-five-nine li:nth-child(3),
.social-five-nine li:nth-child(6),
.social-five-nine li:nth-child(9) {
margin-right: 0;
}
.social-five-nine .btn-social {
height: 2.9em;
width: 3.4em;
line-height: 0.85em;
letter-spacing: -0.0125em;
}
.social-five-nine .btn-social .icon {
display: block;
width: 3.4em;
height: 2em;
border-right-width: 0;
border-bottom-width: 1px;
border-bottom-style: solid;
float: none;
}
.social-five-nine .btn-social .text {
font-size: 0.5em;
}

View file

@ -1,393 +0,0 @@
/* General styles */
@blue-green: #07a1a3;
@blue-green-darker: #077576;
@light-gray: #ddd;
@gray: #777;
@black: #333;
@red: #cb2915;
@font: "Helvetica Neue", Helvetica, Arial, sans-serif;
.btn-pressed {
box-shadow: none;
margin-top: 0.1em;
margin-left: 0;
margin-bottom: -0.1em;
margin-right: 0.1em;
}
a {
color: @blue-green;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
input[type="submit"] {
cursor: pointer;
font-family: @font;
}
strong {
font-weight: bold;
}
span.required {
color: @red;
}
.hidden-element {
display: none;
}
/* */
.register-login {
background: url(images/register-login-bg.png) repeat left top;
margin: 0 auto;
font-size: 62.5%;
font-family: @font;
color: @gray;
.container {
width: 68em;
margin: 0 auto;
}
.header {
margin-top: 7.5em;
margin-left: 4em;
margin-right: 4em;
margin-bottom: 2.5em;
width: 60em;
}
h1 {
font-size: 4em;
font-weight: normal;
color: darken(@light-gray, 10%);
letter-spacing: -0.02em;
float: left;
}
.back {
float: right;
font-size: 1.4em;
margin-top: 1.42857142857143em;
}
}
.feedback {
width: 60em;
margin-left: 2em;
padding: 1.5em 2em;
clear: both;
p {
font-size: 1.6em;
}
}
.feedback-error {
background-color: #ffe7e3;
border-left: 5px solid @red;
margin-bottom: -15px;
z-index: 10;
position: relative;
p {
color: @red;
}
}
.register-login-container {
background-color: #fff;
width: 100%;
form {
padding: 5em 4em 2.2em;
}
}
p.subtitle {
float: right;
margin-top: -2.14285714285714em;
font-size: 1.4em;
color: darken(@light-gray, 15%);
}
label {
font-size: 1.8em;
width: 8.88888888888889em;
text-align: right;
display: inline-block;
position: relative;
.required {
position: absolute;
right: -0.94444444444444em;
}
}
input[type="text"],
input[type="email"],
input[type="password"],
select,
textarea {
font-family: @font;
border: 1px solid @light-gray;
box-shadow: inset 0 2px 5px fade(#000, 10%);
transition: border 0.5s linear 0s, box-shadow 0.5s linear 0s;
color: @black;
&:focus {
border-color: @blue-green;
box-shadow: 0 0 5px fade(@blue-green, 50%);
}
&.error {
border-color: @red;
box-shadow: 0 0 5px fade(@red, 50%);
background-color: fade(@red, 5%);
}
}
label + input {
font-size: 2em;
height: 2em;
margin-left: 1.35em;
padding: 0 0.5em;
}
.register-login {
label + input {
width: 14em;
}
form > div {
margin-bottom: 2.5em;
}
.form-actions {
margin-left: 19em;
}
}
.form-actions {
.btn {
float: left;
}
a {
font-size: 1.4em;
float: left;
margin-left: 1.07142857142857em;
color: (@gray + #222);
margin-top: 1em;
}
}
.btn {
font-size: 2em;
text-transform: uppercase;
letter-spacing: -0.05em;
padding: 0 1.1em;
height: 2em;
line-height: 2em;
border: none;
font-family: @font;
}
.btn-primary {
background-color: @blue-green;
color: #fff;
box-shadow: -2px 2px 0 @blue-green-darker;
margin-left: 0.1em;
&:hover,
&:focus {
background-color: #068e90;
}
&:active {
.btn-pressed;
background-color: @blue-green-darker;
}
}
.bottom-actions {
background-color: fade(@light-gray, 70%);
padding: 2em 4em;
p {
font-size: 1.4em;
}
}
/* Log in: social */
.social {
.login-container {
float: left;
width: 34em;
border-right: 1px solid fade(@light-gray, 70%);
}
form,
.bottom-actions {
clear: both;
}
form {
padding: 4em 4em 1.8em;
}
label {
display: block;
width: auto;
text-align: left;
margin-bottom: 0.55555555555556em;
line-height: 1em;
}
label + input {
margin-left: 0;
width: auto;
width: 11.8em;
}
.form-actions {
margin-left: 0;
}
}
.social-container {
width: 26em;
float: left;
margin-right: 4em;
margin-top: 4em;
padding-top: 2.8em;
padding-left: 3.9em;
}
.btn-social {
color: #fff;
display: block;
padding: 0;
line-height: 2em;
height: 2em;
margin-left: 0.1em;
letter-spacing: -0.025em;
.icon {
display: block;
width: 2em;
border-right-width: 1px;
border-right-style: solid;
text-indent: -9999em;
float: left;
}
.text {
font-size: 0.8em;
text-align: center;
display: block;
}
&:hover {
text-decoration: none;
}
}
.btn-social.facebook {
background-color: #3c5a99;
box-shadow: -2px 2px 0 #293e6b;
&:hover,
&:focus {
background-color: #36518a;
}
&:active {
.btn-pressed;
background-color: #293e6b;
margin-top: 0;
border-top: 2px solid #fff;
}
.icon {
border-color: #293e6b;
background-image: url(images/btn-social-fb.svg);
background-size: 2em;
background-repeat: no-repeat;
background-position: center 0.1em;
}
}
/* Specific social logins */
.social-two-three li {
margin-bottom: 5.5em;
}
.social-four {
padding-top: 1em;
li {
margin-bottom: 3.5em;
}
}
.social-five-nine {
padding-top: 0;
h2 {
font-size: 1.8em;
margin-bottom: 1.11111111111112em;
}
li {
margin-right: 2.5em;
margin-bottom: 2.5em;
float: left;
}
li:nth-child(3),
li:nth-child(6),
li:nth-child(9) {
margin-right: 0;
}
.btn-social {
height: 2.9em;
width: 3.4em;
line-height: 0.85em;
letter-spacing: -0.0125em;
.icon {
display: block;
width: 3.4em;
height: 2em;
border-right-width: 0;
border-bottom-width: 1px;
border-bottom-style: solid;
float: none;
}
.text {
font-size: 0.5em;
}
}
}

View file

@ -1,61 +0,0 @@
fieldset {
border: none;
}
input[type="text"],
input[type="password"],
input[type="email"] {
font-size: 1.1em;
padding: 0 0.545454545454545em;
min-width: 18.1818181818182em;
height: 2.18181818181818em;
border: 1px #b6b6b6 solid;
border-radius: 2px;
box-shadow: inset 0px 2px 2px rgba(0, 0, 0, 0.1);
color: #333;
}
input[type="text"]:hover,
input[type="password"]:hover,
input[type="email"]:hover {
border-color: #62afdb;
}
input[type="text"]:focus,
input[type="password"]:focus,
input[type="email"]:focus {
border-color: #62afdb;
box-shadow: #62afdb 0 0 5px;
}
input[type="button"],
input[type="submit"]{
font-size: 1.3em;
padding: 0.30769230769231em 1.07692307692308em;
border: 1px #21799e solid;
border-radius: 2px;
background-image: linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -o-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -moz-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -webkit-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -ms-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #00a9ec), color-stop(1, 0, #009bd3));
color: #fff;
font-weight: bold;
letter-spacing: 0.04em;
}
input[type="button"]:hover,
input[type="button"]:focus,
input[type="submit"]:hover,
input[type="submit"]:focus
{
background-color: #009BD3;
background-image: none;
cursor: pointer;
}
input[type="button"]:active,
input[type="submit"]:active {
background-color: #0099d4;
background-image: none;
cursor: pointer;
box-shadow: inset 0 0 5px 3px #0074ae;
}
input[type="checkbox"] {
margin-right: 0.5em;
}

View file

@ -1,66 +0,0 @@
fieldset {
border: none;
}
input[type="text"],
input[type="password"],
input[type="email"] {
font-size: 1.1em;
padding: 0 0.545454545454545em;
min-width: 18.1818181818182em;
height: 2.18181818181818em;
border: 1px #b6b6b6 solid;
border-radius: 2px;
box-shadow: inset 0px 2px 2px rgba(0,0,0,0.1);
color: #333;
&:hover {
border-color: #62afdb;
}
&:focus {
border-color: #62afdb;
box-shadow: #62afdb 0 0 5px;
}
}
input[type="button"] {
font-size: 1.3em;
padding: 0.30769230769231em 1.07692307692308em;
border: 1px #21799e solid;
border-radius: 2px;
background-image: linear-gradient(top, #00A9EC 0%, #009BD3 100%);
background-image: -o-linear-gradient(top, #00A9EC 0%, #009BD3 100%);
background-image: -moz-linear-gradient(top, #00A9EC 0%, #009BD3 100%);
background-image: -webkit-linear-gradient(top, #00A9EC 0%, #009BD3 100%);
background-image: -ms-linear-gradient(top, #00A9EC 0%, #009BD3 100%);
background-image: -webkit-gradient(
linear,
left top,
left bottom,
color-stop(0.0, #00A9EC),
color-stop(1,0, #009BD3)
);
color: #fff;
font-weight: bold;
letter-spacing: 0.04em;
&:hover,
&:focus {
background-color: #009BD3;
background-image: none;
cursor: pointer;
}
&:active {
background-color: #0099d4;
background-image: none;
cursor: pointer;
box-shadow: inset 0 0 5px 3px #0074ae;
}
}
input[type="checkbox"] {
margin-right: 0.5em;
}

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="80px" height="76px" viewBox="0 0 80 76" enable-background="new 0 0 80 76" xml:space="preserve">
<path id="f" fill="#FFFFFF" d="M43.717,62V40.104h7.35l1.1-8.533h-8.449v-5.448c0-2.471,0.686-4.154,4.229-4.154l4.518-0.002v-7.632
C51.682,14.231,49,14,45.88,14c-6.514,0-10.975,3.977-10.975,11.279v6.292h-7.368v8.533h7.368V62H43.717z"/>
</svg>

Before

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

View file

@ -1,164 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1680px" height="1080px" viewBox="0 0 1680 1080" enable-background="new 0 0 1680 1080" xml:space="preserve">
<rect fill="#383D42" width="1680" height="1080"/>
<g>
<defs>
<filter id="Adobe_OpacityMaskFilter" filterUnits="userSpaceOnUse" x="1057" y="597" width="704" height="572">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="1057" y="597" width="704" height="572" id="SVGID_1_">
<g filter="url(#Adobe_OpacityMaskFilter)">
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="1302.4395" y1="-269.9951" x2="1622.4397" y2="22.0046" gradientTransform="matrix(-1 0 0 -1 3112 976.6914)">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<rect x="1035" y="573" fill="url(#SVGID_2_)" width="752" height="620"/>
</g>
</mask>
<path mask="url(#SVGID_1_)" fill="#D8D8D8" d="M1761,597c-140,214-410,510-704,572h704V597z"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_1_" filterUnits="userSpaceOnUse" x="1056.742" y="596.315" width="705.304" height="573.907">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="1056.742" y="596.315" width="705.304" height="573.907" id="SVGID_3_">
<g filter="url(#Adobe_OpacityMaskFilter_1_)">
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="1302.4395" y1="-269.9951" x2="1622.4397" y2="22.0046" gradientTransform="matrix(-1 0 0 -1 3112 976.6914)">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<rect x="1035" y="573" fill="url(#SVGID_4_)" width="752" height="620"/>
</g>
</mask>
<path opacity="0.1" mask="url(#SVGID_3_)" fill="none" stroke="#D8D8D8" stroke-width="2.5" stroke-miterlimit="10" d="M1761,597
c-140,214-410,510-704,572"/>
</g>
<defs>
<filter id="Adobe_OpacityMaskFilter_2_" filterUnits="userSpaceOnUse" x="168.747" y="365.576" width="1798.615" height="822.631">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="168.747" y="365.576" width="1798.615" height="822.631" id="SVGID_5_">
<g filter="url(#Adobe_OpacityMaskFilter_2_)">
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="1476.5908" y1="477.5732" x2="2688.6016" y2="21.5689" gradientTransform="matrix(-0.9876 -0.1569 0.1569 -0.9876 3048.3154 1294.3018)">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<polygon fill="url(#SVGID_6_)" points="329.208,58.782 1976.554,320.459 1810.26,1367.334 162.914,1105.656 "/>
</g>
</mask>
<path mask="url(#SVGID_5_)" fill="#E0E0E0" d="M1967.361,365.576c-393.429,322.269-1126.777,782.925-1798.615,728.856
c379.652,70.433,1428.387,135.769,1651.069,59.762L1967.361,365.576z"/>
<path fill="#D8D8D8" d="M-114.695,1221h1160.347c80.272-27.337,158.024-70.67,230.989-123.266
C792.789,983.34-203.837,592.187-368.695,373L-114.695,1221z"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_3_" filterUnits="userSpaceOnUse" x="-395" y="514.337" width="1423.831" height="829.326">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="-395" y="514.337" width="1423.831" height="829.326" id="SVGID_7_">
<g filter="url(#Adobe_OpacityMaskFilter_3_)">
<linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="2111.374" y1="319.9775" x2="3115.3701" y2="81.9786" gradientTransform="matrix(-1.075 0.1117 -0.1167 -1.1224 3229.8789 866.1523)">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="0.0972" style="stop-color:#060606"/>
<stop offset="0.2213" style="stop-color:#151515"/>
<stop offset="0.36" style="stop-color:#303030"/>
<stop offset="0.5093" style="stop-color:#545454"/>
<stop offset="0.6671" style="stop-color:#838383"/>
<stop offset="0.8323" style="stop-color:#BDBDBD"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<polygon fill="url(#SVGID_8_)" points="-543.126,587.599 1129.521,413.746 1223.549,1318.382 -449.1,1492.233 "/>
</g>
</mask>
<path mask="url(#SVGID_7_)" fill="#C6C6C5" d="M-395,1343.663c225.178-156.636,836.847-511.283,1423.831-382.832l-17.056-446.355
C360.896,503.847-136.975,1108.097-395,1343.663z"/>
<path opacity="0.2" fill="none" stroke="#D8D8D8" stroke-width="5" stroke-miterlimit="10" d="M-368.695,373
c164.858,219.187,1161.484,610.34,1645.336,724.734c154.24,39.423,293.768,67.189,413.359,86.745"/>
<path opacity="0.4" fill="none" stroke="#777D82" stroke-width="3" stroke-miterlimit="10" d="M-218.695,311
c338,316,1048,836,1440,990"/>
<path opacity="0.1" fill="none" stroke="#C6C6C5" stroke-width="2" stroke-miterlimit="10" d="M1257.069,1089.063
c124.494-56.997,382.481-291.736,437.979-414.73"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_4_" filterUnits="userSpaceOnUse" x="535.169" y="-135" width="1423.831" height="829.326">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="535.169" y="-135" width="1423.831" height="829.326" id="SVGID_9_">
<g filter="url(#Adobe_OpacityMaskFilter_4_)">
<linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="664.5693" y1="382.668" x2="1668.5647" y2="144.6692" gradientTransform="matrix(1.075 -0.1117 0.1167 1.1224 -117.8789 110.5386)">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<polygon fill="url(#SVGID_10_)" points="2107.126,621.064 434.478,794.917 340.452,-109.719 2013.1,-283.57 "/>
</g>
</mask>
<path mask="url(#SVGID_9_)" fill="#C6C6C5" d="M1959-135C1733.822,21.636,1122.153,376.284,535.169,247.832l17.055,446.356
C1203.104,704.816,1700.975,100.567,1959-135z"/>
<path fill="#D8D8D8" d="M1743-27H582.653C502.38,0.337,424.629,43.67,351.665,96.265C835.516,210.66,1832.142,601.813,1997,821
L1743-27z"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_5_" filterUnits="userSpaceOnUse" x="-49" y="-47" width="704" height="572">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="-49" y="-47" width="704" height="572" id="SVGID_11_">
<g filter="url(#Adobe_OpacityMaskFilter_5_)">
<linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="-97.5605" y1="-124.686" x2="222.4397" y2="167.3137">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<rect x="-75" y="-71" fill="url(#SVGID_12_)" width="752" height="620"/>
</g>
</mask>
<path mask="url(#SVGID_11_)" fill="#D8D8D8" d="M-49,525C91,311,361,15,655-47H-49V525z"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_6_" filterUnits="userSpaceOnUse" x="-209" y="-147.691" width="1662" height="1002.691">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="-209" y="-147.691" width="1662" height="1002.691" id="SVGID_13_">
<g filter="url(#Adobe_OpacityMaskFilter_6_)">
<linearGradient id="SVGID_14_" gradientUnits="userSpaceOnUse" x1="54.2939" y1="584.9688" x2="1266.2927" y2="128.9689">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<rect x="-211" y="-159" fill="url(#SVGID_14_)" width="1668" height="1060"/>
</g>
</mask>
<path mask="url(#SVGID_13_)" fill="#E0E0E0" d="M-209,855C129,475,781-95,1453-147C1067-157,21-57-187,53L-209,855z"/>
<path opacity="0.2" fill="none" stroke="#D8D8D8" stroke-width="5" stroke-miterlimit="10" d="M1997,821
C1832.142,601.813,835.516,210.66,351.665,96.265C197.423,56.843,57.896,29.076-61.695,9.521"/>
<path opacity="0.4" fill="none" stroke="#777D82" stroke-width="3" stroke-miterlimit="10" d="M1847,883C1509,567,799,47,407-107"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_7_" filterUnits="userSpaceOnUse" x="-50.046" y="-48.223" width="705.304" height="573.907">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="-50.046" y="-48.223" width="705.304" height="573.907" id="SVGID_15_">
<g filter="url(#Adobe_OpacityMaskFilter_7_)">
<linearGradient id="SVGID_16_" gradientUnits="userSpaceOnUse" x1="-97.5605" y1="-124.686" x2="222.4397" y2="167.3137">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<rect x="-75" y="-71" fill="url(#SVGID_16_)" width="752" height="620"/>
</g>
</mask>
<path opacity="0.1" mask="url(#SVGID_15_)" fill="none" stroke="#D8D8D8" stroke-width="2.5" stroke-miterlimit="10" d="M-49,525
C91,311,361,15,655-47"/>
<circle fill="#D8D8D8" cx="1247.084" cy="399.5" r="2.5"/>
<circle fill="#D8D8D8" cx="436.333" cy="117.667" r="2"/>
<circle fill="#D8D8D8" cx="254.667" cy="173.667" r="2"/>
<circle fill="#D8D8D8" cx="375" cy="101.667" r="4"/>
<circle fill="#D8D8D8" cx="351.665" cy="96.265" r="5"/>
</svg>

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1px" height="400px" viewBox="0 0 1 400" enable-background="new 0 0 1 400" xml:space="preserve">
<rect opacity="0.15" fill="#FFFFFF" width="1.447" height="400"/>
</svg>

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="324px" height="400px" viewBox="0 0 324 400" enable-background="new 0 0 324 400" xml:space="preserve">
<rect x="6.001" opacity="0.07" fill="#FFFFFF" width="0.997" height="190"/>
<rect x="6" y="209" opacity="0.07" fill="#FFFFFF" width="1" height="191"/>
<rect x="323" opacity="0.15" fill="#FFFFFF" width="1.447" height="400"/>
<g opacity="0.15">
<path fill="#FFFFFF" d="M6.501,200.066c0,1.047-0.264,1.864-0.791,2.452S4.454,203.4,3.524,203.4c-0.574,0-1.084-0.135-1.529-0.404
s-0.789-0.656-1.031-1.16s-0.363-1.094-0.363-1.77c0-1.047,0.262-1.862,0.785-2.446s1.25-0.876,2.18-0.876
c0.898,0,1.612,0.299,2.142,0.896S6.501,199.047,6.501,200.066z M1.608,200.066c0,0.82,0.164,1.445,0.492,1.875
s0.811,0.645,1.447,0.645s1.12-0.214,1.45-0.642s0.495-1.054,0.495-1.878c0-0.816-0.165-1.437-0.495-1.86s-0.817-0.636-1.462-0.636
c-0.637,0-1.117,0.209-1.441,0.627S1.608,199.238,1.608,200.066z"/>
<path fill="#FFFFFF" d="M11.136,196.744c0.285,0,0.541,0.023,0.768,0.07l-0.135,0.902c-0.266-0.059-0.5-0.088-0.703-0.088
c-0.52,0-0.964,0.211-1.333,0.633s-0.554,0.947-0.554,1.576v3.445H8.206v-6.422h0.803l0.111,1.189h0.047
c0.238-0.418,0.525-0.74,0.861-0.967S10.733,196.744,11.136,196.744z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,268 +0,0 @@
body {
min-height: 60em;
}
.rcue-login-register {
background-color: #1D2226;
background-image: url("img/login-screen-background.jpg");
background-position: top left;
background-size: auto;
background-repeat: no-repeat;
color: #fff;
/* Login area */
/* Social login area */
/* Info area */
}
.rcue-login-register h1 a {
position: absolute;
top: 5em;
right: 6.4em;
}
.rcue-login-register .content {
position: absolute;
bottom: 15%;
width: 100%;
min-width: 76em;
}
.rcue-login-register h2 {
padding-left: 4.34782608695652em;
/* 100px */
font-family: "Overpass", sans-serif;
font-size: 2.3em;
font-weight: 100;
text-transform: uppercase;
letter-spacing: 0.005em;
}
.rcue-login-register h2 strong {
font-weight: bold;
}
.rcue-login-register .background-area {
border-top: 0.1em rgba(255, 255, 255, 0.05) solid;
border-bottom: 0.1em rgba(255, 255, 255, 0.05) solid;
background-color: rgba(0, 0, 0, 0.3);
padding: 3em 0 3em 10em;
margin-top: 2.7em;
width: 100%;
min-width: 120em;
}
.rcue-login-register .background-area section {
float: left;
padding: 1.5em 4.5em 1.5em 4.6em;
width: auto;
position: relative;
}
.rcue-login-register .background-area section h3 {
display: none;
}
.rcue-login-register .background-area section:first-child {
padding-right: 4.5em;
}
.rcue-login-register .form-area {
background-image: url(img/login-register-separator.svg);
background-repeat: no-repeat;
background-position: 40.2em center;
}
.rcue-login-register .form-area.social {
background-image: url(img/login-register-social-separators.svg);
background-position: 39.6em center;
}
.rcue-login-register section.app-form {
padding-left: 0;
}
.rcue-login-register form > div {
margin-bottom: 1em;
}
.rcue-login-register label,
.rcue-login-register .social-login > p {
display: inline-block;
font-size: 1.4em;
font-weight: 400;
}
.rcue-login-register label {
width: 6.07142857142857em;
/* 85px */
}
.rcue-login-register label.two-lines {
float: left;
margin-top: -0.28571428571429em;
/* -4px */
line-height: 1.1em;
}
.rcue-login-register input[type="text"],
.rcue-login-register input[type="password"] {
width: 24.7272727272727em;
/* 272px */
}
.rcue-login-register form > div.aside-btn {
float: left;
font-size: 1.1em;
margin-left: 7.72727272727273em;
/* 85px */
margin-top: 0.90909090909091em;
/* 10px */
margin-bottom: 0;
}
.rcue-login-register form > div.aside-btn label {
font-size: 1em;
width: auto;
}
.rcue-login-register form > div.aside-btn input[type="checkbox"] {
margin-bottom: 0.54545454545455em;
/* 6px */
}
.rcue-login-register form > input[type="button"] {
float: right;
margin-top: 0.76923076923077em;
/* 10px */
}
.rcue-login-register p.subtitle {
font-size: 1.1em;
color: #999;
position: absolute;
right: 4.09090909090909em;
top: -0.636363636363636em;
}
.rcue-login-register section.social-login > span {
display: none;
}
.rcue-login-register section.social-login > p {
float: left;
margin-top: 0.28571428571429em;
/* 14px */
width: 6.78571428571429em;
/* 95px */
}
.rcue-login-register section.social-login > ul {
float: left;
}
.rcue-login-register section.social-login li {
margin-bottom: 2em;
}
.rcue-login-register section.social-login li:last-child {
margin-bottom: 0;
}
.rcue-login-register section.info-area {
padding-right: 0;
}
.rcue-login-register section.info-area p,
.rcue-login-register section.info-area li {
font-size: 1.4em;
margin-bottom: 1.64285714285714em;
/* 23px */
}
.rcue-login-register section.info-area li {
color: #999;
margin-bottom: 1em;
}
.rcue-login-register section.info-area li:last-child {
margin-bottom: 0;
}
@media screen and (min-width: 1280px) {
.rcue-login-register {
background-size: 100% auto;
}
}
/* Social buttons */
.zocial,
a.zocial {
padding: 0;
line-height: 2.3em;
height: 2.3em;
width: 131px;
border-radius: 2px;
box-shadow: none;
background-image: none;
text-shadow: none;
}
.zocial .text,
a.zocial .text {
font-size: 1.2em;
line-height: 1.25em;
text-align: center;
display: block;
font-family: "Open Sans", sans-serif;
font-weight: normal;
border-left: 1px solid rgba(0, 0, 0, 0.15);
margin-left: 3em;
/* 36 px */
margin-top: 0.25em;
/* 3px */
}
.zocial:hover,
a.zocial:hover,
.zocial:active,
a.zocial:active,
.zocial:focus,
a.zocial:focus {
text-decoration: none;
background-image: none;
}
.zocial:hover,
a.zocial:hover {
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);
}
.zocial:before,
a.zocial:before {
margin: 0;
padding: 0;
box-shadow: none;
border: none;
width: 3em;
/* 36px */
}
.zocial.facebook:before {
width: 2.66666666666667em;
/* 32px */
}
/* Register page */
.rcue-login-register.register label {
width: 7.5em;
/* 105px */
}
.rcue-login-register.register input[type="text"],
.rcue-login-register.register input[type="email"],
.rcue-login-register.register input[type="password"] {
width: 22.9090909090909em;
/* 252px */
}
.rcue-login-register.register form > div.aside-btn {
margin-left: 9.54545454545454em;
/* 105px */
width: 12.5454545454546em;
/* 138px */
}
.rcue-login-register.register form > div.aside-btn p {
line-height: 1.3em;
}
/* Customer login */
.rcue-login-register.customer {
background-image: url("img/customer-login-screen-bg2.jpg");
}
.rcue-login-register.customer h2 {
display: inline-block;
}
.rcue-login-register.customer p.powered {
display: inline-block;
font-size: 1.3em;
margin-left: 1.2em;
}

View file

@ -1,302 +0,0 @@
body {
min-height: 60em;
}
.rcue-login-register {
background-color: #1D2226;
background-image: url("img/login-screen-background.jpg");
background-position: top left;
background-size: auto;
background-repeat: no-repeat;
color: #fff;
h1 a {
position: absolute;
top: 5em;
right: 6.4em;
}
.content {
position: absolute;
bottom: 15%;
width: 100%;
min-width: 76em;
}
h2 {
padding-left: 4.34782608695652em; /* 100px */
font-family: "Overpass", sans-serif;
font-size: 2.3em;
font-weight: 100;
text-transform: uppercase;
letter-spacing: 0.005em;
strong {
font-weight: bold;
}
}
.background-area {
border-top: 0.1em rgba(255, 255, 255, 0.05) solid;
border-bottom: 0.1em rgba(255, 255, 255, 0.05) solid;
background-color: rgba(0, 0, 0, 0.3);
padding: 3em 0 3em 10em;
margin-top: 2.7em;
width: 100%;
min-width: 120em;
section {
float: left;
padding: 1.5em 4.5em 1.5em 4.6em;
width: auto;
position: relative;
h3 {
display: none;
}
&:first-child {
padding-right: 4.5em;
}
}
}
.form-area {
background-image: url(img/login-register-separator.svg);
background-repeat: no-repeat;
background-position: 40.2em center;
}
.form-area.social {
background-image: url(img/login-register-social-separators.svg);
background-position: 39.6em center;
}
/* Login area */
section.app-form {
padding-left: 0;
}
form > div {
margin-bottom: 1em;
}
label,
.social-login > p {
display: inline-block;
font-size: 1.4em;
font-weight: 400;
}
label {
width: 6.07142857142857em; /* 85px */
}
label.two-lines {
float: left;
margin-top: -0.28571428571429em; /* -4px */
line-height: 1.1em;
}
input[type="text"],
input[type="password"] {
width: 24.7272727272727em; /* 272px */
}
form > div.aside-btn {
float: left;
font-size: 1.1em;
margin-left: 7.72727272727273em; /* 85px */
margin-top: 0.90909090909091em; /* 10px */
margin-bottom: 0;
label {
font-size: 1em;
width: auto;
}
input[type="checkbox"] {
margin-bottom: 0.54545454545455em; /* 6px */
}
}
form > input[type="button"] {
float: right;
margin-top: 0.76923076923077em; /* 10px */
}
p.subtitle {
font-size: 1.1em;
color: #999;
position: absolute;
right: 4.09090909090909em;
top: -0.636363636363636em;
}
/* Social login area */
section.social-login {
> span {
display: none;
}
> p {
float: left;
margin-top: 0.28571428571429em; /* 14px */
width: 6.78571428571429em; /* 95px */
}
> ul {
float: left;
}
li {
margin-bottom: 2em;
&:last-child {
margin-bottom: 0;
}
}
}
/* Info area */
section.info-area {
padding-right: 0;
p,
li {
font-size: 1.4em;
margin-bottom: 1.64285714285714em; /* 23px */
}
li {
color: #999;
margin-bottom: 1em;
}
li:last-child {
margin-bottom: 0;
}
}
}
@media screen and (min-width: 1280px) {
.rcue-login-register {
background-size: 100% auto;
}
}
/* Social buttons */
.zocial,
a.zocial {
padding: 0;
line-height: 2.3em;
height: 2.3em;
width: 131px;
border-radius: 2px;
box-shadow: none;
background-image: none;
text-shadow: none;
.text {
font-size: 1.2em;
line-height: 1.25em;
text-align: center;
display: block;
font-family: "Open Sans", sans-serif;
font-weight: normal;
border-left: 1px solid rgba(0, 0, 0, 0.15);
margin-left: 3em; /* 36 px */
margin-top: 0.25em; /* 3px */
}
&:hover,
&:active,
&:focus {
text-decoration: none;
background-image: none;
}
&:hover {
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);
}
&:before {
margin: 0;
padding: 0;
box-shadow: none;
border: none;
width: 3em; /* 36px */
}
}
.zocial.facebook:before {
width: 2.66666666666667em; /* 32px */
}
/* Register page */
.rcue-login-register.register {
label {
width: 7.5em; /* 105px */
}
input[type="text"],
input[type="email"],
input[type="password"] {
width: 22.9090909090909em; /* 252px */
}
form > div.aside-btn {
margin-left: 9.54545454545454em; /* 105px */
width: 12.5454545454546em; /* 138px */
p {
line-height: 1.3em;
}
}
}
/* Customer login */
.rcue-login-register.customer {
background-image: url("img/customer-login-screen-bg2.jpg");
h2 {
display: inline-block;
}
p.powered {
display: inline-block;
font-size: 1.3em;
margin-left: 1.2em;
}
}

View file

@ -1,71 +0,0 @@
/* 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;
}
/* Clearfix */
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
html[xmlns] .clearfix {
display: block;
}
* html .clearfix {
height: 1%;
}

View file

@ -1,151 +0,0 @@
<?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="zocialregular" horiz-adv-x="1000" >
<font-face units-per-em="1000" ascent="804" descent="-196" />
<missing-glyph horiz-adv-x="250" />
<glyph unicode=" " horiz-adv-x="250" />
<glyph unicode="&#x09;" horiz-adv-x="250" />
<glyph unicode="&#xa0;" horiz-adv-x="250" />
<glyph unicode="!" d="M5 308q0 215 140.5 355.5t355.5 140.5t355.5 -140.5t140.5 -355.5q0 -182 -103 -313t-280 -171q-9 17 -33.5 52t-34.5 56q64 -26 86 -26q16 0 16 50q0 93 -17 93q-25 0 -97 -55q0 14 -15 12h-5q-26 69 -26 123q0 15 3 30q92 -45 148 -45q31 0 93.5 18t62.5 39 q0 13 -17 13q-26 0 -75 -7t-75 -7q-27 0 -59.5 14t-32.5 38q0 5 1.5 7.5t4.5 3t6 0t8 -1t9 -0.5q9 0 26 -2.5t25 -2.5q31 0 127 36.5t96 56.5q0 12 -18.5 17t-34.5 5q-14 0 -42 -7.5t-61 -18t-44 -13.5q4 20 4 32q0 47 -25 109.5t-58 92.5q-27 24 -72 33q-28 36 -87.5 65.5 t-105.5 29.5q-9 0 -27.5 -3.5t-23.5 -4.5l-22 -31l6 -1q7 0 21.5 2t21.5 2q34 0 78 -14q-28 -14 -49 -19q-2 -1 -13 -2.5t-18.5 -3t-14 -6t-6.5 -11.5q56 6 84 6q38 0 60 -7q-77 -9 -118.5 -53t-41.5 -121q0 -27 4 -50q19 -120 73 -358q33 -154 37 -170l1 -4 q-160 50 -251 185.5t-91 307.5zM288 432q0 -6 3 -12q-1 16 18 28t36 12q8 0 20 -5q-10 13 -29 13q-17 0 -32.5 -9.5t-15.5 -26.5zM321 357q0 13 10.5 23.5t23.5 10.5t23.5 -10.5t10.5 -23.5t-10.5 -23.5t-23.5 -10.5t-23.5 10.5t-10.5 23.5zM361 368q0 -8 9 -8t9 8q0 9 -9 9 t-9 -9zM529 455q8 13 37 13q13 0 33 -10q-10 22 -35 22q-31 0 -35 -25zM552 377q0 12 9 20.5t20 8.5q12 0 20.5 -8.5t8.5 -20.5q0 -11 -8.5 -20t-20.5 -9q-11 0 -20 9t-9 20zM587 387q0 -8 7 -8q8 0 8 8q0 7 -8 7q-7 0 -7 -7z" />
<glyph unicode="&#x22;" horiz-adv-x="1294" d="M0 402q0 105 52.5 188t136.5 131.5t180.5 73.5t194.5 25q29 0 43 -1q115 -6 226 -41q87 -28 166 -74.5t146.5 -109t108 -146.5t40.5 -176q0 -13 -1 -19q-11 -152 -120.5 -256t-268.5 -147q-107 -30 -229 -30h-8q-201 0 -315 53q-6 2 -7 6q0 2 3 2q1 0 3.5 -0.5t3.5 -0.5 q50 -12 89 -12q24 0 47 4.5t43.5 20t20.5 39.5q0 12 -6 24q-9 16 -58.5 33.5t-114 33.5t-75.5 20q-80 26 -139 66q0 1 3.5 9.5t6 14.5t7 12t8.5 6h179q9 0 16.5 -21.5t21 -43.5t35.5 -22q18 0 31 11.5t13 29.5q0 11 -84 199t-106 231q-6 15 -16 15q-8 0 -13 -9l-3 -6 q-8 -15 -52 -114l-107 -238l-7 -15q-95 109 -95 234zM218 236q0 10 54 129l5 3q6 0 32.5 -63.5t26.5 -69.5q0 -4 -5 -4h-108q-5 0 -5 5zM525 113q0 -45 47 -45t47 45v388q0 45 -47 45t-47 -45v-388zM710 113q0 -45 47 -45t47 45v181l92 -185q13 -29 41 -29q32 0 46 29 l91 185v-181q0 -45 47 -45q48 0 48 45v388q0 45 -47 45q-35 0 -47 -29l-138 -302l-133 302q-14 29 -48 29q-46 0 -46 -45v-388z" />
<glyph unicode="#" horiz-adv-x="1009" d="M0 -180v501h501v-501h-501zM509 319v501h500v-501h-500z" />
<glyph unicode="$" horiz-adv-x="974" d="M0 -72l194 891h438q50 0 96.5 -18t84.5 -55.5t52.5 -94.5t-0.5 -135q-29 -136 -128.5 -214t-233.5 -78h-183l-63 -296h-257zM100 -181h257l63 295h184q134 0 233 78t129 214q28 135 -43 219q33 -74 12 -170q-29 -136 -128.5 -214t-233.5 -78h-183l-63 -295h-216zM357 394 h83l42 183h125q2 0 17 -3q-8 29 -31.5 46.5t-55.5 17.5h-125zM482 395q48 2 89.5 37t52.5 84q0 2 1 6t1 6h-114z" />
<glyph unicode="%" horiz-adv-x="957" d="M0 -67v514q0 179 84.5 278t259.5 99h288h260q-5 -5 -52.5 -53t-100 -101t-109 -109.5t-95 -93t-41.5 -36.5q-15 0 -15 16v156h-48q-59 0 -94.5 -6.5t-63 -26t-39 -56.5t-11.5 -96v-262zM67 -184q5 5 52.5 53t100 101t109 109.5t95 93t41.5 36.5q15 0 15 -16v-156h48 q116 0 161.5 35.5t45.5 149.5v262l224 223v-514q0 -179 -84.5 -278t-259.5 -99h-288h-260z" />
<glyph unicode="&#x26;" horiz-adv-x="921" d="M0 221v269q0 26 19 44.5t44 18.5q26 0 44.5 -18.5t18.5 -44.5v-269q0 -26 -18.5 -44.5t-44.5 -18.5t-44.5 18.5t-18.5 44.5zM173 121v418h574v-418q0 -26 -18.5 -44.5t-44.5 -18.5h-448q-26 0 -44.5 18.5t-18.5 44.5zM173 586h574q0 115 -85 189t-202 74t-202 -74 t-85 -189zM274 902q0 8 7 8q3 0 7 -2l49 -89l-15 -8q-48 88 -48 91zM289 95q0 27 19 45t47 18q25 0 44 -19t19 -44v-202q0 -28 -19 -45.5t-47 -17.5q-26 0 -44.5 18.5t-18.5 44.5v202zM294 715q0 16 12 27.5t28 11.5t27.5 -11.5t11.5 -27.5q0 -17 -11.5 -28.5t-28.5 -11.5 q-16 0 -27.5 12t-11.5 28zM502 95q0 27 19.5 45t46.5 18q26 0 44.5 -18.5t18.5 -44.5v-202q0 -28 -19 -45.5t-47 -17.5q-26 0 -44.5 18.5t-18.5 44.5v202zM547 715q0 16 12 27.5t28 11.5t27.5 -11.5t11.5 -27.5q0 -17 -12 -28.5t-28 -11.5t-27.5 12t-11.5 28zM583 819 q2 3 14 28.5t23.5 44t18.5 18.5t7 -9v-2l-48 -89zM794 221v268q0 26 18.5 45t44.5 19t44.5 -19t18.5 -45v-268q0 -26 -18.5 -44.5t-44.5 -18.5t-45 18.5t-18 44.5z" />
<glyph unicode="'" horiz-adv-x="824" d="M0 322q0 107 29 202q28 92 83 159q56 67 135 102q81 36 178 36q128 0 217 -61q90 -59 136 -157q46 -95 46 -196q0 -93 -47 -120t-132 -27h-423q0 -85 30 -148q29 -65 76 -96q50 -33 106 -33q41 0 71 10q31 10 62 33q31 22 56 47t66 69q15 16 47 16q34 0 54 -21 q21 -21 21 -58q0 -32 -23 -78q-21 -43 -70 -85q-46 -41 -116 -68q-71 -27 -161 -27q-209 0 -325 135q-116 136 -116 366zM222 400h392q-7 125 -60 188q-51 62 -136 62q-82 0 -133 -63q-52 -63 -63 -187z" />
<glyph unicode="(" horiz-adv-x="571" d="M0 -73v786q0 44 31.5 75.5t75.5 31.5h357q44 0 75.5 -31.5t31.5 -75.5v-786q0 -44 -31.5 -75.5t-75.5 -31.5h-357q-44 0 -75.5 31.5t-31.5 75.5zM33 34h503v608h-503v-608zM199 731q0 -10 6.5 -16.5t16.5 -6.5h127q10 0 16.5 6.5t6.5 16.5q0 9 -6.5 15.5t-16.5 6.5h-127 q-10 0 -16.5 -6.5t-6.5 -15.5zM242 -72q0 -19 13.5 -32t32.5 -13t32 13t13 32t-13 32t-32 13t-32.5 -13t-13.5 -32z" />
<glyph unicode=")" horiz-adv-x="1106" d="M0 158v478q0 46 14 60t60 14h958q46 0 59.5 -14t13.5 -60v-478q0 -46 -13.5 -59.5t-59.5 -13.5h-406v-37h111v-58h-369v58h111v37h-405q-46 0 -60 13.5t-14 59.5zM37 150h1031v516h-1031v-516z" />
<glyph unicode="*" d="M0 582q0 25 16 45.5t41 26.5l197 47q-63 -72 -63 -168q0 -185 253 -283q28 -11 54 -24.5t54.5 -33.5t46 -46.5t17.5 -55.5q0 -43 -35 -67t-80 -24q-58 0 -121 22.5t-105 60.5l-79 -179q56 -31 144 -61q-10 -2 -31.5 -8.5t-38.5 -10t-32 -3.5q-25 0 -45.5 16t-26.5 41 l-164 687q-2 12 -2 18zM419 536q0 38 35 58.5t76 20.5q49 0 110 -17.5t88 -46.5l61 170q-90 48 -186 63q2 0 45 12t71.5 18t42.5 6q25 0 45.5 -16t26.5 -41l164 -687q2 -12 2 -18q0 -25 -16 -45.5t-41 -26.5l-145 -34q47 70 47 152q0 111 -70.5 182.5t-184.5 109.5 q-171 58 -171 140z" />
<glyph unicode="+" horiz-adv-x="1184" d="M0 -1q0 87 89 155t215 68h54q-42 40 -42 86q0 29 16 58q-10 -1 -29 -1q-104 0 -170 65t-66 160q0 91 82 159t187 68h310l-69 -50h-98q47 -18 73.5 -68t26.5 -111q0 -93 -88 -162q-37 -29 -48 -46t-11 -42q0 -19 27 -48t54 -49q61 -43 84.5 -88t23.5 -113 q0 -90 -82 -156.5t-222 -66.5q-133 0 -225 50t-92 132zM112 32q0 -69 58.5 -117.5t145.5 -48.5q119 0 172.5 44t53.5 117q0 19 -4 32q-3 11 -7 20.5t-12 19t-14 16t-19.5 16.5t-20.5 15t-25 17.5t-26 17.5q-39 12 -77 12q-90 1 -157.5 -47t-67.5 -114zM178 591 q11 -79 60.5 -136t109.5 -58q59 -2 94 52t25 133t-59.5 134t-109.5 57t-95 -51t-25 -131zM733 567v50h200v200h50v-200h201v-50h-201v-201h-50v201h-200z" />
<glyph unicode="," horiz-adv-x="1106" d="M0 673v21l2 2h249l2 -2v-20q0 -8 -10 -8l-26 -1q-33 -1 -33 -20q0 -13 7 -28q50 -122 222 -484l6 -1l111 221q-13 30 -22 49l-76 150l-20 40q-26 51 -34 60.5t-33 13.5q-14 2 -14 7v21l3 2h197l5 -1v-21q0 -8 -10 -8l-15 -2q-13 -2 -19 -5t-5.5 -12t4 -17.5t14.5 -30.5 l73 -150l81 162q16 32 5 43q-6 8 -37 11l-9 1q-4 0 -7 3q-3 1 -3 6v19l3 2q57 1 186 0l2 -2v-20q0 -8 -9 -8q-22 -1 -30.5 -4.5t-16.5 -15.5q-23 -34 -30 -48l-105 -196l-3 -7l128 -262l8 -3l202 481q12 28 -3 41q-13 12 -39 13l-19 1q-3 0 -6 3q-4 2 -4 6v20l3 2h229l2 -2 v-20q0 -7 -9 -9q-46 -2 -66 -19q-20 -16 -34 -49l-250 -567q-10 -23 -22.5 -30.5t-24 1t-22.5 30.5q-38 75 -122 263q-105 -216 -131 -264q-41 -71 -71 -1q-32 75 -130 284.5t-130 286.5q-16 42 -28 52q-11 10 -52 13q-14 2 -14 7z" />
<glyph unicode="-" horiz-adv-x="939" d="M-0.5 707q-0.5 11 6 20.5t13.5 16.5t23.5 15.5t27 13t33 14t34.5 14.5q54 22 97 16t54 -35q25 -67 102.5 -319.5t115.5 -361.5q268 88 326 105q16 6 37.5 4t32.5 -23q23 -47 32.5 -98.5t0.5 -74.5q-19 -15 -59.5 -32t-75.5 -29t-89.5 -29t-73.5 -23q-10 -3 -38 -13 t-53 -18.5t-58 -19t-61 -17.5t-54 -11.5t-44.5 -3.5t-25.5 9q-18 18 -32 52t-29 87t-19 66q-42 125 -113 338.5t-104 312.5q-6 13 -6.5 24z" />
<glyph unicode="." horiz-adv-x="778" d="M3 -129v775h92q0 29 0.5 39t4 31.5t11.5 30t24.5 16.5t40.5 8t40.5 -8t24 -16t11.5 -30.5t4 -31.5v-39h55v39t4 31.5t11.5 30.5t24 16t40.5 8q18 0 31 -4t21.5 -8.5t14.5 -17t8.5 -18.5t4 -24.5t1.5 -24.5v-28h54v28t1.5 24.5t4 24.5t8.5 18.5t14.5 17t21.5 8.5t31 4 q24 0 40.5 -8t24 -16t11.5 -30.5t4 -31.5v-39h92v-775h-776zM68 48v-112h139v112h-139zM68 70h139v119h-139v-119zM68 211h139v130h-139v-130zM68 362h139v112h-139v-112zM139 565q0 -33 37 -33t37 33v130q0 33 -37 33t-37 -33v-130zM228 48v-112h152v112h-152zM228 70h152 v119h-152v-119zM228 211h152v130h-152v-130zM228 362h152v112h-152v-112zM354 565q0 -33 37 -33q38 0 38 33v130q0 33 -38 33q-37 0 -37 -33v-130zM401 48v-112h152v112h-152zM401 70h152v119h-152v-119zM401 211h152v130h-152v-130zM401 362h152v112h-152v-112zM569 565 q0 -33 38 -33q37 0 37 33v130q0 33 -37 33q-38 0 -38 -33v-130zM574 48v-112h140v112h-140zM574 70h140v119h-140v-119zM574 211h140v130h-140v-130zM574 362h140v112h-140v-112z" />
<glyph unicode="/" horiz-adv-x="1309" d="M0 110v181h224v-179q0 -28 20 -48.5t49 -20.5t49.5 20t20.5 49v423q0 117 86.5 199.5t205.5 82.5t205.5 -83t86.5 -201v-92l-134 -40l-89 42v80q0 29 -20 49t-49 20t-49.5 -20t-20.5 -49v-417q0 -120 -86 -204.5t-206 -84.5q-121 0 -207 85.5t-86 207.5zM724 107v183 l89 -42l134 40v-184q0 -29 20 -49.5t49 -20.5t49 20.5t20 49.5v187h224v-181q0 -121 -85.5 -207t-206.5 -86t-207 85t-86 205z" />
<glyph unicode="0" horiz-adv-x="1258" d="M-5 196h119q5 -40 29.5 -64t64.5 -24q48 0 76.5 32.5t28.5 81.5q0 48 -28 79t-75 31q-38 0 -65 -24.5t-51 -24.5q-53 0 -80 2q9 52 28.5 160.5t28.5 164.5h330v-98h-243q-14 -71 -24 -134h3q17 21 50.5 32t65.5 11q113 0 160 -103q24 60 72 94t111 34q49 0 91 -19.5 t66 -41.5t63 -66q3 -3 4.5 -5t4 -4.5l4.5 -4.5q35 40 50 55.5t46 40.5t62 34.5t70 9.5q90 0 145 -60.5t55 -151.5q0 -93 -55 -156t-147 -63q-116 0 -226 131q-7 -7 -39 -38.5t-42.5 -39.5t-37 -25.5t-52 -23t-57.5 -5.5q-63 0 -111 33t-74 92q-62 -128 -203 -128 q-95 0 -156.5 47.5t-61.5 138.5zM510 226q0 -42 25.5 -68t67.5 -26q75 0 155 95q-34 35 -48 48.5t-47.5 33t-63.5 19.5q-39 0 -64 -31t-25 -71zM899 226q27 -29 45.5 -45.5t49 -32.5t61.5 -16q43 0 67.5 27.5t24.5 70.5q0 42 -25.5 70t-67.5 28q-25 0 -49 -11.5t-36.5 -21.5 t-37.5 -36t-32 -33z" />
<glyph unicode="1" horiz-adv-x="774" d="M0 458q0 63 26.5 125t76 115t130 86t178.5 33q159 0 261 -98t102 -231q0 -171 -86.5 -282.5t-223.5 -111.5q-45 0 -84.5 21t-55.5 51l-40 -158q-5 -19 -13 -38.5t-17.5 -37.5t-19 -34t-19 -30t-16.5 -23.5t-13 -16.5l-6 -8q-3 -4 -8 -3t-6 6q0 1 -1.5 14t-3 27.5t-3 37.5 t-1 44.5t3 47.5t7.5 48q11 47 74 313q-8 16 -13 38.5t-5 36.5l-1 15q0 64 32.5 106.5t78.5 42.5q37 0 57.5 -24.5t20.5 -61.5q0 -23 -8.5 -56.5t-22.5 -77t-20 -70.5q-10 -45 17.5 -78t73.5 -33q79 0 130.5 89.5t51.5 216.5q0 97 -63 158.5t-176 61.5q-126 0 -204.5 -81 t-78.5 -194q0 -67 38 -113q13 -15 8 -32q-2 -5 -6 -23t-6 -23q-2 -11 -10 -14.5t-18 0.5q-59 24 -88.5 82.5t-29.5 136.5z" />
<glyph unicode="2" d="M15 438q33 132 125.5 227.5t220.5 132.5t260 4t227.5 -125.5t132.5 -220.5t4 -260t-125.5 -227.5t-220.5 -132.5t-260 -4t-227.5 125.5t-132.5 220.5t-4 260zM243 167l72 -18q7 -1 20 -5t19 -5l-23 -91l55 -14l22 90q6 -2 21 -5.5t23 -5.5l-22 -90l55 -13l22 91 q48 -8 85.5 -7.5t66 20.5t42.5 61q32 90 -51 133q60 13 70 80q13 86 -110 126l23 91l-55 13l-22 -88q-8 2 -23 5.5t-21 5.5l22 88l-55 14l-22 -90q-15 2 -35 8l-76 19l-14 -59l39 -9q28 -7 26 -32l-26 -103q2 0 6 -2q-1 1 -3 1t-3 1l-36 -144q-5 -18 -25 -13l-40 10z M426 190l30 121q1 0 19.5 -4t28 -7t28 -9t28.5 -13t21 -16.5t14.5 -22t-0.5 -27.5q-3 -11 -9 -19t-15 -12t-18.5 -7t-23 -2.5t-23.5 1.5t-24 4t-21.5 4.5t-19.5 4.5t-15 4zM470 366l27 110q3 -1 12.5 -3t16.5 -3.5t18 -5t19 -6.5t18 -8.5t15 -11t11.5 -13.5t6 -16.5 t-1.5 -19.5q-3 -13 -10.5 -21.5t-19 -11.5t-22.5 -4.5t-26.5 1t-24 4t-23 5.5t-16.5 4z" />
<glyph unicode="3" horiz-adv-x="1129" d="M0 597h77l107 -363l72 244l-35 119h77l107 -363l107 363h77h213v-36l-109 -188q58 -20 86 -67q30 -50 30 -114q0 -82 -43 -137t-112 -55q-51 0 -90 33q-39 34 -56 89l60 25q13 -34 35 -54q20 -19 51 -19t52 34q22 34 22 84q0 52 -23 83q-27 34 -83 34h-30v36l103 178 h-124l-7 -12l-152 -511h-7l-110 370l-111 -370h-7zM818 180l18 -50q15 -33 33 -58q42 -58 94 -67q45 -9 88 18q19 12 35 31q20 20 28 36q4 7 11 20l-11 59q-8 -16 -16 -28t-12 -17l-4 -4q-34 -37 -61 -49q-33 -15 -68 -11q-27 2 -60 24q-36 31 -43 43q-13 18 -32 53z M845 375q0 84 33 146q16 30 37.5 48t42.5 20q35 4 70 -26q18 -15 37 -50l44 87l12 -76l-44 -85q-8 16 -19 30t-18 20l-8 6q-31 22 -64 15q-24 -5 -47.5 -30t-34.5 -59q-19 -55 -19 -106q-1 -40 5 -63q-12 22 -19 53t-7 51z" />
<glyph unicode="4" horiz-adv-x="1169" d="M0 377q0 105 76.5 179.5t184.5 74.5q85 0 152.5 -48t94.5 -124l66 64l158 -152l437 446v-405l-267 -206l34 -36l-363 -353l-316 307q-107 2 -182 76t-75 177zM37 377q0 -90 65 -153t157 -63q33 0 65 9l220 -195l585 460l1 302l-578 -596l-90 146q20 43 20 90 q0 89 -65.5 152.5t-157.5 63.5t-157 -63.5t-65 -152.5zM85 375q0 70 49.5 119.5t119.5 49.5t119.5 -49t49.5 -120q0 -70 -49.5 -119.5t-119.5 -49.5t-119.5 49.5t-49.5 119.5z" />
<glyph unicode="5" horiz-adv-x="710" d="M16 619h699l-66 -710l-284 -81l-284 81zM81 679v133h45v-44h40v44h44v-133h-44v44h-40v-44h-45zM146 474l24 -266l1 2h300l-10 -113l-96 -27l-97 28l-6 68h-88l12 -136l179 -51l179 51l25 267h-319l-8 89h335l8 88h-439zM230 767v45h122v-45h-39v-88h-44v88h-39zM371 679 v133h47l27 -46l28 46h47v-133h-43v68l-32 -50v1l-30 47v-66h-44zM543 679v133h44v-88h62v-45h-106z" />
<glyph unicode="6" horiz-adv-x="943" d="M0 -32.5q-3 35.5 7 59.5q39 140 92 239q114 216 313 352v14q-59 -25 -118.5 -65.5t-102 -81t-76 -77.5t-50.5 -60l-17 -23q-2 59 16 115t45 94t54.5 67t46.5 43l19 13q4 2 10.5 5.5t27.5 13.5t43.5 18.5t55 17t64 12t70 2t73.5 -11.5q64 47 128.5 73t97.5 29l33 3 q50 5 77.5 -16.5t31 -55t-0.5 -68t-12 -59.5l-9 -24l-5 5q21 57 20.5 93.5t-17.5 56.5t-36.5 29t-36.5 10l-16 2q-4 0 -11.5 -0.5t-32 -5t-49 -12.5t-60.5 -25t-69 -41q69 -11 123 -42t86 -70.5t54.5 -85t31 -88.5t13 -78t3.5 -56l-1 -22h-557q-3 -42 10.5 -73t34 -45.5 t41 -22.5t35.5 -9l15 -1q4 0 11.5 0.5t26.5 5.5t34.5 14t31 28.5t21.5 46.5h292q-16 -59 -47 -107t-68 -77.5t-78 -51t-78.5 -31.5t-68 -16t-48.5 -7h-19q-78 0 -107 6q-60 -47 -126.5 -73.5t-103.5 -29.5l-36 -3q-46 0 -77.5 23.5t-41.5 56t-13 68zM75.5 -27 q-0.5 -24 2.5 -42.5t8 -28.5l4 -9q4 -3 11 -8t33.5 -13.5t57 -8t82 16.5t107.5 50q-8 2 -21.5 5.5t-50.5 18t-69 31.5t-66.5 47.5t-53.5 64.5q-22 -34 -33 -67t-11.5 -57zM358 397h265q1 36 -11.5 63t-32 39t-38.5 19t-33 8l-14 1q-6 0 -15 -1t-33 -8t-42 -19t-32.5 -39 t-13.5 -63z" />
<glyph unicode="7" horiz-adv-x="900" d="M42 581q2 17 15 32l120 120q14 12 21 -4l97 -182q8 -16 -5 -31l-44 -44q-12 -12 -14 -31q0 -30 31 -77t61 -80l31 -32q14 -14 36 -34.5t72.5 -54t79.5 -33.5q19 0 32 13l52 52q14 14 30 4l175 -103q7 -4 8 -10.5t-4 -11.5l-120 -120q-15 -13 -32 -15q-49 -7 -110.5 13.5 t-114 54.5t-97.5 69t-72 60l-26 25q-10 10 -26.5 27.5t-57.5 69t-71 100.5t-52 111.5t-15 111.5z" />
<glyph unicode="8" d="M0 318q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251t-67 -251t-182 -182t-251 -67t-251 67t-182 182t-67 251zM129 318q0 -65 36 -77q5 -2 17 -4q42 -1 85 40q41 36 58 90q25 77 10 200q-2 12 -2 17q-3 6 0 9q1 3 13 -1q38 -10 78 -29q46 -21 102 -70 q45 -39 87 -89q33 -39 80 -104q41 -57 88 -77q29 -10 47.5 -7t29 20t15 37t4.5 45q0 48 -12 96q-3 12 -8 28q-14 43 -41 84q-52 79 -135.5 124t-177.5 45q-66 0 -125 -22q-80 -28 -140.5 -89t-88.5 -142q-1 -5 -4 -14.5t-5 -13.5q-12 -50 -11 -96z" />
<glyph unicode="9" horiz-adv-x="1220" d="M0 669q-1 5 2.5 9.5t8.5 5.5q11 2 31 6.5t28 6.5q0 17 1 49.5t1 48.5q2 12 13 12q14 0 14 -14q-2 -60 -2 -91q11 2 35 7t35 8q18 4 55 10t56 10q402 69 794 72q6 0 9.5 -4.5t2.5 -10.5q0 -11 -2 -33t-2 -33q42 -3 128 -11q5 0 9 -4.5t3 -9.5q-23 -137 -68 -412t-68 -413 q50 -8 76 -12q8 -1 10.5 -8t-0.5 -13t-10 -6h-3q-13 2 -39 6.5t-39 6.5q-1 -12 -5 -31q-2 -9 -10 -11q-1 -1 -4 -1h-4q-297 75 -600 117q-100 2 -149 2q-55 0 -165 -2v-1q1 -1 1 -2q1 -6 -4 -10.5t-11 -4.5q-11 0 -12 11q0 5 -1.5 15.5t-2.5 16.5h-13q-8 0 -10.5 7t1 13.5 t11.5 6.5h1h7l-6 54q-6 40 -25 194.5t-35.5 251.5t-42.5 191zM30 661q21 -78 43 -201q-3 70 -3 209q-16 -2 -40 -8zM97 570q1 -193 21 -424q3 -40 11 -109q1 -9 2.5 -19t3.5 -22t3 -19q67 -3 192 -13t182 -13q354 -20 483 -35q11 160 32.5 455t29.5 411q-468 -4 -960 -107 q-1 -53 0 -105zM189 407q0 -68 42.5 -111t108.5 -43q69 0 109 43h2q-13 -70 -65 -111q-41 -33 -101 -38q-40 -4 -52 -2v-75q35 0 57 2q107 8 171 68q87 82 87 233q0 94 -47 153.5t-132 59.5q-78 0 -129 -53t-51 -126zM283 413q0 45 22.5 73.5t58.5 28.5h1q43 0 65 -35.5 t21 -90.5q0 -16 -5 -26q-26 -42 -81 -42q-38 0 -60 26t-22 66zM372 -64l96 -10l373 -40q140 -30 209 -48l3 18q-55 9 -165 25q-249 35 -516 55zM564 407q0 -68 43 -111t108 -43q69 0 110 43h1q-13 -70 -64 -111q-42 -33 -102 -38q-40 -4 -52 -2v-75q35 0 57 2q107 8 171 68 q87 80 87 233q0 94 -47 153.5t-131 59.5q-78 0 -129.5 -53t-51.5 -126zM658 413q0 45 23 73.5t58 28.5h1q43 0 65 -35.5t21 -90.5q0 -16 -5 -26q-26 -42 -81 -42q-38 0 -60 26t-22 66zM1015 -111q28 -4 43 -6q20 120 64.5 392t68.5 417q-13 1 -35.5 3t-41.5 3.5t-36 2.5 q-6 -85 -27 -366.5t-31 -435.5q0 -5 -4 -9q-1 0 -1 -1z" />
<glyph unicode=":" horiz-adv-x="834" d="M0 -180l417 1000l417 -1000h-369v135l170 85l-13 55l-157 -79v67l98 52l-14 57l-84 -45v87h-92v-157l-86 59l-16 -64l102 -70v-182h-373z" />
<glyph unicode=";" horiz-adv-x="1123" d="M-1 52v372q0 13 13 13h176v129q0 14 13 14h98v-514q0 -14 -12 -14h-288zM108 135h67q13 0 13 14v206h-67q-13 0 -13 -14v-206zM333 52v372q0 13 13 13h98v-371q0 -14 -12 -14h-99zM333 497v69q0 14 12 14h99v-69q0 -14 -12 -14h-99zM482 52v372q0 13 13 13h288v-504 q0 -13 -13 -13h-288l1 69q0 14 12 14h176v49h-189zM592 135h67q12 0 12 14v206h-67q-12 0 -12 -14v-206zM821 -11q0 14 13 14h176v49h-189v372q0 13 13 13h287v-504q0 -13 -12 -13h-288v69zM930 135h67q13 0 13 14v206h-67q-13 0 -13 -14v-206z" />
<glyph unicode="&#x3c;" d="M0 329q0 73 51.5 125t124.5 52q63 0 114 -43l358 179q0 2 -0.5 5.5t-0.5 5.5q0 73 52 124.5t125 51.5t124.5 -51.5t51.5 -124.5t-51.5 -125t-124.5 -52q-64 0 -114 42l-358 -179q0 -1 0.5 -4.5t0.5 -5.5q0 -1 -0.5 -5t-0.5 -5l358 -179q50 42 114 42q73 0 124.5 -51.5 t51.5 -124.5t-51.5 -125t-124.5 -52q-74 0 -125.5 51.5t-51.5 125.5q0 1 0.5 4.5t0.5 5.5l-358 179q-50 -42 -114 -42q-73 0 -124.5 51.5t-51.5 124.5z" />
<glyph unicode="=" d="M0 319q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251q0 -101 -38 -192t-107 -160q-60 73 -145.5 114t-182.5 41q-107 0 -199 -49.5t-151 -134.5q-83 71 -130 170t-47 211zM164 463q0 -17 12 -29.5t30 -12.5q6 0 9 1q144 58 298 58t298 -58q1 0 4 -0.5t5 -0.5 q17 0 29.5 12.5t12.5 29.5q0 25 -23 37q-159 63 -326 63q-170 0 -329 -64q-20 -13 -20 -36zM210 314l6 -16q8 -13 23 -13q3 0 9 2q127 55 265 55q139 0 267 -56q4 -2 7 -2q15 0 23 13l5 17q0 13 -10 21q-138 62 -292 62q-153 0 -293 -62q-10 -10 -10 -21zM258 170 q10 -25 31 -16q108 51 224 51q112 0 219 -48q24 -13 35 12q5 13 0 23t-14 15q-106 53 -240 53q-128 0 -244 -55q-19 -10 -11 -35zM319 -147q37 48 91.5 76t116.5 28q114 0 193 -86q-104 -52 -220 -52q-94 0 -181 34z" />
<glyph unicode="&#x3e;" horiz-adv-x="1205" d="M0 323q0 62 49.5 106t112.5 44q62 0 105 -36h5q134 82 335 82l5 4l70 267l242 -36q0 -1 2 -1q1 0 0 1q2 1 11.5 15.5t14.5 18.5q34 32 82 32q49 0 82.5 -32.5t33.5 -81.5t-33.5 -84t-82.5 -35q-57 0 -87 38.5t-30 96.5q-2 -1 -97.5 13t-109.5 17h-3q-2 -2 -16.5 -53.5 t-30 -109t-17.5 -63.5v-3l5 -4q72 0 147.5 -20.5t130.5 -57.5l3 -2q1 1 2 1t2 1q25 18 35.5 25t29.5 13t43 6q68 0 116 -48t48 -117q0 -47 -26.5 -86t-69.5 -60q0 -195 -260 -303q-41 -18 -56 -23q-32 -10 -91 -19t-93 -9q-120 0 -231 35q-2 2 -72 38q-95 51 -152.5 116 t-57.5 156h-5q-33 17 -59 50l-9 12q-15 27 -19 45.5t-4 50.5zM34 311q0 -66 57 -112q5 59 48 116t101 101q-37 26 -82 26q-49 0 -86.5 -40.5t-37.5 -90.5zM136 165q0 -54 31 -104t79.5 -85.5t102.5 -59.5t105 -34q75 -14 146 -14q123 0 233 39.5t185 122.5h-3q30 38 43 68.5 t13 72.5q0 54 -26.5 103t-69.5 84t-92 60.5t-100 38.5q-85 23 -181 23q-74 0 -151.5 -18t-150 -54t-118.5 -99.5t-46 -143.5zM322 238q0 37 22.5 59.5t59.5 22.5t62 -22.5t25 -59.5q0 -36 -25.5 -60t-61.5 -24t-59 24t-23 60zM358 74h44q25 -45 79.5 -68.5t111.5 -23.5 q58 0 110 23.5t84 68.5h41q-25 -62 -93 -96t-142 -34q-72 0 -141.5 34.5t-93.5 95.5zM694 238q0 38 23 60t61 22q34 0 58 -24t24 -58t-24 -59t-58 -25q-37 0 -60.5 23.5t-23.5 60.5zM949 706q0 -35 25 -60t60 -25q36 0 59 24.5t23 60.5q0 34 -24 58t-58 24t-59.5 -24.5 t-25.5 -57.5zM963 425q55 -36 95 -92.5t56 -119.5q59 43 59 96q0 58 -35.5 100t-92.5 42q-45 0 -82 -26z" />
<glyph unicode="?" horiz-adv-x="767" d="M2 27q0 22 12 64q23 87 86.5 158t147.5 103q-79 63 -79 161q0 86 62.5 146t148.5 60t148.5 -60t62.5 -146q0 -97 -77 -160q106 -38 177 -127t71 -198q0 -92 -73 -106q-3 -10 -13 -26q-6 -16 -23.5 -28.5t-48.5 -20.5t-49.5 -12t-56.5 -9t-39 -5q-2 0 -7 -1t-7 -1h-120 q-51 0 -129 16.5t-89 44.5q-17 17 -25 42q-25 5 -42 21q-38 15 -38 84z" />
<glyph unicode="@" horiz-adv-x="772" d="M4 308v103q0 87 86 200t171 160q78 44 187 44q44 0 88.5 -10t85.5 -31t66.5 -58t25.5 -85q0 -13 -2 -24.5t-7 -24t-9 -21t-14 -21t-14 -18.5t-17.5 -19.5t-16.5 -17t-18.5 -17.5t-17.5 -16h53h115q2 -72 2 -108q0 -253 -42 -326q-35 -61 -94.5 -108t-127.5 -70 q-39 -15 -56 -15h-84q-3 0 -48 17q-120 53 -120 174q0 4 0.5 11t0.5 10q-134 69 -180 215q-13 42 -13 56zM150 438q0 -40 9.5 -81t28.5 -79t52.5 -62t76.5 -24q12 0 39.5 15t49.5 15q14 0 51 -10.5t37 -19.5q0 -21 -26 -21q-130 0 -130 -76q0 -58 42 -87.5t103 -29.5 q47 0 92 16.5t73 49.5q42 50 42 164q0 19 -1 55.5t-1 54.5q0 48 5 80h-193q-1 -8 -1 -23q0 -11 1 -34t1 -35q0 -35 -8 -56q-5 -1 -17 -1q-48 0 -80 32.5t-44 74.5t-12 89q0 45 11.5 91t43 84t77.5 38q10 0 21 -3q-4 -22 -4 -34q0 -35 19 -58t53 -23t57 23t23 58q0 41 -31 70 t-70 40t-79 11q-135 0 -223 -85t-88 -219z" />
<glyph unicode="A" horiz-adv-x="860" d="M1 361q-1 -18 -1 -36q0 -68 20 -144q26 -97 83 -184q89 -136 172 -137q30 0 78 21t95 21h4q46 0 91 -20q47 -22 76 -22q49 1 91 41t85 104q31 48 65 121q-50 19 -85 57t-48 85q-10 35 -9 70v24q4 48 33.5 91.5t78.5 70.5q-38 48 -89 75t-103 27q-48 0 -105.5 -21.5 t-85.5 -21.5q-30 0 -90.5 21.5t-101.5 21.5q-58 0 -114.5 -33.5t-95.5 -92.5q-37 -56 -44 -139zM416 619q-3 15 -3 30q0 65 53 129q27 33 69.5 56t82.5 26q2 -15 2 -30q0 -69 -50 -132q-28 -36 -70 -58q-41 -22 -80 -21h-4z" />
<glyph unicode="B" horiz-adv-x="996" d="M0 135v369q0 130 93 223t223 93h221q65 -8 138.5 -57t104.5 -115q1 -2 5 -9.5t5 -10t3.5 -9.5t4 -12.5t3.5 -15.5t4 -22t4 -29q9 -70 26 -85q14 -13 71 -14.5t65 -7.5l14 -11l8 -17l3 -14l-2 -256q-1 -130 -93 -222.5t-222 -92.5h-363q-130 0 -223 92.5t-93 222.5z M259 140q0 -25 18 -42.5t43 -17.5h356q25 0 42.5 17.5t17.5 42.5t-17.5 42.5t-42.5 17.5h-356q-25 0 -43 -17.5t-18 -42.5zM259 502q0 -25 18 -43t43 -18h175q25 0 42.5 18t17.5 43t-17.5 42.5t-42.5 17.5h-175q-25 0 -43 -17.5t-18 -42.5z" />
<glyph unicode="C" d="M0 320q0 98 38 191q37 90 110 163q144 146 351 146q209 0 357 -146q71 -71 107 -162q37 -89 37 -192q0 -104 -36 -192q-36 -89 -107 -159q-74 -72 -166 -111q-94 -38 -192 -38q-97 0 -190 38q-89 37 -162 110t-110 162t-37 190zM90 320q0 -79 32 -155q31 -75 91 -133 q60 -60 133 -89q72 -31 155 -31q81 0 156 31q74 31 136 90q117 114 117 287q0 85 -31 157q-30 76 -88 132q-120 121 -290 121q-171 0 -288 -120q-59 -59 -91 -134q-32 -76 -32 -156zM215 320q0 71 42 113q41 42 105 42q92 0 133 -72l-67 -35q-11 24 -27 31q-15 9 -29 9 q-67 0 -67 -88q0 -39 17 -64q18 -24 50 -24q44 0 62 42l62 -31q-21 -36 -55 -57q-35 -21 -77 -21q-67 0 -108 41t-41 114zM504 320q0 71 42 113t105 42q93 0 132 -72l-66 -35q-11 23 -26 31q-17 9 -30 9q-67 0 -67 -88q0 -41 17 -64q17 -24 50 -24q43 0 61 42l63 -31 q-22 -37 -56 -57q-35 -21 -75 -21q-69 0 -109 41q-41 41 -41 114z" />
<glyph unicode="D" d="M0 320q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251t-67 -251t-182 -182t-251 -67t-251 67t-182 182t-67 251zM83 320q0 -156 105 -275q48 94 152 179t203 107q-15 35 -29 63q-172 -55 -372 -55q-39 0 -58 1q0 -4 -0.5 -10t-0.5 -10zM96 423q22 -2 65 -2 q167 0 317 45q-76 135 -167 225q-79 -40 -135.5 -111t-79.5 -157zM245 -9q113 -88 255 -88q74 0 147 28q-20 171 -78 331q-92 -20 -185.5 -101t-138.5 -170zM398 723q88 -91 163 -227q136 57 205 145q-116 96 -266 96q-51 0 -102 -14zM597 425q15 -32 34 -81q74 7 161 7 q62 0 123 -3q-8 136 -98 242q-65 -97 -220 -165zM656 274q51 -148 69 -304q79 51 129 131t60 173q-73 5 -133 5q-55 0 -125 -5z" />
<glyph unicode="E" horiz-adv-x="837" d="M0 511q0 40 15 58q9 14 26 21q18 9 47 9h94q15 0 26 11t11 26q0 21 -1 44v59q0 25 12 44q15 21 50 31q11 6 53 6h19q59 -2 98 -17q38 -16 45 -62q26 1 48 1q53 0 89 -5q97 -12 129 -24q42 -13 53 -67q10 -55 18 -210q5 -89 5 -147q0 -44 -3 -71q-16 -172 -43 -254 q-14 -42 -28 -68.5t-27.5 -42.5t-36.5 -23t-42.5 -8.5t-58.5 -1.5q-108 0 -145.5 25.5t-37.5 106.5q0 45 9.5 71.5t33 37.5t46.5 13q15 1 40 1h28q4 0 5.5 -1.5t0.5 -5t-2.5 -7.5t-3 -11t-1.5 -13q0 -9 2 -18.5t1 -12t-7 -2.5h-9.5h-10.5t-10 -0.5t-10 -1.5t-8.5 -2.5t-8 -4 t-5.5 -6t-4 -9t-1 -11.5q0 -14 4 -23t7.5 -14t18 -7t22 -2h32.5q57 0 73 13.5t16 63.5q0 76 -18.5 102.5t-56.5 31.5q-88 9 -119 20q-53 20 -53 119q0 2 -2.5 2t-2.5 -2q0 -67 -18 -120l-8 -24q-11 -25 -37 -26h-6q-24 0 -54 8q-127 16 -198 47q-24 11 -37 40 q-17 35 -35.5 128.5t-23.5 133.5q-4 33 -4 51zM6 630v2l183 180q0 1 1 1l-3 -6q-11 -20 -11 -48q0 -22 1 -103q0 -10 -10 -10h-93q-34 0 -59 -11q-5 -3 -9 -5zM574 340q21 3 46 3q45 -1 81 -18q0 85 -61 87h-3q-30 0 -44 -20q-15 -21 -19 -52z" />
<glyph unicode="F" horiz-adv-x="1053" d="M0 260q0 104 73 177t177 73t177 -73t73 -177t-73 -177t-177 -73t-177 73t-73 177zM552 260q0 104 73 177t177 73t177 -73t73 -177t-73 -177t-177 -73t-177 73t-73 177z" />
<glyph unicode="G" horiz-adv-x="646" d="M0 -1q0 87 89 155t215 68h54q-42 40 -42 86q0 29 16 58q-10 -1 -29 -1q-104 0 -170 65t-66 160q0 91 82 159t187 68h310l-69 -50h-98q47 -18 73.5 -68t26.5 -111q0 -93 -88 -162q-37 -29 -48 -46t-11 -42q0 -19 27 -48t54 -49q61 -43 84.5 -88t23.5 -113 q0 -90 -82 -156.5t-222 -66.5q-133 0 -225 50t-92 132zM112 32q0 -69 58.5 -117.5t145.5 -48.5q119 0 172.5 44t53.5 117q0 19 -4 32q-3 11 -7 20.5t-12 19t-14 16t-19.5 16.5t-20.5 15t-25 17.5t-26 17.5q-39 12 -77 12h-4q-87 0 -153 -47q-68 -48 -68 -114zM178 591 q11 -79 60.5 -136t109.5 -58h4q56 0 90 52q27 42 27 99q0 16 -2 34q-10 79 -59.5 134t-109.5 57h-4q-57 0 -91 -51q-27 -41 -27 -98q0 -16 2 -33z" />
<glyph unicode="H" horiz-adv-x="878" d="M0 194q0 -147 101 -257t260 -110q158 0 259 110q101 108 101 257q0 78 -27 146q-40 -25 -85 -34q22 -51 22 -114q0 -76 -36 -142q-37 -66 -99 -101q-62 -36 -135 -36q-75 0 -136 36q-63 37 -98 101q-37 65 -37 142q0 117 80 202q80 83 191 83q51 0 98 -19q4 39 27 86 q-57 21 -125 21q-160 0 -266 -118q-95 -107 -95 -253zM280 -59l56 -4q74 47 124.5 109t72.5 124t31 126q6 41 6 80q0 21 -2 40q-5 55 -12.5 98.5t-15.5 68.5l-9 25q-22 68 -43.5 119t-31.5 67l-11 17q39 -20 63 -48q23 -29 28 -53q4 -20 4 -39v-7q-1 -22 -6 -35l-5 -13 q4 -58 5 -112q0 -52 -5 -102q-9 -100 -30.5 -167t-49.5 -121.5t-57.5 -85.5t-54.5 -51.5t-41 -28.5zM555 578q4 40 23 64l18 25q12 14 39 26.5t48 18.5l21 6q36 8 66.5 35t43.5 51l13 23q41 -57 49 -129q4 -32 3 -57q0 -34 -6 -59l-11 -45q-12 -33 -33.5 -60t-36.5 -37 l-15 -11q-34 -20 -67 -20l-109 53q58 32 101 65t63.5 57.5t33 44.5t14.5 31l2 10q-18 -40 -48.5 -73t-62 -52t-60.5 -32.5t-47 -18.5l-18 -5q-25 44 -25 79q0 5 1 10z" />
<glyph unicode="I" horiz-adv-x="487" d="M-2 -148q102 6 130 27q30 21 30 107v666q0 82 -30 106q-28 23 -130 28v28h489v-28q-102 -4 -131 -28q-30 -24 -30 -106v-666q0 -86 30 -107t131 -27v-28h-489v28z" />
<glyph unicode="J" horiz-adv-x="1234" d="M0 145q0 161 184 347q117 116 236 162q56 23 97 23q45 0 72 -27q26 -26 26 -72q0 -31 -12 -72q-4 -14 3 -17.5t16 -0.5l10 4q96 40 170 40t106 -42q15 -22 15 -52q0 -31 -16 -71q-7 -10 -2.5 -17t8 -9t14.5 -5q62 -19 106 -62t44 -107q0 -59 -41 -120.5t-111.5 -112.5 t-178 -84t-228.5 -33q-131 0 -247.5 38.5t-193.5 115t-77 174.5zM125 97q10 -101 125 -161q92 -49 209 -49q29 0 60 3q153 15 255 97q92 75 92 165q0 9 -1 18q-10 100 -125 160q-93 49 -210 49q-29 0 -59 -3q-101 -10 -183 -51t-126 -101q-38 -53 -38 -109q0 -9 1 -18z M285 35q-13 29 -13 59q0 35 18 70q31 64 104 96q45 20 91 20q27 0 54 -7q76 -20 109 -82q17 -32 17 -66q0 -32 -15 -65q-31 -71 -109 -104q-44 -19 -88 -19q-34 0 -67 11q-73 23 -101 87zM341 54q6 -25 30 -35q13 -6 27 -6q12 0 24 4q28 9 43 33q10 16 10 32q0 7 -3 15 q-6 24 -30 34q-13 5 -26 5q-12 0 -25 -4q-27 -9 -41 -32q-11 -16 -11 -33q0 -7 2 -13zM482 133q3 -9 13 -13q5 -2 9.5 -2t9.5 2q11 4 16 13t2 18t-12 13q-9 3 -19.5 -0.5t-15.5 -12.5q-3 -6 -3 -12v-6zM803 754q-1 5 -1 10q0 13 8 25q10 16 29 21q34 7 68 7q51 0 100 -15 q83 -27 143 -93t78 -153q7 -35 7 -68q0 -51 -16 -98v-1q-6 -18 -23 -27q-11 -5 -22 -5q-7 0 -15 2q-19 6 -27 23q-5 11 -5 21q0 8 2 15v1q11 34 11 70q0 23 -4 48q-13 62 -56 109t-102 66q-35 10 -70 10q-24 0 -49 -5q-5 -1 -10 -1q-14 0 -26 8q-16 11 -20 30zM843 597 q-1 5 -1 10q0 10 6 21q9 14 26 18q19 4 37 4q67 0 115 -53q29 -33 38 -75q3 -17 3 -33q0 -24 -8 -48q-5 -16 -20 -23q-9 -5 -18 -5q-7 0 -13 2q-16 5 -24 20q-4 9 -4 18q0 7 2 13q4 14 4 26q0 28 -21 50q-22 26 -54 26q-10 0 -20 -2q-5 -1 -9 -1q-11 0 -21 7q-14 9 -18 25z " />
<glyph unicode="K" horiz-adv-x="1086" d="M0 -182v1000h257v-371h229q85 123 257 371h286l-328 -477q0 -12 96.5 -143t192.5 -256l96 -124h-343q-47 66 -143 199.5t-143 200.5h-200v-400h-257z" />
<glyph unicode="L" horiz-adv-x="1040" d="M-5 699q0 50 35 82.5t91 32.5q55 0 89 -32q35 -33 35 -86q0 -48 -34 -80q-35 -33 -92 -33h-1q-55 0 -89 33t-34 83zM8 -176v668h222v-668h-222zM353 -176h222v373q0 35 8 54q14 34 42.5 57.5t71.5 23.5q112 0 112 -151v-357h222v383q0 148 -70 224.5t-185 76.5 q-129 0 -201 -111v-2h-1l1 2v95h-222q2 -32 2 -199t-2 -469z" />
<glyph unicode="M" horiz-adv-x="1348" d="M0 276q0 35 2 105q24 8 48 8h18q17 -23 40 -70t31 -61q2 7 8 36.5t10 42.5t11 36.5t15.5 40.5t19.5 31q28 -5 46 -5q6 0 11 1q24 -54 45.5 -163t38.5 -155q-1 0 -4 1l-3 1q-9 0 -26 -5.5t-22 -6.5q-40 101 -62 203q-15 -26 -15 -89t-11 -88l-5 2q-8 0 -22 -2t-21 -2h-18 q-27 48 -57 89q-3 -6 -3 -15t2.5 -26t2.5 -25l-1 -12q-30 -15 -52 -15q-7 0 -10 1q-17 56 -17 142zM355 200q0 27 8 57.5t28 57t47 26.5q10 0 28 -5t23 -6q9 -40 9 -81q0 -28 -6 -55q-12 4 -38 4.5t-37 3.5q-5 -20 -5 -37q0 -21 10 -37t30 -16q9 0 26 5t26 5q17 0 23 -14 q-42 -16 -82 -16q-46 0 -68 30t-22 78zM413 228l8 1q3 0 8 -2t7 -2l7 3q2 14 2 22q0 18 -5 40q-22 -25 -27 -62zM523 174q0 123 78 182q32 -3 60 -23q-1 -17 -8 -67q-5 -39 -5 -65v-14q-20 -2 -29 -2q-8 0 -43 5q-5 -12 -5 -23q0 -22 17 -37.5t39 -15.5q26 0 41 23 q18 -6 21 -17q-22 -21 -63 -21q-37 0 -70 20t-33 55zM579 217q4 -6 14 -6h9q9 19 9 49q0 13 -6 39q-3 -8 -10 -25t-11.5 -30.5t-4.5 -26.5zM678 236q-2 26 23 26q6 0 18 -1t17 -1q3 15 3 31q0 29 -7.5 86.5t-7.5 86.5q0 43 10 72q5 -3 26.5 -5.5t40.5 -24.5q-6 -26 -6 -67 q0 -20 4 -81q2 -35 2 -61q0 -20 -1 -34h6q7 0 9 6t2 12.5t4 6.5q8 0 18.5 -8.5t22.5 -21.5t15 -16q-9 -7 -40.5 -9t-38.5 -4q-1 -12 -1 -36q0 -16 0.5 -33t1.5 -38t1 -33q-8 -1 -23 -2t-22 -2v10v10q0 21 -3 57q-4 44 -4 61q-6 2 -32 3.5t-38 9.5zM893 244q0 20 2 58 q11 -1 20 -5t21 -10.5t18 -9.5l-1 -27q0 -59 9 -116q19 7 31 23t16.5 41.5t5.5 42t2 44.5v11q3 -1 9 -1q20 -2 49 -25q0 -3 0.5 -9.5t0.5 -9.5q0 -15 -4 -30t-7.5 -22t-14.5 -25t-14 -23q-15 -12 -34 -42q-21 -7 -38 -7q-71 0 -71 142zM1093 136q7 6 24 10q0 3 1 9 q4 35 7 56.5t12.5 59t22 59.5t35.5 39.5t53 17.5q34 0 76 -24q17 -37 17 -75q0 -66 -46.5 -119t-112.5 -68q-2 -32 -2 -48q0 -73 18 -117q-8 2 -37 2q-15 0 -22 2q-9 21 -16.5 96t-29.5 100zM1183 161q39 10 65.5 48t26.5 79q0 30 -15 56q-23 -21 -39.5 -55.5t-23 -60 t-14.5 -67.5z" />
<glyph unicode="N" horiz-adv-x="1213" d="M-9 598q10 8 25 12q14 4 25 4h9q10 0 24 -1q22 -1 32 -1q6 0 38 2q16 1 29 0.5t23 -0.5q20 -2 32 -8q6 -3 13 -13t11.5 -19t11.5 -25.5t10 -21.5q38 -82 94 -163q2 -3 7 -11t8.5 -12.5t9 -11.5t10.5 -11t10.5 -8.5t11.5 -5.5t12 0q28 5 31 117q1 19 1 35q0 74 -15 102 q-6 11 -15.5 17.5t-24.5 12t-23 10.5q14 28 49.5 37t96.5 9h25h28t26 -0.5t27 -3l22 -5.5t19.5 -9t12.5 -14q9 -18 11 -42q0 -7 1 -14q0 -20 -3 -52q-4 -42 -4 -52q-3 -23 -3 -46q0 -18 2 -38q4 -44 30 -61q9 1 16.5 4t15.5 11t11 11.5t12.5 16.5t10.5 14q47 62 94 163 l9 22.5t11.5 26.5t12 19.5t15.5 13.5q16 7 38 7h9q20 0 46 -2q32 -2 47 -2q9 0 27.5 1t32.5 1.5t29.5 -0.5t25.5 -6t14 -13q3 -6 3 -13q0 -29 -35 -87q-17 -29 -34.5 -52.5t-45.5 -58t-37 -46.5q-2 -2 -14 -18t-17.5 -24t-11.5 -22.5t-5 -26.5q0 -8 3 -15t9.5 -15t10 -12 t13.5 -13t12 -11q71 -65 112 -117q40 -52 40 -75q0 -33 -51 -41q-26 -4 -53 -4q-21 0 -43 3q-20 2 -37 2q-26 0 -45 -5h-6q-66 11 -139 94q-4 4 -17 20.5t-22 25.5t-23 17t-27 6q-23 -4 -30.5 -29t-9 -59.5t-9.5 -48.5q-13 -24 -79 -24q-28 0 -66 4q-78 8 -141.5 40 t-100.5 67.5t-81 92.5q-104 133 -197 322q-3 6 -11 22.5t-12 25.5t-9.5 23.5t-8 28t-2.5 26.5z" />
<glyph unicode="O" horiz-adv-x="852" d="M2 287q-1 19 -2 40q0 33 4 73q6 66 24 123q2 7 6.5 18.5t21.5 44t37.5 62t54.5 64.5t72 59q40 25 94 39q41 11 84 10q15 0 30 -1q107 0 191 -44t133.5 -116t74.5 -155t25 -169q0 -279 -160 -425q-55 -50 -121 -68t-157 -21h-11q-39 0 -83 12q-50 14 -105 44t-103 88 t-75 136q-3 9 -8 25t-14 64.5t-13 96.5zM224 189q4 -55 8 -79.5t7 -31.5q8 -66 30 -112.5t47.5 -66.5t49.5 -30.5t40 -10.5h16q54 1 91.5 22.5t59.5 66t33.5 100.5t17.5 139q2 81 2 143q0 47 -1 84q-3 86 -9 123l-5 37q-8 37 -15.5 62t-22.5 55t-33 48t-47.5 30.5 t-67.5 12.5q-10 1 -19 1q-30 0 -56 -14q-34 -20 -53.5 -51.5t-33 -63.5t-17.5 -55l-5 -24q-6 -46 -10 -110t-5 -105v-41q-3 -44 -3 -80q0 -26 1 -49z" />
<glyph unicode="P" horiz-adv-x="1049" d="M0 207q10 139 168 173q12 89 42.5 192t71.5 146q48 49 120 75.5t146 26.5q86 0 164 -39t117 -110q19 -36 41.5 -130.5t30.5 -154.5q15 -6 34 -6q30 0 30 29q0 11 -6 33.5t-5 35.5v4h1q27 0 61 -51q34 -52 34 -81q0 -20 -9.5 -35.5t-19 -24.5t-33 -17.5t-32.5 -10.5 l-36 -8q-5 -1 -8 -2v-26q0 -173 -77 -253l25 -25q4 -2 25 -11.5t35.5 -18.5t18.5 -18q-65 -51 -132 -51q-34 0 -75 17q-88 -37 -180 -37q-118 0 -234 61q-36 -8 -55 -19q-7 -4 -26.5 -18t-36.5 -23.5t-28 -9.5q-3 18 -3 37q0 79 53 126q-60 99 -62 257l-7 1h-3 q-30 1 -76 -17q-48 -18 -64 -19q-4 0 -10 2zM232 114q0 -13 7 -27q27 -96 89 -138q43 -29 106 -46.5t117 -17.5q66 0 145.5 28t119.5 72q68 73 68 257q0 226 -92 379q-12 20 -17.5 27.5t-19 15.5t-32.5 8q-50 0 -107 -61q-76 47 -140 47q-59 0 -104.5 -43t-71 -104.5 t-42 -141t-21.5 -141t-5 -114.5zM413 521q0 22 15.5 37.5t36.5 15.5q22 0 37.5 -15.5t15.5 -37.5t-15.5 -37t-37.5 -15q-21 0 -36.5 15t-15.5 37zM469 539q0 -12 12 -12q5 0 8.5 3.5t3.5 8.5t-3.5 9t-8.5 4q-12 0 -12 -13zM563 479l2 2l-1 -3zM568 484l52 52l51 -52 q-22 -7 -50 -7q-29 0 -53 7zM570 462q27 -5 50 -5q22 0 49 5l-49 -49zM675 478v3l1 -2zM702 521q0 22 15.5 37.5t37.5 15.5t37.5 -15.5t15.5 -37.5t-15.5 -37t-37.5 -15t-37.5 15t-15.5 37zM758 539q0 -5 4 -8.5t8 -3.5q5 0 9 3.5t4 8.5q0 13 -13 13q-5 0 -8.5 -4t-3.5 -9z " />
<glyph unicode="Q" horiz-adv-x="869" d="M3 -163v957q121 21 297 21q140 0 235.5 -24t165.5 -77q165 -125 165 -370q0 -260 -161 -395q-148 -126 -451 -126q-143 0 -251 14zM223 -1q19 -4 77 -4h4q153 0 240 85q89 86 89 256q0 154 -81.5 232t-228.5 78q-66 0 -100 -9v-638z" />
<glyph unicode="R" d="M0 -46q0 55 39 94t94 39t94 -39t39 -94q0 -56 -39 -94.5t-94 -38.5t-94 39t-39 94zM0 289v191q179 0 331 -88.5t240.5 -240.5t88.5 -331h-192q0 194 -137 331q-138 138 -331 138zM0 628v192q203 0 388 -79.5t319 -213.5t213.5 -319t79.5 -388h-192q0 164 -64 314 t-172.5 258t-258 172t-313.5 64z" />
<glyph unicode="S" horiz-adv-x="986" d="M0 547q0 113 80 193t193 80q78 0 145 -42q36 7 80 7q195 0 333 -138t138 -332q0 -49 -11 -101q28 -59 28 -121q0 -113 -80 -193t-193 -80q-68 0 -129 32q-45 -8 -86 -8q-194 0 -332 138t-138 333q0 47 9 94q-37 65 -37 138zM221 181q0 -41 30 -85q71 -104 246 -104 q50 0 96.5 11t87.5 34t66 63.5t25 94.5q0 58 -29.5 98t-73.5 58t-95.5 32.5t-95.5 23t-73.5 26t-29.5 44.5q0 33 36.5 49t74.5 16q40 0 66 -12.5t38 -30t21 -35t24.5 -30t39.5 -12.5q27 0 47.5 19t20.5 46t-15 54q-30 55 -95 80t-138 25q-46 0 -89 -9t-83 -29t-64.5 -56.5 t-24.5 -86.5q0 -66 40 -106.5t97 -57t114.5 -28.5t97.5 -33.5t40 -58.5q0 -29 -23 -49t-50.5 -27t-56.5 -7q-38 0 -64.5 10.5t-38.5 27t-22.5 35t-18 35t-22.5 27t-37 10.5q-28 0 -48.5 -17t-20.5 -45z" />
<glyph unicode="T" horiz-adv-x="1230" d="M0 -83q30 -3 60 -3q176 0 314 108q-82 1 -147 50t-89 125q20 -4 47 -4q35 0 67 9q-88 17 -145.5 86.5t-57.5 160.5v3q53 -30 115 -31q-52 34 -82.5 89.5t-30.5 120.5q0 68 35 127q94 -117 229.5 -186.5t290.5 -77.5q-7 33 -7 58q0 104 74 178t179 74q109 0 184 -80 q87 18 160 62q-28 -91 -110 -140q73 9 144 40q-48 -75 -125 -131v-33q0 -101 -29.5 -202.5t-90 -194t-144.5 -164.5t-201.5 -114.5t-252.5 -42.5q-209 0 -387 113z" />
<glyph unicode="U" horiz-adv-x="859" d="M-15 103q0 54 6 162q4 53 38 86.5t87 36.5q100 5 301 5t301 -5q53 -3 87 -36.5t38 -86.5q5 -90 5 -162t-5 -162q-4 -53 -38 -86.5t-87 -36.5q-100 -5 -301 -5t-301 5q-53 3 -87 36.5t-38 86.5q-6 108 -6 162zM52 244h61v-326h59v326h61v55h-181v-55zM117 847h60l38 -152 h4l36 152h60l-46 -148q-23 -73 -23 -75v-158h-59v151q-2 14 -5.5 25.5t-9 26.5t-8.5 25zM233 -38q0 -48 36 -48q32 0 61 35v-31h52v281h-52v-214q-21 -21 -31 -21q-14 0 -14 19v216h-52v-237zM312 537v146q0 34 22 52.5t56 18.5q33 0 53.5 -20t20.5 -53v-145 q0 -36 -20 -56.5t-56 -20.5q-35 0 -55.5 21.5t-20.5 56.5zM366 530q0 -23 22 -23q23 0 23 25v153q0 9 -7 15t-16 6t-15.5 -5.5t-6.5 -14.5v-156zM433 -82h53v21q20 -25 50 -25q47 0 47 62v156q0 71 -51 71q-25 0 -46 -27v123h-53v-381zM486 -29v176q11 11 22 11q22 0 22 -28 v-148q0 -24 -19 -24q-14 0 -25 13zM509 510v237h52v-215q0 -19 14 -19q13 0 31 21v213h52v-281h-52v31q-29 -35 -61 -35q-36 0 -36 48zM623 -3q0 -38 19 -62.5t57 -24.5q78 0 78 87v21h-54q0 -2 0.5 -13.5t-0.5 -16.5t-2.5 -13.5t-6.5 -12t-14 -3.5q-23 0 -23 40v53h100v72 q0 38 -18.5 60t-56.5 22q-36 0 -57.5 -23t-21.5 -59v-127zM677 96v30q0 31 23 31t23 -31v-30h-46z" />
<glyph unicode="V" horiz-adv-x="1146" d="M0 548q55 65 110 116t95.5 77.5t72.5 43t48 21.5l17 4q12 2 24 2q19 0 35 -6q26 -10 42.5 -34.5t29 -55t21.5 -72t15 -77.5t13.5 -79.5t14.5 -70.5q32 -125 51.5 -177.5t41.5 -52.5q24 0 66.5 55.5t93.5 151.5q26 48 26 91q0 13 -2 23q-9 52 -51 65q-11 4 -24 4 q-35 0 -83 -26q22 130 134 209q85 60 174 60q12 0 24 -1q102 -8 139 -90q18 -38 18 -88q0 -29 -6 -61q-18 -102 -69.5 -208t-113 -187.5t-132.5 -155t-123.5 -117t-90.5 -68.5q-42 -24 -78.5 -24t-69.5 21t-56 48t-38 57q-18 38 -97.5 298.5t-96.5 280.5q-1 2 -4 4 t-13.5 4.5t-24 0t-36.5 -14t-50 -32.5z" />
<glyph unicode="W" horiz-adv-x="1233" d="M0 -73l105 371q35 20 85.5 31t83.5 13l34 1q50 0 104 -10q101 -20 144 -61l-104 -370q-36 28 -79.5 45.5t-68.5 20.5l-26 4q-34 3 -65 3q-16 0 -42.5 -1.5t-83.5 -13.5t-87 -33zM126 404l105 371q35 20 86 31.5t84 12.5l33 1q51 0 104 -10q101 -20 144 -61l-104 -371 q-36 28 -79.5 45.5t-68.5 20.5l-26 4q-35 3 -64 3q-16 0 -42.5 -1.5t-84 -13t-87.5 -32.5zM557 -109l104 371q37 -28 80.5 -45.5t68.5 -20.5l25 -4q34 -3 65 -3q16 0 42.5 1.5t84 13t86.5 32.5l-104 -371q-35 -20 -86 -31t-84 -12l-33 -2q-51 0 -104 10q-101 20 -145 61z M677 366l104 370q37 -28 80.5 -45.5t68.5 -20.5l25 -4q34 -3 65 -3q16 0 42.5 1.5t83.5 13t87 32.5l-104 -370q-35 -20 -86 -31.5t-85 -12.5l-33 -2q-52 0 -103 11q-101 19 -145 61z" />
<glyph unicode="X" horiz-adv-x="899" d="M-50 120h219l173 286l-130 229h-219l130 -229zM312 210l346 608h232l-345 -608l222 -392h-232z" />
<glyph unicode="Y" horiz-adv-x="1379" d="M0 694l6 -19q4 -6 7.5 -10t5.5 -5l2 -2l19 -10h111l287 -344q11 -12 11 -25v-192q0 -8 -2.5 -12t-5.5 -5h-3q-112 0 -142 -3q-10 0 -10 -9v-55h516v57q0 3 -2.5 5t-4.5 2h-2h-144q-9 0 -9 15v202q-1 3 1.5 7t5.5 7l3 3q11 11 264 249h133q9 0 18 7l17 19q6 7 6 18v14 q-1 3 -3 4.5t-3 1.5h-2h-436l-7 -6q-1 -6 1.5 -12.5t5.5 -9.5l2 -4l23 -23l18 -7h115l-207 -195l-228 291h41q13 -1 22 4l68 21q1 0 3 1t4.5 5t2.5 9v14q0 3 -2 5t-4 2h-3h-489q-8 -1 -10 -7v-8zM1190 803l185 -7l-83 -567l-61 3zM1203 40l4 110l110 -4l-4 -110z" />
<glyph unicode="Z" horiz-adv-x="870" d="M0 19q0 22 43 51q7 15 16.5 35.5t16 33t6.5 15.5q0 1 2.5 13.5t7 32t9.5 42.5t12.5 52t15.5 54q13 41 31 75t29 47.5t17 18.5q10 8 3 11q-9 6 -22 21.5t-29 60.5q-11 32 -11 70q0 14 2 29q2 16 7 3q3 -8 6 -25q4 -33 26.5 -74.5t60.5 -56.5q1 0 19.5 7t82 19t156.5 19 q1 37 7 76q-7 5 -11 13.5t-5 14.5l-1 6q-8 -14 -20 -13q-8 1 -8 33q0 17 2 43q1 20 18.5 32t32.5 13q2 1 5.5 2.5t13 3.5t17.5 2q14 15 45 19q19 3 35 3q11 0 20 -1l23 -3q11 1 22 1l40 -4q31 -8 47 -17l15 -9h4q27 0 41 -27q10 -17 16 -41q2 -10 3 -20q0 -14 -5 -29h-4 q-5 5 -10 17q-4 -12 -9.5 -21.5t-8.5 -12.5l-4 -4v-6q0 -44 -27 -102q-3 -8 2 -21q7 -16 23 -86q16 -66 15 -95v-3q-1 -31 -14.5 -65.5t-27.5 -48.5q1 -5 0 -10q0 -32 -21 -72q-7 -11 -17.5 -44t-14.5 -53q-5 -26 -5 -42q0 -14 4 -20q1 -1 10 -12.5t14.5 -20.5t4.5 -15 q-1 -9 -16.5 -18.5t-25.5 -9.5q-12 0 -27 7t-20 19q-6 19 -6 38q0 14 3 28q5 19 11 49q6 29 12 87q2 20 2 38q0 31 -7 51q-5 -2 -15 -5.5t-41.5 -9t-65.5 -5.5q-6 -30 -13 -57t-11 -38l-5 -12q-5 -8 -5 -113q0 -41 14 -103q9 -6 13 -14t4 -13v-5q-2 -13 -15.5 -20.5 t-29.5 -7.5t-31 11t-15 28q0 3 2 49q1 28 0 48v23q-4 78 -7 91q-26 97 -27 143q-7 0 -13 5l-53 -56q1 -5 4 -15.5t5 -18.5t2 -11q0 -8 14 -14q12 -5 25.5 -15t12.5 -20q-1 -12 -23 -14h-6q-20 0 -40 9q-2 1 -6.5 11t-9.5 24.5t-9.5 28.5t-8.5 27t-5 15q-5 21 -1 29 q15 41 15 60v4q-1 14 -22.5 32t-39.5 18q-7 0 -16.5 -5t-16 -10.5t-19.5 -16t-16 -13.5q-15 -11 -38 -32t-24 -22q-5 -3 -37 -61t-41 -81q0 -1 -2.5 -9.5t-4.5 -15t-7.5 -16t-11.5 -16t-15.5 -10.5t-21.5 -4q-22 1 -22 19z" />
<glyph unicode="[" horiz-adv-x="999" d="M0 297q0 75 23 155.5t62 144.5q62 104 182.5 163.5t248.5 59.5q130 0 249.5 -81.5t182.5 -201.5q50 -86 50 -214q0 -150 -71 -266t-192 -177t-270 -60q20 36 61 109.5t73.5 130.5t64.5 108l1 2q3 5 12 18.5t12.5 19.5t9.5 17t9.5 21t5.5 21q6 24 6 48q0 80 -48 142 l275 81q-285 0 -428 -1q-7 1 -22 1q-99 0 -165.5 -74t-55.5 -173q-2 9 -2 28q0 44 15 77l-204 201l198 -341q19 -72 79.5 -117.5t134.5 -45.5q17 0 33 3l-66 -276q-115 0 -223 71t-175 176q-66 102 -66 230zM312 316q0 -77 54.5 -131.5t130.5 -54.5t130.5 54.5t54.5 131.5 q0 76 -54 130.5t-131 54.5t-131 -54.5t-54 -130.5z" />
<glyph unicode="\" horiz-adv-x="831" d="M0 -155q0 27 31 27q12 0 21 0.5t28.5 7t32 17.5t23 35t10.5 57v614q0 127 -92 135q-15 1 -21.5 6.5t-7 10t-0.5 15.5q-2 25 23 25q4 0 62 -1.5t137 -3t135 -1.5q115 0 196.5 5.5t121 10.5t52.5 5q31 0 31 -31q0 -3 -6 -25.5t-6 -41.5q0 -16 3.5 -47t3.5 -44 q0 -18 -12 -27.5t-24 -9.5q-20 0 -21 28q0 4 0.5 14t0 14.5t-3 14.5t-7.5 15t-15 13t-24 12.5t-36 10t-50.5 8.5t-67 5t-85.5 2q-80 0 -115.5 -7.5t-43 -20t-7.5 -42.5q0 -29 0.5 -134.5t0.5 -115.5q0 -19 6.5 -26.5t22.5 -7.5h233q38 0 65.5 21.5t30.5 66.5q1 16 5 24 t8.5 9.5t14.5 1.5q14 0 22.5 -11.5t6.5 -33.5q0 -7 -4.5 -46t-4.5 -65q0 -25 4.5 -67t4.5 -57q0 -26 -22.5 -29.5t-29.5 23.5q-4 17 -6.5 24.5t-11.5 24t-20.5 24.5t-33.5 15.5t-51 7.5h-207q-18 0 -26 -11t-8 -38v-265q0 -43 22 -69t85 -26q5 0 50 -0.5t63 0t60 3t65.5 7.5 t52.5 15.5t47 24.5q24 19 34.5 46.5t19.5 80.5q4 19 26 18q28 0 37 -32q3 -11 2 -24q-1 -12 -16.5 -63.5t-15.5 -74.5q0 -6 0.5 -21.5t0.5 -23t-2 -18t-8 -15t-15 -4.5q-2 0 -33.5 7t-103.5 7q-66 0 -322 -1.5t-285 -1.5q-19 0 -25 5.5t-6 18.5z" />
<glyph unicode="]" horiz-adv-x="1040" d="M2 69v576q0 1 3 19l339 -290l-338 -325q-4 14 -4 20zM47 704q7 3 17 3h913q9 0 18 -3l-340 -291l-45 -36l-89 -73l-89 73l-45 36zM48 10l341 327l132 -107l132 107l341 -327q-8 -3 -17 -3h-913q-8 0 -16 3zM698 374l338 290q3 -9 3 -19v-576q0 -9 -3 -20z" />
<glyph unicode="^" horiz-adv-x="1106" d="M0 207v151q0 10 7 17.5t18 7.5h265l-115 -201h-150q-11 0 -18 7t-7 18zM122 -37l66 -38zM132 6.5q-3 10.5 2 19.5l304 528q5 9 15 11.5t19 -2.5l65 -37q10 -5 12.5 -15.5t-2.5 -19.5l-303 -528q-5 -9 -15.5 -11.5t-19.5 2.5l-65 38q-9 4 -12 14.5zM440 182l115 201h67 l94 -201h-276zM518 807q1 9 6 12q10 5 35.5 -31t71.5 -116t62 -105q28 -44 75.5 -130.5t91 -169t43.5 -83.5q11 -19 -2 -36t-31 -24q-18 -8 -24 -9t-30 7q-30 15 -190 393q-5 11 -13.5 30.5t-17 38t-18.5 42t-18.5 44t-17 42t-13.5 39t-8 32.5t-2 24zM846 383h235 q10 0 17.5 -7.5t7.5 -17.5v-151q0 -10 -7.5 -17.5t-17.5 -7.5h-133q-4 16 -8 23l-24 46q-64 121 -70 132zM859 66.5q3 10.5 13 15.5l37 19q10 5 21 1.5t16 -13.5l31 -60q12 -24 -10 -39l-27 -16q-10 -5 -21 -2.5t-17 12.5l-40 62q-6 10 -3 20.5zM935.5 -78q0.5 16 4 21 t12.5 14l24 9q61 12 72 -70q3 -32 -1 -76q-4 12 -44 29.5t-55 38.5q-13 18 -12.5 34z" />
<glyph unicode="_" horiz-adv-x="1084" d="M-1 2v89v54v207h140v-207h805v207h141v-207v-54v-89h-1086z" />
<glyph unicode="`" d="M0 298q0 141 67 260.5t182 189t251 69.5t251 -69.5t182 -189t67 -260.5q0 -4 -0.5 -10t-0.5 -10q-8 208 -152.5 353t-346.5 145t-346.5 -145t-152.5 -353q0 4 -0.5 10t-0.5 10zM183 299q0 136 93 232.5t224 96.5t224 -96.5t93 -232.5q0 -3 -0.5 -10t-0.5 -10 q-8 129 -99 219t-217 90t-217 -90t-99 -219q0 3 -0.5 10t-0.5 10zM349 104q0 33 4.5 59t10.5 43t18.5 29t23 18t28.5 9.5t31 4t35 0.5t35 -0.5t31 -4t28.5 -9.5t23 -18t18.5 -29t10.5 -43t4.5 -59q0 -118 -44.5 -202.5t-106.5 -84.5t-106.5 84.5t-44.5 202.5zM396 384 q0 44 30.5 76t73.5 32t73.5 -32t30.5 -76t-30.5 -76t-73.5 -32t-73.5 32t-30.5 76z" />
<glyph unicode="a" horiz-adv-x="1099" d="M1 44q5 8 16 1q250 -145 544 -145q196 0 387 73q5 2 14.5 6t13.5 6q15 6 23.5 -6t-5.5 -22q-18 -13 -46 -30q-86 -51 -192 -79t-207 -28q-156 0 -295 54.5t-249 153.5q-6 5 -6 10q0 3 2 6zM302 329q0 69 34 118t93 74q54 23 133 33q27 3 88 8v17q0 64 -14 86 q-21 30 -66 30h-8q-33 -3 -57 -21t-31 -50q-4 -20 -20 -23l-115 14q-17 4 -17 18q0 3 1 7q17 89 83.5 132t155.5 48h25q114 0 178 -59q10 -10 18.5 -21.5t13.5 -20.5t9 -26t6 -23.5t3 -28t1 -25.5v-30v-28v-184q0 -26 7.5 -47.5t14.5 -31t23 -30.5q6 -9 6 -16q0 -8 -8 -14 q-83 -72 -90 -78q-12 -9 -29 -2q-14 12 -24.5 23t-15 16t-14.5 19.5t-14 19.5q-56 -61 -110 -76q-34 -10 -84 -10q-77 0 -126.5 47.5t-49.5 134.5zM474 349q0 -39 19.5 -62.5t52.5 -23.5q3 0 8.5 1t7.5 1q42 11 65 54q11 19 16.5 41.5t6 36.5t0.5 46v25q-58 0 -88 -8 q-88 -25 -88 -111zM894 27q2 4 6 8q25 17 48 23q38 10 74 11q10 1 19 -1q45 -4 54 -15q4 -6 4 -18v-7q0 -35 -19 -82.5t-53 -76.5q-5 -4 -9 -4q-2 0 -4 1q-6 3 -3 11q37 87 37 121q0 11 -4 16q-10 12 -56 12q-17 0 -40 -2q-25 -3 -46 -6q-6 0 -8 2t-1 4q0 1 1 3z" />
<glyph unicode="b" horiz-adv-x="1314" d="M-2 438q0 55 38.5 94t93.5 39q47 0 83.5 -29.5t46.5 -74.5l502 -202q32 19 68 19q2 0 6.5 -0.5t7.5 -0.5l110 159q1 73 53 124.5t125 51.5q74 0 126 -52t52 -126t-52 -126t-126 -52l-170 -124q-5 -51 -43 -85.5t-89 -34.5q-48 0 -84 30t-46 75l-502 201q-32 -19 -68 -19 q-55 0 -93.5 39t-38.5 94zM33 438q0 -40 28.5 -68.5t68.5 -28.5q9 0 21 2l-41 16v1q-28 13 -40 42q-6 14 -6 28q0 15 6 30q12 30 40 42q15 7 31 6q13 0 27 -5v1l49 -20q-29 52 -87 52q-40 0 -68.5 -28.5t-28.5 -69.5zM743 105q29 -52 87 -52q40 0 69 28.5t29 69.5 q0 40 -28.5 68.5t-69.5 28.5q-14 0 -21 -2l40 -16q30 -12 43 -42q7 -15 7 -30q0 -14 -6 -29q-12 -31 -42 -43q-15 -6 -30 -6q-14 0 -29 6q-8 3 -24.5 9.5t-24.5 9.5zM1013 440q0 -49 35 -84t84 -35q50 0 85 35t35 84t-35 84t-85 35q-49 0 -84 -35t-35 -84zM1038 441 q0 -40 27.5 -68t67.5 -28q39 0 67 28t28 68q0 39 -28 67t-67 28q-40 0 -67.5 -28t-27.5 -67z" />
<glyph unicode="c" horiz-adv-x="1107" d="M-2 251q0 104 73.5 178t176.5 74l1 -1q0 3 -0.5 7t-0.5 6q0 118 82.5 201t199.5 83q103 0 181 -66t96 -166h17q117 0 199.5 -83t82.5 -201t-82.5 -201t-199.5 -83q-8 0 -12 1v-1h-555h-9h-9h-5v1q-99 5 -167.5 78t-68.5 173z" />
<glyph unicode="d" horiz-adv-x="1013" d="M-12 286l214 163l-214 162l311 203l203 -174l208 174l302 -193l-198 -165l198 -170l-307 -185l-203 156l-203 -156zM201 35v57l94 -55l203 155l1 -1v-355zM206 451l294 -185l296 196l-294 169zM499 -164l1 355l2 1l202 -155l100 60v-63z" />
<glyph unicode="e" horiz-adv-x="1407" d="M0 181q0 31 5 53.5t21.5 46.5t46.5 38.5t83.5 24t128.5 9.5q88 0 148 -13q39 -8 58 -18v-161h-293q0 -21 2 -33.5t9 -30.5t26.5 -27t49.5 -9q85 0 85 61h63h2h56v-89q-27 -13 -56 -19q-68 -15 -150 -15q-92 0 -151 12.5t-87 39t-37.5 56t-9.5 74.5zM198 215h178 q0 18 -1.5 26.5t-8.5 23.5t-27.5 22t-53.5 7q-31 0 -50.5 -7.5t-26.5 -23t-8.5 -24t-1.5 -24.5zM491 33v89h78q-1 -51 -74 -87q-2 -2 -4 -2zM491 33q2 0 4 2q73 36 74 87h-78v39h81q1 12 1 23q0 45 -13 76q-16 39 -69 62v183h107v-203h2q31 44 88 44q43 0 69 -26 q-40 -29 -40 -102q0 -104 76 -122q-1 -31 -5.5 -54t-15.5 -47t-32.5 -36.5t-53.5 -12.5q-64 0 -91 50h-1v-42h-103v79zM491 161v161q53 -23 69 -62q13 -31 13 -76q0 -11 -1 -23h-81zM598 150q0 -77 8.5 -107.5t35.5 -30.5q28 0 37 30.5t9 107.5v5q0 35 -1 51.5t-5 37 t-13.5 28.5t-26.5 8q-16 0 -25.5 -8.5t-13 -29.5t-4.5 -38t-1 -54zM717 218q0 73 40 102q17 -18 26 -53t10 -55.5t0 -63.5v-52q-76 18 -76 122zM725 377q0 69 40 94q34 26 101 26q4 0 49 -3l107 -218v-102q0 -14 2 -39t2 -34h-100l-5 52h-2q-33 -58 -100 -58q-18 0 -26 1v52 q0 43 -0.5 63.5t-9.5 55.5t-26 53q38 29 135 29h24v31q0 29 -8.5 43t-35.5 14q-26 0 -33 -15.5t-7 -44.5h-107zM822 223q0 -62 41 -62q13 0 22.5 4.5t15.5 14t9.5 18t4.5 24t1.5 23.5t0 24t-0.5 20q-4 0 -17 -0.5t-16.5 -1l-14 -2t-14 -3t-10.5 -5t-9.5 -8t-6.5 -11 t-5 -15.5t-1 -20zM889 546h154l100 -232l109 232h143l-189 -359v-190h-141v190l-43 89v91q0 55 -21.5 86.5t-85.5 40.5zM915 494q64 -9 85.5 -40.5t21.5 -86.5v-91z" />
<glyph unicode="f" horiz-adv-x="817" d="M280 283v191h154v96q0 104 67.5 177t163.5 73h153v-191h-153q-15 0 -27 -16.5t-12 -40.5v-98h192v-191h-192v-463h-192v463h-154z" />
<glyph unicode="g" horiz-adv-x="939" d="M0 -27q0 -63 62 -108t150 -45t150.5 45t62.5 108q0 64 -62.5 109t-150.5 45q-1 0 -3 -0.5t-3 -0.5q-24 22 -24 47.5t24 53.5q71 4 120 55t49 121q0 28 -7 50q28 5 44 14v115q-48 -32 -109 -32h-7q-46 31 -101 31q-75 0 -128 -52t-53 -126q0 -47 24 -87t64 -64 q-28 -36 -28 -74q0 -36 26 -75q-46 -21 -73 -55t-27 -75zM121 405q0 33 21.5 56.5t50.5 23.5q30 0 51 -23.5t21 -56.5t-21 -56.5t-51 -23.5q-29 0 -50.5 23.5t-21.5 56.5zM124 -27q0 27 25.5 45.5t62.5 18.5t63 -18.5t26 -45.5q0 -26 -26 -45t-63 -19t-62.5 19t-25.5 45z M455 739q0 34 23.5 57.5t57.5 23.5t58 -23.5t24 -57.5t-24 -58t-58 -24t-57.5 24t-23.5 58zM474 92v479h134v-479h-134zM655 469h55v-284v-1q4 -30 19.5 -51.5t34.5 -31.5t37.5 -16t30.5 -7h13h7q27 0 48 8q23 8 30 16l7 9l2 99q-42 -13 -65 -13q-5 0 -9 1q-23 3 -27 16 l-4 13q0 3 -1 4v238h91v102h-91v93h-123v-93h-55v-102z" />
<glyph unicode="h" horiz-adv-x="866" d="M0 -196v496v496l501 -496zM0 -196l501 496l134 -133l-202 -117l-433 -250v4zM0 796v4l433 -250l202 -117l-134 -133zM501 300l134 133l231 -133l-231 -133z" />
<glyph unicode="i" d="M0 320q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251t-67 -251t-182 -182t-251 -67t-251 67t-182 182t-67 251zM100 320q0 -166 117 -283t283 -117t283 117t117 283t-117 283t-283 117t-283 -117t-117 -283zM283 144q0 -31 21.5 -52.5t52.5 -21.5q33 0 57 24 t24 57v8v261l200 37v-208q-15 5 -28 5q-33 0 -57 -24t-24 -57q0 -31 21 -52.5t52 -21.5t55.5 23t25.5 54v4v8v382l-290 -50v-300q-15 5 -28 5q-34 0 -58 -24t-24 -57z" />
<glyph unicode="j" horiz-adv-x="764" d="M0 -183v1000h764v-817l-571 3v-186h-193zM191 176h399v450h-399v-450z" />
<glyph unicode="k" d="M0 253v67v67t2.5 59t7 61.5t14 53t23.5 55.5t35.5 46.5t50.5 47.5q146 110 356 110h11h5v-777h124v208q7 -11 39 -63.5t51 -79.5q29 -40 63.5 -53t91.5 -13h36v118q-45 0 -63 7t-42 41q-14 18 -37 56.5t-26 43.5l171 238h-148l-136 -189v453q135 -22 238 -100 q29 -22 50.5 -47.5t35.5 -46.5t23.5 -55.5t14 -53t7 -61.5t2.5 -59v-67v-67t-2.5 -59t-7 -61.5t-14 -53t-23.5 -55.5t-35.5 -46.5t-50.5 -47.5q-146 -110 -367 -110t-367 110q-29 22 -50.5 47.5t-35.5 46.5t-23.5 55.5t-14 53t-7 61.5t-2.5 59zM81 104q66 -67 192 -67 q80 0 137.5 41t57.5 118q0 51 -18 84.5t-45 45.5t-58.5 19.5t-58.5 9t-45 11.5t-18 30q0 47 70 46q57 0 87 -29l78 78q-60 60 -170 60q-78 0 -131.5 -41.5t-53.5 -117.5q0 -51 20.5 -83.5t51.5 -44.5t62.5 -17t59.5 -9t37 -14q10 -11 10 -30q0 -46 -72 -46q-77 0 -113 36z " />
<glyph unicode="l" horiz-adv-x="1332" d="M-1 320q0 164 116 280t280 116q124 0 219.5 -63.5t146.5 -180.5q15 -36 129 -300q21 -48 37.5 -73.5t49 -45t79.5 -21.5h7q67 0 111 36q46 38 47 96q0 27 -8 45t-29.5 32t-40.5 21.5t-59 20.5q-125 41 -180 89.5t-55 135.5q0 91 57.5 145.5t156.5 54.5q127 0 191 -115 l-84 -43q-45 62 -112 62q-46 0 -76.5 -28.5t-30.5 -72.5q0 -13 2 -24.5t8.5 -20.5t12 -16t17.5 -14.5t20 -11.5t25 -10.5t26.5 -9.5t31.5 -10t33 -10q108 -36 154.5 -84t46.5 -140q0 -100 -76 -166q-75 -65 -186 -65h-3q-100 0 -161 46.5t-103 140.5l-14 33l-127 288 q-33 77 -104.5 124t-158.5 47q-119 0 -203.5 -84.5t-84.5 -203.5t84.5 -203.5t203.5 -84.5q82 0 150 42.5t105 112.5l51 -118q-55 -68 -135 -106.5t-171 -38.5q-164 0 -280 116t-116 280z" />
<glyph unicode="m" horiz-adv-x="1210" d="M7 -117v897h185l9 -8h825l9 8h174v-900h-171v7h-855v-4h-176zM183 15v-80h855v74l-345 259l-79 -65l-86 70zM183 75l307 229l-307 252v-481zM266 716l348 -298l347 298h-695zM731 299l307 -230v484z" />
<glyph unicode="n" d="M0 496l316 323v-123l301 -277l187 46l-195 -208l391 -438l-444 392l-188 -192l30 169l-255 316z" />
<glyph unicode="o" horiz-adv-x="1083" d="M0 173q-1 63 24.5 116.5t67 89t92 63t101 43t92.5 25.5t68 13l26 3v-123q-57 -4 -104.5 -19.5t-77.5 -36.5t-53 -45.5t-35 -48t-19 -42.5t-8 -31l-2 -12q-3 -15 -3 -30q0 -22 7 -42q12 -34 38 -58t59 -44.5t68 -33t64 -21.5t47 -13l19 -3v-103q-97 10 -175.5 35 t-126.5 56.5t-83 67.5t-51 70.5t-24.5 62t-9.5 44.5zM510 -180v902l142 98v-922zM686 411h5q38 -1 77 -15q42 -16 64 -31l21 -16l-83 -34l313 -78v245l-107 -61q-40 43 -112.5 69t-125.5 31l-52 5v-115z" />
<glyph unicode="p" d="M0 -47v734q0 55 39 94t94 39h734q55 0 94 -39t39 -94v-734q0 -55 -39 -94t-94 -39h-734q-55 0 -94 39t-39 94zM38 -19q0 -51 36 -87t87 -36h678q51 0 87 36t36 87v678q0 51 -36 87t-87 36h-678q-51 0 -87 -36t-36 -87v-678zM239 13v30h49q28 0 44 18.5t18 36.5l1 19v6v29 v377q0 35 -15 54.5t-30 21.5l-15 2h-50v32h349q46 0 80.5 -15t52 -36.5t28 -42.5t13.5 -36l2 -15v-62q0 -31 -9 -55.5t-23.5 -39.5t-32 -26.5t-35.5 -16.5t-32.5 -7.5t-23.5 -2.5l-9 -1h-143v-168q0 -31 17 -48.5t35 -19.5l17 -2h47v-32h-335zM457 338h109q4 0 10 0.5 t21.5 6t27.5 14.5t21.5 28.5t9.5 46.5l-1 61q0 4 -0.5 10t-6 22.5t-14.5 29.5t-29.5 25t-47.5 14h-100v-258z" />
<glyph unicode="q" horiz-adv-x="889" d="M0 366q0 122 59.5 226t161.5 164.5t223 60.5q184 0 314.5 -132t130.5 -319q0 -119 -57 -220.5t-154 -162.5q1 -2 3.5 -6.5t11.5 -16t21 -22t33 -21.5t45 -17v-76q-36 -7 -67 -7q-50 0 -85 18q-56 29 -91 94q-48 -13 -105 -13q-120 0 -222.5 60.5t-162 164t-59.5 225.5z M221 307q0 -116 66.5 -198.5t160.5 -82.5q26 0 52 8q-2 3 -5.5 8.5t-14.5 18.5t-23.5 23.5t-31 19.5t-36.5 10v79v9q10 1 20 1q119 0 203 -90q63 81 63 194v116q0 116 -66.5 198.5t-160.5 82.5t-160.5 -82.5t-66.5 -198.5v-116z" />
<glyph unicode="r" horiz-adv-x="1201" d="M0 320q0 139 72 254.5t191.5 180.5t257.5 65q86 0 162 -25v-302q-64 35 -132 35q-92 0 -162 -49q-45 -33 -80.5 -82.5t-35.5 -95.5q0 -90 57.5 -141t148.5 -51q78 0 151.5 41.5t108.5 108.5q21 37 21 50q1 67 1 143t-0.5 169t-0.5 144q20 -10 119 -77q135 -92 289 -92 q20 0 26.5 -7.5t6.5 -29.5q0 -51 -53 -100.5t-110 -69.5q4 -31 4 -69q0 -139 -72 -254.5t-191.5 -180.5t-257.5 -65t-257.5 65t-191.5 180.5t-72 254.5z" />
<glyph unicode="s" horiz-adv-x="1153" d="M0 141q0 16 3.5 44t9.5 31q6 -3 10.5 -32.5t4.5 -42.5q0 -14 -4.5 -42.5t-10.5 -31.5q-13 7 -13 74zM64 141q0 25 5 74t6 61q0 6 6 6q4 0 6 -6q12 -129 12 -135q0 -24 -5.5 -71t-6.5 -59q-2 -7 -6 -7q-6 0 -6 7q-1 11 -6 58.5t-5 71.5zM145 141q0 24 5 73.5t5 54.5 q0 9 7 9q8 0 8 -9q11 -113 11 -128t-11 -136q0 -8 -8 -8q-7 0 -7 8q0 7 -5 58.5t-5 77.5zM237 141q0 38 1.5 80.5t4 95t3.5 81.5q0 10 9 10q10 0 10 -10q1 -16 5.5 -111.5t4.5 -145.5q0 -26 -5 -77t-5 -58q0 -10 -10 -10q-9 0 -9 10q-9 132 -9 135zM331 141q0 55 3 159.5 t4 128.5q2 12 12 12t12 -12q1 -32 4.5 -133t3.5 -155q0 -25 -3.5 -72t-4.5 -61q-2 -12 -12 -12t-12 12q0 11 -3.5 59t-3.5 74zM426 141q0 40 1 85t2.5 100t2.5 85q2 15 14 15t14 -15q1 -30 2.5 -85t2.5 -100t1 -85q0 -2 -6 -131v1q-2 -15 -14 -15t-14 14q-6 129 -6 131z M521 140q0 3 6 351q2 18 16 18t16 -18q6 -348 6 -351q0 -1 -6 -127q-2 -17 -16 -17t-16 17q-6 126 -6 127zM601 352.5q0 82.5 1 155.5q-1 10 12.5 18t32.5 11.5t34.5 5.5t24.5 2q97 0 169 -72.5t80 -178.5q28 13 55 13q58 0 99.5 -45.5t42 -110.5t-41.5 -110.5t-100 -45.5 h-393q-6 0 -10.5 6t-4.5 13q0 55 -0.5 155.5t-0.5 183z" />
<glyph unicode="t" horiz-adv-x="616" d="M0 410v142q60 20 101 55q41 33 67 86q26 51 35 127h143v-253h237v-157h-237v-256q0 -86 9 -112q9 -24 34 -39q34 -20 76 -20q77 0 151 49v-157q-63 -31 -116 -43q-52 -12 -112 -12q-68 0 -122 17q-55 19 -89 50q-36 31 -52 68q-14 34 -14 105v350h-111z" />
<glyph unicode="u" horiz-adv-x="916" d="M2 455q4 36 15.5 63t25.5 40t28 21t23 9l9 2h8q43 0 77 -36q38 -40 41 -78q3 -16 3 -33v-6q0 -20 -5.5 -53t-28 -57.5t-59.5 -32.5q-13 -3 -26 -3q-23 0 -43 10q-30 15 -45 43t-21 58q-4 17 -4 32q0 11 2 21zM66 -32q-4 18 -4 36q0 28 10 55q16 44 38.5 68t48.5 45l26 21 q2 2 26.5 22.5t53.5 51.5t49 66q18 31 50 53q33 22 72 28q9 1 17 1q31 0 66 -18q44 -23 79 -77q8 -12 23.5 -31.5t66.5 -72t106 -95.5q26 -20 39.5 -49.5t13.5 -57t-4 -52t-9 -39.5l-6 -15q-2 -6 -7.5 -15t-27.5 -29t-50 -31.5t-79 -11.5t-112 20q-36 12 -79 13h-14 q-33 0 -55 -4l-25 -4q-10 -2 -27 -5q-18 -3 -66 -8q-24 -2 -44 -2.5t-36 2.5h-3q-46 0 -80 33q-35 34 -46 68zM208 72q-2 -14 -2 -27q0 -32 12 -61q22 -43 79 -55h127v307l-57 1v-83h-68q-30 0 -53 -20.5t-30 -41.5zM232 666q0 64 31.5 109t76.5 45t76.5 -45t31.5 -109 t-31.5 -109t-76.5 -45t-76.5 45t-31.5 109zM268 23q-2 8 -2 16q0 14 6 31q10 26 39 35h55v-125h-51q-16 0 -27.5 10.5t-15.5 21.5zM455 -15q0 -18 15 -31.5t30 -18.5l15 -5h146v217h-63v-163h-60q-9 1 -14.5 6t-7.5 9l-1 4v145l-60 -1v-162zM508 657q5 48 49 97q37 41 72 41 q6 0 13 -1q43 -10 74 -58q25 -39 25 -77q0 -9 -1 -18q-9 -55 -48 -101q-34 -39 -80 -40q-7 0 -14 1q-56 8 -76 51q-15 32 -16 75q0 14 2 30zM686 367q0 150 108 150q34 0 59.5 -14.5t38 -36t18.5 -40.5t6 -33v-14v-11v-9q0 -7 -1 -22.5t-4 -25.5t-7.5 -24t-13 -23.5 t-19 -18.5t-26.5 -13.5t-35 -4.5h-6q-38 0 -63 11q-27 12 -38 36.5t-14 44t-3 48.5z" />
<glyph unicode="v" horiz-adv-x="1011" d="M0 -21v678q0 66 43 114.5t108 48.5h697q70 0 116.5 -37.5t46.5 -106.5v-59q-74 14 -111 20q-53 7 -54 7q-10 3 -29.5 10t-34 10.5t-32.5 3.5q-62 0 -132 -47q-34 -3 -95.5 -7t-112 -9t-95.5 -14h-1h-1l-1 -1h-1h-1h-1h-1l-1 -1h-1q-72 -14 -87 -26q-18 -15 -20 -71v-39 v-126l-3 -18l526 -13l80 27q-44 -79 -70 -132l-106 -47l-406 -7q-3 -3 -10 -3.5t-11 -4.5q4 -26 7 -39q12 -52 112 -59q206 -13 335 -13q38 0 120 20t127 20q65 0 111 -29v-54q0 -155 -154 -155h-723q-61 0 -97.5 48t-36.5 111zM690 525q0 14 10 24.5t24 10.5t24.5 -10.5 t10.5 -24.5t-10.5 -24t-24.5 -10t-24 10t-10 24z" />
<glyph unicode="w" d="M0 319q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251t-67 -251t-182 -182t-251 -67t-251 67t-182 182t-67 251zM39 319q0 -135 71.5 -247t188.5 -168l-220 603q-40 -89 -40 -188zM114 572h30q48 0 123 6q12 1 17.5 -8t1.5 -19t-16 -11l-53 -5l168 -499l101 302 l-72 197q-24 3 -48 5q-12 1 -16 11t1.5 19t17.5 8l121 -6q49 0 123 6q12 1 17.5 -8t1.5 -19t-16 -11l-52 -5l166 -496l46 154q36 117 36 149q0 64 -39 128q-2 3 -12.5 21t-13.5 23.5t-9 19t-8 23.5t-2 21q0 33 22.5 57.5t55.5 24.5q1 0 3 -0.5t3 -0.5q-131 121 -312 121 q-119 0 -221 -56t-165 -152zM370 -124q62 -18 130 -18q80 0 153 26l-3 6l-142 389zM732 -80q105 61 167 167.5t62 231.5q0 120 -56 221q3 -21 3 -47q0 -63 -35 -165z" />
<glyph unicode="x" horiz-adv-x="1002" d="M0 320q0 -176 109 -312q-9 25 -9 56q0 32 10 68q20 72 61.5 139.5t86 127.5t78.5 96l33 36q-147 91 -234 130q-135 -145 -135 -341zM139 -25q23 68 68.5 139t94 124t94 96.5t74.5 65.5l29 23q13 -9 34 -26t77.5 -68t102.5 -102t90.5 -121t59.5 -131q-70 -73 -164 -114 t-198 -41q-105 0 -198.5 41t-163.5 114zM176 700q139 120 325 120q185 0 324 -120q-35 20 -81 20t-87 -14.5t-77 -31.5t-58 -32l-21 -14h-1q-8 6 -22.5 15.5t-55.5 30.5t-79 33.5t-85 12.5q-1 0 -2 1q-46 0 -80 -21zM632 531q148 91 235 130q135 -145 135 -341 q0 -176 -110 -312q9 26 9 56q1 30 -9 68q-20 72 -62 139.5t-86.5 127.5t-77.5 96z" />
<glyph unicode="y" horiz-adv-x="749" d="M4 231v-13q0 -43 6 -69q5 -18 19 -25.5t29 -2.5l204 63q22 7 31 26q5 10 5 20t-5 19q-9 19 -32 26l-204 82q-14 3 -27.5 -7.5t-16.5 -30.5q-8 -36 -9 -88zM91 708q-5 8 -5 16q0 9 6 18q12 17 38 27q81 31 171 46h5q45 0 49 -38q25 -313 25 -393q0 -33 -27 -40 q-6 -2 -12 -2q-21 0 -37 25q-148 232 -213 341zM160 -57l139 166q19 21 38 21q8 0 16 -3q25 -11 25 -45q0 -5 -1 -10v-221q-2 -14 -17 -22q-9 -5 -18 -5q-8 0 -16 3q-36 6 -85 25.5t-73 37.5q-18 14 -18 30q0 11 10 23zM454 280q-6 12 -6 23q0 17 15 33l130 179q7 8 20 8 q3 0 7 -1q17 -2 29 -18q25 -26 53 -70.5t37 -73.5q3 -8 3 -15q0 -9 -4 -16q-8 -13 -23 -16l-209 -53q-8 -2 -16 -2q-23 0 -36 22zM466 155q-9 -12 -9 -24q0 -16 13 -32l114 -190q7 -9 24 -9h3q19 1 33 15q27 24 55.5 62.5t41.5 69.5q4 11 4 21q0 7 -3 13q-5 14 -19 19 l-205 70q-10 4 -19 4q-21 0 -33 -19z" />
<glyph unicode="z" horiz-adv-x="722" d="M0 46v13v82q0 6 2.5 12t4.5 9l2 2q65 77 195 230.5t195 230.5q-57 -11 -103 -14q-23 -2 -41 -1q-17 0 -31 1q-26 3 -46.5 10t-28.5 13.5t-12 12.5q-1 0 -1 1q-1 2 -2 3q-4 9 -4 24q0 7 1 15q5 49 49 110q2 2 6 6.5t6 7.5q5 5 12 5q6 0 15 -4q18 -10 20 -10 q55 -22 148 -26q22 -1 44 -1q107 0 222 24q9 2 13.5 -1.5t4.5 -8.5v-5q-1 -14 -4 -42.5t-5 -42.5q0 -4 -5 -9l-13 -13l-8 -7q-8 -9 -161 -188q-126 -146 -190 -219q-20 -24 -60 -70q-11 -13 -13 -18.5t-2 -23.5h7q65 0 144 -49q45 -29 86 -51t59 -29l19 -7q45 -12 83 -12 q65 0 110 35q5 -22 5 -45q0 -27 -7 -56q-12 -53 -50 -90q-32 -31 -77 -31q-8 0 -17 1q-64 8 -166 67q-23 13 -72.5 51t-78.5 53q-48 24 -95 31t-117 7h-31q-8 0 -12 17z" />
<glyph unicode="{" horiz-adv-x="1233" d="M-63 548q174 33 208 71q27 30 45 91q18 -23 23 -48.5t1 -39.5l-5 -13q-6 -13 -10.5 -21t-7.5 -13.5t-9.5 -11t-10 -8.5t-16 -11t-20.5 -14q-35 -27 -33.5 -62.5t30.5 -54.5q26 -16 50.5 6t52.5 78q12 25 18.5 66t19.5 73t47 59q20 16 45.5 19t50 1t51.5 0t60 23.5 t67 64.5q5 6 14 15.5t38 29t59 28t74 -1t86 -44.5q-48 21 -90 21t-67.5 -15t-43.5 -33t-26 -33l-7 -15q-15 -37 -28.5 -61.5t-23.5 -38.5t-25 -22.5t-24 -11.5t-32 -8.5t-38 -9.5q-43 -13 -50 -54q-6 -36 22 -53q32 -18 82 14q37 24 59.5 49.5t30.5 44t27.5 39.5t51.5 37 q43 21 82 28.5t83 8t67 3.5q197 32 246 114q48 79 49 130q17 -58 11.5 -104t-26.5 -80.5t-44 -57t-41 -33.5l-18 -11q-77 -40 -128.5 -55.5t-83.5 -21t-62 -21.5q-103 -55 -52 -155q21 -41 61.5 -44.5t77.5 29.5q6 5 14 14t22.5 39t15.5 61q20 -56 15.5 -96.5t-20.5 -63.5 l-15 -22q-36 -38 -60.5 -53.5t-63 -18.5t-89.5 15q-86 21 -119.5 20.5t-61.5 -17.5q-28 -16 -43 -42.5t-2 -48.5q14 -25 34 -27.5t64 21.5q39 23 66 29.5t68 8.5q87 2 139 -38q37 -24 74 -57q-40 24 -79 30.5t-66 -1t-48.5 -18t-31.5 -21.5l-10 -10q-45 -51 -75.5 -72 t-53 -20.5t-58.5 14.5q-10 4 -39.5 17t-41.5 16v110q0 121 -92 186q-59 40 -134 40q-76 0 -134 -39q-20 29 -51 33v75q0 31 -21.5 52.5t-52.5 21.5h-18zM64 -16v162q0 65 19 99q40 71 134 71q69 0 110.5 -43.5t41.5 -109.5v-135h-202v-67q0 -48 50 -48q45 0 50 49h102 q0 -62 -41 -105q-43 -43 -111 -43q-94 0 -134 71q-19 34 -19 99zM167 105h100v56q0 56 -50 56t-50 -56v-56zM429 -94q11 36 11 71q0 11 -3 20q24 -4 34 -5q62 -6 85 -46q2 -3 4.5 -9t7 -23t-0.5 -31q-31 24 -65.5 30t-53.5 -1z" />
<glyph unicode="|" horiz-adv-x="851" d="M2 -56q3 31 12 66q11 45 72 350.5t71 349.5q12 52 24 72.5t39 29.5t87 9h241q59 0 135 -1t116 -1q41 0 50 -45q10 -48 -23 -92q-30 -40 -81 -40h-401l-50 -233l352 -3q44 0 54 -45t-21 -84q-27 -33 -70 -33h-360l-48 -248h432q64 0 76.5 -43.5t-17 -87.5t-67.5 -44h-553 q-30 0 -47.5 17t-21.5 46t-1 60z" />
<glyph unicode="}" horiz-adv-x="868" d="M0 108q0 44 31.5 76t76.5 32q44 0 76 -32t32 -76q0 -46 -34 -78q65 -74 163 -74q69 0 116 41q47 42 47 106q0 39 -25 77q-23 38 -60 64q-34 23 -115 57q-75 30 -122 59q-42 27 -73 64q-30 36 -46 74q-14 39 -14 79q0 101 81 172q82 71 197 71q77 0 155 -33 q66 -28 113 -80q37 -32 37 -80q0 -45 -32 -76.5t-76 -31.5q-45 0 -76.5 31.5t-31.5 76.5q0 21 10 44q-32 16 -88 16q-69 0 -112 -31t-43 -80q0 -43 38 -76q40 -33 128 -71q92 -40 141 -73q51 -34 82 -74q33 -41 48 -85q0 -1 1 -3t1 -3q-75 -62 -75 -158q0 -53 28 -104 q-11 -13 -24 -27q-87 -82 -206 -82t-208 64t-139 194l3 1q-5 15 -5 29zM613 33q0 -52 36 -88.5t88 -36.5t88 36.5t36 88.5q0 51 -36 87.5t-88 36.5t-88 -36.5t-36 -87.5z" />
<glyph unicode="~" horiz-adv-x="664" d="M0 805h100l8 -121h10l5 3q79 133 246 133q130 0 212.5 -98.5t82.5 -253.5q0 -93 -27 -166.5t-72.5 -117.5t-101 -67t-116.5 -23q-69 0 -125.5 28.5t-86.5 79.5l-2 3h-11l-3 -7v-378h-113v761q0 88 -6 224zM119 392q0 -31 6 -55q19 -70 74 -113t126 -43q101 0 162 76.5 t61 204.5q0 119 -61 194t-157 75q-72 0 -128 -45.5t-74 -117.5q-9 -33 -9 -53v-123z" />
<glyph horiz-adv-x="951" />
<glyph horiz-adv-x="973" />
<glyph horiz-adv-x="1314" />
<glyph unicode="&#xa3;" horiz-adv-x="669" d="M2 467q-11 151 126 252q63 47 145 70q78 23 175 11t181 -59q-2 -40 0 -76q6 -119 -10 -153q-9 1 -52 14q-36 11 -66 16q-31 6 -61 8q-70 6 -99 -38q8 -44 38 -66q30 -21 82 -37q49 -14 69 -26q113 -70 139 -219v-80v-5q0 -81 -44.5 -142.5t-118.5 -92.5 q-105 -44 -244.5 -38.5t-239.5 59.5q3 41 0 79q-3 42 -2 81q2 43 12 69q18 -3 48 -11q53 -15 74 -19q165 -36 177 40q3 22 -10.5 40.5t-34.5 29.5q-28 14 -48 22q-29 12 -37 17q-44 23 -59 32q-57 34 -80 68q-54 77 -60 154z" />
<glyph unicode="&#xad;" horiz-adv-x="939" d="M-0.5 707q-0.5 11 6 20.5t13.5 16.5t23.5 15.5t27 13t33 14t34.5 14.5q54 22 97 16t54 -35q25 -67 102.5 -319.5t115.5 -361.5q268 88 326 105q16 6 37.5 4t32.5 -23q23 -47 32.5 -98.5t0.5 -74.5q-19 -15 -59.5 -32t-75.5 -29t-89.5 -29t-73.5 -23q-10 -3 -38 -13 t-53 -18.5t-58 -19t-61 -17.5t-54 -11.5t-44.5 -3.5t-25.5 9q-18 18 -32 52t-29 87t-19 66q-42 125 -113 338.5t-104 312.5q-6 13 -6.5 24z" />
<glyph unicode="&#xc7;" horiz-adv-x="1294" d="M13 314v51q0 38 87 65t211 27t211 -27t87 -65v-51q-1 -38 -88 -64.5t-210 -26.5t-210 26.5t-88 64.5zM300 557v27q2 19 64 32.5t149 13.5t148.5 -13.5t63.5 -32.5h1v-27h-1q-2 -20 -63.5 -33.5t-148.5 -13.5t-149 13.5t-64 33.5zM511 63v59v5q4 56 117 94.5t271 38.5 t270.5 -38.5t116.5 -94.5v-4v-56v-4q-3 -55 -116 -94t-271 -39t-271 38.5t-117 94.5zM739 404v1v38v3q2 29 75.5 49t175.5 20t175.5 -20t75.5 -49v-2v-39v-1q0 -29 -73.5 -50t-177.5 -21t-177.5 21t-73.5 50z" />
<glyph unicode="&#xc9;" horiz-adv-x="1129" d="M0 644q0 20 13 33t33 13h235q16 0 28.5 -9.5t16.5 -25.5l24 -98h674l7 21q10 32 43 32q9 0 13 -2q15 -4 24 -16t9 -27q0 -5 -2 -13l-118 -393q-4 -15 -16 -24t-27 -9h-559q-16 0 -28.5 10t-16.5 25l-108 438h-199q-19 0 -32.5 13t-13.5 32zM372 466l62 -248h489l2 9 l72 239h-625zM414 -18q0 38 27.5 65t65.5 27t65 -27t27 -65t-27 -65t-65 -27t-65.5 27t-27.5 65zM479 388h166v-92h-146zM724 296l1 92h162l-24 -92h-139zM761 -18q0 38 27.5 65t65.5 27t65 -27t27 -65t-27 -65t-65 -27t-65.5 27t-27.5 65z" />
<glyph unicode="&#xd1;" horiz-adv-x="937" d="M5 -90v333l116 129h85v-64h-56l-80 -89v-245h795v245l-80 89h-56v64h85l115 -129v-333h-924zM206 229v79v64v187l151 151h372v-338v-64v-79h-523zM266 290h403v360h-252v-151h-151v-209z" />
<glyph unicode="&#xd6;" horiz-adv-x="696" d="M-10 86q0 63 28 98q23 31 74 45q-16 40 -16 59q0 33 35 70q37 35 69 35q17 0 40 -9q-48 137 -69 208q-24 81 -24 115q0 48 24 75q25 28 67 28q72 0 173 -295l17 -49q6 15 12 33q100 292 180 292q40 0 63 -27q24 -27 24 -70q0 -28 -24 -113q-21 -73 -66 -200 q57 -14 82 -54q27 -43 27 -133q0 -178 -106 -291q-108 -113 -274 -113q-66 0 -127 24q-59 21 -107 66q-51 48 -76 99q-26 54 -26 107zM55 91q0 -25 14 -59q13 -32 39 -67q41 -53 97 -81q57 -28 129 -28q129 0 217 97q87 96 87 243q0 46 -6 71q-5 22 -19 34q-27 23 -106 40 q-79 18 -168 18q-22 0 -28 -6q-7 -3 -7 -20q0 -41 46 -58q50 -21 165 -21h28q16 0 23 -11q8 -8 11 -31q-17 -17 -55 -31q-36 -13 -53 -26q-40 -29 -64 -69q-23 -39 -23 -74q0 -21 10 -51q11 -33 11 -43v-6l-4 -15q-44 3 -64 41q-17 32 -19 82q-3 -1 -12 -1h-11q1 -5 1 -12 q0 -30 -23 -51t-54 -21q-47 0 -95 45q-48 46 -48 90q0 8 3 16q1 7 16 22q25 -31 34 -43q42 -59 76 -59q9 0 17 6q6 6 6 10q0 8 -12 29q-8 15 -37 53q-28 36 -45 50q-15 14 -22 14q-19 0 -37 -22t-18 -55zM145 282q0 -13 16 -45q14 -27 45 -68q31 -40 56 -62q24 -20 36 -20 q7 0 14 7q7 8 7 16q0 12 -18 58q-21 51 -46 92q-22 35 -39 49q-16 15 -31 15q-11 0 -25 -15q-15 -15 -15 -27zM190 714q0 -34 24 -107q22 -71 66 -190q10 6 28 6q1 0 6.5 -0.5t10.5 -0.5q4 0 26 -2l-69 200q-28 80 -44 104q-13 21 -26 21q-9 0 -15 -8q-7 -9 -7 -23zM356 204 q9 -23 19 -50q20 23 40 38q-5 1 -15 2.5t-15 2.5q-20 4 -29 7zM461 408l67 -12q45 124 69 199q25 81 25 96q0 16 -7 25q-4 7 -15 7q-14 0 -31 -27q-19 -29 -43 -101z" />
<glyph unicode="&#xdc;" d="M0 -100v800q0 41 29.5 70.5t70.5 29.5h800q41 0 70.5 -29.5t29.5 -70.5v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-800q-41 0 -70.5 29.5t-29.5 70.5zM200 300q0 -124 88 -212t212 -88t212 88t88 212t-88 212t-212 88t-212 -88t-88 -212zM300 300q0 82 59 141t141 59t141 -59 t59 -141t-59 -141t-141 -59t-141 59t-59 141z" />
<glyph unicode="&#xe0;" horiz-adv-x="617" d="M0 -43q0 76 57 112q29 19 54 29q114 49 122 54q-21 31 -54 68q-51 60 -60 71q-109 132 -94 247q7 55 42 91q13 14 42 32q37 21 45 25q5 2 22.5 9.5t29.5 12.5l47 21l69 30q58 25 86 40q20 11 25 -6q0 -11 -27 -25q-61 -40 -64 -114q-1 -29 5 -57.5t12.5 -47t25.5 -46 t27 -37.5t34.5 -40t31.5 -36q6 -7 29 -32.5t33 -37.5t28 -38t26 -46t15.5 -48.5t7.5 -58.5q0 -38 -13 -68q-12 -32 -28.5 -51.5t-47.5 -39.5q-35 -21 -53 -30q-23 -12 -61 -27q-16 -6 -35.5 -15t-22.5 -10l-89 -39l-36 -18q-32 -16 -50 -21q-85 -21 -133 24t-48 123z" />
<glyph unicode="&#xe1;" horiz-adv-x="1126" d="M0.5 367.5q9.5 158.5 74.5 265.5q49 80 95.5 113.5t138.5 49.5q30 5 57 5.5t50.5 -4t44 -11.5t39 -20t33.5 -25.5t30 -31.5t26.5 -34.5t24 -38.5t21 -39.5t20.5 -40.5q7 -14 14 -30t15 -35.5t13 -30.5q8 48 56.5 188t67.5 145q91 21 145 0q4 -2 9 -8t7 -8 q-1 -18 -6 -38.5t-8.5 -32.5t-13 -36.5t-11.5 -30.5l-160 -439q-7 -34 18.5 -90t67.5 -93t74 -22q10 5 18 21t14 21q18 15 71 15.5t67 -18.5q16 -29 11 -62.5t-31 -66t-59.5 -57t-74 -36.5t-73.5 -5q-29 6 -54 18.5t-41 25.5t-34 36.5t-27.5 38.5t-27 45t-25.5 44 q-4 -2 -6 -4q-24 -58 -81 -106.5t-127 -75t-150 -19.5t-145 54q-85 62 -131 203.5t-36.5 300zM153 380q-13 -108 9 -211t73 -141q28 -21 56 -30.5t51.5 -11.5t49 9.5t43 21t41 35t35.5 39.5t33 46t27.5 43t24.5 42q5 9 8 14q-38 161 -64 223q-73 173 -202 155 q-56 -8 -81 -22t-50 -49q-41 -55 -54 -163z" />
<glyph unicode="&#xe2;" horiz-adv-x="1078" d="M0 386.5q0 121.5 93 209.5q58 55 133.5 75t153 -1.5t137.5 -84.5q44 -46 62.5 -107t15 -115.5t-23.5 -102.5q-19 -41 -3 -93t40 -88.5t50.5 -68.5t26.5 -33l-11 9q-10 10 -21.5 20.5t-31 25.5t-38 27t-42.5 25t-45 18.5t-44.5 7.5t-42.5 -7q-47 -19 -103.5 -20t-117 22 t-102.5 69q-86 91 -86 212.5zM132 406q-9 -69 33.5 -124.5t111.5 -64.5t124 33.5t64 111.5t-33 124t-111 64t-124.5 -33t-64.5 -111zM610 700q21 59 74 87.5t113 8.5q58 -18 86.5 -72t8.5 -116q-24 -72 -114 -104q-31 -11 -55.5 -33.5t-34.5 -38t-23 -40.5q22 94 -24 159 q-55 80 -31 149zM648 205q2 92 63 155t152 63q89 0 152 -61.5t63 -156.5q0 -110 -110 -195q-38 -29 -62 -71t-30.5 -68t-12.5 -67q-4 40 -10 67t-30 69.5t-65 73.5q-111 83 -110 191zM686 677q-11 -27 0.5 -54.5t38.5 -38.5t54 0t38 38q11 28 0 55t-38 38t-54.5 0t-38.5 -38 zM752.5 162.5q18.5 -45.5 65.5 -65.5q46 -19 92 0.5t65 65.5t0 91.5t-65 65.5q-46 19 -92 0t-65 -65q-19 -47 -0.5 -92.5z" />
<glyph unicode="&#xe3;" horiz-adv-x="999" d="M0 -154q0 51 61 106.5t123 88.5l15 -22q-44 -32 -90.5 -82.5t-58.5 -89.5q87 27 265 379q65 131 103 261q-33 107 -33 202q0 115 47 115q23 0 34 -2t20.5 -13t9.5 -34q0 -15 -3 -28l-27 1q-2 26 -17 41q-12 -20 -12 -69q0 -38 9 -94q3 18 8.5 53.5t9.5 53.5l26 -3 q-2 -152 -14 -218q36 -107 86.5 -174t142.5 -119q68 7 116 7q178 0 178 -70q0 -11 -5 -24l-3 1q-5 -42 -67 -42q-104 0 -240 72q-220 -22 -389 -82q-147 -257 -235 -257q-7 0 -14 2t-12.5 4.5t-13.5 7t-12 6.5q-8 8 -8 22zM318 101q134 54 298 85q-103 73 -164 209 q-36 -121 -134 -294zM804 151q90 -35 142 -35q15 0 22 3q0 32 -145 32h-19z" />
<glyph unicode="&#xe4;" horiz-adv-x="875" d="M0 236q0 70 21 133t48.5 103t64.5 74.5t57 48t38 23.5q10 5 29.5 15t30.5 16t28.5 17t34.5 25q42 34 50 113q73 -88 106 -110q25 -17 73.5 -39t73.5 -37q19 -11 36 -23.5t54 -48.5t62.5 -76t46.5 -105t21 -137q0 -186 -127.5 -305t-306.5 -119q-116 0 -216.5 55.5 t-162.5 155.5t-62 221zM190 85q-2 -63 42 -93q31 -21 94 -21q41 0 97.5 29.5t105 58.5t70.5 28q23 -1 77.5 -56t70.5 -56q20 -1 33.5 8.5t31.5 35.5q33 49 33 117q0 29 -15 54.5t-47 25.5q-22 0 -92 -47t-94 -48q-22 0 -61 27.5t-88.5 55.5t-98.5 28q-65 -1 -111.5 -45 t-47.5 -102zM395 -95q-12 -10 0 -20q46 -42 165 -31q23 2 47.5 11.5t37 17.5t16.5 12t4 16q-3 12 -14 3q-41 -32 -124 -32q-75 0 -110 28q-3 2 -8 2t-14 -7zM485 -43q7 -8 28 11q2 1 8 6t8 6.5t8 5t10 4.5t11.5 2t15.5 1q16 0 26 -4.5t12.5 -8t7.5 -12.5q5 -10 7.5 -11.5 t7.5 0.5q12 7 7 20q-9 26 -22 34q-12 9 -43 9q-26 0 -41 -6q-17 -7 -44 -32q-15 -12 -7 -25z" />
<glyph unicode="&#xe5;" horiz-adv-x="979" d="M0 42q11 15 31.5 25.5t49 20t40.5 15.5q19 0 33.5 -4.5t33.5 -15t25 -12.5q47 -21 260 -119q19 -4 35.5 0t39.5 17.5t24 14.5q20 9 76.5 34.5t87.5 39.5q4 2 41.5 21t60.5 24q13 2 27.5 -1t23.5 -7.5t23 -13t18 -10.5t15.5 -6t18.5 -8t11 -11q3 -4 4 -14q-10 -13 -31 -24 t-51 -22t-40 -16q-43 -20 -128.5 -61.5t-128.5 -61.5q-7 -3 -21 -11.5t-23.5 -13t-25.5 -11t-27.5 -7t-29.5 1.5l-264 123q-6 3 -32 14t-51.5 22t-53.5 24t-46.5 23.5t-21.5 16.5q-4 4 -4 13zM0 310q11 15 31.5 25t50 20t41.5 15q19 0 34 -4.5t34.5 -15t25.5 -13.5 q42 -19 126.5 -58t127.5 -59q19 -5 37 -0.5t39 17t25 14.5q68 32 160 72q11 5 31.5 16.5t38.5 19.5t36 11q16 3 31.5 -1t37.5 -17t23 -13q5 -3 15.5 -6.5t18 -8t11.5 -10.5q3 -5 4 -14q-10 -14 -31.5 -25.5t-52.5 -22.5t-41 -16q-48 -23 -135.5 -65t-122.5 -59 q-7 -3 -26 -14t-29 -15t-32.5 -10t-35.5 0q-214 101 -260 122q-6 3 -44 19t-69.5 30t-61.5 29.5t-34 22.5q-4 4 -4 14zM0 577q10 15 31.5 26.5t52.5 22.5t41 16l348 162q30 0 53.5 -7t56.5 -26t40 -22q39 -18 117 -54.5t117 -54.5q4 -2 36.5 -15t54.5 -24t27 -20q3 -4 4 -13 q-9 -13 -26 -22.5t-43.5 -19t-34.5 -13.5q-47 -22 -140 -66.5t-139 -66.5q-6 -3 -20 -11t-23 -12.5t-25 -10.5t-27 -6t-28 1q-245 114 -256 119q-4 2 -63 27.5t-102 46.5t-48 30q-4 4 -4 13z" />
<glyph unicode="&#xe7;" horiz-adv-x="1137" d="M2.5 474q-7.5 215 11.5 270q4 9 9.5 15.5t14 12.5t13.5 9.5t17.5 10t16.5 8.5q136 0 386 2t329 2h40h54t55 -0.5t56.5 -2.5t45 -6t32.5 -10q16 -9 27 -24t16.5 -29.5t7.5 -40t2 -42t-0.5 -50t-0.5 -49.5q0 -207 -23 -327t-96 -213q-70 -88 -164.5 -139.5t-193 -62.5 t-200 11t-186.5 73.5t-151 133t-96 181.5q-15 52 -22.5 267zM234 476q-26 -28 15 -89.5t104 -123.5q2 -2 39.5 -40t53.5 -52t47 -35.5t57 -28.5q11 -3 22.5 -3t19.5 1t19.5 6.5t16 7.5t15.5 11.5t12 10.5t12 11l3 3q9 9 60.5 56t86 80.5t67.5 79t35 75.5q-15 40 -38 56 t-50.5 8.5t-56 -26t-59 -48t-56 -56t-49.5 -51t-37 -32.5q-27 16 -72.5 59.5t-82 82t-73.5 64t-55 14.5q-25 -15 -56 -41z" />
<glyph unicode="&#xe8;" d="M0 326q0 102 40 194q79 186 265 265q92 40 194 40t194 -40q184 -78 265 -265q40 -95 40 -194t-40 -194q-81 -188 -265 -267q-92 -40 -194 -40t-194 40q-186 80 -265 267q-40 92 -40 194zM78 326q0 -141 84 -252q83 -109 217 -155v80q0 60 40 87q-20 1 -47 7q-51 9 -87 32 q-91 55 -91 199q0 75 50 128q-23 59 5 128h20q10 0 25 -5q39 -12 87 -44q61 16 120 16t121 -16q39 26 73 40q32 12 46 10l12 -1q27 -69 5 -128q50 -53 50 -128q0 -112 -55 -169q-30 -32 -79 -50q-41 -15 -91 -19q41 -29 41 -87v-80q129 46 213 157q82 110 82 250 q0 85 -33 164q-32 76 -90 134q-56 56 -134 89q-80 34 -163 34q-82 0 -164 -34q-75 -32 -134 -89q-56 -58 -90 -134q-33 -79 -33 -164z" />
<glyph unicode="&#xe9;" horiz-adv-x="866" d="M0 660q0 60 127 102t306 42q180 0 306.5 -42t126.5 -102q0 -12 -72 -440q-9 -46 -111 -89t-250 -43t-250 43t-110 89q-73 414 -73 440zM107 79v4q0 17 15 17q6 0 12 -5q47 -37 122 -58t126 -23l51 -3q8 0 21.5 0.5t52.5 5t74.5 12.5t78.5 25t73 41l11 5q16 0 16 -17 q0 -2 -1 -4q-22 -121 -30 -161q-11 -49 -96 -81.5t-200 -32.5t-200 32.5t-95 81.5q-19 95 -31 161zM156 675q0 -24 81.5 -41.5t195.5 -17.5q115 0 196.5 17t81.5 41q0 25 -81.5 42.5t-196.5 17.5t-196 -17t-81 -42zM295 322q0 -57 40.5 -97.5t97.5 -40.5t97.5 40.5 t40.5 97.5t-40.5 97.5t-97.5 40.5t-97.5 -40.5t-40.5 -97.5zM364 322q0 -28 20 -48.5t49 -20.5t49 20.5t20 48.5t-20 48.5t-49 20.5t-49 -20.5t-20 -48.5z" />
<glyph unicode="&#xea;" horiz-adv-x="1272" d="M0 95h24q-7 14 -7 34q0 65 45.5 185.5t87.5 183.5q32 49 84 49q45 0 45 -34q0 -52 -72 -199h82q20 62 53 126q34 68 73 91t116 23q29 0 56.5 -14t27.5 -40t-13 -42t-37.5 -22.5t-43.5 -8.5t-46 -2h-9q-15 -22 -28 -58q18 3 37 3q64 0 64 -38q0 -9 -3 -18h19h-19 q-16 -59 -88 -59q-23 0 -50 5q-16 -48 -21 -73q52 10 77 10t43 -11.5t18 -35.5q0 -34 -23.5 -57t-53.5 -31t-64 -8q-65 0 -96 41h-19h19q-20 24 -20 62q0 23 3 45q8 50 28 112h-82q-9 -19 -26 -55.5t-25 -54.5h-1l-7 -14q22 2 34 2q59 0 59 -40q0 -51 -39 -73.5t-93 -22.5 q-65 0 -85 39h-24zM538 173q0 38 15.5 95t33.5 99q19 45 36 74t43 56.5t60.5 41t80.5 13.5q50 0 87 -19.5t37 -64.5q0 -38 -21 -68.5t-57 -30.5q-52 0 -52 33q0 6 3.5 17.5t3.5 18.5q0 13 -22 13q-17 0 -32.5 -14t-29 -43.5t-18 -40.5t-14.5 -39h16h-16q-32 -84 -32 -119 q0 -29 28 -29q25 0 44 24.5t26 52.5q-42 2 -42 35q0 37 28 54t66 17q52 0 65 -35h37h-37q4 -11 4 -26q0 -50 -28.5 -106t-68.5 -87h40h-40q-53 -41 -120 -41q-68 0 -100 41h-17h17q-24 29 -24 78zM867 95h42q-18 26 -18 66q0 79 49 204q19 47 32.5 74t37 55.5t57 41.5 t78.5 13q120 0 120 -115q0 -50 -22 -120h36h-36q-15 -51 -41 -110h38h-38q-37 -77 -73 -109h36h-36q-46 -41 -119 -41q-72 0 -101 41h-42zM1011 204h3q-6 -35 22 -35q23 0 43 38h-2q17 36 45 115.5t28 102.5q0 24 -21 24q-20 0 -33 -16q-18 -26 -52 -119h37h-37 q-25 -67 -33 -110z" />
<glyph unicode="&#xeb;" d="M0 304q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251t-67 -251t-182 -182t-251 -67t-251 67t-182 182t-67 251zM208 -15q0 -26 26 -26h176q28 0 28 26v48q0 26 -28 26h-29v460h29q28 0 28 26v48q0 26 -28 26h-176q-26 0 -26 -26v-48q0 -26 26 -26h31v-460h-31 q-26 0 -26 -26v-48zM485 -19q0 -24 24 -24h59q22 0 22 24v257q0 103 79 103q42 0 42 -51v-309q0 -24 22 -24h61q21 0 21 24v333q0 122 -110 122q-67 0 -122 -64l-7 36q-4 22 -24 22h-43q-24 0 -24 -25v-424z" />
<glyph unicode="&#xec;" horiz-adv-x="784" d="M0 -196v417l76 -1l-3 -335h501v334h79v-415h-653zM123 23h392v-83h-392v83zM124 88l8 85l393 -38l-8 -85zM145 261l23 82l380 -107l-24 -82zM216 462l44 73l338 -204l-45 -73zM383 667l69 50l230 -321l-70 -50zM635 790l84 14l65 -389l-84 -14z" />
<glyph unicode="&#xed;" horiz-adv-x="917" d="M0 804h161l197 -301q49 -75 102 -170q48 85 109 177l194 294h154l-399 -576v-424h-133v424z" />
<glyph unicode="&#xee;" horiz-adv-x="1200" d="M0 289v34q0 113 84 197t215 84q136 0 247 -112q21 -20 54 -62l96 -126q39 -52 52 -65q74 -74 147 -74q59 0 96 40q33 33 38 85q1 5 1 14q0 22 -6 41q-9 31 -33 57q0 1 -1 1q-38 40 -95 40q-78 0 -147 -74l-85 111h1h-1q-6 8 -10 13q55 60 113 85.5t134 25.5 q124 0 214 -84h1l1 -1q83 -83 83 -215q0 -30 -5 -63q-16 -89 -79 -153q-61 -62 -150 -79q-33 -5 -62 -5q-140 0 -248 109q-23 23 -56 67l-96 124q-39 52 -52 65q-74 74 -149 74q-22 0 -40 -6q-29 -8 -55 -34q-29 -32 -36 -71q-3 -14 -3 -28q0 -57 37 -97l2 -2q39 -40 97 -40 q79 0 147 75l84 -110l9 -12q-57 -61 -115 -87t-130 -26q-131 0 -216 83v1q-63 63 -78 153q-5 25 -5 47z" />
<glyph unicode="&#x2000;" horiz-adv-x="482" />
<glyph unicode="&#x2001;" horiz-adv-x="964" />
<glyph unicode="&#x2002;" horiz-adv-x="482" />
<glyph unicode="&#x2003;" horiz-adv-x="964" />
<glyph unicode="&#x2004;" horiz-adv-x="321" />
<glyph unicode="&#x2005;" horiz-adv-x="241" />
<glyph unicode="&#x2006;" horiz-adv-x="160" />
<glyph unicode="&#x2007;" horiz-adv-x="160" />
<glyph unicode="&#x2008;" horiz-adv-x="120" />
<glyph unicode="&#x2009;" horiz-adv-x="192" />
<glyph unicode="&#x200a;" horiz-adv-x="53" />
<glyph unicode="&#x2010;" horiz-adv-x="939" d="M-0.5 707q-0.5 11 6 20.5t13.5 16.5t23.5 15.5t27 13t33 14t34.5 14.5q54 22 97 16t54 -35q25 -67 102.5 -319.5t115.5 -361.5q268 88 326 105q16 6 37.5 4t32.5 -23q23 -47 32.5 -98.5t0.5 -74.5q-19 -15 -59.5 -32t-75.5 -29t-89.5 -29t-73.5 -23q-10 -3 -38 -13 t-53 -18.5t-58 -19t-61 -17.5t-54 -11.5t-44.5 -3.5t-25.5 9q-18 18 -32 52t-29 87t-19 66q-42 125 -113 338.5t-104 312.5q-6 13 -6.5 24z" />
<glyph unicode="&#x2011;" horiz-adv-x="939" d="M-0.5 707q-0.5 11 6 20.5t13.5 16.5t23.5 15.5t27 13t33 14t34.5 14.5q54 22 97 16t54 -35q25 -67 102.5 -319.5t115.5 -361.5q268 88 326 105q16 6 37.5 4t32.5 -23q23 -47 32.5 -98.5t0.5 -74.5q-19 -15 -59.5 -32t-75.5 -29t-89.5 -29t-73.5 -23q-10 -3 -38 -13 t-53 -18.5t-58 -19t-61 -17.5t-54 -11.5t-44.5 -3.5t-25.5 9q-18 18 -32 52t-29 87t-19 66q-42 125 -113 338.5t-104 312.5q-6 13 -6.5 24z" />
<glyph unicode="&#x2012;" horiz-adv-x="939" d="M-0.5 707q-0.5 11 6 20.5t13.5 16.5t23.5 15.5t27 13t33 14t34.5 14.5q54 22 97 16t54 -35q25 -67 102.5 -319.5t115.5 -361.5q268 88 326 105q16 6 37.5 4t32.5 -23q23 -47 32.5 -98.5t0.5 -74.5q-19 -15 -59.5 -32t-75.5 -29t-89.5 -29t-73.5 -23q-10 -3 -38 -13 t-53 -18.5t-58 -19t-61 -17.5t-54 -11.5t-44.5 -3.5t-25.5 9q-18 18 -32 52t-29 87t-19 66q-42 125 -113 338.5t-104 312.5q-6 13 -6.5 24z" />
<glyph unicode="&#x2013;" horiz-adv-x="499" d="M0 707q0 11 3.5 20.5t7 16.5t12.5 15.5t14.5 13t17.5 14t18 14.5q29 22 52 16t28 -35q14 -67 55 -319.5t61 -361.5q143 88 174 105q8 6 19.5 4t17.5 -23q12 -47 17 -98.5t1 -74.5q-10 -15 -32 -32t-40.5 -29t-47.5 -29t-39 -23q-5 -3 -20 -13t-28.5 -18.5t-31 -19 t-32 -17.5t-28.5 -11.5t-24 -3.5t-14 9q-9 18 -16.5 52t-15.5 87t-10 66q-22 125 -60 338.5t-56 312.5q-3 13 -3 24z" />
<glyph unicode="&#x2014;" d="M0.5 707q-0.5 11 6 20.5t14 16.5t25 15.5t29 13t35.5 14t36 14.5q58 22 103.5 16t57.5 -35q27 -67 109 -319.5t123 -361.5q285 88 347 105q17 6 40 4t34 -23q25 -47 35 -98.5t0 -74.5q-20 -15 -63 -32t-80.5 -29t-95 -29t-78.5 -23q-10 -3 -40 -13t-56.5 -18.5t-61.5 -19 t-65 -17.5t-57.5 -11.5t-47.5 -3.5t-27 9q-19 18 -34 52t-31 87t-20 66q-45 125 -120.5 338.5t-110.5 312.5q-6 13 -6.5 24z" />
<glyph unicode="&#x202f;" horiz-adv-x="192" />
<glyph unicode="&#x205f;" horiz-adv-x="241" />
<glyph unicode="&#xe000;" horiz-adv-x="820" d="M0 0v820h820v-820h-820z" />
<glyph horiz-adv-x="664" />
</font>
</defs></svg>

Before

Width:  |  Height:  |  Size: 77 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,87 +0,0 @@
<%@ page import="org.keycloak.models.RealmModel,org.keycloak.models.RoleModel,org.keycloak.models.UserModel,javax.ws.rs.core.MultivaluedMap" language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ page import="java.util.List" %>
<%
RealmModel realm = (RealmModel)request.getAttribute(RealmModel.class.getName());
String username = (String)request.getAttribute("username");
%>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Keycloak</title>
<link rel="stylesheet" href="<%=application.getContextPath()%>/saas/css/reset.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/base.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/forms.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<%
UserModel client = (UserModel)request.getAttribute("client");
List<RoleModel> realmRolesRequested = (List<RoleModel>)request.getAttribute("realmRolesRequested");
MultivaluedMap<String, RoleModel> resourceRolesRequested = (MultivaluedMap<String, RoleModel>)request.getAttribute("resourceRolesRequested");
%>
<body class="rcue-login-register register">
<h1><a href="#" title="Go to the home page"><img src="<%=application.getContextPath()%>/saas/img/red-hat-logo.png" alt="Red Hat logo"></a></h1>
<div class="content">
<h2>Grant request for <strong><%=client.getLoginName()%></strong></h2>
<div class="background-area">
<div class="form-area social clearfix">
<section class="info-area">
<p>This app would like to:</p>
<hr/>
<ul>
<%
if (realmRolesRequested.size() > 0) {
for (RoleModel role : realmRolesRequested) {
%> <li> <%
String desc = "Have " + role.getName() + " privileges.";
String roleDesc = role.getDescription();
if (roleDesc != null) {
desc = roleDesc;
}
%>
<p><%=desc%></p>
</li>
<%
}
}
%>
</ul>
<%
for (String resource : resourceRolesRequested.keySet()) { %>
<hr/>
<%
List<RoleModel> roles = resourceRolesRequested.get(resource);
out.println("<p>For application " + resource + ":</p> ");
out.println("<ul>");
for (RoleModel role : roles) {
String desc = "Have " + role.getName() + " privileges.";
String roleDesc = role.getDescription();
if (roleDesc != null) {
desc = roleDesc;
}
out.println("<li>" + desc + "</li>");
}
%> </ul> <%
}
%>
<form action="<%=request.getAttribute("action")%>" method="POST">
<input type="hidden" name="code" value="<%=request.getAttribute("code")%>">
<input type="submit" name="accept" value="Accept">
<input type="submit" name="cancel" value="Cancel">
</form>
</section>
</div>
</div>
</div>
<footer>
<p>Powered By Keycloak</p>
</footer>
</body>
</html>

View file

@ -1,23 +0,0 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Keycloak Security Failure</title>
<!-- <link href="<%=application.getContextPath()%>/lib/bootstrap/css/bootstrap.css" rel="stylesheet">
<link href="<%=application.getContextPath()%>/lib/font-awesome/css/font-awesome.css" rel="stylesheet"> -->
<link href="<%=application.getContextPath()%>/saas/css/reset.css" rel="stylesheet">
<link href="<%=application.getContextPath()%>/saas/css/base.css" rel="stylesheet">
</head>
<body>
<h1>Security Failure</h1>
<hr/>
<div class="modal-body">
<div id="error-message" class="alert alert-block alert-error" style="block"><%=request.getAttribute("KEYCLOAK_SECURITY_FAILURE_MESSAGE") %></div>
</div>
</body>
</html>

View file

@ -35,6 +35,5 @@
</build>
<modules>
<module>as7-eap-demo</module>
<module>as7-eap-dev</module>
</modules>
</project>

View file

@ -29,10 +29,6 @@ public interface ApplicationModel extends RoleContainerModel, RoleMapperModel, S
void setManagementUrl(String url);
String getBaseUrl();
void setBaseUrl(String url);
List<String> getDefaultRoles();
void addDefaultRole(String name);

View file

@ -140,6 +140,8 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
OAuthClientModel addOAuthClient(String name);
OAuthClientModel getOAuthClient(String name);
OAuthClientModel getOAuthClientById(String id);
boolean removeOAuthClient(String id);
List<OAuthClientModel> getOAuthClients();

View file

@ -82,15 +82,6 @@ public class ApplicationAdapter implements ApplicationModel {
application.setManagementUrl(url);
}
@Override
public String getBaseUrl() {
return null;
}
@Override
public void setBaseUrl(String url) {
}
@Override
public RoleModel getRole(String name) {
Collection<RoleEntity> roles = application.getRoles();

View file

@ -575,9 +575,13 @@ public class RealmAdapter implements RealmModel {
return false;
}
realm.getApplications().remove(application);
removeUser(application.getApplicationUser());
em.createQuery("delete from " + ApplicationScopeMappingEntity.class.getSimpleName() + " where application = :application").setParameter("application", application).executeUpdate();
em.createQuery("delete from " + ApplicationUserRoleMappingEntity.class.getSimpleName() + " where application = :application").setParameter("application", application).executeUpdate();
em.createQuery("delete from " + ApplicationScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", application.getApplicationUser()).executeUpdate();
em.createQuery("delete from " + RealmScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", application.getApplicationUser()).executeUpdate();
em.createQuery("delete from " + ApplicationUserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", application.getApplicationUser()).executeUpdate();
em.createQuery("delete from " + RealmUserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", application.getApplicationUser()).executeUpdate();
removeUser(application.getApplicationUser());
em.remove(application);
return true;
}
@ -723,6 +727,19 @@ public class RealmAdapter implements RealmModel {
return new OAuthClientAdapter(data);
}
@Override
public boolean removeOAuthClient(String id) {
OAuthClientEntity client = em.find(OAuthClientEntity.class, id);
em.createQuery("delete from " + ApplicationScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", client.getAgent()).executeUpdate();
em.createQuery("delete from " + RealmScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", client.getAgent()).executeUpdate();
em.createQuery("delete from " + ApplicationUserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", client.getAgent()).executeUpdate();
em.createQuery("delete from " + RealmUserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", client.getAgent()).executeUpdate();
removeUser(client.getAgent());
em.remove(client);
return true;
}
@Override
public OAuthClientModel getOAuthClient(String name) {
TypedQuery<OAuthClientEntity> query = em.createNamedQuery("findOAuthClientByUser", OAuthClientEntity.class);
@ -731,7 +748,15 @@ public class RealmAdapter implements RealmModel {
List<OAuthClientEntity> entities = query.getResultList();
if (entities.size() == 0) return null;
return new OAuthClientAdapter(entities.get(0));
}
}
@Override
public OAuthClientModel getOAuthClientById(String id) {
OAuthClientEntity client = em.find(OAuthClientEntity.class, id);
if (client == null) return null;
return new OAuthClientAdapter(client);
}
@Override
public List<OAuthClientModel> getOAuthClients() {

View file

@ -105,17 +105,6 @@ public class ApplicationAdapter implements ApplicationModel {
updateApplication();
}
@Override
public String getBaseUrl() {
return applicationData.getBaseUrl();
}
@Override
public void setBaseUrl(String url) {
applicationData.setBaseUrl(url);
updateApplication();
}
@Override
public RoleAdapter getRole(String name) {
Role role = SampleModel.getRole(getIdm(), name);

View file

@ -746,6 +746,19 @@ public class RealmAdapter implements RealmModel {
return new OAuthClientAdapter(rel, getIdm(), getRelationshipManager());
}
@Override
public boolean removeOAuthClient(String id) {
RelationshipQuery<OAuthClientRelationship> query = getRelationshipManager().createRelationshipQuery(OAuthClientRelationship.class);
query.setParameter(OAuthClientRelationship.REALM, realm.getName());
query.setParameter(OAuthClientRelationship.ID, id);
List<OAuthClientRelationship> results = query.getResultList();
if (results.size() == 0) return false;
OAuthClientRelationship relationship = results.get(0);
getRelationshipManager().remove(relationship);
return true;
}
@Override
public OAuthClientModel getOAuthClient(String name) {
User user = findPicketlinkUser(name);
@ -757,6 +770,17 @@ public class RealmAdapter implements RealmModel {
return new OAuthClientAdapter(results.get(0), getIdm(), getRelationshipManager());
}
@Override
public OAuthClientModel getOAuthClientById(String id) {
RelationshipQuery<OAuthClientRelationship> query = getRelationshipManager().createRelationshipQuery(OAuthClientRelationship.class);
query.setParameter(OAuthClientRelationship.REALM, realm.getName());
query.setParameter(OAuthClientRelationship.ID, id);
List<OAuthClientRelationship> results = query.getResultList();
if (results.size() == 0) return null;
return new OAuthClientAdapter(results.get(0), getIdm(), getRelationshipManager());
}
@Override
public List<OAuthClientModel> getOAuthClients() {
RelationshipQuery<OAuthClientRelationship> query = getRelationshipManager().createRelationshipQuery(OAuthClientRelationship.class);

View file

@ -13,7 +13,6 @@ public class ApplicationData extends AbstractPartition {
private boolean enabled;
private boolean surrogateAuthRequired;
private String managementUrl;
private String baseUrl;
private User resourceUser;
private String[] defaultRoles;
@ -68,15 +67,6 @@ public class ApplicationData extends AbstractPartition {
this.managementUrl = managementUrl;
}
@AttributeProperty
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
@AttributeProperty
public String[] getDefaultRoles() {
return defaultRoles;

View file

@ -31,8 +31,6 @@ public class ApplicationEntity implements Serializable {
private boolean surrogateAuthRequired;
@AttributeValue
private String managementUrl;
@AttributeValue
private String baseUrl;
@AttributeValue
private String[] defaultRoles;
@ -82,14 +80,6 @@ public class ApplicationEntity implements Serializable {
this.managementUrl = managementUrl;
}
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public AccountTypeEntity getResourceUser() {
return resourceUser;
}

View file

@ -31,13 +31,20 @@ public class ApplicationManager {
this.realmManager = realmManager;
}
/**
* Does not create scope or role mappings!
*
* @param realm
* @param loginRole
* @param resourceRep
* @return
*/
public ApplicationModel createApplication(RealmModel realm, RoleModel loginRole, ApplicationRepresentation resourceRep) {
logger.debug("************ CREATE APPLICATION: {0}" + resourceRep.getName());
ApplicationModel applicationModel = realm.addApplication(resourceRep.getName());
applicationModel.setEnabled(resourceRep.isEnabled());
applicationModel.setManagementUrl(resourceRep.getAdminUrl());
applicationModel.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
applicationModel.setBaseUrl(resourceRep.getBaseUrl());
applicationModel.updateApplication();
UserModel resourceUser = applicationModel.getApplicationUser();
@ -75,6 +82,10 @@ public class ApplicationManager {
applicationModel.updateDefaultRoles(resourceRep.getDefaultRoles());
}
return applicationModel;
}
public void createMappings(RealmModel realm, ApplicationRepresentation resourceRep, ApplicationModel applicationModel) {
if (resourceRep.getRoleMappings() != null) {
for (UserRoleMappingRepresentation mapping : resourceRep.getRoleMappings()) {
UserModel user = realm.getUser(mapping.getUsername());
@ -102,7 +113,6 @@ public class ApplicationManager {
}
}
}
return applicationModel;
}
public ApplicationModel createApplication(RealmModel realm, ApplicationRepresentation resourceRep) {
@ -114,7 +124,6 @@ public class ApplicationManager {
resource.setName(rep.getName());
resource.setEnabled(rep.isEnabled());
resource.setManagementUrl(rep.getAdminUrl());
resource.setBaseUrl(rep.getBaseUrl());
resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired());
resource.updateApplication();
@ -140,7 +149,6 @@ public class ApplicationManager {
rep.setEnabled(applicationModel.isEnabled());
rep.setAdminUrl(applicationModel.getManagementUrl());
rep.setSurrogateAuthRequired(applicationModel.isSurrogateAuthRequired());
rep.setBaseUrl(applicationModel.getBaseUrl());
Set<String> redirectUris = applicationModel.getApplicationUser().getRedirectUris();
if (redirectUris != null) {

View file

@ -4,8 +4,16 @@ import org.keycloak.models.Constants;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@ -26,11 +34,30 @@ public class OAuthClientManager {
public OAuthClientModel create(OAuthClientRepresentation rep) {
OAuthClientModel model = create(rep.getName());
model.getOAuthAgent().setEnabled(rep.isEnabled());
update(rep, model);
UserModel resourceUser = model.getOAuthAgent();
if (rep.getCredentials() != null) {
for (CredentialRepresentation cred : rep.getCredentials()) {
UserCredentialModel credential = new UserCredentialModel();
credential.setType(cred.getType());
credential.setValue(cred.getValue());
realm.updateCredential(resourceUser, credential);
}
}
return model;
}
public void update(OAuthClientRepresentation rep, OAuthClientModel model) {
model.getOAuthAgent().setEnabled(rep.isEnabled());
List<String> redirectUris = rep.getRedirectUris();
if (redirectUris != null) {
model.getOAuthAgent().setRedirectUris(new HashSet<String>(redirectUris));
}
List<String> webOrigins = rep.getWebOrigins();
if (webOrigins != null) {
model.getOAuthAgent().setWebOrigins(new HashSet<String>(webOrigins));
}
}
public static OAuthClientRepresentation toRepresentation(OAuthClientModel model) {
@ -38,6 +65,15 @@ public class OAuthClientManager {
rep.setId(model.getId());
rep.setName(model.getOAuthAgent().getLoginName());
rep.setEnabled(model.getOAuthAgent().isEnabled());
Set<String> redirectUris = model.getOAuthAgent().getRedirectUris();
if (redirectUris != null) {
rep.setRedirectUris(new LinkedList<String>(redirectUris));
}
Set<String> webOrigins = model.getOAuthAgent().getWebOrigins();
if (webOrigins != null) {
rep.setWebOrigins(new LinkedList<String>(webOrigins));
}
return rep;
}
}

View file

@ -4,6 +4,7 @@ import org.jboss.resteasy.logging.Logger;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
@ -13,6 +14,7 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserModel.RequiredAction;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.ScopeMappingRepresentation;
@ -227,14 +229,6 @@ public class RealmManager {
}
}
if (rep.getClients() != null) {
for (UserRepresentation clientRep : rep.getClients()) {
UserModel client = createUser(newRealm, clientRep);
newRealm.grantRole(client, newRealm.getRole(Constants.IDENTITY_REQUESTER_ROLE));
userMap.put(client.getLoginName(), client);
}
}
if (rep.getRoles() != null) {
for (RoleRepresentation roleRep : rep.getRoles()) {
createRole(newRealm, roleRep);
@ -247,13 +241,34 @@ public class RealmManager {
}
}
Map<String, ApplicationModel> appMap = null;
if (rep.getApplications() != null) {
Map<String, ApplicationModel> appMap = createApplications(rep, newRealm);
appMap = createApplications(rep, newRealm);
for (ApplicationModel app : appMap.values()) {
userMap.put(app.getApplicationUser().getLoginName(), app.getApplicationUser());
}
}
if (rep.getOauthClients() != null) {
Map<String, OAuthClientModel> oauthMap = createOAuthClients(rep, newRealm);
for (OAuthClientModel app : oauthMap.values()) {
userMap.put(app.getOAuthAgent().getLoginName(), app.getOAuthAgent());
}
}
// Now that all possible users are created (users, apps, and oauth clients), do role mappings and scope mappings
if (rep.getApplications() != null) {
ApplicationManager manager = new ApplicationManager(this);
for (ApplicationRepresentation appRep : rep.getApplications()) {
ApplicationModel model = appMap.get(appRep.getName());
manager.createMappings(newRealm, appRep, model);
}
}
if (rep.getRoleMappings() != null) {
for (UserRoleMappingRepresentation mapping : rep.getRoleMappings()) {
UserModel user = userMap.get(mapping.getUsername());
@ -381,6 +396,17 @@ public class RealmManager {
return appMap;
}
protected Map<String, OAuthClientModel> createOAuthClients(RealmRepresentation realmRep, RealmModel realm) {
Map<String, OAuthClientModel> appMap = new HashMap<String, OAuthClientModel>();
OAuthClientManager manager = new OAuthClientManager(realm);
for (OAuthClientRepresentation rep : realmRep.getOauthClients()) {
OAuthClientModel app = manager.create(rep);
appMap.put(app.getOAuthAgent().getLoginName(), app);
}
return appMap;
}
public static UserRepresentation toRepresentation(UserModel user) {
UserRepresentation rep = new UserRepresentation();
rep.setUsername(user.getLoginName());

View file

@ -12,6 +12,7 @@ import org.keycloak.services.managers.OAuthClientManager;
import org.keycloak.services.managers.RealmManager;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
@ -46,11 +47,16 @@ public class OAuthClientResource {
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public OAuthClientRepresentation getApplication() {
OAuthClientManager manager = new OAuthClientManager(realm);
public OAuthClientRepresentation getOAuthClient() {
return OAuthClientManager.toRepresentation(oauthClient);
}
@DELETE
@NoCache
public void deleteOAuthClient() {
realm.removeOAuthClient(oauthClient.getId());
}
@Path("credentials")
@PUT
@Consumes("application/json")

View file

@ -54,12 +54,12 @@ public class OAuthClientsResource {
public Response createOAuthClient(final @Context UriInfo uriInfo, final OAuthClientRepresentation rep) {
OAuthClientManager resourceManager = new OAuthClientManager(realm);
OAuthClientModel oauth = resourceManager.create(rep);
return Response.created(uriInfo.getAbsolutePathBuilder().path(oauth.getOAuthAgent().getLoginName()).build()).build();
return Response.created(uriInfo.getAbsolutePathBuilder().path(oauth.getId()).build()).build();
}
@Path("{id}")
public OAuthClientResource getOAuthClient(final @PathParam("id") String id) {
OAuthClientModel oauth = realm.getOAuthClient(id);
OAuthClientModel oauth = realm.getOAuthClientById(id);
if (oauth == null) {
throw new NotFoundException();
}

View file

@ -40,7 +40,6 @@ public class ApplicationModelTest extends AbstractKeycloakServerTest {
realm = manager.createRealm("original");
application = realm.addApplication("application");
application.setBaseUrl("http://base");
application.setManagementUrl("http://management");
application.setName("app-name");
application.addRole("role-1");
@ -83,7 +82,6 @@ public class ApplicationModelTest extends AbstractKeycloakServerTest {
public static void assertEquals(ApplicationModel expected, ApplicationModel actual) {
Assert.assertEquals(expected.getName(), actual.getName());
Assert.assertEquals(expected.getBaseUrl(), actual.getBaseUrl());
Assert.assertEquals(expected.getManagementUrl(), actual.getManagementUrl());
Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());

View file

@ -25,9 +25,9 @@
]
}
],
"clients" : [
"oauthClients" : [
{
"username" : "third-party",
"name" : "third-party",
"enabled": true,
"credentials" : [
{ "type" : "Password",

View file

@ -32,9 +32,9 @@
]
}
],
"clients" : [
"oauthClients" : [
{
"username" : "third-party",
"name" : "third-party",
"enabled": true,
"credentials" : [
{ "type" : "password",