Merge branch 'master' into stable

stable
Alejandro Alonso 2014-11-18 16:10:00 +01:00
commit 1f3e500ca7
45 changed files with 831 additions and 152 deletions

View File

@ -3,9 +3,12 @@
## 1.3.0 Dryas hookeriana (Unreleased)
### Features
- GitHub integration (Phase I):
+ Add button to login/singin with a GitHub account.
+ Create Admin Panel with the GitHub webhooks settings.
- Differentiate blocked user stories on a milestone.
### Misc
### Misc
- Lots of small and not so small bugfixes.
@ -27,12 +30,12 @@
## 1.1.0 Alnus maximowiczii (2014-10-13)
### Features ###
### Features
- Promote an issue to a user story.
- Changed configuration format from coffeescript file to json.
- Add builtin analytics support.
### Misc ###
### Misc
- Fix bug related to stange behavior of browser autofill and angularjs on login page.
- Fix bug on userstories ordering on sprints.
- Fix bug of projects list visualization on project nav on first page loading.
@ -40,10 +43,10 @@
## 1.0.0 (2014-10-07)
### Features ###
### Features
- Redesign for taskboard and backlog summaries
- Allow feedback for users from the platform
- Real time changes for backlog, taskboard, kanban and issues
### Misc ###
### Misc
- Lots of small and not so small bugfixes

View File

@ -94,18 +94,20 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
{templateUrl: "/partials/admin-memberships.html"})
$routeProvider.when("/project/:pslug/admin/roles",
{templateUrl: "/partials/admin-roles.html"})
$routeProvider.when("/project/:pslug/admin/third-parties/github",
{templateUrl: "/partials/admin-third-parties-github.html"})
# User settings
$routeProvider.when("/project/:pslug/user-settings/user-profile",
{templateUrl: "/partials/user-profile.html"})
{templateUrl: "/partials/user-profile.html"})
$routeProvider.when("/project/:pslug/user-settings/user-change-password",
{templateUrl: "/partials/user-change-password.html"})
{templateUrl: "/partials/user-change-password.html"})
$routeProvider.when("/project/:pslug/user-settings/user-avatar",
{templateUrl: "/partials/user-avatar.html"})
{templateUrl: "/partials/user-avatar.html"})
$routeProvider.when("/project/:pslug/user-settings/mail-notifications",
{templateUrl: "/partials/mail-notifications.html"})
{templateUrl: "/partials/mail-notifications.html"})
$routeProvider.when("/change-email/:email_token",
{templateUrl: "/partials/change-email.html"})
{templateUrl: "/partials/change-email.html"})
$routeProvider.when("/cancel-account/:cancel_token",
{templateUrl: "/partials/cancel-account.html"})
@ -216,6 +218,7 @@ modules = [
"taigaUserSettings",
"taigaFeedback",
"taigaPlugins",
"taigaIntegrations",
# Vendor modules
"ngRoute",

View File

@ -0,0 +1,123 @@
###
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán Merino <bameda@dbarragan.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: modules/admin/third-parties.coffee
###
taiga = @.taiga
mixOf = @.taiga.mixOf
module = angular.module("taigaAdmin")
#############################################################################
## Github Controller
#############################################################################
class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.FiltersMixin)
@.$inject = [
"$scope",
"$tgRepo",
"$tgResources",
"$routeParams",
"$appTitle"
]
constructor: (@scope, @repo, @rs, @params, @appTitle) ->
_.bindAll(@)
@scope.sectionName = "Github" #i18n
@scope.project = {}
@scope.anyComputableRole = true
promise = @.loadInitialData()
promise.then () =>
@appTitle.set("Github - " + @scope.project.name)
promise.then null, @.onInitialDataError.bind(@)
loadModules: ->
return @rs.modules.list(@scope.projectId, "github").then (github) =>
@scope.github = github
loadProject: ->
return @rs.projects.get(@scope.projectId).then (project) =>
@scope.project = project
@scope.$emit('project:loaded', project)
@scope.anyComputableRole = _.some(_.map(project.roles, (point) -> point.computable))
return project
loadInitialData: ->
promise = @repo.resolve({pslug: @params.pslug}).then (data) =>
@scope.projectId = data.project
return data
return promise.then(=> @.loadProject())
.then(=> @.loadModules())
module.controller("GithubController", GithubController)
SelectInputText = ->
link = ($scope, $el, $attrs) ->
$el.on "click", ".select-input-content", () ->
$el.find("input").select()
$el.find(".help-copy").addClass("visible")
return {link:link}
module.directive("tgSelectInputText", SelectInputText)
#############################################################################
## GithubWebhooks Directive
#############################################################################
GithubWebhooksDirective = ($repo, $confirm, $loading) ->
link = ($scope, $el, $attrs) ->
form = $el.find("form").checksley({"onlyOneErrorElement": true})
submit = (target) =>
return if not form.validate()
$loading.start(target)
promise = $repo.saveAttribute($scope.github, "github")
promise.then ->
$loading.finish(target)
$confirm.notify("success")
promise.then null, (data) ->
$loading.finish(target)
form.setErrors(data)
if data._error_message
$confirm.notify("error", data._error_message)
$el.on "click", "a.button-green", (event) ->
event.preventDefault()
target = angular.element(event.currentTarget)
submit(target)
$el.on "submit", "form", (event) ->
event.preventDefault()
submit()
return {link:link}
module.directive("tgGithubWebhooks", ["$tgRepo", "$tgConfirm", "$tgLoading", GithubWebhooksDirective])

View File

@ -89,6 +89,7 @@ urls = {
"project-admin-project-values-issue-severities": "/project/:project/admin/project-values/issue-severities"
"project-admin-memberships": "/project/:project/admin/memberships"
"project-admin-roles": "/project/:project/admin/roles"
"project-admin-third-parties-github": "/project/:project/admin/third-parties/github"
# User settings
"user-settings-user-profile": "/project/:project/user-settings/user-profile"

View File

@ -31,6 +31,9 @@ class RepositoryService extends taiga.Service
idAttrName = model.getIdAttrName()
return "#{@urls.resolve(model.getName())}/#{model[idAttrName]}"
resolveUrlForAttributeModel: (model) ->
return @urls.resolve(model.getName(), model.parent)
create: (name, data, dataTypes={}, extraParams={}) ->
defered = @q.defer()
url = @urls.resolve(name)
@ -89,6 +92,37 @@ class RepositoryService extends taiga.Service
return defered.promise
saveAttribute: (model, attribute, patch=true) ->
defered = @q.defer()
if not model.isModified() and patch
defered.resolve(model)
return defered.promise
url = @.resolveUrlForAttributeModel(model)
data = {}
data[attribute] = model.getAttrs()
if patch
promise = @http.patch(url, data)
else
promise = @http.put(url, data)
promise.success (data, status) =>
model._isModified = false
model._attrs = _.extend(model.getAttrs(), data)
model._modifiedAttrs = {}
model.applyCasts()
defered.resolve(model)
promise.error (data, status) ->
defered.reject(data)
return defered.promise
refresh: (model) ->
defered = @q.defer()
@ -115,6 +149,19 @@ class RepositoryService extends taiga.Service
return @http.get(url, params, httpOptions).then (data) =>
return _.map(data.data, (x) => @model.make_model(name, x))
queryOneAttribute: (name, id, attribute, params, options={}) ->
url = @urls.resolve(name, id)
httpOptions = {headers: {}}
if not options.enablePagination
httpOptions.headers["x-disable-pagination"] = "1"
return @http.get(url, params, httpOptions).then (data) =>
model = @model.make_model(name, data.data[attribute])
model.parent = id
return model
queryOne: (name, id, params, options={}) ->
url = @urls.resolve(name)
url = "#{url}/#{id}" if id

View File

@ -29,10 +29,10 @@ module = angular.module("taigaCommon", [])
CheckPermissionDirective = ->
render = ($el, project, permission) ->
$el.show() if project.my_permissions.indexOf(permission) > -1
$el.removeClass('hidden') if project.my_permissions.indexOf(permission) > -1
link = ($scope, $el, $attrs) ->
$el.hide()
$el.addClass('hidden')
permission = $attrs.tgCheckPermission
$scope.$watch "project", (project) ->

View File

@ -132,8 +132,12 @@ CreatedByDisplayDirective = ->
link = ($scope, $el, $attrs) ->
render = (model) ->
owner = $scope.usersById?[model.owner] or {
full_name_display: "external user"
photo: "/images/unnamed.png"
}
html = template({
owner: $scope.usersById?[model.owner]
owner: owner
date: moment(model.created_date).format("DD MMM YYYY HH:mm")
})
$el.html(html)

View File

@ -97,8 +97,6 @@ Loader = () ->
startCurrentPageLoader: () ->
if config.enabled
start()
else
pageLoaded(true)
onStart: (fn) ->
$rootscope.$on("loader:start", fn)

View File

@ -0,0 +1,22 @@
###
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán Merino <bameda@dbarragan.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: modules/integrations.coffee
###
module = angular.module("taigaIntegrations", [])

View File

@ -0,0 +1,111 @@
###
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán Merino <bameda@dbarragan.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: modules/integrations/github.coffee
###
taiga = @.taiga
module = angular.module("taigaIntegrations")
AUTH_URL = "https://github.com/login/oauth/authorize"
#############################################################################
## User story team requirements button directive
#############################################################################
GithubLoginButtonDirective = ($window, $params, $location, $config, $events, $confirm, $auth, $navUrls, $loader) ->
# Login or registar a user with his/her github account.
#
# Example:
# tg-github-login-button()
#
# Requirements:
# - ...
template = """
<a class="button button-github" href="" title="Enter with your github account">
<span class="icon icon-github"></span>
<span>Login with Github</span>
</a>
""" #TODO: i18n
link = ($scope, $el, $attrs) ->
clientId = $config.get("gitHubClientId", null)
return if not clientId
renderGitHubButton = ->
$el.html(template) if clientId
loginOnSuccess = (response) ->
if $params.next and $params.next != $navUrls.resolve("login")
nextUrl = $params.next
else
nextUrl = $navUrls.resolve("home")
$events.setupConnection()
$location.search("next", null)
$location.search("token", null)
$location.search("state", null)
$location.search("code", null)
$location.path(nextUrl)
loginOnError = (response) ->
$location.search("state", null)
$location.search("code", null)
$loader.pageLoaded()
if response.data.error_message
$confirm.notify("light-error", response.data.error_message )
else
$confirm.notify("light-error", "Our Oompa Loompas have not been able to get you
credentials from GitHub.") #TODO: i18n
loginWithGitHubAccount = ->
type = $params.state
code = $params.code
token = $params.token
return if not (type == "github" and code)
$loader.start()
data = {code: code, token: token}
$auth.login(data, type).then(loginOnSuccess, loginOnError)
renderGitHubButton()
loginWithGitHubAccount()
$el.on "click", ".button-github", (event) ->
redirectToUri = $location.absUrl()
url = "#{AUTH_URL}?client_id=#{clientId}&redirect_uri=#{redirectToUri}&state=github&scope=user:email"
$window.location.href = url
$scope.$on "$destroy", ->
$el.off()
return {
link: link
restrict: "EA"
template: ""
}
module.directive("tgGithubLoginButton", ["$window", '$routeParams', "$tgLocation", "$tgConfig", "$tgEvents",
"$tgConfirm", "$tgAuth", "$tgNavUrls", "tgLoader",
GithubLoginButtonDirective])

View File

@ -276,25 +276,6 @@ KanbanDirective = ($repo, $rootscope) ->
module.directive("tgKanban", ["$tgRepo", "$rootScope", KanbanDirective])
#############################################################################
## Kanban Row Size Fixer Directive
#############################################################################
KanbanRowWidthFixerDirective = ->
link = ($scope, $el, $attrs) ->
bindOnce $scope, "usStatusList", (statuses) ->
itemSize = 310
size = (statuses.length * itemSize) - 10
$el.css("width", "#{size}px")
$scope.$on "$destroy", ->
$el.off()
return {link: link}
module.directive("tgKanbanRowWidthFixer", KanbanRowWidthFixerDirective)
#############################################################################
## Kanban Column Height Fixer Directive
#############################################################################
@ -355,6 +336,36 @@ KanbanUserstoryDirective = ($rootscope) ->
module.directive("tgKanbanUserstory", ["$rootScope", KanbanUserstoryDirective])
#############################################################################
## Kanban Squish Column Directive
#############################################################################
KanbanSquishColumnDirective = (rs) ->
link = ($scope, $el, $attrs) ->
$scope.$on "project:loaded", (event, project) ->
$scope.folds = rs.kanban.getStatusColumnModes(project.id)
updateTableWidth()
$scope.foldStatus = (status) ->
$scope.folds[status.id] = !!!$scope.folds[status.id]
rs.kanban.storeStatusColumnModes($scope.projectId, $scope.folds)
updateTableWidth()
return
updateTableWidth = ->
columnWidths = _.map $scope.usStatusList, (status) ->
if $scope.folds[status.id]
return 40
else
return 310
totalWidth = _.reduce columnWidths, (total, width) ->
return total + width
$el.find('.kanban-table-inner').css("width", totalWidth)
return {link: link}
module.directive("tgKanbanSquishColumn", ["$tgResources", KanbanSquishColumnDirective])
#############################################################################
## Kaban WIP Limit Directive

View File

@ -83,6 +83,7 @@ urls = {
"issue-types": "/issue-types"
"priorities": "/priorities"
"severities": "/severities"
"project-modules": "/projects/%s/modules"
# History
"history/us": "/history/userstory"
@ -138,5 +139,6 @@ module.run([
"$tgMdRenderResourcesProvider",
"$tgHistoryResourcesProvider",
"$tgKanbanResourcesProvider",
"$tgModulesResourcesProvider",
initResources
])

View File

@ -27,6 +27,7 @@ generateHash = taiga.generateHash
resourceProvider = ($storage) ->
service = {}
hashSuffixStatusViewModes = "kanban-statusviewmodels"
hashSuffixStatusColumnModes = "kanban-statuscolumnmodels"
service.storeStatusViewModes = (projectId, params) ->
ns = "#{projectId}:#{hashSuffixStatusViewModes}"
@ -38,6 +39,16 @@ resourceProvider = ($storage) ->
hash = generateHash([projectId, ns])
return $storage.get(hash) or {}
service.storeStatusColumnModes = (projectId, params) ->
ns = "#{projectId}:#{hashSuffixStatusColumnModes}"
hash = generateHash([projectId, ns])
$storage.set(hash, params)
service.getStatusColumnModes = (projectId) ->
ns = "#{projectId}:#{hashSuffixStatusColumnModes}"
hash = generateHash([projectId, ns])
return $storage.get(hash) or {}
return (instance) ->
instance.kanban = service

View File

@ -0,0 +1,12 @@
resourceProvider = ($repo) ->
service = {}
service.list = (projectId, module) ->
return $repo.queryOneAttribute("project-modules", projectId, module)
return (instance) ->
instance.modules = service
module = angular.module("taigaResources")
module.factory("$tgModulesResourcesProvider", ["$tgRepo", resourceProvider])

Binary file not shown.

View File

@ -11,39 +11,41 @@
<glyph unicode="&#98;" d="M328 511l-284 1c0 0-2-336-2-492l46 0 59 38 43-58 60 97 56-75 57 56c5-5 12-11 19-18 8-8 17-17 25-24 7-7 12-13 17-16l46 0 0 349z m50-386l-16 15-51-51-65 86-59-97-29 39-63-46 0 393 223 1 0-102c0-2 0-3 1-4 1-1 3-1 4-1l95 0 0-277c-21 19-40 44-40 44z"/>
<glyph unicode="&#99;" d="M0 512l0-512 512 0 0 512z m51-49l104 0 0-413-104 0z m158 0l98 0 0-415-98 0z m151-2l101 0 0-410-101 0z"/>
<glyph unicode="&#100;" d="M224 512c-123 0-223-104-223-232 0-128 100-231 223-231 52 0 100 18 137 49l99-98 51 52-101 101c23 37 37 80 37 127 0 128-100 232-223 232z m0-32c107 0 193-89 193-200 0-111-86-200-193-200-107 0-193 89-193 200 0 111 86 200 193 200z"/>
<glyph unicode="&#101;" d="M17 512l0-389 59 0 0-123 124 124 295 0 0 387-15 0-448 1z m48-45l381-2 0-296-263 0-5-4-59-63 0 66-54 0z"/>
<glyph unicode="&#102;" d="M0 510l0-508 512 0 0 508z m52-51l409 0 0-408-409 0z m32-86l344 0 0-35-344 0z m0-68l344 0 0-35-344 0z m0-67l344 0 0-36-344 0z m0-68l344 0 0-35-344 0z"/>
<glyph unicode="&#103;" d="M329 256c0 20-7 37-21 52-15 14-32 21-52 21-20 0-37-7-52-21-14-15-21-32-21-52 0-20 7-37 21-52 15-14 32-21 52-21 20 0 37 7 52 21 14 15 21 32 21 52z m146 31l0-63c0-3 0-5-2-7-1-2-3-3-6-4l-52-8c-4-10-8-19-12-26 7-9 17-22 31-39 2-2 3-5 3-7 0-3-1-5-3-7-5-7-14-17-28-31-14-13-23-20-27-20-2 0-5 1-7 3l-40 31c-8-5-17-8-26-11-3-26-6-44-8-53-1-6-5-8-10-8l-64 0c-2 0-5 0-7 2-2 2-3 4-3 6l-8 53c-9 3-18 6-26 10l-40-30c-2-2-4-3-7-3-3 0-5 1-7 3-24 22-40 38-47 48-2 2-2 4-2 7 0 2 0 4 2 6 3 4 8 11 14 19 7 9 12 16 16 21-5 9-9 19-12 28l-52 8c-3 0-5 1-6 3-2 2-2 4-2 7l0 63c0 3 0 5 2 7 1 2 3 3 5 4l53 8c3 8 7 17 12 26-8 11-18 24-31 39-2 3-3 5-3 7 0 2 1 4 3 7 5 7 14 17 28 30 14 14 23 21 27 21 2 0 5-1 7-3l40-31c8 5 17 8 26 11 3 26 6 44 8 53 1 6 5 8 10 8l64 0c2 0 5 0 7-2 2-2 3-4 3-6l8-53c9-3 18-6 26-10l40 30c2 2 4 3 7 3 3 0 5-1 7-3 25-23 41-39 47-49 2-1 2-3 2-6 0-2 0-4-2-6-3-4-8-11-14-19-7-9-12-16-16-21 5-9 9-18 12-28l52-8c3 0 5-1 6-3 2-2 2-4 2-7z"/>
<glyph unicode="&#104;" d="M512 174l0-55c0-3-1-5-3-7-2-1-4-2-6-2l-393 0 0-55c0-3-1-5-3-7-2-1-4-2-6-2-3 0-5 1-7 3l-91 91c-2 2-3 4-3 6 0 3 1 5 3 7l91 91c2 2 4 3 7 3 2 0 4-1 6-3 2-2 3-4 3-6l0-55 393 0c2 0 4-1 6-3 2-2 3-4 3-6z m0 155c0-3-1-5-3-6l-91-92c-2-2-4-2-7-2-2 0-4 0-6 2-2 2-3 4-3 7l0 55-393 0c-2 0-4 0-6 2-2 2-3 4-3 7l0 55c0 2 1 4 3 6 2 2 4 3 6 3l393 0 0 55c0 2 1 4 3 6 2 2 4 3 6 3 3 0 5-1 7-3l91-91c2-2 3-4 3-7z"/>
<glyph unicode="&#105;" d="M456 428c3-8 2-15-4-20l-141-141 0-212c0-8-4-14-11-17-3-1-5-1-7-1-6 0-10 1-13 5l-73 73c-4 4-6 8-6 13l0 139-141 141c-6 5-7 12-4 20 4 7 9 11 17 11l366 0c8 0 13-4 17-11z"/>
<glyph unicode="&#106;" d="M399 174c0-3-1-5-3-7l-15-14c-1-2-4-3-6-3-3 0-5 1-7 3l-112 112-112-112c-2-2-4-3-7-3-2 0-5 1-6 3l-15 14c-2 2-3 4-3 7 0 2 1 4 3 6l133 133c2 2 5 3 7 3 2 0 5-1 7-3l133-133c2-2 3-4 3-6z"/>
<glyph unicode="&#107;" d="M335 238c0-3-1-5-3-7l-133-133c-2-2-5-3-7-3-2 0-5 1-7 3l-14 14c-2 2-3 4-3 7 0 2 1 5 3 6l112 113-112 112c-2 2-3 4-3 7 0 2 1 4 3 6l14 14c2 2 5 3 7 3 2 0 5-1 7-3l133-133c2-2 3-4 3-6z"/>
<glyph unicode="&#108;" d="M344 357c0-3-1-5-3-7l-112-112 112-113c2-1 3-4 3-6 0-3-1-5-3-7l-14-14c-2-2-5-3-7-3-2 0-5 1-7 3l-133 133c-2 2-3 4-3 7 0 2 1 4 3 6l133 133c2 2 5 3 7 3 2 0 5-1 7-3l14-14c2-2 3-4 3-6z"/>
<glyph unicode="&#109;" d="M399 302c0-3-1-5-3-7l-133-133c-2-2-5-3-7-3-2 0-5 1-7 3l-133 133c-2 2-3 4-3 7 0 2 1 4 3 6l15 15c1 1 4 2 6 2 3 0 5-1 7-2l112-113 112 113c2 1 4 2 7 2 2 0 5-1 6-2l15-15c2-2 3-4 3-6z"/>
<glyph unicode="&#110;" d="M455 362l-93 93c-5 5-14 5-20 0l-253-254 1 0-1 0-35-130 0 0c-2-4 0-10 3-14 5-4 11-5 16-2l0 0 128 34 0 0 0 0 254 254c5 5 5 14 0 19z m-359-265l21 76 56-56z"/>
<glyph unicode="&#111;" d="M434 160l-96 96 96 96c4 4 4 10 0 14l-68 68c-4 4-10 4-14 0l-96-96-96 96c-4 4-11 4-14 0l-68-68c-2-1-3-4-3-7 0-2 1-5 3-7l96-96-96-96c-2-2-3-5-3-7 0-3 1-6 3-7l68-68c1-2 4-3 7-3 2 0 5 1 7 3l96 96 96-96c2-2 5-3 7-3 3 0 5 1 7 3l68 68c4 4 4 10 0 14z"/>
<glyph unicode="&#112;" d="M364 364c-17 6-31 20-35 38l-36 0c5-34 28-61 59-71 21-7 36-27 36-50l0-18-226 0 0-88-36 0 0 106c0 23 15 43 36 50 31 10 54 37 59 71l-36 0c-5-18-18-32-35-38-34-12-59-45-59-83l0-246c0-20 16-37 36-37l259 0 0 1c21 0 37 16 37 36l0 246c0 38-25 71-59 83z m-101-133c28 0 51-22 51-50 0-15-6-28-16-37-1-2-2-3-2-5l0-2c0-2-1-4-2-4-9-6-18-9-28-9l-5 0c-10 0-20 3-28 9-1 0-2 2-2 4l0 2c0 2-1 3-2 5-10 9-16 22-16 37 0 28 22 50 50 50z m64-136c-3 0-6 2-8 4l-31-11 25-9c2 3 6 5 9 5 6 0 11-4 11-10 0-3-2-6-4-7 1-2 1-3 1-5 0-6-5-12-11-12-7 0-12 6-12 12 0 0 0 1 0 1l-43 16-45-16c0 0 0-1 0-1 0-6-6-12-12-12-7 0-12 6-12 12 0 2 1 3 1 5-2 1-3 4-3 7 0 6 5 10 10 10 4 0 7-2 9-5l27 9-27 10c-2-2-4-4-7-4-6 0-10 4-10 10 0 4 3 7 6 8 0 0 0 0 0 0 0 5 4 9 8 9 5 0 8-4 9-8l45-16 51 17c0 5 4 8 8 8 5 0 8-4 8-8l0 0c4-2 6-5 6-9 0-5-4-10-9-10z m-154 327l168 0c2 0 4 1 4 4l0 48c0 2-2 4-4 4l-12 0 0 23c0 3-2 6-6 6l-132 0c-4 0-6-3-6-6l0-23-12 0c-2 0-4-2-4-4l0-48c0-3 2-4 4-4z m82-255c0-7-6-13-13-13-8 0-14 6-14 13 0 7 6 13 14 13 7 0 13-6 13-13z m43 0c0-7-6-13-13-13-7 0-13 6-13 13 0 7 6 13 13 13 7 0 13-6 13-13z"/>
<glyph unicode="&#113;" d="M165 302l0-55c0-8-3-14-8-20-6-5-12-8-20-8l-55 0c-7 0-14 3-19 8-5 6-8 12-8 20l0 55c0 7 3 14 8 19 5 5 12 8 19 8l55 0c8 0 14-3 20-8 5-5 8-12 8-19z m146 0l0-55c0-8-3-14-8-20-5-5-12-8-20-8l-54 0c-8 0-15 3-20 8-5 6-8 12-8 20l0 55c0 7 3 14 8 19 5 5 12 8 20 8l54 0c8 0 15-3 20-8 5-5 8-12 8-19z m146 0l0-55c0-8-3-14-8-20-5-5-12-8-19-8l-55 0c-8 0-14 3-20 8-5 6-8 12-8 20l0 55c0 7 3 14 8 19 6 5 12 8 20 8l55 0c7 0 14-3 19-8 5-5 8-12 8-19z"/>
<glyph unicode="&#114;" d="M311 155l0-54c0-8-3-15-8-20-5-5-12-8-20-8l-54 0c-8 0-15 3-20 8-5 5-8 12-8 20l0 54c0 8 3 15 8 20 5 5 12 8 20 8l54 0c8 0 15-3 20-8 5-5 8-12 8-20z m0 147l0-55c0-8-3-14-8-20-5-5-12-8-20-8l-54 0c-8 0-15 3-20 8-5 6-8 12-8 20l0 55c0 7 3 14 8 19 5 5 12 8 20 8l54 0c8 0 15-3 20-8 5-5 8-12 8-19z m0 146l0-55c0-7-3-14-8-19-5-6-12-8-20-8l-54 0c-8 0-15 2-20 8-5 5-8 12-8 19l0 55c0 8 3 14 8 19 5 6 12 8 20 8l54 0c8 0 15-2 20-8 5-5 8-11 8-19z"/>
<glyph unicode="&#115;" d="M366 174l0-19c0-2-1-4-3-6-2-2-4-3-6-3l-202 0c-2 0-4 1-6 3-2 2-3 4-3 6l0 19c0 2 1 5 3 6 2 2 4 3 6 3l202 0c2 0 4-1 6-3 2-1 3-4 3-6z m0 73l0-18c0-3-1-5-3-7-2-2-4-3-6-3l-202 0c-2 0-4 1-6 3-2 2-3 4-3 7l0 18c0 3 1 5 3 6 2 2 4 3 6 3l202 0c2 0 4-1 6-3 2-1 3-3 3-6z m-256-174l292 0 0 220-119 0c-7 0-14 2-19 8-5 5-8 11-8 19l0 119-146 0z m183 256l107 0c-2 6-4 10-6 12l-90 89c-2 3-6 5-11 7z m146-9l0-256c0-8-3-14-8-19-5-6-12-8-20-8l-310 0c-8 0-15 2-20 8-5 5-8 11-8 19l0 384c0 8 3 14 8 19 5 6 12 8 20 8l182 0c8 0 16-1 26-5 9-4 16-9 21-14l89-89c6-5 10-13 14-22 4-9 6-17 6-25z"/>
<glyph unicode="&#116;" d="M432 309l-123 0 0 123c0 5-5 10-10 10l-86 0c-5 0-10-5-10-10l0-123-123 0c-5 0-10-5-10-10l0-86c0-3 1-5 3-7 2-2 4-3 7-3l123 0 0-123c0-3 1-5 3-7 2-2 4-3 7-3l86 0c3 0 5 1 7 3 2 2 3 4 3 7l0 123 123 0c3 0 5 1 7 3 2 2 3 4 3 7l0 86c0 5-5 10-10 10z"/>
<glyph unicode="&#117;" d="M468 210c0-1 0-1 0-2-12-51-38-92-77-124-38-32-84-47-136-47-28 0-55 5-81 15-26 11-49 26-69 45l-37-37c-4-3-8-5-13-5-5 0-9 2-13 5-4 4-5 8-5 13l0 128c0 5 1 9 5 13 4 4 8 5 13 5l128 0c5 0 9-1 13-5 3-4 5-8 5-13 0-5-2-9-5-13l-39-39c13-12 28-22 46-29 17-7 35-10 53-10 26 0 49 6 71 18 23 13 40 30 54 51 2 4 7 15 15 34 1 4 4 6 8 6l55 0c3 0 5 0 7-2 1-2 2-4 2-7z m7 229l0-128c0-5-1-9-5-13-4-4-8-5-13-5l-128 0c-5 0-9 1-13 5-3 4-5 8-5 13 0 5 2 9 5 13l40 39c-28 26-62 39-100 39-26 0-49-6-71-18-23-13-40-30-54-51-2-4-7-15-15-34-1-4-4-6-8-6l-57 0c-3 0-5 0-7 2-1 2-2 4-2 7l0 2c12 51 38 92 77 124 39 32 85 47 137 47 28 0 55-5 81-15 26-11 50-26 70-45l37 37c4 3 8 5 13 5 5 0 9-2 13-5 4-4 5-8 5-13z"/>
<glyph unicode="&#118;" d="M256 475c40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110 0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29z m37-356l0 54c0 3-1 5-3 7-2 2-4 3-6 3l-55 0c-3 0-5-1-7-3-2-2-3-4-3-7l0-54c0-2 1-5 3-6 2-2 4-3 7-3l55 0c2 0 4 1 6 2 2 2 3 4 3 7z m-1 98l5 178c0 2-1 4-3 5-2 2-4 2-7 2l-62 0c-3 0-5 0-7-2-2-1-3-3-3-5l5-178c0-1 1-3 3-5 1-1 4-2 6-2l53 0c3 0 5 1 7 2 2 2 3 4 3 5z"/>
<glyph unicode="&#119;" d="M350 204l-42-42c-2-2-4-3-6-3-3 0-5 1-7 3l-39 39-39-39c-2-2-4-3-7-3-2 0-4 1-6 3l-42 42c-2 2-3 4-3 6 0 3 1 5 3 7l39 39-39 39c-2 2-3 4-3 7 0 2 1 4 3 6l42 42c2 2 4 3 6 3 3 0 5-1 7-3l39-39 39 39c2 2 4 3 7 3 2 0 4-1 6-3l42-42c2-2 3-4 3-6 0-3-1-5-3-7l-39-39 39-39c2-2 3-4 3-7 0-2-1-4-3-6z m61 52c0 28-7 54-20 78-14 24-33 43-57 57-24 13-50 20-78 20-28 0-54-7-78-20-24-14-43-33-57-57-13-24-20-50-20-78 0-28 7-54 20-78 14-24 33-43 57-57 24-13 50-20 78-20 28 0 54 7 78 20 24 14 43 33 57 57 13 24 20 50 20 78z m64 0c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
<glyph unicode="&#120;" d="M201 165c0-8-1-16-3-24-3-8-7-15-13-22-6-6-12-9-20-9-8 0-15 3-21 9-6 7-10 14-12 22-3 8-4 16-4 24 0 7 1 15 4 23 2 8 6 15 12 22 6 6 13 9 21 9 8 0 14-3 20-9 6-7 10-14 13-22 2-8 3-16 3-23z m183 0c0-8-1-16-4-24-2-8-6-15-12-22-6-6-13-9-21-9-8 0-14 3-20 9-6 7-10 14-13 22-2 8-3 16-3 24 0 7 1 15 3 23 3 8 7 15 13 22 6 6 12 9 20 9 8 0 15-3 21-9 6-7 10-14 12-22 3-8 4-16 4-23z m46 0c0 22-7 42-20 58-13 16-31 24-53 24-8 0-27-2-56-6-14-2-29-3-45-3-16 0-31 1-45 3-29 4-47 6-56 6-22 0-40-8-53-24-13-16-20-36-20-58 0-17 3-32 9-44 7-13 14-23 24-30 9-7 21-13 34-17 14-4 28-7 40-8 13-2 27-2 43-2l48 0c16 0 30 0 43 2 12 1 26 4 40 8 13 4 25 10 34 17 10 7 17 17 24 30 6 12 9 27 9 44z m64 50c0-40-6-71-18-95-7-14-17-27-30-38-13-10-26-19-40-24-14-6-30-11-49-14-18-3-34-5-49-6-14-1-30-1-47-1-15 0-29 0-41 0-12 1-26 2-42 4-16 2-31 5-44 9-13 3-26 8-39 14-13 6-24 14-34 23-11 10-19 21-25 33-12 24-18 55-18 95 0 45 13 83 39 113-5 16-8 32-8 49 0 22 5 42 15 62 21 0 39-4 54-11 16-8 34-20 54-36 28 7 58 10 89 10 28 0 54-3 80-9 20 16 37 27 53 35 16 7 34 11 54 11 10-20 15-40 15-62 0-17-3-33-8-48 26-31 39-69 39-114z"/>
<glyph unicode="&#121;" d="M232 141l176 175c3 4 5 8 5 13 0 5-2 9-5 13l-29 29c-4 4-8 6-13 6-5 0-10-2-13-6l-134-133-60 60c-3 4-8 5-13 5-5 0-9-1-13-5l-29-29c-3-4-5-8-5-13 0-5 2-9 5-13l103-102c3-4 7-6 12-6 5 0 10 2 13 6z m243 252l0-274c0-23-8-42-24-58-16-16-35-24-58-24l-274 0c-23 0-42 8-58 24-16 16-24 35-24 58l0 274c0 23 8 42 24 58 16 16 35 24 58 24l274 0c23 0 42-8 58-24 16-16 24-35 24-58z"/>
<glyph unicode="&#122;" d="M256 484c-126 0-228-102-228-228 0-126 102-228 228-228 126 0 228 102 228 228 0 126-102 228-228 228z m0-399c-94 0-171 77-171 171 0 94 77 171 171 171 94 0 171-77 171-171 0-94-77-171-171-171z m-2 312c-23-2-40-23-37-46l12-118c2-13 12-24 26-26 16-1 30 10 31 26l13 118c0 3 0 6 0 8-2 23-22 40-45 38z m-21-220c-7-7-11-16-11-25 0-10 4-19 11-26 7-6 16-10 25-10 9 0 19 4 25 10 7 7 11 16 11 26 0 9-4 18-11 25-13 13-37 13-50 0z"/>
<glyph unicode="&#65;" d="M388 461c0 0 73-80 73-80 0 0 0-279 0-279 0-13-5-25-15-35-10-11-22-16-36-16 0 0-308 0-308 0-13 0-25 5-35 16-11 10-16 22-16 35 0 0 0 308 0 308 0 14 5 26 16 36 10 10 22 15 35 15 0 0 286 0 286 0m-30-154c0 0 0 128 0 128 0 0-204 0-204 0 0 0 0-128 0-128 0-7 2-13 7-18 5-5 11-7 18-7 0 0 154 0 154 0 7 0 13 2 18 7 5 5 7 11 7 18m-25 103c0 0 0-103 0-103 0 0-51 0-51 0 0 0 0 103 0 103 0 0 51 0 51 0"/>
<glyph unicode="&#66;" d="M453 425c-1 9-8 16-17 16l-360 0 0 0c-9 0-16-7-17-16l0 0 0-288 0 0c2-8 9-14 17-14l0 0 59 0 0-35c0-9 8-17 17-17 6 0 11 3 14 8l45 44 225 0c8 0 15 6 17 14l0 0 0 288z"/>
<glyph unicode="&#67;" d="M411 448l0 0 0 21c0 4-4 8-9 8l-168 0-133-132 0-302c0-4 4-8 9-8l292 0c5 0 9 4 9 8l0 13 0 0z m-259-362l0 241 91 0c5 0 9 4 9 9l0 90 108 0 0-340z"/>
<glyph unicode="&#68;" d="M155 59c-14 0-32 5-50 23-24 24-27 47-25 62 2 17 11 34 27 50l150 151c43 42 71 26 83 13 16-15 26-42-14-82l-138-139-27 27 138 139c22 21 17 26 14 28-1 2-7 8-29-13l-150-151c-7-7-15-17-16-28-1-9 4-19 14-30 13-13 23-12 26-11 9 1 19 7 30 18 13 12 167 166 178 178 15 15 24 29 28 42 5 20-1 38-20 57-19 19-51 40-98-8l-165-165c-8-7-20-7-27 0-8 8-8 20 0 27l165 165c51 51 106 54 152 8 36-36 36-71 30-94-6-20-18-39-38-59-11-12-166-166-178-178-17-17-34-26-51-29-3 0-6-1-9-1z"/>
<glyph unicode="&#69;" d="M402 165c0-5-2-10-5-13-4-4-8-6-13-6l-256 0c-5 0-9 2-13 6-3 3-5 8-5 13 0 5 2 9 5 12l128 128c4 4 8 6 13 6 5 0 9-2 13-6l128-128c3-3 5-7 5-12z"/>
<glyph unicode="&#70;" d="M402 311c0-5-2-9-5-13l-128-128c-4-4-8-5-13-5-5 0-9 1-13 5l-128 128c-3 4-5 8-5 13 0 5 2 9 5 13 4 3 8 5 13 5l256 0c5 0 9-2 13-5 3-4 5-8 5-13z"/>
<glyph unicode="&#71;" d="M128 384l64 0 0-64-64 0z m0-96l64 0 0-64-64 0z m0-96l64 0 0-64-64 0z m128 0l128 0 0-64-128 0z m224 320l-448 0c-18 0-32-14-32-32l0-448c0-18 14-32 32-32l448 0c18 0 32 14 32 32l0 448c0 18-14 32-32 32z m-32-448l-384 0 0 384 384 0z m-192 224l128 0 0-64-128 0z m0 96l128 0 0-64-128 0z"/>
<glyph unicode="&#72;" d="M184 20c0 0 0 54 0 54 0 0 144 0 144 0 0 0 0-54 0-54-24-14-48-21-73-20-23-1-47 6-71 20m141 84c0 0-138 0-138 0 0 25-6 49-19 72-12 23-25 43-40 58-14 15-26 34-37 57-11 23-16 47-14 71 3 41 19 77 48 106 30 29 73 44 130 44 58 0 102-15 131-44 29-29 45-65 49-106 1-20-2-39-9-57-6-18-15-35-26-50-11-14-22-29-33-43-12-14-21-31-30-49-8-19-12-38-12-59m-193 254c-2-1-2-4 0-10 1-5 1-9 1-10-1-1 0-5 2-10 3-5 4-8 3-9 0-1 1-4 4-9 3-5 5-9 6-10 1-1 3-5 7-10 3-5 6-8 7-9 1-2 3-5 7-11 5-6 7-10 9-12 30-42 49-78 57-108 0 0 42 0 42 0 8 32 27 68 57 108 2 2 6 8 13 18 7 10 12 16 13 18 1 3 4 8 9 15 4 8 7 13 8 17 1 4 2 9 3 14 1 6 1 12 0 18-5 67-47 101-125 101-77 0-118-34-123-101"/>
<glyph unicode="&#73;" d="M480 224l-64 0c-18 0-32 14-32 32 0 18 14 32 32 32l64 0c18 0 32-14 32-32 0-18-14-32-32-32z m-88 122c-13-12-33-12-45 0-13 13-13 33 0 46l45 45c12 12 33 12 45 0 13-13 13-33 0-45z m-136-346c-18 0-32 14-32 32l0 64c0 18 14 32 32 32 18 0 32-14 32-32l0-64c0-18-14-32-32-32z m0 384c-18 0-32 14-32 32l0 64c0 18 14 32 32 32 18 0 32-14 32-32l0-64c0-18-14-32-32-32z m-136-309c-12-13-32-13-45 0-12 12-12 33 0 45l45 45c13 13 33 13 46 0 12-12 12-32 0-45z m0 271l-45 46c-12 12-12 32 0 45 13 12 33 12 45 0l46-45c12-13 12-33 0-46-13-12-33-12-46 0z m8-90c0-18-14-32-32-32l-64 0c-18 0-32 14-32 32 0 18 14 32 32 32l64 0c18 0 32-14 32-32z m264-91l45-45c13-12 13-33 0-45-12-13-33-13-45 0l-45 45c-13 13-13 33 0 45 12 13 32 13 45 0z"/>
<glyph unicode="&#74;" d="M184 54l24 145c1 3 0 5-2 7 0 0 0 0 0 0-2 2-5 3-7 3l-145-25c-3 0-5-2-6-5-1-3 0-7 2-9l28-28-76-76c-3-3-3-8 0-11l53-53c3-3 8-3 11 0l76 76 28-28c3-2 6-3 9-2 3 1 5 3 5 6z m144 404l-24-145c-1-3 0-5 2-7 0 0 0 0 0 0 2-2 5-3 7-3l145 25c3 0 5 2 6 5 1 3 0 7-2 9l-28 28 76 76c3 3 3 8 0 11l-53 53c-3 3-8 3-11 0l-76-76-28 28c-3 2-6 3-9 2-3-1-5-3-5-6z m130-274l-145 24c-3 1-5 0-7-2 0 0 0 0 0 0-2-2-3-5-3-7l25-145c0-3 2-5 5-6 3-1 7 0 9 2l28 28 76-76c3-3 8-3 11 0l53 53c3 3 3 8 0 11l-76 76 28 28c2 3 3 6 2 9-1 3-3 5-6 5z m-404 144l145-24c3-1 5 0 7 2 0 0 0 0 0 0 2 2 3 5 3 7l-25 145c0 3-2 5-5 6-3 1-6 0-9-2l-28-28-76 76c-3 3-8 3-11 0l-53-53c-3-3-3-8 0-11l76-76-28-28c-2-3-3-6-2-9 1-3 3-5 6-5z"/>
<glyph unicode="&#75;" d="M24 154l-24-144c0-3 1-6 2-8 0 0 0 0 0 0 2-1 5-2 8-2l144 25c3 0 6 2 6 5 1 3 1 6-2 8l-28 29 76 75c3 4 3 9 0 12l-52 52c-3 4-9 4-12 0l-76-75-28 28c-2 2-5 3-8 2-3-1-5-4-6-7z m464 204l24 144c0 3-1 6-2 8 0 0 0 0 0 0-2 1-5 2-8 2l-144-25c-3 0-6-2-6-5-1-3-1-6 2-8l28-29-76-75c-3-4-3-9 0-12l52-52c3-4 9-4 12 0l76 75 28-28c2-2 5-3 8-2 3 1 5 4 6 7z m-130-334l144-24c3 0 6 1 8 2 0 0 0 0 0 0 1 2 2 5 2 8l-25 144c0 3-2 6-5 6-3 1-6 1-8-2l-29-28-75 76c-4 3-9 3-12 0l-52-52c-4-3-4-9 0-12l75-76-28-28c-2-2-3-5-2-8 1-3 4-5 7-6z m-204 464l-144 24c-3 0-6-1-8-2 0 0 0 0 0 0-1-2-2-5-2-8l25-144c0-3 2-6 5-6 3-1 6-1 8 2l29 28 75-76c4-3 9-3 12 0l52 52c4 3 4 9 0 12l-75 76 28 28c2 2 3 5 2 8-1 3-4 5-7 6z"/>
<glyph unicode="&#76;" d="M435 486c8 0 14-2 19-7 4-5 7-11 7-18 0 0 0-435 0-435 0 0-103 0-103 0 0 0 0 435 0 435 0 17 7 25 21 25 0 0 56 0 56 0m-153-153c7 0 13-3 18-8 5-5 7-11 7-18 0 0 0-281 0-281 0 0-102 0-102 0 0 0 0 281 0 281 0 17 7 26 20 26 0 0 57 0 57 0m-154-154c8 0 14-2 18-7 5-6 8-12 8-18 0 0 0-128 0-128 0 0-103 0-103 0 0 0 0 128 0 128 0 17 7 25 21 25 0 0 56 0 56 0"/>
<glyph unicode="&#77;" d="M384 64l-320 0 0 288 320 0 0-96 32 0 0 160c0 17-14 32-32 32l-96 0c0 35-28 64-64 64-35 0-64-29-64-64l-96 0c-17 0-32-15-32-32l0-352c0-18 15-32 32-32l320 0c18 0 32 14 32 32l0 64-32 0z m-256 352c15 0 15 0 32 0 18 0 32 14 32 32 0 17 15 32 32 32 18 0 32-15 32-32 0-18 16-32 32-32 16 0 17 0 32 0 16 0 32-15 32-32l-256 0c0 19 14 32 32 32z m-32-256l64 0 0 32-64 0z m224 64l0 64-128-96 128-96 0 64 160 0 0 64z m-224-128l96 0 0 32-96 0z m160 224l-160 0 0-32 160 0z m-96-64l-64 0 0-32 64 0z"/>
<glyph unicode="&#101;" d="M0 510l0-508 512 0 0 508z m52-51l409 0 0-408-409 0z m32-86l344 0 0-35-344 0z m0-68l344 0 0-35-344 0z m0-67l344 0 0-36-344 0z m0-68l344 0 0-35-344 0z"/>
<glyph unicode="&#102;" d="M329 256c0 20-7 37-21 52-15 14-32 21-52 21-20 0-37-7-52-21-14-15-21-32-21-52 0-20 7-37 21-52 15-14 32-21 52-21 20 0 37 7 52 21 14 15 21 32 21 52z m146 31l0-63c0-3 0-5-2-7-1-2-3-3-6-4l-52-8c-4-10-8-19-12-26 7-9 17-22 31-39 2-2 3-5 3-7 0-3-1-5-3-7-5-7-14-17-28-31-14-13-23-20-27-20-2 0-5 1-7 3l-40 31c-8-5-17-8-26-11-3-26-6-44-8-53-1-6-5-8-10-8l-64 0c-2 0-5 0-7 2-2 2-3 4-3 6l-8 53c-9 3-18 6-26 10l-40-30c-2-2-4-3-7-3-3 0-5 1-7 3-24 22-40 38-47 48-2 2-2 4-2 7 0 2 0 4 2 6 3 4 8 11 14 19 7 9 12 16 16 21-5 9-9 19-12 28l-52 8c-3 0-5 1-6 3-2 2-2 4-2 7l0 63c0 3 0 5 2 7 1 2 3 3 5 4l53 8c3 8 7 17 12 26-8 11-18 24-31 39-2 3-3 5-3 7 0 2 1 4 3 7 5 7 14 17 28 30 14 14 23 21 27 21 2 0 5-1 7-3l40-31c8 5 17 8 26 11 3 26 6 44 8 53 1 6 5 8 10 8l64 0c2 0 5 0 7-2 2-2 3-4 3-6l8-53c9-3 18-6 26-10l40 30c2 2 4 3 7 3 3 0 5-1 7-3 25-23 41-39 47-49 2-1 2-3 2-6 0-2 0-4-2-6-3-4-8-11-14-19-7-9-12-16-16-21 5-9 9-18 12-28l52-8c3 0 5-1 6-3 2-2 2-4 2-7z"/>
<glyph unicode="&#103;" d="M512 174l0-55c0-3-1-5-3-7-2-1-4-2-6-2l-393 0 0-55c0-3-1-5-3-7-2-1-4-2-6-2-3 0-5 1-7 3l-91 91c-2 2-3 4-3 6 0 3 1 5 3 7l91 91c2 2 4 3 7 3 2 0 4-1 6-3 2-2 3-4 3-6l0-55 393 0c2 0 4-1 6-3 2-2 3-4 3-6z m0 155c0-3-1-5-3-6l-91-92c-2-2-4-2-7-2-2 0-4 0-6 2-2 2-3 4-3 7l0 55-393 0c-2 0-4 0-6 2-2 2-3 4-3 7l0 55c0 2 1 4 3 6 2 2 4 3 6 3l393 0 0 55c0 2 1 4 3 6 2 2 4 3 6 3 3 0 5-1 7-3l91-91c2-2 3-4 3-7z"/>
<glyph unicode="&#104;" d="M456 428c3-8 2-15-4-20l-141-141 0-212c0-8-4-14-11-17-3-1-5-1-7-1-6 0-10 1-13 5l-73 73c-4 4-6 8-6 13l0 139-141 141c-6 5-7 12-4 20 4 7 9 11 17 11l366 0c8 0 13-4 17-11z"/>
<glyph unicode="&#105;" d="M399 174c0-3-1-5-3-7l-15-14c-1-2-4-3-6-3-3 0-5 1-7 3l-112 112-112-112c-2-2-4-3-7-3-2 0-5 1-6 3l-15 14c-2 2-3 4-3 7 0 2 1 4 3 6l133 133c2 2 5 3 7 3 2 0 5-1 7-3l133-133c2-2 3-4 3-6z"/>
<glyph unicode="&#106;" d="M335 238c0-3-1-5-3-7l-133-133c-2-2-5-3-7-3-2 0-5 1-7 3l-14 14c-2 2-3 4-3 7 0 2 1 5 3 6l112 113-112 112c-2 2-3 4-3 7 0 2 1 4 3 6l14 14c2 2 5 3 7 3 2 0 5-1 7-3l133-133c2-2 3-4 3-6z"/>
<glyph unicode="&#107;" d="M344 357c0-3-1-5-3-7l-112-112 112-113c2-1 3-4 3-6 0-3-1-5-3-7l-14-14c-2-2-5-3-7-3-2 0-5 1-7 3l-133 133c-2 2-3 4-3 7 0 2 1 4 3 6l133 133c2 2 5 3 7 3 2 0 5-1 7-3l14-14c2-2 3-4 3-6z"/>
<glyph unicode="&#108;" d="M399 302c0-3-1-5-3-7l-133-133c-2-2-5-3-7-3-2 0-5 1-7 3l-133 133c-2 2-3 4-3 7 0 2 1 4 3 6l15 15c1 1 4 2 6 2 3 0 5-1 7-2l112-113 112 113c2 1 4 2 7 2 2 0 5-1 6-2l15-15c2-2 3-4 3-6z"/>
<glyph unicode="&#109;" d="M455 362l-93 93c-5 5-14 5-20 0l-253-254 1 0-1 0-35-130 0 0c-2-4 0-10 3-14 5-4 11-5 16-2l0 0 128 34 0 0 0 0 254 254c5 5 5 14 0 19z m-359-265l21 76 56-56z"/>
<glyph unicode="&#110;" d="M434 160l-96 96 96 96c4 4 4 10 0 14l-68 68c-4 4-10 4-14 0l-96-96-96 96c-4 4-11 4-14 0l-68-68c-2-1-3-4-3-7 0-2 1-5 3-7l96-96-96-96c-2-2-3-5-3-7 0-3 1-6 3-7l68-68c1-2 4-3 7-3 2 0 5 1 7 3l96 96 96-96c2-2 5-3 7-3 3 0 5 1 7 3l68 68c4 4 4 10 0 14z"/>
<glyph unicode="&#111;" d="M364 364c-17 6-31 20-35 38l-36 0c5-34 28-61 59-71 21-7 36-27 36-50l0-18-226 0 0-88-36 0 0 106c0 23 15 43 36 50 31 10 54 37 59 71l-36 0c-5-18-18-32-35-38-34-12-59-45-59-83l0-246c0-20 16-37 36-37l259 0 0 1c21 0 37 16 37 36l0 246c0 38-25 71-59 83z m-101-133c28 0 51-22 51-50 0-15-6-28-16-37-1-2-2-3-2-5l0-2c0-2-1-4-2-4-9-6-18-9-28-9l-5 0c-10 0-20 3-28 9-1 0-2 2-2 4l0 2c0 2-1 3-2 5-10 9-16 22-16 37 0 28 22 50 50 50z m64-136c-3 0-6 2-8 4l-31-11 25-9c2 3 6 5 9 5 6 0 11-4 11-10 0-3-2-6-4-7 1-2 1-3 1-5 0-6-5-12-11-12-7 0-12 6-12 12 0 0 0 1 0 1l-43 16-45-16c0 0 0-1 0-1 0-6-6-12-12-12-7 0-12 6-12 12 0 2 1 3 1 5-2 1-3 4-3 7 0 6 5 10 10 10 4 0 7-2 9-5l27 9-27 10c-2-2-4-4-7-4-6 0-10 4-10 10 0 4 3 7 6 8 0 0 0 0 0 0 0 5 4 9 8 9 5 0 8-4 9-8l45-16 51 17c0 5 4 8 8 8 5 0 8-4 8-8l0 0c4-2 6-5 6-9 0-5-4-10-9-10z m-154 327l168 0c2 0 4 1 4 4l0 48c0 2-2 4-4 4l-12 0 0 23c0 3-2 6-6 6l-132 0c-4 0-6-3-6-6l0-23-12 0c-2 0-4-2-4-4l0-48c0-3 2-4 4-4z m82-255c0-7-6-13-13-13-8 0-14 6-14 13 0 7 6 13 14 13 7 0 13-6 13-13z m43 0c0-7-6-13-13-13-7 0-13 6-13 13 0 7 6 13 13 13 7 0 13-6 13-13z"/>
<glyph unicode="&#112;" d="M165 302l0-55c0-8-3-14-8-20-6-5-12-8-20-8l-55 0c-7 0-14 3-19 8-5 6-8 12-8 20l0 55c0 7 3 14 8 19 5 5 12 8 19 8l55 0c8 0 14-3 20-8 5-5 8-12 8-19z m146 0l0-55c0-8-3-14-8-20-5-5-12-8-20-8l-54 0c-8 0-15 3-20 8-5 6-8 12-8 20l0 55c0 7 3 14 8 19 5 5 12 8 20 8l54 0c8 0 15-3 20-8 5-5 8-12 8-19z m146 0l0-55c0-8-3-14-8-20-5-5-12-8-19-8l-55 0c-8 0-14 3-20 8-5 6-8 12-8 20l0 55c0 7 3 14 8 19 6 5 12 8 20 8l55 0c7 0 14-3 19-8 5-5 8-12 8-19z"/>
<glyph unicode="&#113;" d="M311 155l0-54c0-8-3-15-8-20-5-5-12-8-20-8l-54 0c-8 0-15 3-20 8-5 5-8 12-8 20l0 54c0 8 3 15 8 20 5 5 12 8 20 8l54 0c8 0 15-3 20-8 5-5 8-12 8-20z m0 147l0-55c0-8-3-14-8-20-5-5-12-8-20-8l-54 0c-8 0-15 3-20 8-5 6-8 12-8 20l0 55c0 7 3 14 8 19 5 5 12 8 20 8l54 0c8 0 15-3 20-8 5-5 8-12 8-19z m0 146l0-55c0-7-3-14-8-19-5-6-12-8-20-8l-54 0c-8 0-15 2-20 8-5 5-8 12-8 19l0 55c0 8 3 14 8 19 5 6 12 8 20 8l54 0c8 0 15-2 20-8 5-5 8-11 8-19z"/>
<glyph unicode="&#114;" d="M366 174l0-19c0-2-1-4-3-6-2-2-4-3-6-3l-202 0c-2 0-4 1-6 3-2 2-3 4-3 6l0 19c0 2 1 5 3 6 2 2 4 3 6 3l202 0c2 0 4-1 6-3 2-1 3-4 3-6z m0 73l0-18c0-3-1-5-3-7-2-2-4-3-6-3l-202 0c-2 0-4 1-6 3-2 2-3 4-3 7l0 18c0 3 1 5 3 6 2 2 4 3 6 3l202 0c2 0 4-1 6-3 2-1 3-3 3-6z m-256-174l292 0 0 220-119 0c-7 0-14 2-19 8-5 5-8 11-8 19l0 119-146 0z m183 256l107 0c-2 6-4 10-6 12l-90 89c-2 3-6 5-11 7z m146-9l0-256c0-8-3-14-8-19-5-6-12-8-20-8l-310 0c-8 0-15 2-20 8-5 5-8 11-8 19l0 384c0 8 3 14 8 19 5 6 12 8 20 8l182 0c8 0 16-1 26-5 9-4 16-9 21-14l89-89c6-5 10-13 14-22 4-9 6-17 6-25z"/>
<glyph unicode="&#115;" d="M432 309l-123 0 0 123c0 5-5 10-10 10l-86 0c-5 0-10-5-10-10l0-123-123 0c-5 0-10-5-10-10l0-86c0-3 1-5 3-7 2-2 4-3 7-3l123 0 0-123c0-3 1-5 3-7 2-2 4-3 7-3l86 0c3 0 5 1 7 3 2 2 3 4 3 7l0 123 123 0c3 0 5 1 7 3 2 2 3 4 3 7l0 86c0 5-5 10-10 10z"/>
<glyph unicode="&#116;" d="M468 210c0-1 0-1 0-2-12-51-38-92-77-124-38-32-84-47-136-47-28 0-55 5-81 15-26 11-49 26-69 45l-37-37c-4-3-8-5-13-5-5 0-9 2-13 5-4 4-5 8-5 13l0 128c0 5 1 9 5 13 4 4 8 5 13 5l128 0c5 0 9-1 13-5 3-4 5-8 5-13 0-5-2-9-5-13l-39-39c13-12 28-22 46-29 17-7 35-10 53-10 26 0 49 6 71 18 23 13 40 30 54 51 2 4 7 15 15 34 1 4 4 6 8 6l55 0c3 0 5 0 7-2 1-2 2-4 2-7z m7 229l0-128c0-5-1-9-5-13-4-4-8-5-13-5l-128 0c-5 0-9 1-13 5-3 4-5 8-5 13 0 5 2 9 5 13l40 39c-28 26-62 39-100 39-26 0-49-6-71-18-23-13-40-30-54-51-2-4-7-15-15-34-1-4-4-6-8-6l-57 0c-3 0-5 0-7 2-1 2-2 4-2 7l0 2c12 51 38 92 77 124 39 32 85 47 137 47 28 0 55-5 81-15 26-11 50-26 70-45l37 37c4 3 8 5 13 5 5 0 9-2 13-5 4-4 5-8 5-13z"/>
<glyph unicode="&#117;" d="M256 475c40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110 0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29z m37-356l0 54c0 3-1 5-3 7-2 2-4 3-6 3l-55 0c-3 0-5-1-7-3-2-2-3-4-3-7l0-54c0-2 1-5 3-6 2-2 4-3 7-3l55 0c2 0 4 1 6 2 2 2 3 4 3 7z m-1 98l5 178c0 2-1 4-3 5-2 2-4 2-7 2l-62 0c-3 0-5 0-7-2-2-1-3-3-3-5l5-178c0-1 1-3 3-5 1-1 4-2 6-2l53 0c3 0 5 1 7 2 2 2 3 4 3 5z"/>
<glyph unicode="&#118;" d="M350 204l-42-42c-2-2-4-3-6-3-3 0-5 1-7 3l-39 39-39-39c-2-2-4-3-7-3-2 0-4 1-6 3l-42 42c-2 2-3 4-3 6 0 3 1 5 3 7l39 39-39 39c-2 2-3 4-3 7 0 2 1 4 3 6l42 42c2 2 4 3 6 3 3 0 5-1 7-3l39-39 39 39c2 2 4 3 7 3 2 0 4-1 6-3l42-42c2-2 3-4 3-6 0-3-1-5-3-7l-39-39 39-39c2-2 3-4 3-7 0-2-1-4-3-6z m61 52c0 28-7 54-20 78-14 24-33 43-57 57-24 13-50 20-78 20-28 0-54-7-78-20-24-14-43-33-57-57-13-24-20-50-20-78 0-28 7-54 20-78 14-24 33-43 57-57 24-13 50-20 78-20 28 0 54 7 78 20 24 14 43 33 57 57 13 24 20 50 20 78z m64 0c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
<glyph unicode="&#119;" d="M201 165c0-8-1-16-3-24-3-8-7-15-13-22-6-6-12-9-20-9-8 0-15 3-21 9-6 7-10 14-12 22-3 8-4 16-4 24 0 7 1 15 4 23 2 8 6 15 12 22 6 6 13 9 21 9 8 0 14-3 20-9 6-7 10-14 13-22 2-8 3-16 3-23z m183 0c0-8-1-16-4-24-2-8-6-15-12-22-6-6-13-9-21-9-8 0-14 3-20 9-6 7-10 14-13 22-2 8-3 16-3 24 0 7 1 15 3 23 3 8 7 15 13 22 6 6 12 9 20 9 8 0 15-3 21-9 6-7 10-14 12-22 3-8 4-16 4-23z m46 0c0 22-7 42-20 58-13 16-31 24-53 24-8 0-27-2-56-6-14-2-29-3-45-3-16 0-31 1-45 3-29 4-47 6-56 6-22 0-40-8-53-24-13-16-20-36-20-58 0-17 3-32 9-44 7-13 14-23 24-30 9-7 21-13 34-17 14-4 28-7 40-8 13-2 27-2 43-2l48 0c16 0 30 0 43 2 12 1 26 4 40 8 13 4 25 10 34 17 10 7 17 17 24 30 6 12 9 27 9 44z m64 50c0-40-6-71-18-95-7-14-17-27-30-38-13-10-26-19-40-24-14-6-30-11-49-14-18-3-34-5-49-6-14-1-30-1-47-1-15 0-29 0-41 0-12 1-26 2-42 4-16 2-31 5-44 9-13 3-26 8-39 14-13 6-24 14-34 23-11 10-19 21-25 33-12 24-18 55-18 95 0 45 13 83 39 113-5 16-8 32-8 49 0 22 5 42 15 62 21 0 39-4 54-11 16-8 34-20 54-36 28 7 58 10 89 10 28 0 54-3 80-9 20 16 37 27 53 35 16 7 34 11 54 11 10-20 15-40 15-62 0-17-3-33-8-48 26-31 39-69 39-114z"/>
<glyph unicode="&#120;" d="M232 141l176 175c3 4 5 8 5 13 0 5-2 9-5 13l-29 29c-4 4-8 6-13 6-5 0-10-2-13-6l-134-133-60 60c-3 4-8 5-13 5-5 0-9-1-13-5l-29-29c-3-4-5-8-5-13 0-5 2-9 5-13l103-102c3-4 7-6 12-6 5 0 10 2 13 6z m243 252l0-274c0-23-8-42-24-58-16-16-35-24-58-24l-274 0c-23 0-42 8-58 24-16 16-24 35-24 58l0 274c0 23 8 42 24 58 16 16 35 24 58 24l274 0c23 0 42-8 58-24 16-16 24-35 24-58z"/>
<glyph unicode="&#121;" d="M256 484c-126 0-228-102-228-228 0-126 102-228 228-228 126 0 228 102 228 228 0 126-102 228-228 228z m0-399c-94 0-171 77-171 171 0 94 77 171 171 171 94 0 171-77 171-171 0-94-77-171-171-171z m-2 312c-23-2-40-23-37-46l12-118c2-13 12-24 26-26 16-1 30 10 31 26l13 118c0 3 0 6 0 8-2 23-22 40-45 38z m-21-220c-7-7-11-16-11-25 0-10 4-19 11-26 7-6 16-10 25-10 9 0 19 4 25 10 7 7 11 16 11 26 0 9-4 18-11 25-13 13-37 13-50 0z"/>
<glyph unicode="&#122;" d="M388 461c0 0 73-80 73-80 0 0 0-279 0-279 0-13-5-25-15-35-10-11-22-16-36-16 0 0-308 0-308 0-13 0-25 5-35 16-11 10-16 22-16 35 0 0 0 308 0 308 0 14 5 26 16 36 10 10 22 15 35 15 0 0 286 0 286 0m-30-154c0 0 0 128 0 128 0 0-204 0-204 0 0 0 0-128 0-128 0-7 2-13 7-18 5-5 11-7 18-7 0 0 154 0 154 0 7 0 13 2 18 7 5 5 7 11 7 18m-25 103c0 0 0-103 0-103 0 0-51 0-51 0 0 0 0 103 0 103 0 0 51 0 51 0"/>
<glyph unicode="&#65;" d="M453 425c-1 9-8 16-17 16l-360 0 0 0c-9 0-16-7-17-16l0 0 0-288 0 0c2-8 9-14 17-14l0 0 59 0 0-35c0-9 8-17 17-17 6 0 11 3 14 8l45 44 225 0c8 0 15 6 17 14l0 0 0 288z"/>
<glyph unicode="&#66;" d="M411 448l0 0 0 21c0 4-4 8-9 8l-168 0-133-132 0-302c0-4 4-8 9-8l292 0c5 0 9 4 9 8l0 13 0 0z m-259-362l0 241 91 0c5 0 9 4 9 9l0 90 108 0 0-340z"/>
<glyph unicode="&#67;" d="M155 59c-14 0-32 5-50 23-24 24-27 47-25 62 2 17 11 34 27 50l150 151c43 42 71 26 83 13 16-15 26-42-14-82l-138-139-27 27 138 139c22 21 17 26 14 28-1 2-7 8-29-13l-150-151c-7-7-15-17-16-28-1-9 4-19 14-30 13-13 23-12 26-11 9 1 19 7 30 18 13 12 167 166 178 178 15 15 24 29 28 42 5 20-1 38-20 57-19 19-51 40-98-8l-165-165c-8-7-20-7-27 0-8 8-8 20 0 27l165 165c51 51 106 54 152 8 36-36 36-71 30-94-6-20-18-39-38-59-11-12-166-166-178-178-17-17-34-26-51-29-3 0-6-1-9-1z"/>
<glyph unicode="&#68;" d="M402 165c0-5-2-10-5-13-4-4-8-6-13-6l-256 0c-5 0-9 2-13 6-3 3-5 8-5 13 0 5 2 9 5 12l128 128c4 4 8 6 13 6 5 0 9-2 13-6l128-128c3-3 5-7 5-12z"/>
<glyph unicode="&#69;" d="M402 311c0-5-2-9-5-13l-128-128c-4-4-8-5-13-5-5 0-9 1-13 5l-128 128c-3 4-5 8-5 13 0 5 2 9 5 13 4 3 8 5 13 5l256 0c5 0 9-2 13-5 3-4 5-8 5-13z"/>
<glyph unicode="&#70;" d="M128 384l64 0 0-64-64 0z m0-96l64 0 0-64-64 0z m0-96l64 0 0-64-64 0z m128 0l128 0 0-64-128 0z m224 320l-448 0c-18 0-32-14-32-32l0-448c0-18 14-32 32-32l448 0c18 0 32 14 32 32l0 448c0 18-14 32-32 32z m-32-448l-384 0 0 384 384 0z m-192 224l128 0 0-64-128 0z m0 96l128 0 0-64-128 0z"/>
<glyph unicode="&#71;" d="M184 20c0 0 0 54 0 54 0 0 144 0 144 0 0 0 0-54 0-54-24-14-48-21-73-20-23-1-47 6-71 20m141 84c0 0-138 0-138 0 0 25-6 49-19 72-12 23-25 43-40 58-14 15-26 34-37 57-11 23-16 47-14 71 3 41 19 77 48 106 30 29 73 44 130 44 58 0 102-15 131-44 29-29 45-65 49-106 1-20-2-39-9-57-6-18-15-35-26-50-11-14-22-29-33-43-12-14-21-31-30-49-8-19-12-38-12-59m-193 254c-2-1-2-4 0-10 1-5 1-9 1-10-1-1 0-5 2-10 3-5 4-8 3-9 0-1 1-4 4-9 3-5 5-9 6-10 1-1 3-5 7-10 3-5 6-8 7-9 1-2 3-5 7-11 5-6 7-10 9-12 30-42 49-78 57-108 0 0 42 0 42 0 8 32 27 68 57 108 2 2 6 8 13 18 7 10 12 16 13 18 1 3 4 8 9 15 4 8 7 13 8 17 1 4 2 9 3 14 1 6 1 12 0 18-5 67-47 101-125 101-77 0-118-34-123-101"/>
<glyph unicode="&#72;" d="M480 224l-64 0c-18 0-32 14-32 32 0 18 14 32 32 32l64 0c18 0 32-14 32-32 0-18-14-32-32-32z m-88 122c-13-12-33-12-45 0-13 13-13 33 0 46l45 45c12 12 33 12 45 0 13-13 13-33 0-45z m-136-346c-18 0-32 14-32 32l0 64c0 18 14 32 32 32 18 0 32-14 32-32l0-64c0-18-14-32-32-32z m0 384c-18 0-32 14-32 32l0 64c0 18 14 32 32 32 18 0 32-14 32-32l0-64c0-18-14-32-32-32z m-136-309c-12-13-32-13-45 0-12 12-12 33 0 45l45 45c13 13 33 13 46 0 12-12 12-32 0-45z m0 271l-45 46c-12 12-12 32 0 45 13 12 33 12 45 0l46-45c12-13 12-33 0-46-13-12-33-12-46 0z m8-90c0-18-14-32-32-32l-64 0c-18 0-32 14-32 32 0 18 14 32 32 32l64 0c18 0 32-14 32-32z m264-91l45-45c13-12 13-33 0-45-12-13-33-13-45 0l-45 45c-13 13-13 33 0 45 12 13 32 13 45 0z"/>
<glyph unicode="&#73;" d="M184 54l24 145c1 3 0 5-2 7 0 0 0 0 0 0-2 2-5 3-7 3l-145-25c-3 0-5-2-6-5-1-3 0-7 2-9l28-28-76-76c-3-3-3-8 0-11l53-53c3-3 8-3 11 0l76 76 28-28c3-2 6-3 9-2 3 1 5 3 5 6z m144 404l-24-145c-1-3 0-5 2-7 0 0 0 0 0 0 2-2 5-3 7-3l145 25c3 0 5 2 6 5 1 3 0 7-2 9l-28 28 76 76c3 3 3 8 0 11l-53 53c-3 3-8 3-11 0l-76-76-28 28c-3 2-6 3-9 2-3-1-5-3-5-6z m130-274l-145 24c-3 1-5 0-7-2 0 0 0 0 0 0-2-2-3-5-3-7l25-145c0-3 2-5 5-6 3-1 7 0 9 2l28 28 76-76c3-3 8-3 11 0l53 53c3 3 3 8 0 11l-76 76 28 28c2 3 3 6 2 9-1 3-3 5-6 5z m-404 144l145-24c3-1 5 0 7 2 0 0 0 0 0 0 2 2 3 5 3 7l-25 145c0 3-2 5-5 6-3 1-6 0-9-2l-28-28-76 76c-3 3-8 3-11 0l-53-53c-3-3-3-8 0-11l76-76-28-28c-2-3-3-6-2-9 1-3 3-5 6-5z"/>
<glyph unicode="&#74;" d="M24 154l-24-144c0-3 1-6 2-8 0 0 0 0 0 0 2-1 5-2 8-2l144 25c3 0 6 2 6 5 1 3 1 6-2 8l-28 29 76 75c3 4 3 9 0 12l-52 52c-3 4-9 4-12 0l-76-75-28 28c-2 2-5 3-8 2-3-1-5-4-6-7z m464 204l24 144c0 3-1 6-2 8 0 0 0 0 0 0-2 1-5 2-8 2l-144-25c-3 0-6-2-6-5-1-3-1-6 2-8l28-29-76-75c-3-4-3-9 0-12l52-52c3-4 9-4 12 0l76 75 28-28c2-2 5-3 8-2 3 1 5 4 6 7z m-130-334l144-24c3 0 6 1 8 2 0 0 0 0 0 0 1 2 2 5 2 8l-25 144c0 3-2 6-5 6-3 1-6 1-8-2l-29-28-75 76c-4 3-9 3-12 0l-52-52c-4-3-4-9 0-12l75-76-28-28c-2-2-3-5-2-8 1-3 4-5 7-6z m-204 464l-144 24c-3 0-6-1-8-2 0 0 0 0 0 0-1-2-2-5-2-8l25-144c0-3 2-6 5-6 3-1 6-1 8 2l29 28 75-76c4-3 9-3 12 0l52 52c4 3 4 9 0 12l-75 76 28 28c2 2 3 5 2 8-1 3-4 5-7 6z"/>
<glyph unicode="&#75;" d="M435 486c8 0 14-2 19-7 4-5 7-11 7-18 0 0 0-435 0-435 0 0-103 0-103 0 0 0 0 435 0 435 0 17 7 25 21 25 0 0 56 0 56 0m-153-153c7 0 13-3 18-8 5-5 7-11 7-18 0 0 0-281 0-281 0 0-102 0-102 0 0 0 0 281 0 281 0 17 7 26 20 26 0 0 57 0 57 0m-154-154c8 0 14-2 18-7 5-6 8-12 8-18 0 0 0-128 0-128 0 0-103 0-103 0 0 0 0 128 0 128 0 17 7 25 21 25 0 0 56 0 56 0"/>
<glyph unicode="&#76;" d="M384 64l-320 0 0 288 320 0 0-96 32 0 0 160c0 17-14 32-32 32l-96 0c0 35-28 64-64 64-35 0-64-29-64-64l-96 0c-17 0-32-15-32-32l0-352c0-18 15-32 32-32l320 0c18 0 32 14 32 32l0 64-32 0z m-256 352c15 0 15 0 32 0 18 0 32 14 32 32 0 17 15 32 32 32 18 0 32-15 32-32 0-18 16-32 32-32 16 0 17 0 32 0 16 0 32-15 32-32l-256 0c0 19 14 32 32 32z m-32-256l64 0 0 32-64 0z m224 64l0 64-128-96 128-96 0 64 160 0 0 64z m-224-128l96 0 0 32-96 0z m160 224l-160 0 0-32 160 0z m-96-64l-64 0 0-32 64 0z"/>
<glyph unicode="&#77;" d="M1 454l0-396c0-32 25-57 57-57l396 0c32 0 57 25 57 57l0 396c0 32-25 57-57 57l-396 0c-32 0-57-25-57-57z m340-113c0-47-38-85-85-85-47 0-85 38-85 85 0 47 38 85 85 85 47 0 85-38 85-85z m-255-227c0 57 113 88 170 88 57 0 170-31 170-88l0-28-340 0z"/>
<glyph unicode="&#78;" d="M125 68l40-41 91 91 91-91 40 41-131 131z m262 376l-40 41-91-91-91 91-40-41 131-131z"/>
<glyph unicode="&#79;" d="M256 435l87-88 39 39-126 126-126-126 39-39z m0-358l-87 88-39-39 126-126 126 126-39 39z"/>
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Binary file not shown.

BIN
app/images/github-help.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,95 @@
block head
title Taiga Your agile, free, and open source project management tool
block content
div.wrapper.roles(tg-github-webhooks, ng-controller="GithubController as ctrl",
ng-init="section='admin'")
sidebar.menu-secondary.sidebar(tg-admin-navigation="third-parties")
include views/modules/admin-menu
sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-github")
include views/modules/admin-submenu-third-parties
section.main.admin-common.admin-third-parties
include views/components/mainTitle
form
fieldset
label(for="secret-key") Secret key
input(type="text", name="secret-key", ng-model="github.secret", placeholder="Secret key", id="secret-key")
fieldset
.select-input-text(tg-select-input-text)
div
label(for="payload-url") Payload URL
.field-with-option
input(type="text", ng-model="github.webhooks_url", name="payload-url", readonly="readonly", placeholder="Payload URL", id="payload-url")
.option-wrapper.select-input-content
.icon.icon-copy
.help-copy Copy to clipboard: Ctrl+C
input(type="submit", class="hidden")
a.button.button-green(href="") Save
.help
h2 How to use it
h3 Configure Taiga
ol
li Fill
span Secret key
| or use the auto generated one
li Copy the
span Payload URL field.
h3 Configure Github
ol
li Go to your github repository.
li Click on
span Settings
| >
span Webhooks & Services
| >
span Add webhook
li On that screen set the payload url with the payload url of this screen.
li Secret must be filled with the same content as the secret field of this screen.
li Content type must be
span application/json.
li Taiga currently listen for three different kind of events:
ol
li Push events: changing element status via commit message
li Issues: issues created in github appear automatically in Taiga
li Issue comment: issue comments created in github appear automatically in Taiga
p Just check "send me everything" or just the events you want Taiga to listen for.
.img
.alt-image Github Webhooke page
img(src="/images/github-help.png", alt="webhook")
h2 Changing elements status via commit message
p
| The status of any issue, task or user story can be changed via commit message.
| Just add to your commit message something like:
code
| TG-REF #STATUS
ul.code-info
li
span REF:
| US/Issue/Task reference of the element you want to modify
li
span STATUS:
| New status slug to set, you can find all of them in:
a(href="", tg-nav="project-admin-project-values-us-status:project=project.slug") US STATUSES.
h3 An example please!
code
| TG-123 #closed
p In this example, 123 is an issue reference and with this command, the issue will change its status to closed.

View File

@ -23,6 +23,10 @@ block content
tg-nav="project-userstories-detail:project=project.slug, ref=us.ref")
span(tg-bo-ref="us.ref")
p.external-reference(ng-if="issue.external_reference") This issue has been created from
a(target="_blank", tg-bo-href="issue.external_reference[1]", title="Go to origin")
span {{ issue.external_reference[1] }}
p.block-desc-container(ng-show="issue.is_blocked")
span.block-description-title Blocked
span.block-description(ng-bind="issue.blocked_note || 'This issue is blocked'")

View File

@ -21,12 +21,18 @@ block content
h2.us-title-text
span.us-number(tg-bo-ref="task.ref")
span.us-name(tg-editable-subject, ng-model="task", required-perm="modify_task")
h3.us-related-task This task belongs to
a(tg-check-permission="view_us", href="", title="Go to user story",
tg-nav="project-userstories-detail:project=project.slug, ref=us.ref",
ng-if="us")
span(tg-bo-ref="us.ref")
span(tg-bo-bind="us.subject")
p.external-reference(ng-if="task.external_reference") This task has been created from
a(target="_blank", tg-bo-href="task.external_reference[1]", title="Go to origin")
span {{ task.external_reference[1] }}
p.block-desc-container(ng-show="task.is_blocked")
span.block-description-title Blocked
span.block-description(ng-bind="task.blocked_note || 'This task is blocked'")

View File

@ -28,6 +28,10 @@ block content
tg-bo-title="'#' + us.origin_issue.ref + ' ' + us.origin_issue.subject")
span(tg-bo-ref="us.origin_issue.ref")
p.external-reference(ng-if="us.external_reference") This US has been created from
a(target="_blank", tg-bo-href="us.external_reference[1]", title="Go to origin")
span {{ us.external_reference[1] }}
p.block-desc-container(ng-show="us.is_blocked")
span.block-description-title Blocked
span.block-description(ng-bind="us.blocked_note || 'This user story is blocked'")

View File

@ -20,3 +20,7 @@ section.admin-menu
a(href="" tg-nav="project-admin-roles:project=project.slug")
span.title Roles & Permissions
span.icon.icon-arrow-right
li#adminmenu-third-parties
a(href="" tg-nav="project-admin-third-parties-github:project=project.slug")
span.title Third parties
span.icon.icon-arrow-right

View File

@ -0,0 +1,10 @@
section.admin-submenu
header
h1 Third parties
nav
ul
li#adminmenu-third-parties-github
a(href="", tg-nav="project-admin-third-parties-github:project=project.slug")
span.title Github
span.icon.icon-arrow-right

View File

@ -29,7 +29,7 @@ section.project-values-table
data-required="true")
div.project-values-value
input(name="name", type="text", placeholder="Value", ng-model="value.value",
input(name="value", type="text", placeholder="Value", ng-model="value.value",
data-type="number")
div.project-values-settings

View File

@ -3,6 +3,7 @@ section.colors-table
div.row
div.color-column Color
div.status-name Name
div.status-slug Slug
div.is-closed-column Is closed?
div.options-column
@ -17,6 +18,9 @@ section.colors-table
div.status-name
span {{ value.name }}
div.status-slug
span {{ value.slug }}
div.is-closed-column
div.icon.icon-check-square(ng-show="value.is_closed")

View File

@ -3,6 +3,7 @@ section.colors-table
div.row
div.color-column Color
div.status-name Name
div.status-slug Slug
div.is-closed-column Is closed?
div.status-wip-limit WIP Limit
div.options-column
@ -19,6 +20,9 @@ section.colors-table
div.status-name
span {{ value.name }}
div.status-slug
span {{ value.slug }}
div.is-closed-column
div.icon.icon-check-square(ng-show="value.is_closed")

View File

@ -10,3 +10,5 @@ form.login-form
fieldset
a.button.button-login.button-gray(href="", title="Log in") Enter
input(type="submit", style="display:none")
fieldset(tg-github-login-button)

View File

@ -23,4 +23,4 @@ form.register-form
a.button.button-register.button-gray(href="", title="Sign up") Sign up
input(type="submit", style="display:none")
tg-terms-notice
tg-terms-notice

View File

@ -1,31 +1,36 @@
div.kanban-table
div.kanban-table(tg-kanban-squish-column)
div.kanban-table-header
div.kanban-table-inner(tg-kanban-row-width-fixer)
h2.task-colum-name(ng-repeat="s in usStatusList track by s.id",
ng-style="{'border-top-color':s.color}")
div.kanban-table-inner
h2.task-colum-name(ng-repeat="s in usStatusList track by s.id", ng-style="{'border-top-color':s.color}", tg-bo-title="s.name", ng-class='{vfold:folds[s.id]}')
span(tg-bo-bind="s.name")
div.options
a.icon.icon-minimize(href="", title="Minimize",
ng-if="statusViewModes[s.id] == 'maximized'",
ng-click="ctrl.updateStatusViewMode(s.id, 'minimized')")
a.icon.icon-maximize(href="", title="Maximize",
ng-if="statusViewModes[s.id] == 'minimized'",
ng-click="ctrl.updateStatusViewMode(s.id, 'maximized')")
a.icon.icon-plus(href="", title="Add New task",
ng-click="ctrl.addNewUs('standard', s.id)",
tg-check-permission="add_us")
a.icon.icon-vfold.hfold(href="", ng-click='foldStatus(s)' title="Fold Column", ng-class='{hidden:folds[s.id]}')
a.icon.icon-vunfold.hunfold(href="", ng-click='foldStatus(s)', title="Unfold Column", ng-class='{hidden:!folds[s.id]}')
a.icon.icon-bulk(href="", title="Add New bulk",
ng-click="ctrl.addNewUs('bulk', s.id)",
tg-check-permission="add_us")
a.icon.icon-vfold(href="", title="Fold Cards",
ng-class="{hidden:statusViewModes[s.id] == 'minimized'}",
ng-click="ctrl.updateStatusViewMode(s.id, 'minimized')")
a.icon.icon-vunfold(href="", title="Unfold Cards",
ng-class="{hidden:statusViewModes[s.id] == 'maximized'}",
ng-click="ctrl.updateStatusViewMode(s.id, 'maximized')")
a.icon.icon-plus(href="", title="Add New task",
ng-click="ctrl.addNewUs('standard', s.id)",
tg-check-permission="add_us")
a.icon.icon-bulk(href="", title="Add New bulk",
ng-click="ctrl.addNewUs('bulk', s.id)",
tg-check-permission="add_us")
div.kanban-table-body
div.kanban-table-inner(tg-kanban-row-width-fixer)
div.kanban-uses-box.task-column(ng-repeat="status in usStatusList track by status.id",
div.kanban-uses-box.task-column(ng-class='{vfold:folds[s.id]}', ng-repeat="s in usStatusList track by s.id",
tg-kanban-sortable,
tg-kanban-wip-limit,
tg-kanban-column-height-fixer)
div.kanban-task(ng-repeat="us in usByStatus[status.id] track by us.id",
div.kanban-task(ng-repeat="us in usByStatus[s.id] track by us.id",
tg-kanban-userstory, ng-model="us",
ng-class="ctrl.getCardClass(status.id)")
ng-class="ctrl.getCardClass(s.id)")

View File

@ -13,4 +13,6 @@ div.login-form-container(tg-login)
a.button.button-login.button-gray(href="", title="Sign in") Sign in
input(type="submit", style="display:none")
fieldset(tg-github-login-button)
tg-public-register-message

View File

@ -17,13 +17,15 @@ div.register-form-container(tg-register)
fieldset
input(type="password", name="password", ng-model="data.password",
data-required="true", data-minlength="4",
data-required="true", data-minlength="4",
placeholder="Set a password (case sensitive)")
fieldset
a.button.button-register.button-gray(href="", title="Sign up") Sign up
input(type="submit", class="hidden")
fieldset(tg-github-login-button)
// Only displays terms notice when terms plugin is loaded.
tg-terms-notice

View File

@ -34,7 +34,7 @@ a.button-green {
a.button-gray {
background: $button-gray;
&:hover {
background: $button-gray-hover;
background: $fresh-taiga;
color: $white;
}
span {
@ -102,3 +102,18 @@ a.button-bulk {
background: $fresh-taiga;
}
}
.button-github {
@extend %button;
background: $grayer;
vertical-align: middle;
.icon {
@extend %large;
color: $white;
margin-right: .5rem;
vertical-align: text-bottom;
}
&:hover {
@include transition (background .3s linear);
background: $black;
}
}

View File

@ -44,10 +44,12 @@
}
.invitation-form {
@include table-flex();
fieldset {
margin-bottom: .5rem;
}
input {
background: $white;
color: $gray;
margin-bottom: 1rem;
position: relative;
@include placeholder {
color: $gray-light;
@ -80,16 +82,28 @@
background: $fresh-taiga;
}
}
.button-github {
&:hover {
background: $black;
}
}
}
.login-form,
.register-form {
@include table-flex-child(1, 200px, 0, 200px);
padding: 1rem;
text-align: center;
.form-header {
color: #999;
}
}
.register-form {
fieldset {
&:last-child {
margin-bottom: 1rem;
}
}
}
.register-text {
@extend %small;
color: $white;

View File

@ -1,5 +1,3 @@
.login-main {
//@include table-flex(center, center, flex, row, wrap, center);
@include display(flex);
@ -60,11 +58,7 @@
.button {
color: $white;
display: block;
margin-bottom: .5rem;
text-align: center;
&:hover {
background: $fresh-taiga;
}
}
a {
&:hover {

View File

@ -138,108 +138,115 @@ a:visited {
.icon-search:before {
content: 'd';
}
.icon-video:before {
.icon-wiki:before {
content: 'e';
}
.icon-wiki:before {
.icon-settings:before {
content: 'f';
}
.icon-settings:before {
.icon-move:before {
content: 'g';
}
.icon-move:before {
.icon-filter:before {
content: 'h';
}
.icon-filter:before {
.icon-arrow-up:before {
content: 'i';
}
.icon-arrow-up:before {
.icon-arrow-right:before {
content: 'j';
}
.icon-arrow-right:before {
.icon-arrow-left:before {
content: 'k';
}
.icon-arrow-left:before {
.icon-arrow-bottom:before {
content: 'l';
}
.icon-arrow-bottom:before {
.icon-edit:before {
content: 'm';
}
.icon-edit:before {
.icon-delete:before {
content: 'n';
}
.icon-delete:before {
.icon-iocaine:before {
content: 'o';
}
.icon-iocaine:before {
.icon-drag-h:before {
content: 'p';
}
.icon-drag-h:before {
.icon-drag-v:before {
content: 'q';
}
.icon-drag-v:before {
.icon-document:before {
content: 'r';
}
.icon-document:before {
.icon-plus:before {
content: 's';
}
.icon-plus:before {
.icon-reload:before {
content: 't';
}
.icon-reload:before {
.icon-warning:before {
content: 'u';
}
.icon-warning:before {
.icon-notification-error:before {
content: 'v';
}
.icon-notification-error:before {
.icon-github:before {
content: 'w';
}
.icon-github:before {
.icon-check-square:before {
content: 'x';
}
.icon-check-square:before {
.icon-warning-alt:before {
content: 'y';
}
.icon-warning-alt:before {
.icon-floppy:before {
content: 'z';
}
.icon-floppy:before {
.icon-comment:before {
content: 'A';
}
.icon-comment:before {
.icon-documents:before {
content: 'B';
}
.icon-documents:before {
.icon-attachments:before {
content: 'C';
}
.icon-attachments:before {
.icon-caret-up:before {
content: 'D';
}
.icon-caret-up:before {
.icon-caret-down:before {
content: 'E';
}
.icon-caret-down:before {
.icon-bulk:before {
content: 'F';
}
.icon-bulk:before {
.icon-idea:before {
content: 'G';
}
.icon-idea:before {
.icon-spinner:before {
content: 'H';
}
.icon-spinner:before {
.icon-minimize:before {
content: 'I';
}
.icon-minimize:before {
.icon-maximize:before {
content: 'J';
}
.icon-maximize:before {
.icon-stats:before {
content: 'K';
}
.icon-stats:before {
.icon-copy:before {
content: 'L';
}
.icon-copy:before {
.icon-team:before {
content: 'M';
}
.icon-vfold:before {
content: 'N';
}
.icon-vunfold:before {
content: 'O';
}

View File

@ -0,0 +1,91 @@
.admin-third-parties {
form {
margin-top: 1rem;
max-width: 700px;
width: 100%;
}
input[type="text"],
textarea {
@extend %title;
}
fieldset {
margin-bottom: 1rem;
}
label {
@extend %title;
display: block;
margin-bottom: .2rem;
}
textarea {
height: 10rem;
}
.button-green {
color: $white;
display: block;
text-align: center;
}
.select-input-text {
.field-with-option {
@include display(flex);
}
.option-wrapper {
@include display(flex);
@include align-items(center);
border: 1px solid $gray-light;
border-left: 0;
border-radius: 0 5px 5px 0;
cursor: pointer;
padding: 0 1rem;
}
.help-copy {
@extend %small;
opacity: 0;
&.visible {
@include transition(opacity .2s linear);
opacity: 1;
}
}
}
.help {
margin-top: 2rem;
h3 {
font-family: opensans-semibold;
margin-bottom: 1rem;
}
ol {
padding: 0 0 0 2rem;
span {
font-family: opensans-semibold;
}
}
.img {
margin-bottom: 1rem;
}
.alt-image {
@extend %small;
font-style: italic;
}
code {
@extend %small;
background: $whitish;
direction: ltr;
display: block;
font-family: 'courier new', 'monospace';
line-height: 1.4rem;
margin-bottom: 1rem;
padding: .5rem;
unicode-bidi: embed;
white-space: pre;
width: 100%;
}
.code-info {
padding-left: 1rem;
li {
margin-bottom: .5rem;
}
span {
font-family: opensans-semibold;
}
}
}
}

View File

@ -1,5 +1,4 @@
.login-form-container {
//display: none;
.login-password {
position: relative;
}

View File

@ -50,6 +50,10 @@
display: block;
}
}
.status-slug {
@include table-flex-child(6, 150px, 0);
padding: 0 10px;
}
.options-column {
max-width: 100px;
opacity: 0;

View File

@ -0,0 +1,29 @@
.blocked {
.external-reference {
color: $white;
a {
@include transition(color .3s linear);
color: $white;
&:hover {
color: $red-light;
}
}
}
}
.external-reference {
@extend %small;
color: $gray-light;
margin-top: .5rem;
a {
@include transition(color .3s linear);
border-left: 1px solid $gray-light;
padding: 0 .2rem;
&:hover {
color: $green-taiga;
}
&:first-child {
border: 0;
}
}
}

View File

@ -1,13 +1,46 @@
//Table basic shared vars
$column-width: 300px;
$column-flex: 1;
$column-folded-width: 30px;
$column-flex: 0;
$column-shrink: 0;
$column-margin: 0 10px 0 0;
.kanban-table {
overflow: hidden;
width: 100%;
.vfold {
&.task-colum-name {
@include table-flex();
@include align-items(center);
@include justify-content(center);
@include transition(opacity .3s linear);
cursor: pointer;
opacity: .8;
padding: .5rem 0;
.icon-plus,
.icon-bulk,
.icon-vfold,
.icon-vunfold,
span {
display: none;
}
.hunfold {
margin: 0;
}
}
&.task-colum-name,
&.task-column {
@include table-flex-child(1, 0, 0);
max-width: $column-folded-width;
min-height: 2.5rem;
min-width: $column-folded-width;
width: $column-folded-width;
}
.kanban-task {
display: none;
}
}
}
.kanban-table-header {
@ -20,34 +53,31 @@ $column-margin: 0 10px 0 0;
position: absolute;
}
.task-colum-name {
@include table-flex-child();
@include table-flex-child($column-flex, $column-width, $column-shrink, $column-width);
@include table-flex();
@include justify-content(space-between);
@extend %large;
background: $whitish;
border-top: 3px solid $gray-light;
margin: $column-margin;
padding: .5rem 0;
padding: .5rem .5rem .5rem 1rem;
position: relative;
text-align: center;
text-transform: uppercase;
&:last-child {
margin-right: 0;
}
.icon {
@extend %medium;
@include transition(color .2s linear);
color: $gray-light;
position: absolute;
right: .5rem;
top: .5rem;
margin-right: .3rem;
&:hover {
color: $green-taiga;
}
&.icon-plus {
right: 2rem;
}
&.icon-maximize,
&.icon-minimize {
left: .5rem;
right: inherit;
&.hfold,
&.hunfold {
@include transform(rotate(90deg));
display: inline-block;
}
}
}
@ -60,7 +90,7 @@ $column-margin: 0 10px 0 0;
overflow-x: auto;
width: 100%;
.task-column {
@include table-flex-child();
@include table-flex-child($column-flex, $column-width, $column-shrink, $column-width);
margin: $column-margin;
overflow-y: auto;
&:last-child {

View File

@ -6,5 +6,6 @@
"feedbackEnabled": true,
"privacyPolicyUrl": null,
"termsOfServiceUrl": null,
"maxUploadFileSize": null
"maxUploadFileSize": null,
"gitHubClientId": null
}

View File

@ -73,6 +73,7 @@ paths.coffee = [
paths.app + "coffee/modules/base/*.coffee",
paths.app + "coffee/modules/resources/*.coffee",
paths.app + "coffee/modules/user-settings/*.coffee"
paths.app + "coffee/modules/integrations/*.coffee"
paths.app + "plugins/**/*.coffee"
]

View File

@ -71,6 +71,7 @@ exports.files = function () {
'modules/common/related-tasks',
'modules/common/history',
'modules/common/wizard',
'modules/common/external-reference',
//Project modules
'modules/home-projects-list',
@ -120,6 +121,7 @@ exports.files = function () {
'modules/admin/admin-project-profile',
'modules/admin/default-values',
'modules/admin/project-values',
'modules/admin/third-parties',
//Modules user Settings
'modules/user-settings/user-profile',