Actualiza el plugin Additionals a 3.0.2-master

This commit is contained in:
Manuel Cillero 2021-03-20 11:12:56 +01:00
parent 3b6a41320c
commit cfa0d58b18
164 changed files with 2027 additions and 58190 deletions

View file

@ -0,0 +1,47 @@
name: Run Linters
on:
push:
pull_request:
schedule:
- cron: '30 5 * * *'
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
bundler-cache: true
- name: Set Gemfile
run: |
echo "">> Gemfile
echo "group :test do">> Gemfile
echo " gem 'pandoc-ruby', require: false" >> Gemfile
echo " gem 'rubocop', require: false" >> Gemfile
echo " gem 'rubocop-performance', require: false" >> Gemfile
echo " gem 'rubocop-rails', require: false" >> Gemfile
echo " gem 'slim_lint', require: false" >> Gemfile
echo "end">> Gemfile
- name: Setup gems
run: |
bundle install --jobs 4 --retry 3
- name: Run RuboCop
run: |
bundle exec rubocop -S
- name: Run Slim-Lint
run: |
bundle exec slim-lint app/views
if: always()
- name: Run Brakeman
run: |
bundle exec brakeman -5

View file

@ -0,0 +1,124 @@
name: Tests
on:
push:
pull_request:
schedule:
- cron: '0 5 * * *'
jobs:
test:
name: ${{ matrix.redmine }} ${{ matrix.db }} ruby-${{ matrix.ruby }}
runs-on: ubuntu-latest
strategy:
matrix:
ruby: ['2.6', '2.4']
redmine: ['4.1-stable', 'master']
db: ['postgres', 'mysql']
fail-fast: false
services:
postgres:
image: postgres:13
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: 'BestPasswordEver'
ports:
# will assign a random free host port
- 3306/tcp
options: >-
--health-cmd="mysqladmin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
steps:
- name: Verify MySQL connection from host
run: |
mysql --host 127.0.0.1 --port ${{ job.services.mysql.ports[3306] }} -uroot -pBestPasswordEver -e "SHOW DATABASES"
if: matrix.db == 'mysql'
- name: Checkout Redmine
uses: actions/checkout@v2
with:
repository: redmine/redmine
ref: ${{ matrix.redmine }}
path: redmine
- name: Checkout additionals
uses: actions/checkout@v2
with:
repository: AlphaNodes/additionals
path: redmine/plugins/additionals
- name: Update package archives
run: sudo apt-get update --yes --quiet
- name: Install package dependencies
run: >
sudo apt-get install --yes --quiet
build-essential
cmake
libicu-dev
libpq-dev
libmysqlclient-dev
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- name: Prepare Redmine source
working-directory: redmine
run: |
sed -i '/rubocop/d' Gemfile
rm -f .rubocop*
cp plugins/additionals/test/support/database-${{ matrix.db }}.yml config/database.yml
cp plugins/additionals/test/support/configuration.yml config/configuration.yml
- name: Install Ruby dependencies
working-directory: redmine
run: |
bundle install --jobs=4 --retry=3 --without development
- name: Run Redmine rake tasks
env:
RAILS_ENV: test
MYSQL_PORT: ${{ job.services.mysql.ports[3306] }}
working-directory: redmine
run: |
bundle exec rake generate_secret_token
bundle exec rake db:create db:migrate redmine:plugins:migrate
bundle exec rake db:test:prepare
- name: Run tests
env:
RAILS_ENV: test
MYSQL_PORT: ${{ job.services.mysql.ports[3306] }}
working-directory: redmine
run: bundle exec rake redmine:plugins:test NAME=additionals RUBYOPT="-W0"
- name: Run uninstall test
env:
RAILS_ENV: test
MYSQL_PORT: ${{ job.services.mysql.ports[3306] }}
working-directory: redmine
run: bundle exec rake redmine:plugins:migrate NAME=additionals VERSION=0
- name: Run build gem file
working-directory: redmine/plugins/additionals
run: gem build additionals.gemspec

View file

@ -1,8 +1,11 @@
.DS_Store
.buildpath
*.gem
coverage/
tmp/
Gemfile.lock
.project
.vscode
.settings/
docs/_build
docs/_static

View file

@ -70,3 +70,12 @@ Style/HashTransformKeys:
Style/HashTransformValues:
Enabled: false
Naming/VariableNumber:
Enabled: true
Exclude:
- 'test/**/*'
Style/StringConcatenation:
Exclude:
- 'app/views/additionals/_select2_ajax_call.*'

View file

@ -4,15 +4,10 @@ linters:
RuboCop:
ignored_cops:
- Layout/ArgumentAlignment
- Layout/ArrayAlignment
- Layout/BlockEndNewline
- Layout/EmptyLineAfterGuardClause
- Layout/HashAlignment
- Layout/IndentationConsistency
- Layout/IndentationWidth
- Layout/IndentFirstArgument
- Layout/IndentFirstArrayElement
- Layout/IndentFirstHashElement
- Layout/MultilineArrayBraceLayout
- Layout/MultilineAssignmentLayout
- Layout/MultilineBlockLayout
@ -21,19 +16,11 @@ linters:
- Layout/MultilineMethodCallIndentation
- Layout/MultilineMethodDefinitionBraceLayout
- Layout/MultilineOperationIndentation
- Layout/TrailingBlankLines
- Layout/SpaceBeforeBrackets
- Layout/TrailingEmptyLines
- Layout/TrailingWhitespace
- Lint/BlockAlignment
- Lint/EndAlignment
- Lint/Void
- Metrics/BlockLength
- Metrics/BlockNesting
- Metrics/LineLength
- Naming/FileName
- Rails/OutputSafety
- Style/ConditionalAssignment
- Style/FrozenStringLiteralComment
- Style/IdenticalConditionalBranches
- Style/IfUnlessModifier
- Style/Next

View file

@ -1,43 +0,0 @@
language: ruby
os: linux
dist: xenial
rvm:
- 2.6.6
- 2.5.8
- 2.4.10
services:
- mysql
- postgresql
env:
- REDMINE_VER=4.1-stable DB=postgresql
- REDMINE_VER=master DB=postgresql
- REDMINE_VER=4.1-stable DB=mysql
- REDMINE_VER=master DB=mysql
before_install:
- export PLUGIN_NAME=additionals
- export REDMINE_GIT_REPO=git://github.com/redmine/redmine.git
- export REDMINE_PATH=$HOME/redmine
- export BUNDLE_GEMFILE=$REDMINE_PATH/Gemfile
- export RAILS_ENV=test
- git clone $REDMINE_GIT_REPO $REDMINE_PATH
- cd $REDMINE_PATH
- if [[ "$REDMINE_VER" != "master" ]]; then git checkout -b $REDMINE_VER origin/$REDMINE_VER; fi
- sed -i '/rubocop/d' $REDMINE_PATH/Gemfile
- rm -f $REDMINE_PATH/.rubocop*
- cp $TRAVIS_BUILD_DIR/test/support/Gemfile.local $REDMINE_PATH
- ln -s $TRAVIS_BUILD_DIR $REDMINE_PATH/plugins/$PLUGIN_NAME
- cp $TRAVIS_BUILD_DIR/test/support/additional_environment.rb $REDMINE_PATH/config/
- cp $TRAVIS_BUILD_DIR/test/support/database-$DB-travis.yml $REDMINE_PATH/config/database.yml
before_script:
- bundle exec rake db:create db:migrate redmine:plugins:migrate
script:
- if [[ "$REDMINE_VER" != "master" ]] && [[ "$DB" == "postgresql" ]]; then brakeman plugins/$PLUGIN_NAME; fi
- if [[ "$REDMINE_VER" != "master" ]] && [[ "$DB" == "postgresql" ]]; then rubocop plugins/$PLUGIN_NAME; fi
- bundle exec rake redmine:plugins:test NAME=$PLUGIN_NAME RUBYOPT="-W0"
- bundle exec rake redmine:plugins:migrate NAME=$PLUGIN_NAME VERSION=0

View file

@ -1,6 +1,33 @@
Changelog
=========
3.0.2
+++++
- d3plus to v2.0.0-alpha.30 support
- Mermaid 8.9.1 support
- Bug fix for select2 loading without named field
- FontAwesome 5.15.2 support
- D3 6.6.0 support
- Fix news limit for welcome dashboard block
- Frensh translation updated, thanks to Brice BEAUMESNIL!
- clipboard.js updated to v2.0.8
-
3.0.1
+++++
- Do not show "Assign to me" if assigned_to is disabled for tracker
- FontAwesome 5.15.1 support
- D3 6.3.1 support
- Mermaid 8.8.4 support
- add current_user as special login name for user macro (which shows current login user)
- add text parameter to user macro (which disable link to user)
- add asynchronous text block
- gemify plugin to use it with Gemfile.local or other plugins
- remove spam protection functionality
- Chart.js 2.9.4 support
- Allow overwrite mermaid theme and variables
3.0.0
+++++

View file

@ -1,13 +1,4 @@
source 'https://rubygems.org'
gem 'deface', '1.5.3'
gem 'gemoji', '~> 3.0.0'
gem 'invisible_captcha'
gem 'render_async'
gem 'rss'
gem 'slim-rails'
group :development, :test do
gem 'brakeman', require: false
gem 'slim_lint', require: false
end
# Specify your gem's dependencies in additionals.gemspec
gemspec

View file

@ -1 +0,0 @@
docs/index.rst

View file

@ -0,0 +1,11 @@
require 'bundler/gem_tasks'
require 'rake/testtask'
Rake::TestTask.new do |t|
t.libs << 'test'
files = FileList['test/**/*test.rb']
t.test_files = files
t.verbose = true
end
task default: :test

View file

@ -0,0 +1,30 @@
lib = File.expand_path '../lib', __FILE__
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'additionals/version'
Gem::Specification.new do |spec|
spec.name = 'additionals'
spec.version = Additionals::VERSION
spec.authors = ['AlphaNodes']
spec.email = ['alex@alphanodes.com']
spec.summary = 'Redmine plugin for adding dashboard functionality, wiki macros and libraries for other Redmine plugins'
spec.description = 'Redmine plugin for adding dashboard functionality, wiki macros and libraries for other Redmine plugins'
spec.homepage = 'https://github.com/alphanodes/alphanodes'
spec.license = 'GPL-2.0'
spec.files = Dir['**/*'] - Dir['test/**/*'] - Dir['Gemfile', 'Gemfile.lock', 'README.rst']
spec.require_paths = ['lib']
spec.required_ruby_version = '>= 2.4'
spec.add_runtime_dependency 'deface', '1.5.3'
spec.add_runtime_dependency 'gemoji', '~> 3.0.0'
spec.add_runtime_dependency 'render_async'
spec.add_runtime_dependency 'rss'
spec.add_runtime_dependency 'slim-rails'
spec.add_development_dependency 'brakeman'
spec.add_development_dependency 'bundler'
spec.add_development_dependency 'rake'
spec.add_development_dependency 'slim_lint'
end

View file

@ -13,7 +13,7 @@ class AdditionalsChangeStatusController < ApplicationController
return
end
@issue.init_journal(User.current)
@issue.init_journal User.current
@issue.status_id = new_status_id
@issue.assigned_to = User.current if @issue.status_x_affected?(new_status_id) && issue_old_user != User.current

View file

@ -6,7 +6,6 @@ class DashboardAsyncBlocksController < ApplicationController
helper :additionals_routes
helper :additionals_queries
helper :additionals_tag
helper :queries
helper :issues
helper :activities
@ -14,6 +13,12 @@ class DashboardAsyncBlocksController < ApplicationController
include DashboardsHelper
# support for redmine_contacts_helpdesk plugin
if Redmine::Plugin.installed? 'redmine_contacts_helpdesk'
include HelpdeskHelper
helper :helpdesk
end
rescue_from Query::StatementInvalid, with: :query_statement_invalid
rescue_from StandardError, with: :dashboard_with_invalid_block

View file

@ -17,7 +17,6 @@ class DashboardsController < ApplicationController
helper :dashboards
helper :additionals_issues
helper :additionals_queries
helper :additionals_tag
include AdditionalsRoutesHelper
include AdditionalsQueriesHelper
@ -92,7 +91,7 @@ class DashboardsController < ApplicationController
respond_to do |format|
format.html
format.xml {}
format.api
end
end

View file

@ -6,7 +6,7 @@ module AdditionalsChartjsHelper
end
def select_options_for_chartjs_colorscheme(selected)
data = YAML.safe_load(ERB.new(IO.read(Rails.root.join('plugins/additionals/config/colorschemes.yml'))).result) || {}
data = YAML.safe_load(ERB.new(IO.read(File.join(Additionals.plugin_dir, 'config', 'colorschemes.yml'))).result) || {}
grouped_options_for_select(data, selected)
end
end

View file

@ -3,20 +3,34 @@ module AdditionalsClipboardjsHelper
render_clipboardjs_button(target, clipboard_text_from_button) + render_clipboardjs_javascript(target)
end
def render_text_with_clipboardjs(text)
return if text.blank?
tag.acronym text,
class: 'clipboard-text',
title: l(:label_copy_to_clipboard),
data: clipboardjs_data(text: text)
end
def clipboardjs_data(clipboard_data)
data = { 'label-copied' => l(:label_copied_to_clipboard),
'label-to-copy' => l(:label_copy_to_clipboard) }
clipboard_data.each do |key, value|
data["clipboard-#{key}"] = value if value.present?
end
data
end
private
def render_clipboardjs_button(target, clipboard_text_from_button)
data = { 'clipboard-target' => "##{target}",
'label-copied' => l(:label_copied_to_clipboard),
'label-to-copy' => l(:label_copy_to_clipboard) }
data['clipboard-text'] = clipboard_text_from_button if clipboard_text_from_button.present?
tag.button id: "zc_#{target}",
class: 'clipboard_button far fa-copy',
class: 'clipboard-button far fa-copy',
type: 'button',
title: l(:label_copy_to_clipboard),
data: data
data: clipboardjs_data(target: "##{target}", text: clipboard_text_from_button)
end
def render_clipboardjs_javascript(target)

View file

@ -100,12 +100,9 @@ module AdditionalsMenuHelper
def additionals_custom_top_menu_item(item, user_roles)
show_entry = false
item[:roles].each do |role|
if user_roles.empty? && role.to_i == Role::BUILTIN_ANONYMOUS
show_entry = true
break
elsif User.current.logged? && role.to_i == Role::BUILTIN_NON_MEMBER
# if user is logged in and non_member is active in item,
# always show it
if user_roles.empty? && role.to_i == Role::BUILTIN_ANONYMOUS ||
# if user is logged in and non_member is active in item, always show it
User.current.logged? && role.to_i == Role::BUILTIN_NON_MEMBER
show_entry = true
break
end

View file

@ -4,8 +4,8 @@ module AdditionalsQueriesHelper
end
def additionals_retrieve_query(object_type, options = {})
session_key = additionals_query_session_key(object_type)
query_class = Object.const_get("#{object_type.camelcase}Query")
session_key = additionals_query_session_key object_type
query_class = Object.const_get "#{object_type.camelcase}Query"
if params[:query_id].present?
additionals_load_query_id(query_class, session_key, params[:query_id], options, object_type)
elsif api_request? ||
@ -28,7 +28,7 @@ module AdditionalsQueriesHelper
else
# retrieve from session
@query = query_class.find_by(id: session[session_key][:id]) if session[session_key][:id]
session_data = Rails.cache.read(additionals_query_cache_key(object_type))
session_data = Rails.cache.read additionals_query_cache_key(object_type)
@query ||= query_class.new(name: '_',
filters: session_data.nil? ? nil : session_data[:filters],
group_by: session_data.nil? ? nil : session_data[:group_by],
@ -79,11 +79,11 @@ module AdditionalsQueriesHelper
def additionals_select2_search_users(options = {})
q = params[:q].to_s.strip
exclude_id = params[:user_id].to_i
scope = User.active.where(type: 'User')
scope = User.active.where type: 'User'
scope = scope.visible unless options[:all_visible]
scope = scope.where.not(id: exclude_id) if exclude_id.positive?
scope = scope.where(options[:where_filter], options[:where_params]) if options[:where_filter]
q.split(' ').map { |search_string| scope = scope.like(search_string) } if q.present?
q.split.map { |search_string| scope = scope.like(search_string) } if q.present?
scope = scope.order(last_login_on: :desc)
.limit(Additionals::SELECT2_INIT_ENTRIES)
@users = scope.to_a.sort! { |x, y| x.name <=> y.name }
@ -140,13 +140,13 @@ module AdditionalsQueriesHelper
def xlsx_write_header_row(workbook, worksheet, columns)
columns_width = []
columns.each_with_index do |c, index|
value = if c.class.name == 'String'
value = if c.is_a? String
c
else
c.caption.to_s
end
worksheet.write(0, index, value, workbook.add_format(xlsx_cell_format(:header)))
worksheet.write 0, index, value, workbook.add_format(xlsx_cell_format(:header))
columns_width << xlsx_get_column_width(value)
end
columns_width
@ -224,13 +224,11 @@ module AdditionalsQueriesHelper
def xlsx_hyperlink_cell?(token)
# Match http, https or ftp URL
if %r{\A[fh]tt?ps?://}.match?(token)
true
# Match mailto:
elsif token.present? && token.start_with?('mailto:')
true
# Match internal or external sheet link
elsif /\A(?:in|ex)ternal:/.match?(token)
if %r{\A[fh]tt?ps?://}.match?(token) ||
# Match mailto:
token.present? && token.start_with?('mailto:') ||
# Match internal or external sheet link
/\A(?:in|ex)ternal:/.match?(token)
true
end
end

View file

@ -1,9 +1,10 @@
module AdditionalsSelect2Helper
def additionals_select2_tag(name, option_tags = nil, options = {})
s = select_tag(name, option_tags, options)
id = options.delete(:id) || sanitize_to_id(name)
s << hidden_field_tag("#{name}[]", '') if options[:multiple] && options.fetch(:include_hidden, true)
s + javascript_tag("select2Tag('#{sanitize_to_id name}', #{options.to_json});")
s + javascript_tag("select2Tag('#{id}', #{options.to_json});")
end
# Transforms select filters of +type+ fields into select2

View file

@ -4,7 +4,6 @@ module AdditionalsSettingsHelper
{ name: 'wiki', partial: 'additionals/settings/wiki', label: :label_wiki },
{ name: 'macros', partial: 'additionals/settings/macros', label: :label_macro_plural },
{ name: 'rules', partial: 'additionals/settings/issues', label: :label_issue_plural },
{ name: 'users', partial: 'additionals/settings/users', label: :label_user_plural },
{ name: 'web', partial: 'additionals/settings/web_apis', label: :label_web_apis }]
unless Redmine::Plugin.installed? 'redmine_hrm'
@ -46,6 +45,22 @@ module AdditionalsSettingsHelper
text_field_tag("settings[#{name}]", value, options)]
end
def additionals_settings_passwordfield(name, options = {})
label_title = options.delete(:label).presence || l("label_#{name}")
value = options.delete(:value).presence || @settings[name]
safe_join [label_tag("settings[#{name}]", label_title),
password_field_tag("settings[#{name}]", value, options)]
end
def additionals_settings_urlfield(name, options = {})
label_title = options.delete(:label).presence || l("label_#{name}")
value = options.delete(:value).presence || @settings[name]
safe_join [label_tag("settings[#{name}]", label_title),
url_field_tag("settings[#{name}]", value, options)]
end
def additionals_settings_textarea(name, options = {})
label_title = options.delete(:label).presence || l("label_#{name}")
value = options.delete(:value).presence || @settings[name]

View file

@ -1,113 +0,0 @@
require 'digest/md5'
module AdditionalsTagHelper
def additionals_tag_cloud(tags, options = {})
return if tags.blank?
options[:show_count] = true
# prevent ActsAsTaggableOn::TagsHelper from calling `all`
# otherwise we will need sort tags after `tag_cloud`
tags = tags.all if tags.respond_to?(:all)
s = []
tags.each do |tag|
s << additionals_tag_link(tag, options)
end
sep = if options[:tags_without_color]
', '
else
' '
end
tag.div safe_join(s, sep), class: 'tags'
end
# plain list of tags
def render_additionals_tags(tags, sep = ' ')
s = if tags.blank?
['']
else
tags.map(&:name)
end
s.join(sep)
end
def additionals_tag_links(tag_list, options = {})
return unless tag_list
sep = if options[:tags_without_color]
', '
else
' '
end
safe_join(tag_list.map do |tag|
additionals_tag_link tag, options
end, sep)
end
def additionals_tag_link(tag_object, options = {})
tag_name = []
tag_name << tag_object.name
unless options[:tags_without_color]
tag_bg_color = additionals_tag_color tag_object.name
tag_fg_color = additionals_tag_fg_color tag_bg_color
tag_style = "background-color: #{tag_bg_color}; color: #{tag_fg_color}"
end
tag_name << tag.span("(#{tag_object.count})", class: 'tag-count') if options[:show_count]
if options[:tags_without_color]
tag.span link_to(safe_join(tag_name), additionals_tag_url(tag_object.name, options)),
class: 'tag-label'
else
tag.span link_to(safe_join(tag_name),
additionals_tag_url(tag_object.name, options),
style: tag_style),
class: 'additionals-tag-label-color',
style: tag_style
end
end
def additionals_tag_url(tag_name, options = {})
action = options[:tag_action].presence || (controller_name == 'hrm_user_resources' ? 'show' : 'index')
{ controller: options[:tag_controller].presence || controller_name,
action: action,
set_filter: 1,
project_id: options[:project],
fields: [:tags],
values: { tags: [tag_name] },
operators: { tags: '=' } }
end
private
def tag_cloud(tags, classes)
return [] if tags.empty?
max_count = tags.max_by(&:count).count.to_f
tags.each do |tag|
index = ((tag.count / max_count) * (classes.size - 1))
yield tag, classes[index.nan? ? 0 : index.round]
end
end
def additionals_tag_color(tag_name)
"##{Digest::MD5.hexdigest(tag_name)[0..5]}"
end
def additionals_tag_fg_color(bg_color)
# calculate contrast text color according to YIQ method
# https://24ways.org/2010/calculating-color-contrast/
# https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
r = bg_color[1..2].hex
g = bg_color[3..4].hex
b = bg_color[5..6].hex
(r * 299 + g * 587 + b * 114) >= 128_000 ? 'black' : 'white'
end
end

View file

@ -86,10 +86,10 @@ module DashboardsHelper
tag.div class: 'active-dashboards' do
out = [tag.h3(l(:label_active_dashboard)),
tag.ul do
concat tag.ul "#{l :field_name}: #{dashboard.name}"
concat tag.ul safe_join([l(:field_author), link_to_user(dashboard.author)], ': ')
concat tag.ul "#{l :field_created_on}: #{format_time dashboard.created_at}"
concat tag.ul "#{l :field_updated_on}: #{format_time dashboard.updated_at}"
concat tag.li "#{l :field_name}: #{dashboard.name}"
concat tag.li safe_join([l(:field_author), link_to_user(dashboard.author)], ': ')
concat tag.li "#{l :field_created_on}: #{format_time dashboard.created_at}"
concat tag.li "#{l :field_updated_on}: #{format_time dashboard.updated_at}"
end]
if dashboard.description.present?
@ -105,7 +105,7 @@ module DashboardsHelper
return '' unless dashboards.any?
tag.h3(title, class: 'dashboards') +
tag.ul do
tag.ul(class: 'dashboards') do
dashboards.each do |dashboard|
selected = dashboard.id == if params[:dashboard_id].present?
params[:dashboard_id].to_i
@ -115,19 +115,24 @@ module DashboardsHelper
css = 'dashboard'
css << ' selected' if selected
li_class = nil
link = [dashboard_link(dashboard, project, class: css)]
if dashboard.system_default?
link << if dashboard.project_id.nil?
font_awesome_icon('fas_cube',
li_class = 'global'
font_awesome_icon 'fas_cube',
title: l(:field_system_default),
class: 'dashboard-system-default global')
class: "dashboard-system-default #{li_class}"
else
font_awesome_icon('fas_cube',
li_class = 'project'
font_awesome_icon 'fas_cube',
title: l(:field_project_system_default),
class: 'dashboard-system-default project')
class: "dashboard-system-default #{li_class}"
end
end
concat tag.li safe_join(link)
concat tag.li safe_join(link), class: li_class
end
end
end
@ -325,7 +330,7 @@ module DashboardsHelper
max_entries = settings[:max_entries] || DashboardContent::DEFAULT_MAX_ENTRIES
news = if dashboard.content_project.nil?
News.latest User.current
News.latest User.current, max_entries
else
dashboard.content_project
.news
@ -378,7 +383,7 @@ module DashboardsHelper
max_entries = max_entries.present? ? max_entries.to_i : 10
begin
URI.open(url) do |rss_feed|
URI.parse(url).open do |rss_feed|
rss = RSS::Parser.parse(rss_feed)
rss.items.each do |item|
cnt += 1

View file

@ -1,5 +0,0 @@
class AdditionalsRemoveUnusedTagJob < AdditionalsJob
def perform
AdditionalsTag.remove_unused_tags
end
end

View file

@ -1,4 +1,5 @@
class AdditionalsChart < ActiveRecord::Base
class AdditionalsChart
include ActiveRecord::Sanitization
include Redmine::I18n
CHART_DEFAULT_HEIGHT = 350

View file

@ -6,7 +6,7 @@ class AdditionalsFontAwesome
class << self
def load_icons(type)
data = YAML.safe_load(ERB.new(IO.read(Rails.root.join('plugins/additionals/config/fontawesome_icons.yml'))).result) || {}
data = YAML.safe_load(ERB.new(IO.read(File.join(Additionals.plugin_dir, 'config', 'fontawesome_icons.yml'))).result) || {}
icons = {}
data.each do |key, values|
icons[key] = { unicode: values['unicode'], label: values['label'] } if values['styles'].include?(convert_type2style(type))

View file

@ -31,7 +31,7 @@ class AdditionalsImport < Import
next unless value
h[v.custom_field.id.to_s] =
if value.is_a?(Array)
if value.is_a? Array
value.map { |val| v.custom_field.value_from_keyword(val.strip, object) }.flatten!&.compact
else
v.custom_field.value_from_keyword(value, object)

View file

@ -0,0 +1,73 @@
class AdditionalsInfo
include Redmine::I18n
class << self
def system_infos
{ system_info: { label: l(:label_system_info), value: system_info },
system_uptime: { label: l(:label_uptime), value: system_uptime } }
end
def system_info
if windows_platform?
win_info = `wmic os get Caption,CSDVersion,BuildNumber /value`
return 'unknown' if win_info.blank?
windows_version = ''
windows_build = ''
build_names = %w[BuildNumber CSDVersion]
win_info.split(/\n+/).each do |line|
line_info = line.split '='
if line_info[0] == 'Caption'
windows_version = line_info[1]
elsif build_names.include?(line_info[0]) && line_info[1]&.present?
windows_build = line_info[1]
end
end
"#{windows_version} build #{windows_build}"
else
`uname -a`
end
end
def system_uptime(format: :time_tag)
if windows_platform?
`net stats srv | find "Statist"`
elsif File.exist? '/proc/uptime'
secs = `cat /proc/uptime`.to_i
min = 0
hours = 0
days = 0
if secs.positive?
min = (secs / 60).round
hours = (secs / 3_600).round
days = (secs / 86_400).round
end
if days >= 1
"#{days} #{l(:days, count: days)}"
elsif hours >= 1
"#{hours} #{l(:hours, count: hours)}"
else
"#{min} #{l(:minutes, count: min)}"
end
else
# this should be work on macOS
seconds = `sysctl -n kern.boottime | awk '{print $4}'`.tr ',', ''
so = DateTime.strptime seconds.strip, '%s'
if so.present?
if format == :datetime
so
else
ApplicationController.helpers.time_tag so
end
else
days = `uptime | awk '{print $3}'`.to_i.round
"#{days} #{l(:days, count: days)}"
end
end
end
def windows_platform?
/cygwin|mswin|mingw|bccwin|wince|emx/.match? RUBY_PLATFORM
end
end
end

View file

@ -22,6 +22,17 @@ module AdditionalsQuery
sql.join(' AND ')
end
def fix_sql_for_text_field(field, operator, value, table_name = nil, target_field = nil)
table_name = queried_table_name if table_name.blank?
target_field = field if target_field.blank?
sql = []
sql << "(#{sql_for_field(field, operator, value, table_name, target_field)})"
sql << "#{table_name}.#{target_field} != ''" if operator == '*'
sql.join(' AND ')
end
def initialize_ids_filter(options = {})
if options[:label]
add_available_filter 'ids', type: :integer, label: options[:label]
@ -44,30 +55,44 @@ module AdditionalsQuery
end
end
def sql_for_project_identifier_field(field, operator, values)
value = values.first
values = value.split(',').map(&:strip) if ['=', '!'].include?(operator) && value.include?(',')
sql_for_field field, operator, values, Project.table_name, 'identifier'
end
def sql_for_project_status_field(field, operator, value)
sql_for_field field, operator, value, Project.table_name, 'status'
end
def initialize_project_status_filter
return if project&.leaf?
def initialize_project_identifier_filter
return if project
add_available_filter('project.status',
add_available_filter 'project.identifier',
type: :string,
name: l(:label_attribute_of_project, name: l(:field_identifier))
end
def initialize_project_status_filter
return if project
add_available_filter 'project.status',
type: :list,
name: l(:label_attribute_of_project, name: l(:field_status)),
values: -> { project_statuses_values })
values: -> { project_statuses_values }
end
def initialize_project_filter(options = {})
if project.nil? || options[:always]
add_available_filter('project_id', order: options[:position],
add_available_filter 'project_id', order: options[:position],
type: :list,
values: -> { project_values })
values: -> { project_values }
end
return if project.nil? || project.leaf? || subproject_values.empty?
add_available_filter('subproject_id', order: options[:position],
add_available_filter 'subproject_id', order: options[:position],
type: :list_subprojects,
values: -> { subproject_values })
values: -> { subproject_values }
end
def initialize_created_filter(options = {})
@ -83,16 +108,9 @@ module AdditionalsQuery
end
def initialize_tags_filter(options = {})
values = if project
queried_class.available_tags(project: project.id)
else
queried_class.available_tags
end
return if values.blank?
add_available_filter 'tags', order: options[:position],
type: :list,
values: values.collect { |t| [t.name, t.name] }
type: :list_optional,
values: -> { tag_values(project) }
end
def initialize_approved_filter
@ -106,27 +124,35 @@ module AdditionalsQuery
end
def initialize_author_filter(options = {})
return if author_values.empty?
add_available_filter('author_id', order: options[:position],
add_available_filter 'author_id', order: options[:position],
type: :list_optional,
values: options[:no_lambda].nil? ? author_values : -> { author_values })
values: -> { author_values }
end
def initialize_assignee_filter(options = {})
return if author_values.empty?
add_available_filter('assigned_to_id', order: options[:position],
add_available_filter 'assigned_to_id', order: options[:position],
type: :list_optional,
values: options[:no_lambda] ? assigned_to_all_values : -> { assigned_to_all_values })
values: -> { assigned_to_all_values }
end
def initialize_watcher_filter(options = {})
return if watcher_values.empty? || !User.current.logged?
return unless User.current.logged?
add_available_filter('watcher_id', order: options[:position],
add_available_filter 'watcher_id', order: options[:position],
type: :list,
values: options[:no_lambda] ? watcher_values : -> { watcher_values })
values: -> { watcher_values }
end
def tag_values(project)
values = if project
queried_class.available_tags project: project.id
else
queried_class.available_tags
end
return [] if values.blank?
values.collect { |t| [t.name, t.name] }
end
# issue independend values. Use assigned_to_values from Redmine, if you want it only for issues
@ -154,7 +180,7 @@ module AdditionalsQuery
end
def sql_for_tags_field(field, _operator, value)
AdditionalsTag.sql_for_tags_field(queried_class, operator_for(field), value)
AdditionalTags.sql_for_tags_field queried_class, operator_for(field), value
end
def sql_for_is_private_field(_field, operator, value)

View file

@ -1,76 +0,0 @@
class AdditionalsTag
TAG_TABLE_NAME = RedmineCrm::Tag.table_name if defined? RedmineCrm
TAGGING_TABLE_NAME = RedmineCrm::Tagging.table_name if defined? RedmineCrm
PROJECT_TABLE_NAME = Project.table_name
class << self
def all_type_tags(klass, options = {})
RedmineCrm::Tag.where({})
.joins(tag_joins(klass, options))
.distinct
.order("#{TAG_TABLE_NAME}.name")
end
def get_available_tags(klass, options = {})
scope = RedmineCrm::Tag.where({})
scope = scope.where("#{PROJECT_TABLE_NAME}.id = ?", options[:project]) if options[:project]
if options[:permission]
scope = scope.where(tag_access(options[:permission]))
elsif options[:visible_condition]
scope = scope.where(klass.visible_condition(User.current))
end
scope = scope.where("LOWER(#{TAG_TABLE_NAME}.name) LIKE ?", "%#{options[:name_like].downcase}%") if options[:name_like]
scope = scope.where("#{TAG_TABLE_NAME}.name=?", options[:name]) if options[:name]
scope = scope.where("#{TAGGING_TABLE_NAME}.taggable_id!=?", options[:exclude_id]) if options[:exclude_id]
scope = scope.where(options[:where_field] => options[:where_value]) if options[:where_field].present? && options[:where_value]
scope.select("#{TAG_TABLE_NAME}.*, COUNT(DISTINCT #{TAGGING_TABLE_NAME}.taggable_id) AS count")
.joins(tag_joins(klass, options))
.group("#{TAG_TABLE_NAME}.id, #{TAG_TABLE_NAME}.name").having('COUNT(*) > 0')
.order("#{TAG_TABLE_NAME}.name")
end
def remove_unused_tags
RedmineCrm::Tag.where.not(id: RedmineCrm::Tagging.select(:tag_id).distinct)
.each(&:destroy)
end
def sql_for_tags_field(klass, operator, value)
compare = operator.eql?('=') ? 'IN' : 'NOT IN'
ids_list = klass.tagged_with(value).collect(&:id).push(0).join(',')
"( #{klass.table_name}.id #{compare} (#{ids_list}) ) "
end
private
def tag_access(permission)
projects_allowed = if permission.nil?
Project.visible.ids
else
Project.where(Project.allowed_to_condition(User.current, permission)).ids
end
if projects_allowed.present?
"#{PROJECT_TABLE_NAME}.id IN (#{projects_allowed.join ','})" unless projects_allowed.empty?
else
'1=0'
end
end
def tag_joins(klass, options = {})
table_name = klass.table_name
joins = ["JOIN #{TAGGING_TABLE_NAME} ON #{TAGGING_TABLE_NAME}.tag_id = #{TAG_TABLE_NAME}.id"]
joins << "JOIN #{table_name} " \
"ON #{table_name}.id = #{TAGGING_TABLE_NAME}.taggable_id AND #{TAGGING_TABLE_NAME}.taggable_type = '#{klass}'"
if options[:project_join]
joins << options[:project_join]
elsif options[:project] || !options[:without_projects]
joins << "JOIN #{PROJECT_TABLE_NAME} ON #{table_name}.project_id = #{PROJECT_TABLE_NAME}.id"
end
joins
end
end
end

View file

@ -4,6 +4,7 @@ class Dashboard < ActiveRecord::Base
include Additionals::EntityMethods
class SystemDefaultChangeException < StandardError; end
class ProjectSystemDefaultChangeException < StandardError; end
belongs_to :project
@ -302,7 +303,10 @@ class Dashboard < ActiveRecord::Base
config = { dashboard_id: id,
block: block }
settings[:user_id] = User.current.id if !options.key?(:skip_user_id) || !options[:skip_user_id]
if !options.key?(:skip_user_id) || !options[:skip_user_id]
settings[:user_id] = User.current.id
settings[:user_is_admin] = User.current.admin?
end
if settings.present?
settings.each do |key, setting|
@ -321,11 +325,11 @@ class Dashboard < ActiveRecord::Base
unique_params = settings.flatten
unique_params += options[:unique_params].reject(&:blank?) if options[:unique_params].present?
Rails.logger.debug "debug async_params for #{block}: unique_params=#{unique_params.inspect}"
# Rails.logger.debug "debug async_params for #{block}: unique_params=#{unique_params.inspect}"
config[:unique_key] = Digest::SHA256.hexdigest(unique_params.join('_'))
end
Rails.logger.debug "debug async_params for #{block}: config=#{config.inspect}"
# Rails.logger.debug "debug async_params for #{block}: config=#{config.inspect}"
config
end
@ -358,7 +362,10 @@ class Dashboard < ActiveRecord::Base
end
def validate_system_default
return if new_record? || system_default_was == system_default || system_default?
return if new_record? ||
system_default_was == system_default ||
system_default? ||
project_id.present?
raise SystemDefaultChangeException
end

View file

@ -41,9 +41,13 @@ class DashboardContent
with_project: true
},
max_occurs: DashboardContent::MAX_MULTIPLE_OCCURS },
'text' => { label: l(:label_text),
'text' => { label: l(:label_text_sync),
max_occurs: MAX_MULTIPLE_OCCURS,
partial: 'dashboards/blocks/text' },
'text_async' => { label: l(:label_text_async),
max_occurs: MAX_MULTIPLE_OCCURS,
async: { required_settings: %i[text],
partial: 'dashboards/blocks/text_async' } },
'news' => { label: l(:label_news_latest),
permission: :view_news },
'documents' => { label: l(:label_document_plural),

View file

@ -3,4 +3,7 @@ class DashboardRole < ActiveRecord::Base
belongs_to :dashboard
belongs_to :role
validates :dashboard, :role,
presence: true
end

View file

@ -1,5 +0,0 @@
Deface::Override.new virtual_path: 'account/register',
name: 'add-invisble-captcha',
insert_top: 'div.box',
original: 'a9c303821376a8d83cba32654629d71cc3926a1d',
partial: 'account/invisible_captcha'

View file

@ -1,8 +1,15 @@
unless Redmine::Plugin.installed? 'redmine_servicedesk'
# redmine_contacts does not provide hook
Deface::Override.new virtual_path: 'contacts/_form',
name: 'contacts-form-hook',
insert_bottom: 'div#contact_data',
original: 'df6cae24cfd26e5299c45c427fbbd4e5f23c313e',
partial: 'hooks/view_contacts_form'
if defined?(CONTACTS_VERSION_TYPE) && CONTACTS_VERSION_TYPE == 'PRO version'
Deface::Override.new virtual_path: 'contacts/_form',
name: 'contacts-pro-form-hook',
insert_bottom: 'div#contact_data',
original: 'df6cae24cfd26e5299c45c427fbbd4e5f23c313e',
partial: 'hooks/view_contacts_form'
else
Deface::Override.new virtual_path: 'contacts/_form',
name: 'contacts-form-hook',
insert_bottom: 'div#contact_data',
original: '217049684a0bcd7e404dc6b5b2348aae47ac8a72',
partial: 'hooks/view_contacts_form'
end
end

View file

@ -0,0 +1,5 @@
Deface::Override.new virtual_path: 'wiki/edit',
name: 'wiki-edit-bottom',
insert_before: 'fieldset',
original: 'ededb6cfd5adfe8a9723d00ce0ee23575c7cc44c',
partial: 'hooks/view_wiki_form_bottom'

View file

@ -0,0 +1,5 @@
Deface::Override.new virtual_path: 'wiki/show',
name: 'wiki-show-bottom',
insert_before: 'p.wiki-update-info',
original: 'd9f52aa98f1cb335314570d3f5403690f1b29145',
partial: 'hooks/view_wiki_show_bottom'

View file

@ -1,2 +0,0 @@
- if Additionals.setting?(:invisible_captcha)
= f.invisible_captcha :url, autocomplete: 'off'

View file

@ -1,7 +1,7 @@
- footer = Additionals.setting(:global_footer)
- footer = Additionals.setting :global_footer
- if footer.present?
.additionals-footer
= textilizable(footer)
= textilizable footer
- if @additionals_help_items.present?
javascript:
@ -9,7 +9,7 @@
$('a.help').parent().append("<ul class=\"menu-children\">#{escape_javascript @additionals_help_items}</ul>");
});
- if Additionals.setting?(:open_external_urls)
- if Additionals.setting? :open_external_urls
javascript:
$(function() {
$('a.external').attr({ 'target': '_blank',

View file

@ -1,2 +1,2 @@
- if Additionals.setting?(:add_go_to_top)
- if Additionals.setting? :add_go_to_top
a#gototop

View file

@ -7,8 +7,7 @@ table.list.issue-report.table-of-values
tbody
- options = { set_filter: 1 }
- @chart[:filters].each do |line|
- if line[:filter]
- options.merge! line[:filter]
- options.merge! line[:filter] if line[:filter]
tr class="#{cycle 'odd', 'even'}"
td.name class="#{line[:id].to_s == '0' ? 'summary' : ''}"
- if line[:filter].nil?

View file

@ -1,11 +1,13 @@
= render(partial: 'additionals/live_search_ajax_call.js', layout: false, formats: [:js])
- unless defined? classes
- classes = 'title'
- classes = 'title' unless defined? classes
h2 class="#{classes}"
= @query.new_record? ? l(title) : h(@query.name)
span.additionals-live-search
= text_field_tag(:search,
= text_field_tag :search,
q,
autocomplete: 'off',
class: 'live-search-field',
placeholder: l(:label_query_name_search))
placeholder: defined?(placeholder) ? placeholder : l(:label_query_name_search)
javascript:
observeLiveSearchField('search',
'query-result-list')

View file

@ -2,5 +2,4 @@
= additionals_library_load :font_awesome
= stylesheet_link_tag 'additionals', plugin: 'additionals'
= javascript_include_tag 'additionals', plugin: 'additionals'
- unless Redmine::Plugin.installed? 'redmine_hrm'
- render_custom_top_menu_item
- render_custom_top_menu_item unless Redmine::Plugin.installed? 'redmine_hrm'

View file

@ -1,18 +0,0 @@
javascript:
$(function() {
// when the #search field changes
$('#search').live_observe_field(2, function() {
var form = $('#query_form'); // grab the form wrapping the search bar.
var url = form.attr('action');
form.find('[name="c[]"] option').each(function(i, elem) {
$(elem).attr('selected', true)
})
var formData = form.serialize();
form.find('[name="c[]"] option').each(function(i, elem) {
$(elem).attr('selected', false)
})
$.get(url, formData, function(data) { // perform an AJAX get, the trailing function is what happens on successful get.
$("#query-result-list").html(data); // replace the "results" div with the result of action taken
});
});
});

View file

@ -21,7 +21,7 @@ javascript:
placeholder: "#{options[:placeholder].presence}",
allowClear: #{options[:allow_clear].present? && options[:allow_clear] ? 'true' : 'false'},
minimumInputLength: 0,
width: "#{options[:width].presence || '60%'}",
width: "#{options[:width].presence || '90%'}",
templateResult: #{options[:template_result].presence || 'formatNameWithIcon'},
#{options[:template_selection].present? ? ('templateSelection: ' + options[:template_selection]) : nil}
})

View file

@ -16,8 +16,8 @@ fieldset.box
- columns.each do |s|
label.inline
- value = @settings[setting_name_totals.to_sym].present? ? @settings[setting_name_totals.to_sym].include?(s.name.to_s) : false
= check_box_tag("settings[#{setting_name_totals}][]",
= check_box_tag "settings[#{setting_name_totals}][]",
s.name,
value,
id: nil)
id: nil
= s.caption

View file

@ -1,30 +0,0 @@
- if defined?(show_always) && show_always || entry.tag_list.present?
.tags.attribute
- unless defined? hide_label
span.label
= l(:field_tag_list)
' :
- if defined?(editable) && editable
#tags-data
= additionals_tag_links(entry.tags,
project: @project,
tags_without_color: defined?(tags_without_color) ? tags_without_color : false)
'
span.contextual
= link_to l(:label_edit_tags),
{},
onclick: "$('#edit_tags_form').show(); $('#tags-data').hide(); return false;",
id: 'edit_tags_link'
#edit_tags_form style="display: none;"
= form_tag(update_url, method: :put, multipart: true) do
= render partial: 'tags_form'
'
= submit_tag l(:button_save), class: 'button-small'
'
= link_to l(:button_cancel), {}, onclick: "$('#edit_tags_form').hide(); $('#tags-data').show(); return false;"
- else
= additionals_tag_links(entry.tags,
project: @project,
tags_without_color: defined?(tags_without_color) ? tags_without_color : false)

View file

@ -1,7 +1,3 @@
' Need Help? :
= link_to(l(:label_additionals_doc),
'https://additionals.readthedocs.io/en/latest/',
class: 'external',
target: '_blank',
rel: 'noopener')
= link_to_external l(:label_additionals_doc), 'https://additionals.readthedocs.io/en/latest/'
= render_tabs additionals_settings_tabs

View file

@ -1,5 +0,0 @@
p
= additionals_settings_checkbox :invisible_captcha,
disabled: (true unless Setting.self_registration?)
em.info
= t(:invisible_captcha_info_html)

View file

@ -1,6 +1,6 @@
h2 = l(:label_settings_macros) + " (#{@available_macros.count})"
.info = t(:label_top_macros_help_html)
.info = t :label_top_macros_help_html
br
.box
- @available_macros.each do |macro, options|

View file

@ -1,13 +1,6 @@
table.list
tr
td.name
= l :label_system_info
| :
td.name
= system_info
tr
td.name
= l :label_uptime
| :
td.name
= system_uptime
- AdditionalsInfo.system_infos.each_value do |system_info|
tr
td.name
= "#{system_info[:label]}:"
td.name = system_info[:value]

View file

@ -1 +0,0 @@
== @tags.collect { |tag| { 'id' => tag.name, 'text' => tag.name } }.to_json

View file

@ -9,10 +9,7 @@
.splitcontent
.splitcontentleft
- if @dashboard.new_record?
= hidden_field_tag 'dashboard[dashboard_type]', @dashboard.dashboard_type
= hidden_field_tag 'dashboard[dashboard_type]', @dashboard.dashboard_type if @dashboard.new_record?
- if @project && @allowed_projects.present? && @allowed_projects.count > 1
p
= f.select :project_id,

View file

@ -6,6 +6,6 @@
- events_by_day = activity_dashboard_data settings, dashboard
- title = Additionals.true?(settings[:me_only]) ? l(:label_my_activity) : l(:label_activity)
h3 = link_to title, activity_path(user_id: User.current,
from: events_by_day.keys.first)
from: events_by_day.keys.first)
= render partial: 'activities/activities', locals: { events_by_day: events_by_day }

View file

@ -1,17 +1,17 @@
- max_entries = settings[:max_entries].presence || DashboardContent::DEFAULT_MAX_ENTRIES
div id="#{block}-settings" style="#{'display: none;' if hide}"
= form_tag(_update_layout_setting_dashboard_path(@project, @dashboard), remote: true) do
= hidden_field_tag "settings[#{block}][me_only]", '0'
.box
p
label
= l(:label_max_entries)
= l :label_max_entries
' :
= number_field_tag "settings[#{block}][max_entries]", max_entries, min: 1, max: 1000, required: true
= number_field_tag "settings[#{block}][max_entries]",
settings[:max_entries].presence || DashboardContent::DEFAULT_MAX_ENTRIES,
min: 1, max: 1000, required: true
p
label
= l(:label_only_my_activities)
= l :label_only_my_activities
' :
= check_box_tag "settings[#{block}][me_only]", '1', Additionals.true?(settings[:me_only])

View file

@ -11,10 +11,7 @@
- if feed[:items].count.positive?
ul.reporting-list.feed
- feed[:items].each do |item|
li
= link_to item[:title],
item[:link],
class: 'external', rel: 'noopener noreferrer', target: '_blank'
li = link_to_external item[:title], item[:link]
- else
p.nodata = l :label_no_data
- elsif settings[:url].blank?

View file

@ -6,7 +6,7 @@ h3.icon.icon-news = l :label_news_latest
.box
p
label
= l(:label_max_entries)
= l :label_max_entries
' :
= number_field_tag "settings[#{block}][max_entries]", max_entries, min: 1, max: 1000, required: true
p

View file

@ -1,7 +1,7 @@
- if @subprojects.any?
h3.icon.icon-projects
= l(:label_subproject_plural)
= l :label_subproject_plural
ul.subprojects
- @subprojects.each do |project|
li
= link_to(project.name, project_path(project), class: project.css_classes).html_safe
= link_to project.name, project_path(project), class: project.css_classes

View file

@ -22,6 +22,7 @@
- if count.positive?
/ required by some helpers of other plugins
- @query = query
= render partial: query_block[:list_partial],
locals: { query_block[:entities_var] => query.send(query_block[:entries_method],
limit: settings[:max_entries] || DashboardContent::DEFAULT_MAX_ENTRIES),

View file

@ -1,26 +1,12 @@
ruby:
title = settings[:title] || l(:label_text)
text = settings[:text]
- if title.present?
h3 = title
- if settings[:text].nil?
h3
= l :label_text_sync
- elsif settings[:title].present?
h3
= settings[:title]
- if @can_edit
div id="#{block}-settings" style='display: none;'
= form_tag(_update_layout_setting_dashboard_path(@project, @dashboard), remote: true) do
.box
p
label
= l :field_title
' :
= text_field_tag "settings[#{block}][title]", title
p
= text_area_tag "settings[#{block}][text]", text, rows: addtionals_textarea_cols(text), class: 'wiki-edit'
= wikitoolbar_for "settings_#{block}_text"
p
= submit_tag l(:button_save)
'
= link_to_function l(:button_cancel), "$('##{block}-settings').toggle();"
= render partial: 'dashboards/blocks/text_async_settings', locals: { block: block, settings: settings }
.wiki
= textilizable text
= textilizable settings[:text]

View file

@ -0,0 +1,10 @@
- cache render_async_cache_key(_dashboard_async_blocks_path(@project,
dashboard.async_params(block, async, settings))),
expires_in: async[:cache_expires_in] || DashboardContent::RENDER_ASYNC_CACHE_EXPIRES_IN,
skip_digest: true do
- if settings[:title].present?
h3 = settings[:title]
.wiki
= textilizable settings[:text]

View file

@ -0,0 +1,15 @@
div id="#{block}-settings" style='display: none;'
= form_tag(_update_layout_setting_dashboard_path(@project, @dashboard), remote: true) do
.box
p
label
= l :field_title
' :
= text_field_tag "settings[#{block}][title]", (settings[:title] || l(:label_text_sync))
p
= text_area_tag "settings[#{block}][text]", settings[:text], rows: addtionals_textarea_cols(settings[:text]), class: 'wiki-edit'
= wikitoolbar_for "settings_#{block}_text"
p
= submit_tag l :button_save
'
= link_to_function l(:button_cancel), "$('##{block}-settings').toggle();"

View file

@ -1,7 +1,6 @@
h2 = l(:button_dashboard_edit)
= labelled_form_for :dashboard,
@dashboard,
url: { action: 'update', id: @dashboard.id },
html: { multipart: true, method: :put, id: 'dashboard-form' } do |f|
html: { multipart: true, id: 'dashboard-form' } do |f|
= render partial: 'form', locals: { f: f }
= submit_tag l(:button_save)

View file

@ -0,0 +1 @@
= call_hook :view_wiki_form_bottom, content: @content, page: @page

View file

@ -0,0 +1 @@
= call_hook :view_wiki_show_bottom, content: @content, page: @page

View file

@ -1,5 +1,9 @@
- if User.current.logged? && @issue.editable? && Additionals.setting?(:issue_assign_to_me) && \
@issue.assigned_to_id != User.current.id && @project.assignable_users.detect { |u| u.id == User.current.id }
- if User.current.logged? && \
Additionals.setting?(:issue_assign_to_me) && \
@issue.editable? && \
@issue.safe_attribute?('assigned_to_id') && \
@issue.assigned_to_id != User.current.id && \
@project.assignable_users.detect { |u| u.id == User.current.id }
= link_to font_awesome_icon('far_user-circle', post_text: l(:button_assign_to_me)),
issue_assign_to_me_path(@issue), method: :put,
class: 'assign-to-me'

View file

@ -1,19 +1,19 @@
- if Additionals.setting?(:issue_change_status_in_sidebar) && \
@issue && \
User.current.allowed_to?(:edit_issues, @project) && \
(!@issue.closed? || User.current.allowed_to?(:edit_closed_issues, @project))
- statuses = @issue.sidbar_change_status_allowed_to(User.current)
@issue && \
User.current.allowed_to?(:edit_issues, @project) && \
(!@issue.closed? || User.current.allowed_to?(:edit_closed_issues, @project))
- statuses = @issue.sidbar_change_status_allowed_to User.current
- if statuses.present?
h3 = l(:label_issue_change_status)
h3 = l :label_issue_change_status
ul.issue-status-change-sidebar
- statuses.each do |s|
- if s != @issue.status
- unless s == @issue.status
li
- if s.is_closed?
= link_to(font_awesome_icon('fas_caret-square-left', post_text: s.name),
= link_to font_awesome_icon('fas_caret-square-left', post_text: s.name),
issue_change_status_path(@issue, new_status_id: s.id),
method: :put, class: "status-switch status-#{s.id}")
method: :put, class: "status-switch status-#{s.id}"
- else
= link_to(font_awesome_icon('far_caret-square-left', post_text: s.name),
= link_to font_awesome_icon('far_caret-square-left', post_text: s.name),
issue_change_status_path(@issue, new_status_id: s.id),
method: :put, class: "status-switch status-#{s.id}")
method: :put, class: "status-switch status-#{s.id}"

View file

@ -6,8 +6,7 @@
edit_project_dashboard_path(@project, @dashboard),
class: 'icon icon-edit'
- unless Redmine::Plugin.installed? 'redmine_reporting'
= bookmark_link @project
= bookmark_link @project unless Redmine::Plugin.installed? 'redmine_reporting'
= call_hook :view_project_contextual_links, project: @project
- if @dashboard&.editable?
@ -49,9 +48,7 @@
class: 'icon icon-del'
= sidebar_action_toggle @dashboard_sidebar, @dashboard, @project
- unless @dashboard_sidebar
= render_dashboard_actionlist @dashboard, @project
= render_dashboard_actionlist @dashboard, @project unless @dashboard_sidebar
= call_hook :view_project_actions_dropdown, project: @project
- if User.current.allowed_to?(:edit_project, @project)

View file

@ -1,4 +1,3 @@
- if Additionals.setting?(:new_issue_on_profile) && @memberships.present?
- project_url = memberships_new_issue_project_url(user, @memberships)
- if project_url.present?
= link_to(l(:label_issue_new), project_url, class: 'user-new-issue icon icon-add')
- project_url = memberships_new_issue_project_url user, @memberships
= link_to l(:label_issue_new), project_url, class: 'user-new-issue icon icon-add' if project_url.present?

View file

@ -21,8 +21,7 @@
= delete_dashboard_link dashboard_path(@dashboard),
class: 'icon icon-del'
= sidebar_action_toggle @dashboard_sidebar, @dashboard
- unless @dashboard_sidebar
= render_dashboard_actionlist @dashboard
= render_dashboard_actionlist @dashboard unless @dashboard_sidebar
= call_hook :view_welcome_show_actions_dropdown

View file

@ -7,6 +7,7 @@
= avatar(user, size: 50)
.user.line[style="font-weight: bold;"]
= link_to_user user
- if !user_roles.nil? && user_roles[user.id]
.user.line
= l :field_role
@ -16,6 +17,7 @@
= l :field_login
' :
= link_to user.login, "/users/#{user.id}"
- unless user.pref.hide_mail
.user.line
= l :field_mail

File diff suppressed because one or more lines are too long

View file

@ -32,3 +32,61 @@ function formatFontawesomeText(icon) {
return icon.text;
}
}
/* exported observeLiveSearchField */
function observeLiveSearchField(fieldId, targetId, target_url) {
$('#'+fieldId).each(function() {
var $this = $(this);
$this.addClass('autocomplete');
$this.attr('data-search-was', $this.val());
var check = function() {
var val = $this.val();
if ($this.attr('data-search-was') != val){
$this.attr('data-search-was', val);
var form = $('#query_form'); // grab the form wrapping the search bar.
var formData;
var url;
form.find('[name="c[]"] option').each(function(i, elem) {
$(elem).attr('selected', true);
});
if (typeof target_url === 'undefined') {
url = form.attr('action');
formData = form.serialize();
} else {
url = target_url;
formData = { q: val };
}
form.find('[name="c[]"] option').each(function(i, elem) {
$(elem).attr('selected', false);
});
$.ajax({
url: url,
type: 'get',
data: formData,
success: function(data){ if(targetId) $('#'+targetId).html(data); },
beforeSend: function(){ $this.addClass('ajax-loading'); },
complete: function(){ $this.removeClass('ajax-loading'); }
});
}
};
/* see https://stackoverflow.com/questions/1909441/how-to-delay-the-keyup-handler-until-the-user-stops-typing */
var search_delay = function(callback) {
var timer = 0;
return function() {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
callback.apply(context, args);
}, 400 || 0);
};
};
$this.keyup(search_delay(check));
});
}

View file

@ -1,52 +0,0 @@
// see https://github.com/splendeo/jquery.observe_field
(function($) {
'use strict';
$.fn.live_observe_field = function(frequency, callback) {
frequency = frequency * 100; // translate to milliseconds
return this.each(function() {
var $this = $(this);
var prev = $this.val();
var prevChecked = $this.prop('checked');
var check = function() {
if (removed()) {
// if removed clear the interval and don't fire the callback
if (ti)
clearInterval(ti);
return;
}
var val = $this.val();
var checked = $this.prop('checked');
if (prev != val || checked != prevChecked) {
prev = val;
prevChecked = checked;
$this.map(callback); // invokes the callback on $this
}
};
var removed = function() {
return $this.closest('html').length == 0;
};
var reset = function() {
if (ti) {
clearInterval(ti);
ti = setInterval(check, frequency);
}
};
check();
var ti = setInterval(check, frequency); // invoke check periodically
// reset counter after user interaction
$this.bind('keyup click mousemove', reset); // mousemove is for selects
});
};
})(jQuery);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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,5 +1,16 @@
$(function() {
mermaid.initialize({ startOnLoad: true,
theme: 'default',
themeVariables: { 'fontSize': '12px' } });
if (globalThis !== undefined && globalThis.mermaidTheme !== undefined) {
var mermaidTheme = globalThis.mermaidTheme;
} else {
var mermaidTheme = 'default';
}
if (globalThis !== undefined && globalThis.mermaidThemeVariables !== undefined) {
var mermaidThemeVariables = globalThis.mermaidThemeVariables;
} else {
var mermaidThemeVariables = { 'fontSize': '12px' };
}
mermaid.initialize({
startOnLoad: true,
theme: mermaidTheme,
themeVariables: mermaidThemeVariables });
});

View file

@ -14,7 +14,7 @@ function filterAdditionalsFormatState (opt) {
function additionals_transform_to_select2(field){
var field_format = availableFilters[field]['field_format'];
var initialized_select2 = $('#tr_' + field + ' .values .select2');
if (initialized_select2.length == 0 && $.inArray(field_format, additionals_field_formats) >= 0) {
if (initialized_select2.length == 0 && (typeof additionals_field_formats !== 'undefined') && $.inArray(field_format, additionals_field_formats) >= 0) {
$('#tr_' + field + ' .toggle-multiselect').hide();
$('#tr_' + field + ' .values .value').attr('multiple', 'multiple');
$('#tr_' + field + ' .values .value').select2({
@ -32,7 +32,7 @@ function additionals_transform_to_select2(field){
},
placeholder: ' ',
minimumInputLength: 1,
width: '60%',
width: '90%',
templateResult: filterAdditionalsFormatState
}).on('select2:open', function (e) {
$(this).parent('span').find('.select2-search__field').val(' ').trigger($.Event('input', { which: 13 })).val('');
@ -168,7 +168,7 @@ function buildSelect2Options(options) {
allowClear: !!options['allow_clear'],
minimumInputLength: options['min_input_length'] || 0,
templateResult: window[options['format_state']],
width: options['width'] || '60%'
width: options['width'] || '90%'
};
addDataSourceOptions(result, options);

View file

@ -16,6 +16,10 @@
padding-bottom: 10px;
}
span.additionals-live-search input::placeholder {
font-size: 90%;
}
.query-description,
.dashboard-description {
color: #666;
@ -34,7 +38,6 @@
/* Go to top link */
.gototop {
border-top: 1px solid #eee;
display: block;
margin-top: 20px;
padding: 10px 0;
@ -42,6 +45,14 @@
clear: both;
}
.gototop::before {
font-family: Font Awesome\ 5 Free;
font-weight: 900;
content: "\f139"; /* fas fa-chevron-circle-up */
padding-right: 4px;
opacity: 0.8;
}
/* Footer */
.additionals-footer {
text-align: center;
@ -169,83 +180,22 @@ div.clear-both { clear: both; }
text-align: left;
}
.clipboard_button {
.clipboard-button {
padding-bottom: 2px;
padding-top: 2px;
text-align: center;
float: left;
}
/* TAGs */
ul.tags {
list-style: none;
padding: 0;
}
span.additionals-tag-label-color {
display: inline-block;
margin-bottom: 5px !important;
border-radius: 2px !important;
}
td.tags span.additionals-tag-label-color {
display: inline-block;
line-height: normal;
margin: 2px !important;
}
.additionals-tag-label-color {
padding: 2px 4px;
font-size: 10px !important;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 2px;
}
.additionals-tag-label-color a::before {
font-family: Font Awesome\ 5 Free;
font-size: 0.9em;
font-weight: 900;
content: "\f02b"; /* fas fa-tag */
padding-right: 3px;
}
ul.tags li { margin: 0.25em 0; }
.additionals-tag-label-color .tag-count,
.tag-label .tag-count {
font-size: 0.75em;
margin-left: 0.5em;
}
span.additionals-tag-label-color:hover a {
text-decoration: none !important;
}
#edit_tags_form.box { margin: 1px 5px 0 0; }
#edit_tags_form.box label {
margin-right: 5px;
font-weight: bold;
}
#edit_tags_form.box #contact_tags {
margin-bottom: 10px;
}
div#tags-data span.contextual {
float: none;
padding-left: 0;
}
#edit_tags_link { opacity: 0; }
#tags-data:hover #edit_tags_link { opacity: 1; }
.clipboard-text { cursor: pointer; }
img.additionals-avatar { margin-right: 0.25em; }
/* Live search */
.additionals-live-search input.live-search-field { font-size: 16px; }
.additionals-live-search input.live-search-field {
font-size: 16px;
width: 65%;
}
.additionals-live-search {
margin-left: 5px;

File diff suppressed because one or more lines are too long

View file

@ -5,6 +5,7 @@
position: relative;
vertical-align: middle;
}
.select2-container .select2-selection--single {
box-sizing: border-box;
cursor: pointer;
@ -13,6 +14,7 @@
user-select: none;
-webkit-user-select: none;
}
.select2-container .select2-selection--single .select2-selection__rendered {
display: block;
padding-left: 8px;
@ -21,13 +23,16 @@
text-overflow: ellipsis;
white-space: nowrap;
}
.select2-container .select2-selection--single .select2-selection__clear {
position: relative;
}
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
padding-right: 8px;
padding-left: 20px;
}
.select2-container .select2-selection--multiple {
box-sizing: border-box;
cursor: pointer;
@ -36,16 +41,19 @@
user-select: none;
-webkit-user-select: none;
}
.select2-container .select2-selection--multiple .select2-selection__rendered {
/*display: inline-block;*/
/* display: inline-block; */
overflow: hidden;
padding-left: 8px;
text-overflow: ellipsis;
white-space: nowrap;
}
.select2-container .select2-search--inline {
float: left;
}
.select2-container .select2-search--inline .select2-search__field {
box-sizing: border-box;
border: none;
@ -53,6 +61,7 @@
margin-top: 2px;
padding: 0;
}
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none;
}
@ -84,6 +93,7 @@
user-select: none;
-webkit-user-select: none;
}
.select2-results__option[aria-selected] {
cursor: pointer;
}
@ -108,14 +118,17 @@
display: block;
padding: 4px;
}
.select2-search--dropdown .select2-search__field {
padding: 4px;
width: 100%;
box-sizing: border-box;
}
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none;
}
.select2-search--dropdown.select2-search--hide {
display: none;
}
@ -153,15 +166,19 @@
.select2-container--default .select2-selection--single {
background-color: #fff;
background-image: none !important;
border: 1px solid #9eb1c2;
border-radius: 2px;
height: 21px;
height: 24px;
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
padding-left: 21px;
padding-left: 8px !important;
padding-top: 2px;
line-height: 18px;
font-size: 11px;
height: 23px;
position: relative;
}
.select2-container--default .select2-selection--single .select2-selection__clear {
@ -170,16 +187,19 @@
font-weight: normal;
color: #888;
}
.select2-container--default .select2-selection--single .select2-selection__placeholder {
color: #999;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 20px;
position: absolute;
top: 0px;
top: 0;
right: 1px;
width: 20px;
}
.select2-container--default .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
@ -192,42 +212,51 @@
top: 50%;
width: 0;
}
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left;
}
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
left: 1px;
right: auto;
}
.select2-container--default.select2-container--disabled .select2-selection--single {
background-color: #eee;
cursor: default;
}
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
display: none;
}
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px;
}
.select2-container--default .select2-selection--multiple {
background-color: white;
border: 1px solid #9eb1c2;
border: 1px solid #ccc;
border-radius: 2px;
cursor: text;
min-height: 20px;
}
#sidebar .select2-container--default .select2-selection--multiple .select2-selection__rendered,
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
box-sizing: border-box;
list-style: none;
margin: 0;
padding: 0 2px 2px 2px;
margin: -3px 0 -4px 0;
padding: 2px 2px 2px 2px;
width: 100%;
}
.select2-container--default .select2-selection--multiple .select2-selection__rendered li {
list-style: none;
}
.select2-container--default .select2-selection--multiple .select2-selection__clear {
cursor: pointer;
float: right;
@ -247,6 +276,7 @@
margin-top: 3px;
padding: 0 3px;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
color: #aaa;
cursor: pointer;
@ -254,43 +284,53 @@
font-weight: normal;
margin-right: 2px;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #333;
}
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
float: right;
}
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto;
}
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto;
}
.select2-container--default.select2-container--focus .select2-selection--multiple {
border: solid #aaa 1px;
outline: 0;
}
.select2-container--default.select2-container--disabled .select2-selection--multiple {
background-color: #eee;
cursor: default;
}
.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
display: none;
}
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.select2-container--default .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa;
}
.select2-container--default .select2-search--inline .select2-search__field {
background: transparent;
border: none;
@ -298,48 +338,61 @@
box-shadow: none;
-webkit-appearance: textfield;
}
.select2-container--default .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto;
}
.select2-container--default .select2-results__option[role=group] {
padding: 0;
}
.select2-container--default .select2-results__option[aria-disabled=true] {
color: #999;
}
.select2-container--default .select2-results__option[aria-selected=true] {
background-color: #eee;
}
.select2-container--default .select2-results__option .select2-results__option {
padding-left: 1em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__group {
padding-left: 0;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option {
margin-left: -1em;
padding-left: 2em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -2em;
padding-left: 3em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -3em;
padding-left: 4em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -4em;
padding-left: 5em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -5em;
padding-left: 6em;
}
.select2-container--default .select2-results__option--highlighted[aria-selected] {
background-color: #eef5fd;
}
.select2-container--default .select2-results__group {
cursor: default;
display: block;
@ -351,13 +404,12 @@
}
.filter .select2-selection--multiple .select2-search--inline .select2-search__field {
border: 0px !important;
height: inherit !important;
padding: 0px !important;
border: 0 !important;
padding: 0 !important;
width: 2em !important;
}
.filter .select2-container--default .select2-selection--multiple .select2-selection__choice {
border: 0px;
border: 0;
padding: 2px 5px;
}

View file

@ -1,16 +1,12 @@
<?xml version="1.0" standalone="no"?>
<!--
Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->
<!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" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20200314 at Wed Jul 15 11:59:41 2020
Created by FontForge 20200314 at Wed Jan 13 11:57:55 2021
By Robert Madole
Copyright (c) Font Awesome
</metadata>
<defs>
<!-- Font Awesome Free 5.15.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><defs>
<font id="FontAwesome5Brands-Regular" horiz-adv-x="448" >
<font-face
font-family="Font Awesome 5 Brands Regular"
@ -160,6 +156,79 @@ c-0.00292969 -0.337891 -0.00488281 -0.676758 -0.00488281 -1.01562c0 -7.25977 0.6
c0.00878906 0 0.140625 -0.0732422 0.149414 -0.0732422v-87.3799z" />
<glyph glyph-name="unsplash" unicode="&#xe07c;"
d="M448 217.83v-249.83h-448v249.83h141.13v-124.92h165.74v124.92h141.13zM306.87 416v-124.91h-165.74v124.91h165.74z" />
<glyph glyph-name="cloudflare" unicode="&#xe07d;" horiz-adv-x="640"
d="M407.906 128.087c12.1836 -0.574219 22.2178 -5.50977 28.2334 -13.9023c6.54883 -9.09961 8 -21.5 4.10059 -34.8994l-3.27344 -11.2656c-0.681641 -2.28125 -2.7793 -3.95508 -5.27051 -4c-0.0419922 -0.000976562 -0.0791016 -0.0195312 -0.12207 -0.0195312
l-426.101 0.0507812c-2.26172 0.00878906 -4.13379 1.69238 -4.44434 3.87109c-0.676758 4.58691 -1.02637 9.18457 -1.0293 13.958c0 52.3926 41.9238 95.0137 94.2002 96.5303c-1.37402 5.39062 -2.05469 10.9785 -2.05469 16.7939
c0 37.5967 30.5234 68.1201 68.1201 68.1201c15.3838 0 29.583 -5.11035 40.9912 -13.7246c20.542 59.582 77.085 102.308 143.607 102.308c72.1562 0 132.629 -50.417 148.085 -117.914c0.107422 -0.513672 0.164062 -1.03906 0.164062 -1.58398v-0.046875
c0 -0.0332031 -0.00292969 -0.0683594 -0.00292969 -0.101562c0 -0.998047 -0.18457 -1.9541 -0.521484 -2.83496l-13.2861 -34.542c-10.4756 -27.21 -40.3906 -49.5234 -68.0215 -50.7842l-232.94 -2.93555c-2.48145 -0.173828 -4.5625 -1.82227 -5.36035 -4.07617
c-0.178711 -0.493164 -0.275391 -1.03223 -0.275391 -1.58691c0 -0.945312 0.283203 -1.8252 0.768555 -2.55957c0.8125 -1.14258 2.13379 -1.89355 3.63281 -1.92676zM513.856 226.9c69.668 0 126.144 -56.2002 126.147 -125.533
c0 -0.0458984 -0.0175781 -0.0644531 -0.0175781 -0.110352c0 -11.7441 -1.62598 -23.1123 -4.66406 -33.8896c-0.571289 -1.94629 -2.37012 -3.37012 -4.5 -3.37012h-0.0390625h-175.91c-0.0478516 0 -0.0898438 0.0166016 -0.135742 0.0166016
c-1.44727 0.0595703 -2.60449 1.25391 -2.60449 2.71484c0 0.339844 0.0634766 0.666016 0.176758 0.96582l3.69531 9.60547c10.4766 27.21 40.3916 49.5146 68.1455 50.7842l51.125 2.93945c2.47559 0.179688 4.55078 1.82617 5.35059 4.07422
c0.177734 0.492188 0.274414 1.03027 0.274414 1.58301c0 0.957031 -0.291016 1.84766 -0.788086 2.58594c-0.785156 1.11035 -2.06152 1.84375 -3.51074 1.89453l-49.1992 2.93848c-12.1846 0.577148 -22.2188 5.5 -28.2383 13.9004
c-6.54883 9.10352 -8 21.4902 -4.09961 34.8896l9.07617 31.1934c0.447266 1.45508 1.75391 2.53613 3.32422 2.65332c2.12012 0.101562 4.25 0.164062 6.3916 0.164062z" />
<glyph glyph-name="guilded" unicode="&#xe07e;"
d="M443.427 384c0.00195312 -0.518555 0.0253906 -0.367188 0.0253906 -0.885742c0 -29.1934 -2.00293 -57.9229 -5.87891 -86.0576h-336.147s0.366211 -52.0498 27.0918 -105.883c27.458 -51.8174 65.3164 -85.1025 96.5488 -98.3623
c32.2695 15.082 63.4434 41.2695 80.4561 69.4824h-88.5898c-22.9229 18.998 -40.96 50.5146 -45.0996 86.9443h259.889c-12.8154 -58.5713 -40.0088 -111.838 -65.916 -145.762c-35.8154 -46.7773 -84.2695 -82.8105 -140.55 -103.477
c-1.25586 0 -113.21 33.8652 -177.267 161.642c-21.2266 42.2988 -43.418 119.099 -43.418 222.358h438.855z" />
<glyph glyph-name="hive" unicode="&#xe07f;" horiz-adv-x="512"
d="M260.353 193.122c0.191406 -0.329102 0.300781 -0.716797 0.300781 -1.12402c0 -0.404297 -0.107422 -0.783203 -0.294922 -1.11133l-127.412 -221.777c-0.380859 -0.666992 -1.09473 -1.11621 -1.91602 -1.11621c-0.818359 0 -1.53223 0.445312 -1.91406 1.10645
l-128.816 221.778c-0.189453 0.328125 -0.297852 0.713867 -0.297852 1.12012s0.108398 0.787109 0.297852 1.11523l127.409 221.777c0.380859 0.666016 1.09473 1.11523 1.91602 1.11523c0.817383 0 1.53125 -0.445312 1.91309 -1.10547zM299.431 218.835l-110.624 193.824
c-0.189453 0.327148 -0.298828 0.709961 -0.298828 1.11523c0 1.21973 0.983398 2.21094 2.19922 2.22559h66.5078c0.81543 -0.00195312 1.52539 -0.447266 1.90039 -1.11133l110.625 -193.823c0.189453 -0.328125 0.298828 -0.709961 0.298828 -1.11523
c0 -1.21973 -0.983398 -2.21191 -2.19922 -2.22656h-66.5088c-0.81543 0.00292969 -1.52441 0.448242 -1.90039 1.11133zM511.7 193.114c0.1875 -0.328125 0.294922 -0.711914 0.294922 -1.11621c0 -0.405273 -0.107422 -0.78418 -0.294922 -1.1123l-126.808 -221.773
c-0.376953 -0.664062 -1.08887 -1.11035 -1.90527 -1.1123h-66.6006c-1.21875 0.0117188 -2.20312 1.00684 -2.20312 2.22852c0 0.404297 0.108398 0.78418 0.297852 1.11133l126.171 220.66l-126.168 220.66c-0.189453 0.327148 -0.298828 0.708984 -0.298828 1.11426
c0 1.2207 0.985352 2.21387 2.2041 2.22559h66.6006c0.818359 -0.000976562 1.53125 -0.447266 1.91016 -1.1123zM366.016 163.083c1.2168 -0.0136719 2.19922 -1.00879 2.19922 -2.22852c0 -0.405273 -0.108398 -0.785156 -0.297852 -1.1123l-108.8 -190.631
c-0.375 -0.664062 -1.08496 -1.10938 -1.90039 -1.11133h-66.5088c-1.21582 0.0146484 -2.19824 1.00879 -2.19824 2.22852c0 0.405273 0.108398 0.785156 0.297852 1.1123l108.801 190.631c0.374023 0.664062 1.08398 1.10938 1.89941 1.11133h66.5078z" />
<glyph glyph-name="innosoft" unicode="&#xe080;"
d="M422.559 288.29l0.00292969 -190.955c0.0253906 -12.4102 -5.87793 -22.8965 -16.623 -29.5283l-164.527 -94.9951c-5.08008 -3.04102 -11.0938 -4.79004 -17.4404 -4.79004c-6.11523 0 -11.8545 1.62402 -16.8096 4.46387l-118.794 68.583l247.049 142.627v-56
l-150.051 -86.627l32.7227 -18.9004c1.74805 -0.97168 3.78613 -1.52441 5.92676 -1.52441c2.18457 0 4.23633 0.576172 6.01074 1.58691l138.111 79.7441c3.54883 2.08008 5.91992 5.92578 5.91992 10.332v0.0361328v138.281l-308.407 -178.066
c-3.94629 -2.25293 -8.57129 -3.54102 -13.4365 -3.54102c-4.83301 0 -9.37207 1.27051 -13.2998 3.49609c-8.39453 4.75586 -13.3037 13.293 -13.4736 23.4287v191.5c0.518555 12.7334 6.65527 23.0039 17.2891 29.124l164.601 95.0254
c11.5 5.98535 22.8076 5.85938 33.7998 -0.269531l118.513 -68.4072l-247.061 -142.637v56l150.062 86.6367l-32.6553 18.8525c-1.76367 0.998047 -3.82715 1.56738 -5.99609 1.56738c-2.15137 0 -4.17285 -0.55957 -5.92578 -1.54199l-138.076 -79.7129
c-3.60352 -2.04785 -6.02734 -5.90723 -6.04688 -10.3398v-138.387l308.539 178.142c3.88281 2.24414 8.44531 3.5293 13.25 3.5293c4.70801 0 9.13086 -1.23438 12.9609 -3.39648c8.16406 -4.63184 13.6914 -13.3291 13.8652 -23.3369z" />
<glyph glyph-name="instalod" unicode="&#xe081;" horiz-adv-x="512"
d="M153.384 -32l50.8447 146.789l298.325 57.4463l-115.44 -204.235h-233.729zM504.726 207.922l-144.495 -27.8223l-204.562 235.9h231.444zM124.386 399.191l101.241 -116.752l-102.391 -295.594l-115.962 205.154z" />
<glyph glyph-name="octopus-deploy" unicode="&#xe082;" horiz-adv-x="512"
d="M455.6 98.7998c12.4395 -10.5996 42.6348 -26.4775 42.5244 -45.2666c-0.15332 -24.6084 -48.4248 5.24121 -53.8184 9.51953c6.13965 -10.7275 66.998 -74.1787 28.2627 -78.6943c-35.6562 -4.1582 -67.1406 45.6416 -88.5615 67.0225
c-36 35.9082 -29.7373 -43.5332 -29.8994 -59.9443c-0.257812 -25.9082 -18.5586 -78.4209 -51.4121 -44.2207c-27.1387 28.2314 -16.873 73.2607 -35.7383 104.622c-20.6641 34.3535 -55.0361 -34.3535 -63.627 -46.9258
c-9.59668 -14.042 -57.6094 -82.041 -76.709 -45.8125c-15.499 29.4004 9.2793 75.5127 21.4629 102.103c-4.44336 -9.65723 -35.9297 -23.9414 -45.1299 -28.5879c-20.7871 -10.4971 -41.8867 -16.7256 -65.2646 -15.0449
c-27.8916 2.00098 -38.3789 11.6572 8.42773 41.8574c38.5615 24.8389 83.8613 67.4209 66.6621 117.582c-9.37305 27.3301 -22.3574 50.7568 -24.0898 80.2998c-0.209961 3.56152 -0.25 7.08008 -0.25 10.6924c0 22.0957 3.9707 43.2715 11.2373 62.8516
c34.5752 92.8066 137.363 136.747 230.253 108.848c86.0371 -25.8398 145.23 -125.74 109.575 -212.79c-20.5752 -50.2334 -29.7959 -89.0205 16.0947 -128.11z" />
<glyph glyph-name="perbyte" unicode="&#xe083;"
d="M305.314 163.422c15.9307 0.000976562 28.5732 -4.5 37.9277 -13.5059s14.0322 -20.7842 14.0322 -35.335c0 -14.8936 -4.58984 -26.9307 -13.7705 -36.1113c-9.17969 -9.17969 -21.9111 -13.7695 -38.1934 -13.7695h-58.7109v98.7217h58.7148zM149.435 319.301
c15.9346 0.00488281 28.5791 -4.49609 37.9316 -13.5039s14.0283 -20.7871 14.0283 -35.3379c0 -14.8896 -4.58984 -26.9258 -13.7695 -36.1084c-9.17969 -9.18164 -21.9102 -13.7725 -38.1904 -13.7725h-58.7109v98.7227h58.7109zM366.648 416.002
c22.4385 -0.0253906 41.5996 -7.98145 57.4854 -23.8672s23.8418 -35.0479 23.8672 -57.4854v-285.296c-0.0253906 -22.4375 -7.98145 -41.5996 -23.8672 -57.4854s-35.0479 -23.8418 -57.4854 -23.8672h-285.295c-22.4385 0.0253906 -41.6006 7.98145 -57.4863 23.8672
s-23.8418 35.0479 -23.8672 57.4863v285.296c0.0253906 22.4375 7.98145 41.5996 23.8672 57.4854s35.0479 23.8408 57.4863 23.8662h285.295zM430.282 49.3535l-0.000976562 285.296c-0.0195312 17.5518 -6.24219 32.54 -18.668 44.9658s-27.4141 18.6484 -44.9648 18.668
h-285.295c-17.5508 -0.0195312 -32.5391 -6.24219 -44.9648 -18.668s-18.6484 -27.4141 -18.668 -44.9658v-285.296c0.0195312 -17.5508 6.24219 -32.5391 18.668 -44.9648s27.4141 -18.6484 44.9648 -18.668h285.295c17.5518 0.0195312 32.54 6.24219 44.9658 18.668
s18.6484 27.4141 18.668 44.9648zM305.313 319.301c15.9307 0.00488281 28.5732 -4.49609 37.9277 -13.5039s14.0322 -20.7871 14.0322 -35.3379c0 -14.8896 -4.58984 -26.9258 -13.7705 -36.1084c-9.17969 -9.18164 -21.9111 -13.7725 -38.1934 -13.7725h-58.7109v98.7227
h58.7148z" />
<glyph glyph-name="uncharted" unicode="&#xe084;"
d="M171.73 215.187c-0.0605469 -0.00195312 -0.12207 -0.000976562 -0.183594 -0.000976562c-0.673828 0 -1.3125 0.148438 -1.88672 0.414062l-115.933 67.9004v-85.2891c-0.0830078 -2.71289 -1.16895 -5.18555 -2.89941 -7.03906
c-1.6748 -1.54297 -3.91113 -2.4873 -6.36621 -2.4873c-0.0859375 0 -0.172852 0.000976562 -0.258789 0.00390625c-0.146484 -0.0078125 -0.296875 -0.00585938 -0.444336 -0.00585938c-1.65332 0 -3.2002 0.455078 -4.52344 1.24707l-22.3584 12.835
c-2.9541 1.50684 -4.9707 4.57031 -4.9707 8.1123c0 0.0566406 0.000976562 0.112305 0.00195312 0.168945v115.107c0.118164 3.54102 2.08105 6.61523 4.96875 8.28027l100.2 57.9668c1.40625 0.787109 3.04688 1.23535 4.77148 1.23535s3.3457 -0.448242 4.75098 -1.23535
l22.3584 -12.8389c2.9541 -1.50586 4.96973 -4.56934 4.96973 -8.11035c0 -0.0566406 -0.000976562 -0.113281 -0.00195312 -0.169922c-0.117188 -3.54199 -2.08008 -6.61523 -4.96777 -8.28125l-74.5293 -43.4727l116.757 -68.3184
c1.16016 -0.680664 1.96191 -1.89941 2.07129 -3.31152c0 -1.65723 -0.414062 -3.31348 -1.65723 -4.1416c-7.34473 -6.5459 -12.6475 -15.3301 -14.8994 -25.2559c-0.810547 -1.94629 -2.72949 -3.31348 -4.96777 -3.31348h-0.00195312zM323.272 70.2695
c4.96777 0 9.52734 -4.55469 10.3506 -9.1084v-26.085c-0.117188 -3.54199 -2.08105 -6.61523 -4.96777 -8.28125l-100.2 -57.5527c-1.48633 -0.772461 -3.18359 -1.22363 -4.96875 -1.24219c-0.146484 -0.00683594 -0.296875 -0.00488281 -0.444336 -0.00488281
c-1.65332 0 -3.2002 0.455078 -4.52441 1.24707l-100.199 57.5527c-2.95508 1.50586 -4.9707 4.56934 -4.9707 8.11035c0 0.0576172 0 0.114258 0.000976562 0.170898v26.085c0.0585938 5.22852 4.29492 9.46484 9.52344 9.52246
c0.146484 0.0078125 0.296875 0.00585938 0.444336 0.00585938c1.65332 0 3.20117 -0.456055 4.52441 -1.24707l74.5293 -43.0615v133.323c0.0615234 2.62891 2.21387 4.74609 4.85742 4.74609c0.469727 0 0.922852 -0.0673828 1.35254 -0.191406
c4.39453 -1.18066 8.99414 -1.80664 13.7588 -1.80664c5.29102 0 10.4023 0.776367 15.2256 2.2207c3.31055 1.24512 6.21094 -1.65527 6.21094 -4.55469v-134.152l74.5273 43.0625c1.50684 0.730469 3.2002 1.17383 4.96973 1.24121zM286.007 370
c-12.6943 0 -23 10.3057 -23 23s10.3057 23 23 23s23 -10.3057 23 -23s-10.3057 -23 -23 -23zM349.634 380.086c12.6943 0 23 -10.3057 23 -23s-10.3057 -23 -23 -23c-12.6934 0 -23 10.3057 -23 23s10.3066 23 23 23zM412.816 296.4c-12.6943 0 -23 10.3057 -23 23
c0 12.6934 10.3057 23 23 23c12.6934 0 23 -10.3066 23 -23c0 -12.6943 -10.3066 -23 -23 -23zM349.634 305.6c12.6943 0 23 -10.3057 23 -23c0 -12.6934 -10.3057 -23 -23 -23c-12.6934 0 -23 10.3066 -23 23c0 12.6943 10.3066 23 23 23zM286.007 222.356
c-12.6943 0 -23 10.3018 -23 22.9951v0.00488281c0 12.6934 10.3057 23 23 23s23 -10.3066 23 -23c0 -12.6943 -10.3057 -23 -23 -23zM223.933 185.998c-12.6934 0 -23 10.3018 -23 22.9961v0.00390625c0 12.6943 10.3066 23 23 23c12.6943 0 23 -10.3057 23 -23
s-10.3057 -23 -23 -23zM412.816 268.356c12.6924 0 22.9971 -10.3086 23 -23c0 -12.6943 -10.3066 -23 -23 -23c-12.6943 0 -23 10.3057 -23 23c0 12.6934 10.3057 23 23 23zM412.816 196.084c12.6924 0 22.9971 -10.3076 23 -23c0 -12.6943 -10.3066 -23 -23 -23
c-12.6943 0 -23 10.3057 -23 23s10.3057 23 23 23z" />
<glyph glyph-name="watchman-monitoring" unicode="&#xe087;" horiz-adv-x="512"
d="M256 432c132.548 0 240 -107.452 240 -240s-107.452 -240 -240 -240s-240 107.452 -240 240s107.452 240 240 240zM121.69 18.8779l27.6846 204.861l-9.46777 7.39941c-2.98242 2.34082 -4.89062 5.9668 -4.89062 10.0479
c0 0.100586 0.000976562 0.201172 0.00292969 0.301758c0 7.04883 0.144531 19.5488 0.144531 19.5488l13.9434 2.0127l0.120117 10.9668l-102.899 -17.8945c-6.20508 -20.251 -9.58691 -41.7412 -9.58691 -64.0137v-0.108398c0 -70.3223 33.3145 -132.972 84.9492 -173.122
zM227.382 302.148l0.0400391 -3.61816l193.512 37.7002c-40.1152 46.0273 -99.1426 75.0244 -164.934 75.0244c-74.4863 0 -140.374 -37.3623 -180.018 -94.2998l73.5068 -19.1758l0.0478516 4.36914l-8.48145 7.61719s-6.93359 5.38086 0.144531 9.34473
c7.18652 4.02539 39.5283 34.5 39.5283 34.5c7.20312 7.34668 10.1123 5.47656 15.4609 0c0 0 32.3418 -30.4766 39.5293 -34.5c7.07715 -3.96387 0.143555 -9.34473 0.143555 -9.34473zM261.445 -27.1211c118.386 2.90918 213.813 100.047 213.813 219.121
c-0.0107422 17.2881 -2.04297 33.9951 -5.85059 50.1299l-241.711 31.3916l0.116211 -10.4746l13.9424 -2.0127s0.144531 -12.5049 0.144531 -19.5488c0.00195312 -0.100586 0.0126953 -0.19043 0.0126953 -0.290039c0 -4.08203 -1.91797 -7.71973 -4.90137 -10.0596
l-9.4668 -7.39941z" />
<glyph glyph-name="wodu" unicode="&#xe088;" horiz-adv-x="640"
d="M178.414 108.294h-37.3145l-28.9336 116.231h-0.477539l-28.4609 -116.231h-38.0273l-45.2002 170.76h37.5479l27.0264 -116.23h0.477539l29.6553 116.23h35.1572l29.1777 -117.667h0.479492l27.9785 117.667h36.8311zM271.4 235.287
c38.9834 0 64.0996 -25.8281 64.0996 -65.291c0 -39.2217 -25.1113 -65.0498 -64.0996 -65.0498c-38.7432 0 -63.8555 25.8281 -63.8555 65.0498c0.00195312 39.4629 25.1143 65.291 63.8555 65.291zM271.4 130.534c23.1992 0 30.1328 19.8516 30.1328 39.4619
c0 19.8516 -6.93457 39.7002 -30.1328 39.7002c-27.7002 0 -29.8945 -19.8506 -29.8945 -39.7002c0.00195312 -19.6104 6.9375 -39.4619 29.8945 -39.4619zM435.084 124.078h-0.477539c-7.89355 -13.3926 -21.7656 -19.1318 -37.5488 -19.1318
c-37.3096 0 -55.4844 32.0449 -55.4844 66.2461c0 33.2422 18.415 64.0947 54.7666 64.0947c14.5889 0 28.9385 -6.21777 36.8311 -18.416h0.240234v62.1826h33.96v-170.76h-32.2871v15.7842zM405.428 209.7c-22.2393 0 -29.8936 -19.1338 -29.8936 -39.4629
c0 -19.3711 8.84766 -39.7002 29.8936 -39.7002c22.4824 0 29.1787 19.6133 29.1787 39.9395c0 20.0879 -7.1748 39.2236 -29.1787 39.2236zM592.96 108.294h-32.2871v17.2188h-0.717773c-8.60938 -13.8701 -23.4365 -20.5664 -37.7861 -20.5664
c-36.1133 0 -45.2002 20.3281 -45.2002 50.9404v76.0527h33.959v-69.8398c0 -20.3281 5.97949 -30.3721 21.7656 -30.3721c18.415 0 26.3057 10.2832 26.3057 35.3936v64.8184h33.9609v-123.646zM602.453 145.124h37.5469v-36.8301h-37.5469v36.8301z" />
<glyph glyph-name="twitter-square" unicode="&#xf081;"
d="M400 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352zM351.1 257.2c12.8008 9.2998 24 20.8994 32.9004 34c-11.7998 -5.10059 -24.5996 -8.7998 -37.7998 -10.2002
c13.5996 8.09961 23.8994 20.9004 28.7998 36.0996c-12.5996 -7.5 -26.7998 -13 -41.5996 -15.7998c-12 12.7998 -29 20.7002 -47.9004 20.7002c-40 0 -73.2998 -36.0996 -64 -80.5996c-54.4004 2.7998 -102.9 28.7998 -135.2 68.5996
@ -1228,15 +1297,17 @@ c-4.2998 22.5 -31.4004 20.9004 -49 20.9004h-24.6006v-127.8zM382.5 157.4v36c0 17.
c5.69922 -6.7998 11.8994 -9.7998 20.8994 -9.7998c19.7998 0 22.2002 15.2002 22.2002 30.9004zM265 218.1v-49.2998c0 -9.7002 1.90039 -18.7002 -10.2998 -18.3994v83.6992c11.8994 0 10.2998 -6.2998 10.2998 -16zM350.5 192v-32.7002
c0 -5.39941 1.59961 -14.3994 -6.2002 -14.3994c-1.59961 0 -3 0.799805 -3.7998 2.39941c-2.2002 5.10059 -1.09961 44.1006 -1.09961 44.7002c0 3.7998 -1.10059 12.7002 4.89941 12.7002c7.2998 0 6.2002 -7.2998 6.2002 -12.7002z" />
<glyph glyph-name="ravelry" unicode="&#xf2d9;" horiz-adv-x="512"
d="M407.4 386.5c72.6992 -37.9004 112 -117.2 103.3 -199.5c-1.7002 -16.7002 -4.40039 -36.2002 -9.7998 -52.2002c-22.2002 -65.7002 -52.9004 -108.6 -123.101 -147.7c-6.39941 -4.39941 -13.2998 -8.59961 -20.2002 -10.7998
c-12.5 -4.39941 -26.0996 -5.39941 -40.0996 -3.89941c-5.90039 -0.5 -11.7998 -0.700195 -18 -0.700195c-93.7002 0 -173 64 -196.9 151.399c-0.699219 0 -1.5 0.200195 -2.19922 0.200195c-5.60059 -44.2998 27.0996 -104.1 27.0996 -104.1s2 -3 13.2998 -20.2002
c-62.7998 33.2002 -64.5 131.2 -64.5 131.2c-15 5.59961 -67.2002 23.3994 -76.2998 37.8994c0 0 40.9004 -22.3994 76.2002 -27c-0.200195 0.300781 0.5 7.90039 0.5 7.90039c2.2002 30 12.5 53.4004 23.0996 71.4004c6.90039 33.7998 22.1006 64.2998 43.2998 89.8994
c3.7002 15.2998 9.60059 33.5 19.9004 52.7002c4.40039 8.40039 8.59961 13.7998 19.9004 19c74.8994 35 148.699 43.9004 224.5 4.5zM138.8 284.8c-7.59961 -11.2998 -13.7002 -23.5996 -18.8994 -36.3994c8.09961 8.59961 14.7998 14.1992 18.1992 16.6992
c-0.5 7.40039 0.700195 19.7002 0.700195 19.7002zM107.6 162.9c0.700195 -9.60059 2 -18.9004 4.2002 -28.1006l41.4004 -6.89941c-14.1006 42.0996 -15.7998 90.0996 -15.7998 90.0996c-16.5 -16 -25.4004 -37.9004 -29.8008 -55.0996zM115.5 120.1
c21.4004 -69.6992 81 -122.8 154.1 -134.399c-1 0.299805 -1.69922 0.5 -2.69922 1c0 0 -81 47.5 -108.301 124.3c-9.09961 1.5 -28.2998 5.90039 -43.0996 9.09961zM386 3.90039c63 32 106.6 98 106.8 174c0 107.399 -86.5996 194.5 -193 194.5
c-49.2998 0 -94.0996 -18.7002 -128.3 -49.5c-5.2002 -10.1006 -8.59961 -22.9004 -11.0996 -39.4004c52.5 44.5996 146 33.5 146 33.5c23.3994 -1 20.5996 -21.7002 20.3994 -28.0996c-85.2002 7.19922 -127 -17.2002 -168.399 -52.4004
c0 0 8.09961 -78.7998 26.7998 -110.8c107.8 -4.90039 189.8 53.7002 189.8 53.7002c10.2998 7.39941 19.4004 8.09961 21.4004 -4.7002c1.5 -10.4004 2.19922 -24.4004 -9.60059 -29.7998c-36 -16.8008 -75.5996 -27.3008 -115 -33
c-25.5996 -3.7002 -39.7998 -4.60059 -78 -3.90039c36.4004 -84.7002 127.5 -107.8 127.5 -107.8c28.5 -4.7002 50.2002 -1 64.7002 3.7002z" />
d="M498.252 213.777c0.129883 -0.613281 0.322266 -1.21777 0.561523 -1.78223v-37.0557c-0.194336 -0.300781 -0.516602 -0.583008 -0.552734 -0.900391c-0.619141 -5.36426 -0.837891 -10.8076 -1.87012 -16.0869c-2.06934 -10.6074 -4.15723 -21.2393 -7.0166 -31.6523
c-4.94531 -18.0205 -12.7578 -34.8809 -22.2998 -50.9258c-8.94336 -15.126 -19.4043 -28.9668 -31.4268 -41.6387c-3.74609 -3.92188 -7.54688 -7.80078 -11.5107 -11.5c-5.31152 -4.95703 -10.5146 -10.1094 -16.2998 -14.457
c-9.3418 -7.02344 -18.9883 -13.6533 -28.7373 -20.1006c-15.083 -9.81543 -31.6211 -17.9053 -48.9512 -23.8174c-15.3828 -5.38281 -31.1533 -9.38574 -47.4893 -10.7178c-2.52734 -0.206055 -5.02051 -0.753906 -7.52734 -1.14258h-32.2891
c-0.358398 0.245117 -0.762695 0.436523 -1.18945 0.55957c-6.1377 0.620117 -12.3418 0.863281 -18.4121 1.87305c-13.8301 2.22949 -27.5977 5.58398 -40.6416 9.83496c-19.5498 6.43359 -38.4463 15.0176 -55.8994 25.2773
c-15.0488 8.79004 -28.9365 18.9688 -41.7871 30.5859c-9.6875 8.70605 -18.3936 18.0898 -26.3584 28.416c-9.38184 12.1963 -17.4385 25.4316 -24 39.5283c-7.5918 16.6592 -13.3467 34.7812 -16.7295 53.2998c-2.35547 13.1611 -3.85059 26.5459 -4.4248 40.2402
c-0.136719 3.0332 -0.209961 5.74121 -0.209961 8.80859c0 9.05566 0.599609 17.9717 1.76172 26.7119c1.52637 11.874 4.15625 23.6367 7.69043 34.7588c5.05762 15.7021 12.0283 30.7871 20.4941 44.6006c9.58203 15.9961 20.7793 30.6025 33.6484 43.9502
c9.55469 9.83496 19.7539 19.0605 29.9268 28.2676c5.70605 5.1582 11.8066 9.9082 17.9736 14.5186c12.0029 9.04004 24.6963 17.1025 38.0801 24.1572c12.5137 6.63281 25.9795 12.1963 39.7686 16.3555c10.9453 3.41016 22.5254 5.84375 34.2559 7.09961
c2.42773 0.225586 4.82617 0.761719 7.23633 1.15039c10.7627 -0.00195312 21.5254 0 32.2881 0.00585938c0.299805 -0.195312 0.583984 -0.516602 0.899414 -0.552734c6.87793 -0.81543 13.8467 -1.16797 20.627 -2.48242
c11.2432 -2.18359 22.4971 -4.51465 33.5156 -7.61523c19.999 -5.78125 39.2266 -14.2031 56.7227 -24.668c17.2832 -10.0947 32.9639 -22.1357 47.1133 -36.1152c6.71973 -6.90527 12.9209 -14.0508 18.8174 -21.6895c13.4639 -16.959 24.0283 -36.4561 30.874 -57.5
c3.88867 -11.8086 7.16211 -24.2148 9.62207 -36.5996c2.0459 -10.1748 2.53809 -20.6602 3.74609 -31zM337.135 214.927l0.00488281 67.2695c-35.2686 0 -53.1152 -9.36719 -62.04 -36.1895v31.9316h-73.5176v-190.738h73.5127v93.667
c0 22.1396 6.37012 37.04 33.5703 37.04c11.8984 0 28.4697 -2.98047 28.4697 -2.98047z" />
<glyph glyph-name="sellcast" unicode="&#xf2da;"
d="M353.4 416c52.0996 0 94.6992 -42.5996 94.6992 -94.5996v-258.801c0 -52 -42.5996 -94.5996 -94.6992 -94.5996h-258.7c-52.1006 0 -94.7002 42.5996 -94.7002 94.7002v258.7c0 52 42.5996 94.5996 94.7002 94.5996h258.7zM303.4 99.5996
c27.8994 48.2002 11.1992 110.5 -37.2002 138.5c-18.6006 10.8008 0.0996094 -0.0996094 -18.5 10.7002c-25 14.4004 -46.2002 -23.2998 -21.6006 -37.5c18 -10.2002 0.800781 -0.399414 18.6006 -10.5996c27.5996 -16 37.2002 -51.7998 21.2998 -79.4004
@ -1917,13 +1988,21 @@ c-42.5 0 -47.3994 -14.8008 -47.3994 -25.9004c0 -13.4004 5.7998 -17.2998 63.2002
<glyph glyph-name="npm" unicode="&#xf3d4;" horiz-adv-x="576"
d="M288 160h-32v64h32v-64zM576 288v-192h-288v-32h-128v32h-160v192h576zM160 256h-128v-128h64v96h32v-96h32v128zM320 256h-128v-160h64v32h64v128zM544 256h-192v-128h64v96h32v-96h32v96h32v-96h32v128z" />
<glyph glyph-name="ns8" unicode="&#xf3d5;" horiz-adv-x="640"
d="M187.1 288.1h44.9004l-48.5 -160.1h-56.9004l-50.5996 106.5l-31.0996 -106.5h-44.9004l49 160.1h49.4004l54.5 -113.699zM639.6 289c4.60059 -28.5996 -36.0996 -44.7002 -65.6992 -50.5996h-0.100586c17.5 -29.3008 22.1006 -69.3008 3.40039 -105.5
c-26.4004 -51.2002 -86.5 -79.9004 -135.101 -68c-29.3994 7.19922 -51.3994 29 -56.7998 59.5c-0.700195 3.5 -1 7.09961 -1.2002 10.7998c-5.5 -2.7998 -11.8994 -4.2002 -18.5 -4.90039c-15.5996 -1.7002 -21 -2.2998 -160.899 -2.2998l11.5996 39.5h126.8
c9.10059 0 12.2002 3.2002 13.8008 7.40039c1.69922 4.59961 3.39941 10.1992 4.5 14.5996c1.09961 3.90039 0.0996094 6.59961 -7.7002 6.59961h-87.2998c-33.4004 0 -38.2002 9.2002 -32.8008 28.6006c3.2002 11.5 10.8008 37.2002 17.6006 47.0996
c7.09961 10.2002 18.2998 13.7002 30.5996 15c15.6006 1.7002 20.4004 1.2002 160.101 1.2002l-9.7002 -31.5h-133.5c-5.5 0 -11.2002 -0.700195 -13.2998 -7.09961c-1.80078 -5.40039 -2.10059 -6.7002 -3.7002 -12.2002c-1.40039 -5.10059 2.2002 -7.40039 11.5 -7.40039
h87.5996c20.4004 0 31 -6.7998 34 -16.5996c19.9004 21.3994 50.4004 39.5 94.2002 48.2002v0.0996094c-13.4004 42.5 43.9004 66.5996 88.5 58.7998c18.2002 -3.2002 39.2002 -13.2998 42.0996 -31.2998zM530.7 184.3c3.09961 15.7998 -0.5 33.7002 -7.2002 47.7998
c-23.2998 -2.89941 -52.2998 -10.0996 -68.5 -26.8994c-24.4004 -25.2998 -16.7998 -60 14.0996 -64.7998c25 -3.90039 55.7002 14.3994 61.6006 43.8994zM552.5 267.4c10.5996 1.5 23.5 3.5 34.2002 9.59961c14.7998 8.5 10.3994 21 -4.90039 24.4004
c-10.8994 2.39941 -25.0996 -0.5 -31.7998 -7.7002c-7.2998 -7.7998 -1.7002 -20.2998 2.5 -26.2998z" />
d="M104.324 178.828v26.1777h26.0664v-26.1777h-26.0664zM156.79 205.006h-26.3428v26.1777c-0.124023 7.05762 -5.8916 12.748 -12.9785 12.748c-7.08594 0 -12.8535 -5.69043 -12.9775 -12.748v-0.166016h-26.4004v0.166016
c-0.000976562 0.119141 -0.000976562 0.220703 -0.000976562 0.339844c0 21.7041 17.6211 39.3242 39.3242 39.3242c21.5039 0 38.999 -17.2959 39.3213 -38.7227v-0.941406zM209.146 179.16v26.0117h26.3438v-26.0117
c0 -0.0371094 -0.000976562 -0.0722656 -0.000976562 -0.109375c0 -64.7373 -52.5439 -117.3 -117.274 -117.331h-0.774414c-0.0380859 0 -0.0732422 0.000976562 -0.110352 0.000976562c-64.7373 0 -117.299 52.543 -117.33 117.273v0.166016h26.3369
c0 -50.2793 40.8203 -91.1006 91.0996 -91.1006h0.609375c50.2793 0 91.1006 40.8213 91.1006 91.1006zM51.9131 179.16v25.96h-26.291v25.3994c0 50.6445 41.1162 91.7617 91.7607 91.7617s91.7607 -41.1172 91.7607 -91.7617v-25.293h-26.3438v25.293v0.200195
c0 36.1055 -29.3135 65.4199 -65.4199 65.4199c-35.7656 0 -64.8672 -28.7646 -65.4121 -64.4023v-26.6201h26.2891v-25.957c0.356445 -21.2305 17.7031 -38.3564 39.0176 -38.3564s38.6611 17.126 39.0176 38.3564h26.3438
c-0.140625 -35.9551 -29.374 -65.1016 -65.3613 -65.1016s-65.2207 29.1465 -65.3613 65.1016zM470.313 250.333c-11.3467 0 -20.8633 -4.75977 -24.2402 -12.1172v-8.41211c2.21875 -4.53809 6.30859 -7.69238 12.6191 -9.62988
c4.75879 -1.37891 9.76562 -2.3623 14.832 -2.87793c6.36426 -0.827148 13.0068 -1.71484 20.6992 -4.42676c13.7256 -4.59375 24.0742 -13.2275 28.9443 -24.2412l0.166016 -0.664062l-0.166016 -25.8994c-7.69238 -17.0479 -28.668 -28.4473 -52.2998 -28.4473
c-25.6797 0 -47.374 12.6182 -55.2891 32.0439l-0.552734 1.43848l23.0205 11.5078l0.719727 -1.49414c5.97754 -12.1211 17.5996 -19.0391 31.9336 -19.0391c12.0098 0 22.083 4.81445 25.791 12.3418v9.85059c-2.37988 4.59473 -6.47656 7.75098 -12.8398 9.85156
c-5.20312 1.71582 -10.3506 2.37988 -15.8291 3.09961c-6.78809 0.675781 -13.4814 2.04199 -19.8135 3.98438c-14.1123 4.87109 -23.9678 13.2275 -28.668 24.2412c-0.158203 0.949219 -0.123047 -2.02637 0 24.8496c7.36133 17.0469 27.8379 28.4473 50.9727 28.4473
c24.9062 0 45.3818 -12.0098 53.4062 -31.2705l0.609375 -1.43848l-23.2451 -11.5117l-0.71875 1.5498c-5.47949 11.6221 -16.3818 18.2637 -30.0518 18.2637zM287.568 136.656v68.3994h26.0664v-68.3994h-26.0664zM639.834 189.956l0.166016 -0.722656l-0.166016 -28.8906
c-7.52734 -15.9941 -27.8916 -26.7305 -50.584 -26.7305s-43.0029 10.7363 -50.585 26.7305l-0.166016 0.720703l0.166016 28.8887c2.93262 6.25391 8.24121 12.0137 15.4414 16.7139c-5.57422 3.90332 -10.0391 9.14453 -13.0068 15.3311l-0.166016 0.664062
l0.166016 25.3467c7.36133 15.9922 26.7334 26.7324 48.1504 26.7324s40.7881 -10.7402 48.1504 -26.7295l0.166016 -0.664062l-0.166016 -25.3467c-2.90137 -6.22852 -7.38379 -11.4873 -13.0078 -15.3301c7.1416 -4.7041 12.5088 -10.46 15.4414 -16.7139z
M566.614 240.762v-13.7246c3.48535 -6.19922 12.5068 -10.3486 22.5801 -10.3486c10.0723 0 19.0938 4.14844 22.6357 10.3486v13.7246c-3.59766 6.31055 -12.6191 10.5166 -22.6357 10.5166c-10.0176 0 -18.9805 -4.20605 -22.5801 -10.5166zM613.933 168.593v16.1572
c-3.76367 6.36523 -13.3379 10.5146 -24.6826 10.5146c-11.1836 0 -20.9756 -4.20605 -24.6836 -10.5146v-16.1572c3.70801 -6.52734 13.5586 -10.8994 24.6836 -10.8994c11.3447 0 20.9189 4.25879 24.6826 10.8994zM376.4 182.038v89.7129h25.8994v-135.095h-25.6777
l-62.5391 94.085v0.386719h-26.5098v40.623h29z" />
<glyph glyph-name="nutritionix" unicode="&#xf3d6;" horiz-adv-x="400"
d="M88 439.9c0 0 133.4 8.19922 121 -104.4c0 0 19.0996 74.9004 103 40.5996c0 0 -17.7002 -74 -88 -56c0 0 14.5996 54.6006 66.0996 56.6006c0 0 -39.8994 10.2998 -82.0996 -48.7998c0 0 -19.7998 94.5 -93.5996 99.6992c0 0 75.1992 -19.3994 77.5996 -107.5
c0 -0.0996094 -106.4 -7 -104 119.801zM400 124.3c0 -48.5 -9.7002 -95.2998 -32 -132.3c-42.2002 -30.9004 -105 -48 -168 -48c-62.9004 0 -125.8 17.0996 -168 48c-22.2998 37 -32 83.7998 -32 132.3c0 48.4004 17.7002 94.7002 40 131.7
@ -2025,13 +2104,16 @@ d="M281.2 169.8l-197.9 -57.2002l-28.5996 98.6006l188.2 54.0996c52.6992 15.2998 6
c-46 0 -89.5 12.7002 -126.3 34.7002l-23 80.2002l286.8 -37.3008l48.0996 13.3008l-9.69922 34.1992l-220.4 27.1006l92.5996 26.5996c30.2002 8.7002 42 15.7998 61.4004 33.2002c24.5 23 31.7002 45.5 23.5 73.5996l-10.7002 37.8008
c-8.7002 30.1992 -25.0996 49.0996 -61.3994 55.1992c-25.1006 3.5 -44.5 2 -79.3008 -8.19922l-221.899 -63.9004c26 108.8 124.2 189.5 241.3 189.5zM38.2998 59.4004c-24 38.3994 -38.2998 83.2998 -38.2998 131.8z" />
<glyph glyph-name="rocketchat" unicode="&#xf3e8;" horiz-adv-x="576"
d="M486.41 340.43c119.649 -76.54 119.26 -221 0 -297.14c-77.1201 -50.9199 -179.37 -62.3896 -264.12 -47.1602c-95.5205 -91.1895 -201.72 -49.1602 -222.29 -37c0 0 73.0801 62.1006 61.21 116.49c-45.3896 46.3701 -86.5195 144.57 0 232.77
c11.8701 54.3906 -61.21 116.49 -61.21 116.49c20.7695 12.1201 127.26 54.2803 222.29 -37.3799c84.9404 15.3301 187.19 3.75977 264.12 -47.0703zM294.18 43.7803c126.67 0 229.409 66.2197 229.409 148.22s-102.74 148.43 -229.41 148.43
s-229.41 -66.4297 -229.41 -148.43c0 -35.79 19.4707 -68.5195 52 -94.1299c9.11426 -29.127 3.78125 -62.0234 -15.999 -98.6904c-0.889648 -1.67969 -1.76953 -3.45996 -2.76953 -5.23926c18.3555 1.62988 35.999 6.81934 51.71 14.7295
c13.4121 7.59277 25.6025 16.7344 36.5898 27.3896l19.7705 19.0908c27.8438 -7.39355 56.958 -11.3721 87.1162 -11.3721c0.331055 0 0.662109 0.000976562 0.993164 0.00195312zM184.119 156.7c-0.164062 -0.00292969 -0.329102 -0.00390625 -0.494141 -0.00390625
c-18.7393 0 -33.9814 15.0615 -34.3057 33.7236c-0.700195 45.3896 67.8301 46.3799 68.5195 1.08984v-0.509766c0.000976562 -0.109375 0.00195312 -0.217773 0.00195312 -0.327148c0 -18.6709 -15.0869 -33.8398 -33.7217 -33.9932v0.0205078zM257.889 190.42
c-0.790039 45.3896 67.7402 46.4805 68.5303 1.19043v-0.610352c0.389648 -45.0801 -67.7402 -45.5703 -68.5303 -0.580078zM401.269 156.7c-0.164062 -0.00292969 -0.329102 -0.00390625 -0.494141 -0.00390625c-18.7402 0 -33.9854 15.0605 -34.3154 33.7236
c-0.69043 45.3896 67.8398 46.3799 68.5303 1.08984v-0.509766c0.00195312 -0.145508 0.00292969 -0.291992 0.00292969 -0.438477c0 -18.6475 -15.0967 -33.79 -33.7236 -33.8818v0.0205078z" />
d="M284.046 223.2c0.0341797 0 0.0664062 -0.00195312 0.100586 -0.00195312c18.8496 0 34.1592 -15.2754 34.2168 -34.1113c0 -18.8281 -15.2822 -34.1143 -34.1104 -34.1143s-34.1143 15.2861 -34.1143 34.1143c0 18.7588 15.1748 34.002 33.9072 34.1133zM173.596 223.2
c0.0332031 0 0.0673828 -0.00195312 0.100586 -0.00195312c18.8496 0 34.1592 -15.2754 34.2168 -34.1113c0 -18.8281 -15.2822 -34.1143 -34.1104 -34.1143s-34.1143 15.2861 -34.1143 34.1143c0 18.7588 15.1748 34.002 33.9072 34.1133zM394.519 223.2
c0.0351562 0 0.0683594 -0.00195312 0.102539 -0.00195312c18.8496 0 34.1592 -15.2754 34.2148 -34.1113c0 -18.8281 -15.2822 -34.1143 -34.1104 -34.1143s-34.1133 15.2861 -34.1133 34.1143c0 18.7588 15.1738 34.002 33.9062 34.1133zM548.326 278.519
c17.3076 -26.9443 26.0674 -55.9189 26.0898 -86.9395c0 -30.209 -8.76074 -59.2021 -26.0703 -86.125c-15.5342 -24.1934 -37.3076 -45.5703 -64.6787 -63.6191c-52.8672 -34.8164 -122.354 -53.9746 -195.667 -53.9746
c-0.150391 -0.000976562 0.0664062 -0.00585938 -0.0830078 -0.00585938c-24.5488 0 -48.5908 2.18359 -71.9443 6.36621c-14.8564 -14.2842 -31.3604 -26.5059 -49.5098 -36.5889c-66.7744 -33.3467 -125.6 -20.9092 -155.324 -10.2002
c-5.54492 1.96289 -9.51758 7.25488 -9.51758 13.4697c0 3.82715 1.50879 7.30469 3.96289 9.87109c20.9619 21.6748 55.6416 64.5342 47.1162 103.49c-33.1426 33.9004 -51.1123 74.7764 -51.1123 118.148c0 42.5605 17.9697 83.4365 51.1123 117.337
c8.52148 38.9521 -26.1582 81.7939 -47.1201 103.47c-2.45996 2.56738 -3.97656 6.0498 -3.97656 9.88281c0 6.21973 3.98047 11.5156 9.53125 13.4785c29.7246 10.71 88.5488 23.1211 155.302 -10.2109c18.1504 -10.0811 34.6553 -22.3027 49.5107 -36.5879
c23.3457 4.18066 47.0137 6.35742 71.5547 6.35742c0.15918 0 0.318359 -0.000976562 0.476562 -0.000976562c73.293 0 142.78 -19.1826 195.666 -54c27.3711 -18.0479 49.1465 -39.4453 64.6816 -63.6182zM284.987 38.0996c128.612 0 232.866 67.376 232.866 150.487
c0 83.0957 -104.274 150.469 -232.866 150.469c-128.593 0 -232.847 -67.3691 -232.847 -150.469c0 -36.2002 19.7861 -69.4375 52.7783 -95.4004c9.28809 -29.5986 3.84668 -62.958 -16.3252 -100.078c-0.960938 -1.79297 -1.8584 -3.58496 -2.8418 -5.35645
c18.6367 1.63574 36.5557 6.875 52.5225 14.8701c13.5889 7.65625 25.9609 16.8633 37.1377 27.585l20.1289 19.3926c28.2617 -7.47852 57.8037 -11.501 88.4033 -11.501c0.347656 0 0.695312 0 1.04297 0.000976562z" />
<glyph glyph-name="rockrms" unicode="&#xf3e9;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM405.4 20.5l-101.5 118.9s73.5996 0.199219 74.1992 0.199219c29.6006 -1.09961 46.6006 33.3008 27.6006 56.1006l-157.7 185.1c-13.2002 17.2998 -40.0996 18.4004 -54.5 0
l-147.1 -172.5h90l84.2998 98.9004l84.5996 -99.2998h-75.2998c-30.5 0 -44.5 -35.7002 -26.5996 -56.1006l112 -131.3h90z" />
@ -3286,8 +3368,6 @@ c0 -0.0498047 -0.00195312 -0.0986328 -0.00585938 -0.147461v-0.799805c0.00195312
v-25.7998h16.1006c0.0380859 0.00195312 0.0742188 0.00488281 0.113281 0.00488281c1.04297 0 1.88965 -0.847656 1.88965 -1.89062c0 -0.0380859 -0.000976562 -0.0761719 -0.00292969 -0.114258v-0.800781
c0.00195312 -0.0380859 0.00488281 -0.0742188 0.00488281 -0.113281c0 -1.04297 -0.847656 -1.88965 -1.89062 -1.88965c-0.0380859 0 -0.0761719 0.000976562 -0.114258 0.00292969h-16.1006v-26.6992h19.4004zM288.301 262.799l2.2998 -6.7998l7.10059 -0.0996094
l-5.7002 -4.30078l2.09961 -6.7998l-5.7998 4.10059l-5.7998 -4.10059l2.09961 6.7998l-5.69922 4.30078l7.09961 0.0996094z" />
<glyph glyph-name="adobe" unicode="&#xf778;" horiz-adv-x="512"
d="M315.5 384h170.9v-384zM196.5 384l-170.9 -384v384h170.9zM256 241.9l107.5 -241.9h-73l-30.7002 76.7998h-78.7002z" />
<glyph glyph-name="artstation" unicode="&#xf77a;" horiz-adv-x="512"
d="M2 70.5996h315.1l59.2002 -102.6h-285.399c-0.00488281 0 0.0205078 -0.0498047 0.015625 -0.0498047c-20.0742 0 -37.4736 11.5439 -45.916 28.3496zM501.8 98c19 -29.4004 -0.0996094 -55.9004 -2 -59.0996l-40.7002 -70.5l-257.3 447.6h88.4004
c0.00390625 0 -0.0234375 0.0527344 -0.0195312 0.0527344c19.6797 0 36.79 -11.0879 45.4189 -27.3525zM275 143.5h-231l115.5 200z" />

Before

Width:  |  Height:  |  Size: 713 KiB

After

Width:  |  Height:  |  Size: 730 KiB

Before After
Before After

View file

@ -1,16 +1,12 @@
<?xml version="1.0" standalone="no"?>
<!--
Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->
<!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" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20200314 at Wed Jul 15 11:59:40 2020
Created by FontForge 20200314 at Wed Jan 13 11:57:54 2021
By Robert Madole
Copyright (c) Font Awesome
</metadata>
<defs>
<!-- Font Awesome Free 5.15.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><defs>
<font id="FontAwesome5Free-Regular" horiz-adv-x="512" >
<font-face
font-family="Font Awesome 5 Free Regular"

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

Before After
Before After

View file

@ -1,16 +1,12 @@
<?xml version="1.0" standalone="no"?>
<!--
Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->
<!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" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20200314 at Wed Jul 15 11:59:41 2020
Created by FontForge 20200314 at Wed Jan 13 11:57:55 2021
By Robert Madole
Copyright (c) Font Awesome
</metadata>
<defs>
<!-- Font Awesome Free 5.15.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><defs>
<font id="FontAwesome5Free-Solid" horiz-adv-x="512" >
<font-face
font-family="Font Awesome 5 Free Solid"
@ -311,6 +307,23 @@ s9.55762 21.3301 21.3301 21.3301h16.1602c38.0195 0 57.0498 45.96 30.1699 72.8398
c26.8398 -26.8799 72.8398 -7.83008 72.8398 30.1699v16.1602c0 11.7725 9.55762 21.3301 21.3301 21.3301s21.3301 -9.55762 21.3301 -21.3301v-16.1602c0 -38.0195 45.96 -57.0498 72.8398 -30.1699l11.4297 11.4297c3.85742 3.83301 9.17578 6.19531 15.0361 6.19531
c11.7725 0 21.3301 -9.55762 21.3301 -21.3291c0 -5.85938 -2.36621 -11.1689 -6.19629 -15.0254l-11.4297 -11.4404c-26.8799 -26.8398 -7.83008 -72.8398 30.1699 -72.8398h16.1602c11.7725 0 21.3301 -9.55762 21.3301 -21.3301s-9.55762 -21.3301 -21.3301 -21.3301
h-16.1602zM160 256c17.6611 0 32 14.3389 32 32s-14.3389 32 -32 32s-32 -14.3389 -32 -32s14.3389 -32 32 -32zM240 224c8.83105 0 16 7.16895 16 16s-7.16895 16 -16 16s-16 -7.16895 -16 -16s7.16895 -16 16 -16z" />
<glyph glyph-name="vest" unicode="&#xe085;" horiz-adv-x="448"
d="M437.252 208.123c6.76562 -10.1484 10.748 -22.3994 10.748 -35.5v-204.623c0 -17.6611 -14.3389 -32 -32 -32h-192v224l73.8115 221.438c-21.7695 -12.3281 -47.0635 -19.5205 -73.8115 -19.6729c-26.748 0.150391 -52.042 7.34277 -73.8115 19.6699l56.9463 -170.836
l-13.4922 -40.4805c-1.05957 -3.17969 -1.64258 -6.58496 -1.64258 -10.1191v-224h-160c-17.6611 0 -32 14.3389 -32 32v204.623c0 13.1006 3.98242 25.3516 10.748 35.5l53.252 79.877v128c0 17.6611 14.3389 32 32 32h32
c4.91211 -0.00195312 9.50586 -1.49512 13.3115 -4.03125l25 -16.6719c16.4814 -11.0186 36.4971 -17.4463 57.793 -17.4463s41.1025 6.42773 57.584 17.4463l25 16.6719c3.80566 2.53613 8.39941 4.0293 13.3115 4.03125h32c17.6611 0 32 -14.3389 32 -32v-128z
M131.312 76.6885c2.78125 2.87891 4.48828 6.80078 4.48828 11.1152c0 8.83105 -7.16992 16 -16 16c-4.31445 0 -8.23242 -1.71094 -11.1113 -4.49219l-48 -48c-2.78125 -2.87891 -4.48828 -6.80078 -4.48828 -11.1152c0 -8.83105 7.16992 -16 16 -16
c4.31445 0 8.23242 1.71094 11.1113 4.49219zM387.312 28.6885c2.89746 2.89453 4.69043 6.89844 4.69043 11.3135s-1.79297 8.41504 -4.69043 11.3096l-48 48c-2.87891 2.78125 -6.80078 4.48828 -11.1152 4.48828c-8.83105 0 -16 -7.16992 -16 -16
c0 -4.31445 1.71094 -8.23242 4.49219 -11.1113l48 -48c2.89453 -2.89746 6.89844 -4.69043 11.3135 -4.69043s8.41504 1.79297 11.3096 4.69043z" />
<glyph glyph-name="vest-patches" unicode="&#xe086;" horiz-adv-x="448"
d="M437.252 208.123c6.76562 -10.1484 10.748 -22.3994 10.748 -35.5v-204.623c0 -17.6611 -14.3389 -32 -32 -32h-192v224l73.8105 221.434c-21.7705 -12.3252 -47.0635 -19.5156 -73.8105 -19.668c-26.7471 0.154297 -52.041 7.34668 -73.8115 19.6738l56.9463 -170.84
l-13.4922 -40.4805c-1.05957 -3.17969 -1.64258 -6.58496 -1.64258 -10.1191v-224h-160c-17.6611 0 -32 14.3389 -32 32v204.623c0 13.1006 3.98242 25.3516 10.748 35.5l53.252 79.877v128c0 17.6611 14.3389 32 32 32h32l0.0283203 -0.0146484
c4.91113 0 9.47949 -1.47949 13.2832 -4.0166l25 -16.6719c16.4814 -11.0186 36.4971 -17.4463 57.793 -17.4463s41.1025 6.42773 57.584 17.4463l25 16.6719c3.80371 2.53711 8.39551 4.03125 13.3066 4.03125h0.00488281h32c17.6611 0 32 -14.3389 32 -32v-128z
M63.5 175.516l15.5156 -15.5156l-15.5156 -15.5156c-2.12402 -2.16699 -3.43066 -5.1377 -3.43066 -8.4082c0 -6.62891 5.38086 -12.0107 12.0098 -12.0107c3.2793 0 6.25293 1.31738 8.4209 3.4502l15.5 15.5l15.5 -15.5
c2.16797 -2.13281 5.14551 -3.44629 8.42383 -3.44629c6.62891 0 12.0107 5.38184 12.0107 12.0098c0 3.27051 -1.31055 6.23828 -3.43457 8.40527l-15.5156 15.5156l15.5156 15.5156c2.12402 2.16699 3.43066 5.1377 3.43066 8.4082
c0 6.62891 -5.38086 12.0107 -12.0098 12.0107c-3.2793 0 -6.25293 -1.31738 -8.4209 -3.4502l-15.5 -15.5l-15.5 15.5c-2.16797 2.13281 -5.14551 3.44629 -8.42383 3.44629c-6.62891 0 -12.0107 -5.38184 -12.0107 -12.0098c0 -3.27051 1.31055 -6.23828 3.43457 -8.40527
zM96 -8c22.0762 0 40 17.9238 40 40s-17.9238 40 -40 40s-40 -17.9238 -40 -40s17.9238 -40 40 -40zM359.227 112.215c13.6875 0.0966797 24.7734 11.2139 24.7734 24.9229c0 0.757812 -0.0341797 1.50684 -0.0996094 2.24707
c-1.16406 12.8008 -12.5742 22.1113 -25.4004 22.0762l-5.05078 -0.0371094l0.0371094 5.05762c0.0722656 12.7998 -9.26758 24.2568 -22.0566 25.4189c-0.742188 0.0664062 -1.46973 0.0947266 -2.22949 0.0947266c-13.7012 0 -24.8418 -11.0527 -24.9854 -24.7207
l-0.214844 -48.5742c0 -0.00976562 -0.000976562 -0.0195312 -0.000976562 -0.0292969c0 -3.68164 2.98926 -6.6709 6.6709 -6.6709h0.0302734z" />
<glyph glyph-name="glass-martini" unicode="&#xf000;"
d="M502.05 390.4l-214.05 -214.04v-192.36h56c22.0898 0 40 -17.9102 40 -40c0 -4.41992 -3.58008 -8 -8 -8h-240c-4.41992 0 -8 3.58008 -8 8c0 22.0898 17.9102 40 40 40h56v192.36l-214.05 214.04c-21.25 21.2598 -6.2002 57.5996 23.8496 57.5996h444.4
c30.0498 0 45.0996 -36.3398 23.8496 -57.5996z" />

Before

Width:  |  Height:  |  Size: 893 KiB

After

Width:  |  Height:  |  Size: 896 KiB

Before After
Before After

Some files were not shown because too many files have changed in this diff Show more