Fixed #1543: Emojis support on tags
|
@ -70,10 +70,14 @@ promise.fail () ->
|
||||||
console.error "Your conf.json file is not a valid json file, please review it."
|
console.error "Your conf.json file is not a valid json file, please review it."
|
||||||
|
|
||||||
promise.always ->
|
promise.always ->
|
||||||
|
emojisPromise = $.getJSON("/#{window._version}/emojis/emojis-data.json").then (emojis) ->
|
||||||
|
window.emojis = emojis
|
||||||
if window.taigaConfig.contribPlugins.length > 0
|
if window.taigaConfig.contribPlugins.length > 0
|
||||||
loadPlugins(window.taigaConfig.contribPlugins).then () ->
|
loadPlugins(window.taigaConfig.contribPlugins).then () ->
|
||||||
ljs.load "/#{window._version}/js/app.js", ->
|
ljs.load "/#{window._version}/js/app.js", ->
|
||||||
|
emojisPromise.then ->
|
||||||
angular.bootstrap(document, ['taiga'])
|
angular.bootstrap(document, ['taiga'])
|
||||||
else
|
else
|
||||||
ljs.load "/#{window._version}/js/app.js", ->
|
ljs.load "/#{window._version}/js/app.js", ->
|
||||||
|
emojisPromise.then ->
|
||||||
angular.bootstrap(document, ['taiga'])
|
angular.bootstrap(document, ['taiga'])
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
###
|
###
|
||||||
|
|
||||||
@taiga = taiga = {}
|
@taiga = taiga = {}
|
||||||
|
taiga.emojis = window.emojis
|
||||||
@.taigaContribPlugins = @.taigaContribPlugins or window.taigaContribPlugins or []
|
@.taigaContribPlugins = @.taigaContribPlugins or window.taigaContribPlugins or []
|
||||||
|
|
||||||
# Generic function for generate hash from a arbitrary length
|
# Generic function for generate hash from a arbitrary length
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
###
|
||||||
|
# Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
# Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
|
||||||
|
# Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
|
||||||
|
# Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
|
||||||
|
# Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
|
||||||
|
# Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# File: modules/common/analytics.coffee
|
||||||
|
###
|
||||||
|
|
||||||
|
taiga = @.taiga
|
||||||
|
module = angular.module("taigaCommon")
|
||||||
|
|
||||||
|
|
||||||
|
class EmojisService extends taiga.Service
|
||||||
|
@.$inject = []
|
||||||
|
|
||||||
|
constructor: () ->
|
||||||
|
@.emojis = _.map taiga.emojis, (it) ->
|
||||||
|
it.image = "/#{window._version}/emojis/" + it.image
|
||||||
|
|
||||||
|
return it
|
||||||
|
@.emojisById = _.keyBy(@.emojis, 'id')
|
||||||
|
@.emojisByName = _.keyBy(@.emojis, 'name')
|
||||||
|
|
||||||
|
|
||||||
|
searchByName: (name) =>
|
||||||
|
return _.filter @.emojis, (it) -> it.name.indexOf(name) != -1
|
||||||
|
|
||||||
|
getEmojiById: (id) =>
|
||||||
|
return @.emojisById[id]
|
||||||
|
|
||||||
|
getEmojiByName: (name) =>
|
||||||
|
return @.emojisByName[name]
|
||||||
|
|
||||||
|
replaceImgsByEmojiName: (html) =>
|
||||||
|
emojiIds = taiga.getMatches(html, /emojis\/([^"]+).png"/gi)
|
||||||
|
|
||||||
|
for emojiId in emojiIds
|
||||||
|
regexImgs = new RegExp('<img(.*)' + emojiId + '[^>]+\>', 'g')
|
||||||
|
emoji = @.getEmojiById(emojiId)
|
||||||
|
html = html.replace(regexImgs, ':' + emoji.name + ':')
|
||||||
|
|
||||||
|
return html
|
||||||
|
|
||||||
|
replaceEmojiNameByImgs: (text) =>
|
||||||
|
emojiIds = taiga.getMatches(text, /:([\w +-]*):/g)
|
||||||
|
|
||||||
|
for emojiId in emojiIds
|
||||||
|
regexImgs = new RegExp(':' + emojiId + ':', 'g')
|
||||||
|
emoji = @.getEmojiByName(emojiId)
|
||||||
|
|
||||||
|
if emoji
|
||||||
|
text = text.replace(regexImgs, '')
|
||||||
|
|
||||||
|
return text
|
||||||
|
|
||||||
|
replaceEmojiNameByHtmlImgs: (text) =>
|
||||||
|
emojiIds = taiga.getMatches(text, /:([\w +-]*):/g)
|
||||||
|
|
||||||
|
for emojiId in emojiIds
|
||||||
|
regexImgs = new RegExp(':' + _.escapeRegExp(emojiId) + ':', 'g')
|
||||||
|
emoji = @.getEmojiByName(emojiId)
|
||||||
|
|
||||||
|
if emoji
|
||||||
|
text = text.replace(regexImgs, '<img src="' + emoji.image + '" />')
|
||||||
|
|
||||||
|
return text
|
||||||
|
|
||||||
|
module.service("$tgEmojis", EmojisService)
|
|
@ -143,3 +143,12 @@ inArray = ($filter) ->
|
||||||
return filter list, (listItem) ->
|
return filter list, (listItem) ->
|
||||||
return arrayFilter.indexOf(listItem[element]) != -1
|
return arrayFilter.indexOf(listItem[element]) != -1
|
||||||
module.filter("inArray", ["$filter", inArray])
|
module.filter("inArray", ["$filter", inArray])
|
||||||
|
|
||||||
|
emojify = ($emojis) ->
|
||||||
|
return (input) ->
|
||||||
|
if input
|
||||||
|
return $emojis.replaceEmojiNameByHtmlImgs(_.escape(input))
|
||||||
|
|
||||||
|
return ""
|
||||||
|
|
||||||
|
module.filter("emojify", ["$tgEmojis", emojify])
|
||||||
|
|
|
@ -58,14 +58,14 @@ TagsDirective = ->
|
||||||
module.directive("tgTags", TagsDirective)
|
module.directive("tgTags", TagsDirective)
|
||||||
|
|
||||||
|
|
||||||
ColorizeTagsBacklogDirective = ->
|
ColorizeTagsBacklogDirective = ($emojis) ->
|
||||||
template = _.template("""
|
template = _.template("""
|
||||||
<% _.each(tags, function(tag) { %>
|
<% _.each(tags, function(tag) { %>
|
||||||
<% if (tag[1] !== null) { %>
|
<% if (tag[1] !== null) { %>
|
||||||
<span class="tag"
|
<span class="tag"
|
||||||
style="border-left: 5px solid <%- tag[1] %>"
|
style="border-left: 5px solid <%- tag[1] %>"
|
||||||
title="<%- tag[0] %>">
|
title="<%- tag[0] %>">
|
||||||
<%- tag[0] %>
|
<%= emojify(tag[0]) %>
|
||||||
</span>
|
</span>
|
||||||
<% } %>
|
<% } %>
|
||||||
<% }) %>
|
<% }) %>
|
||||||
|
@ -73,7 +73,7 @@ ColorizeTagsBacklogDirective = ->
|
||||||
<% if (tag[1] === null) { %>
|
<% if (tag[1] === null) { %>
|
||||||
<span class="tag"
|
<span class="tag"
|
||||||
title="<%- tag[0] %>">
|
title="<%- tag[0] %>">
|
||||||
<%- tag[0] %>
|
<%= emojify(tag[0]) %>
|
||||||
</span>
|
</span>
|
||||||
<% } %>
|
<% } %>
|
||||||
<% }) %>
|
<% }) %>
|
||||||
|
@ -81,7 +81,7 @@ ColorizeTagsBacklogDirective = ->
|
||||||
|
|
||||||
link = ($scope, $el, $attrs, $ctrl) ->
|
link = ($scope, $el, $attrs, $ctrl) ->
|
||||||
render = (tags) ->
|
render = (tags) ->
|
||||||
html = template({tags: tags})
|
html = template({tags: tags, emojify: (text) -> $emojis.replaceEmojiNameByHtmlImgs(_.escape(text))})
|
||||||
$el.html(html)
|
$el.html(html)
|
||||||
|
|
||||||
$scope.$watch $attrs.tgColorizeBacklogTags, (tags) ->
|
$scope.$watch $attrs.tgColorizeBacklogTags, (tags) ->
|
||||||
|
@ -92,7 +92,7 @@ ColorizeTagsBacklogDirective = ->
|
||||||
|
|
||||||
return {link: link}
|
return {link: link}
|
||||||
|
|
||||||
module.directive("tgColorizeBacklogTags", ColorizeTagsBacklogDirective)
|
module.directive("tgColorizeBacklogTags", ["$tgEmojis", ColorizeTagsBacklogDirective])
|
||||||
|
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
|
@ -18,7 +18,15 @@ form(name="vm.filtersForm")
|
||||||
.filters-step-cat
|
.filters-step-cat
|
||||||
.filters-applied
|
.filters-applied
|
||||||
.single-filter.ng-animate-disabled(ng-repeat="it in vm.selectedFilters track by it.key")
|
.single-filter.ng-animate-disabled(ng-repeat="it in vm.selectedFilters track by it.key")
|
||||||
span.name(ng-attr-style="{{it.color ? 'border-left: 3px solid ' + it.color: ''}}") {{it.name}}
|
span.name(
|
||||||
|
ng-attr-style="{{it.color ? 'border-left: 3px solid ' + it.color: ''}}"
|
||||||
|
ng-if="it.dataType === 'tags'"
|
||||||
|
ng-bind-html="it.name | emojify"
|
||||||
|
)
|
||||||
|
span.name(
|
||||||
|
ng-if="it.dataType !== 'tags'"
|
||||||
|
ng-attr-style="{{it.color ? 'border-left: 3px solid ' + it.color: ''}}"
|
||||||
|
) {{it.name}}
|
||||||
a.remove-filter.e2e-remove-filter(
|
a.remove-filter.e2e-remove-filter(
|
||||||
ng-click="vm.unselectFilter(it)"
|
ng-click="vm.unselectFilter(it)"
|
||||||
href=""
|
href=""
|
||||||
|
@ -77,7 +85,15 @@ form(name="vm.filtersForm")
|
||||||
ng-if="!vm.isFilterSelected(filter, it) && !(it.count == 0 && filter.hideEmpty)"
|
ng-if="!vm.isFilterSelected(filter, it) && !(it.count == 0 && filter.hideEmpty)"
|
||||||
ng-click="vm.selectFilter(filter, it)"
|
ng-click="vm.selectFilter(filter, it)"
|
||||||
)
|
)
|
||||||
span.name(ng-attr-style="{{it.color ? 'border-left: 3px solid ' + it.color: ''}}") {{it.name}}
|
span.name(
|
||||||
|
ng-if="filter.dataType === 'tags'",
|
||||||
|
ng-attr-style="{{it.color ? 'border-left: 3px solid ' + it.color: ''}}"
|
||||||
|
ng-bind-html="it.name | emojify"
|
||||||
|
)
|
||||||
|
span.name(
|
||||||
|
ng-if="filter.dataType !== 'tags'",
|
||||||
|
ng-attr-style="{{it.color ? 'border-left: 3px solid ' + it.color: ''}}"
|
||||||
|
) {{it.name}}
|
||||||
span.number.e2e-filter-count(ng-if="it.count > 0") {{it.count}}
|
span.number.e2e-filter-count(ng-if="it.count > 0") {{it.count}}
|
||||||
|
|
||||||
li.custom-filters.e2e-custom-filters(
|
li.custom-filters.e2e-custom-filters(
|
||||||
|
|
|
@ -128,6 +128,9 @@ tg-filter {
|
||||||
@include ellipsis(100%);
|
@include ellipsis(100%);
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
img {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.number {
|
.number {
|
||||||
background: darken($whitish, 20%); // Fallback
|
background: darken($whitish, 20%); // Fallback
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
span {{ tag[0] }}
|
span(ng-bind-html="tag[0] | emojify")
|
||||||
tg-svg.icon-close.e2e-delete-tag(
|
tg-svg.icon-close.e2e-delete-tag(
|
||||||
ng-if="hasPermissions"
|
ng-if="hasPermissions"
|
||||||
svg-icon="icon-close"
|
svg-icon="icon-close"
|
||||||
|
|
|
@ -19,4 +19,7 @@
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
width: 1rem;
|
width: 1rem;
|
||||||
}
|
}
|
||||||
|
img {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,8 +208,6 @@ Medium = ($translate, $confirm, $storage, wysiwygService, animationFrame, tgLoad
|
||||||
$scope.codeEditorVisible = false
|
$scope.codeEditorVisible = false
|
||||||
$scope.codeLans = []
|
$scope.codeLans = []
|
||||||
|
|
||||||
wysiwygService.loadEmojis()
|
|
||||||
|
|
||||||
wysiwygCodeHightlighterService.getLanguages().then (codeLans) ->
|
wysiwygCodeHightlighterService.getLanguages().then (codeLans) ->
|
||||||
$scope.codeLans = codeLans
|
$scope.codeLans = codeLans
|
||||||
|
|
||||||
|
|
|
@ -26,49 +26,13 @@ class WysiwygService
|
||||||
@.$inject = [
|
@.$inject = [
|
||||||
"tgWysiwygCodeHightlighterService",
|
"tgWysiwygCodeHightlighterService",
|
||||||
"tgProjectService",
|
"tgProjectService",
|
||||||
"$tgNavUrls"
|
"$tgNavUrls",
|
||||||
|
"$tgEmojis"
|
||||||
]
|
]
|
||||||
constructor: (@wysiwygCodeHightlighterService, @projectService, @navurls) ->
|
constructor: (@wysiwygCodeHightlighterService, @projectService, @navurls, @emojis) ->
|
||||||
|
|
||||||
searchEmojiByName: (name) ->
|
searchEmojiByName: (name) ->
|
||||||
return _.filter @.emojis, (it) -> it.name.indexOf(name) != -1
|
return @emojis.searchByName(name)
|
||||||
|
|
||||||
setEmojiImagePath: (emojis) ->
|
|
||||||
@.emojis = _.map emojis, (it) ->
|
|
||||||
it.image = "/#{window._version}/emojis/" + it.image
|
|
||||||
|
|
||||||
return it
|
|
||||||
|
|
||||||
loadEmojis: () ->
|
|
||||||
$.getJSON("/#{window._version}/emojis/emojis-data.json").then(@.setEmojiImagePath.bind(this))
|
|
||||||
|
|
||||||
getEmojiById: (id) ->
|
|
||||||
return _.find @.emojis, (it) -> it.id == id
|
|
||||||
|
|
||||||
getEmojiByName: (name) ->
|
|
||||||
return _.find @.emojis, (it) -> it.name == name
|
|
||||||
|
|
||||||
replaceImgsByEmojiName: (html) ->
|
|
||||||
emojiIds = taiga.getMatches(html, /emojis\/([^"]+).png"/gi)
|
|
||||||
|
|
||||||
for emojiId in emojiIds
|
|
||||||
regexImgs = new RegExp('<img(.*)' + emojiId + '[^>]+\>', 'g')
|
|
||||||
emoji = @.getEmojiById(emojiId)
|
|
||||||
html = html.replace(regexImgs, ':' + emoji.name + ':')
|
|
||||||
|
|
||||||
return html
|
|
||||||
|
|
||||||
replaceEmojiNameByImgs: (text) ->
|
|
||||||
emojiIds = taiga.getMatches(text, /:([\w ]*):/g)
|
|
||||||
|
|
||||||
for emojiId in emojiIds
|
|
||||||
regexImgs = new RegExp(':' + emojiId + ':', 'g')
|
|
||||||
emoji = @.getEmojiByName(emojiId)
|
|
||||||
|
|
||||||
if emoji
|
|
||||||
text = text.replace(regexImgs, '')
|
|
||||||
|
|
||||||
return text
|
|
||||||
|
|
||||||
pipeLinks: (text) ->
|
pipeLinks: (text) ->
|
||||||
return text.replace /\[\[(.*?)\]\]/g, (match, p1, offset, str) ->
|
return text.replace /\[\[(.*?)\]\]/g, (match, p1, offset, str) ->
|
||||||
|
@ -134,7 +98,7 @@ class WysiwygService
|
||||||
}
|
}
|
||||||
|
|
||||||
html = html.replace(/ (<\/.*>)/g, "$1")
|
html = html.replace(/ (<\/.*>)/g, "$1")
|
||||||
html = @.replaceImgsByEmojiName(html)
|
html = @emojis.replaceImgsByEmojiName(html)
|
||||||
html = @.replaceUrls(html)
|
html = @.replaceUrls(html)
|
||||||
html = @.removeTrailingListBr(html)
|
html = @.removeTrailingListBr(html)
|
||||||
|
|
||||||
|
@ -211,7 +175,7 @@ class WysiwygService
|
||||||
breaks: true
|
breaks: true
|
||||||
}
|
}
|
||||||
|
|
||||||
text = @.replaceEmojiNameByImgs(text)
|
text = @emojis.replaceEmojiNameByImgs(text)
|
||||||
text = @.pipeLinks(text)
|
text = @.pipeLinks(text)
|
||||||
|
|
||||||
md = window.markdownit({
|
md = window.markdownit({
|
||||||
|
|
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 484 B |
Before Width: | Height: | Size: 460 B After Width: | Height: | Size: 449 B |
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 422 B |
Before Width: | Height: | Size: 277 B After Width: | Height: | Size: 268 B |
Before Width: | Height: | Size: 455 B After Width: | Height: | Size: 443 B |
Before Width: | Height: | Size: 468 B After Width: | Height: | Size: 464 B |
Before Width: | Height: | Size: 424 B After Width: | Height: | Size: 414 B |
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 458 B |
Before Width: | Height: | Size: 443 B After Width: | Height: | Size: 432 B |
Before Width: | Height: | Size: 392 B After Width: | Height: | Size: 384 B |
Before Width: | Height: | Size: 458 B After Width: | Height: | Size: 448 B |
Before Width: | Height: | Size: 446 B After Width: | Height: | Size: 440 B |
BIN
emojis/1f004.png
Before Width: | Height: | Size: 467 B After Width: | Height: | Size: 457 B |
BIN
emojis/1f0cf.png
Before Width: | Height: | Size: 607 B After Width: | Height: | Size: 603 B |
BIN
emojis/1f170.png
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 460 B |
BIN
emojis/1f171.png
Before Width: | Height: | Size: 436 B After Width: | Height: | Size: 427 B |
BIN
emojis/1f17e.png
Before Width: | Height: | Size: 512 B After Width: | Height: | Size: 505 B |
BIN
emojis/1f17f.png
Before Width: | Height: | Size: 404 B After Width: | Height: | Size: 389 B |
BIN
emojis/1f18e.png
Before Width: | Height: | Size: 596 B After Width: | Height: | Size: 595 B |
BIN
emojis/1f191.png
Before Width: | Height: | Size: 532 B After Width: | Height: | Size: 530 B |
BIN
emojis/1f192.png
Before Width: | Height: | Size: 482 B After Width: | Height: | Size: 478 B |
BIN
emojis/1f193.png
Before Width: | Height: | Size: 531 B After Width: | Height: | Size: 526 B |
BIN
emojis/1f194.png
Before Width: | Height: | Size: 472 B After Width: | Height: | Size: 463 B |
BIN
emojis/1f195.png
Before Width: | Height: | Size: 486 B After Width: | Height: | Size: 486 B |
BIN
emojis/1f196.png
Before Width: | Height: | Size: 591 B After Width: | Height: | Size: 589 B |
BIN
emojis/1f197.png
Before Width: | Height: | Size: 596 B After Width: | Height: | Size: 592 B |
BIN
emojis/1f198.png
Before Width: | Height: | Size: 587 B After Width: | Height: | Size: 586 B |
BIN
emojis/1f199.png
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 510 B |
BIN
emojis/1f19a.png
Before Width: | Height: | Size: 650 B After Width: | Height: | Size: 649 B |
Before Width: | Height: | Size: 571 B After Width: | Height: | Size: 563 B |
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 332 B |
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 214 B |
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 333 B |
Before Width: | Height: | Size: 529 B After Width: | Height: | Size: 509 B |
Before Width: | Height: | Size: 573 B After Width: | Height: | Size: 564 B |
Before Width: | Height: | Size: 343 B After Width: | Height: | Size: 336 B |
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 360 B After Width: | Height: | Size: 342 B |
Before Width: | Height: | Size: 409 B After Width: | Height: | Size: 400 B |
Before Width: | Height: | Size: 291 B After Width: | Height: | Size: 258 B |
Before Width: | Height: | Size: 566 B After Width: | Height: | Size: 558 B |
Before Width: | Height: | Size: 187 B After Width: | Height: | Size: 176 B |
Before Width: | Height: | Size: 559 B After Width: | Height: | Size: 547 B |
Before Width: | Height: | Size: 274 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 302 B After Width: | Height: | Size: 292 B |
Before Width: | Height: | Size: 281 B After Width: | Height: | Size: 263 B |
Before Width: | Height: | Size: 399 B After Width: | Height: | Size: 388 B |
Before Width: | Height: | Size: 307 B After Width: | Height: | Size: 299 B |
Before Width: | Height: | Size: 307 B After Width: | Height: | Size: 298 B |
Before Width: | Height: | Size: 197 B After Width: | Height: | Size: 183 B |
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 243 B |
Before Width: | Height: | Size: 195 B After Width: | Height: | Size: 180 B |
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 359 B |
Before Width: | Height: | Size: 658 B After Width: | Height: | Size: 643 B |
Before Width: | Height: | Size: 210 B After Width: | Height: | Size: 191 B |
Before Width: | Height: | Size: 556 B After Width: | Height: | Size: 467 B |
Before Width: | Height: | Size: 550 B After Width: | Height: | Size: 544 B |
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 529 B |
Before Width: | Height: | Size: 317 B After Width: | Height: | Size: 300 B |
Before Width: | Height: | Size: 484 B After Width: | Height: | Size: 473 B |
Before Width: | Height: | Size: 539 B After Width: | Height: | Size: 526 B |
Before Width: | Height: | Size: 368 B After Width: | Height: | Size: 366 B |
Before Width: | Height: | Size: 465 B After Width: | Height: | Size: 444 B |
Before Width: | Height: | Size: 303 B After Width: | Height: | Size: 291 B |
Before Width: | Height: | Size: 210 B After Width: | Height: | Size: 181 B |
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 511 B |
Before Width: | Height: | Size: 357 B After Width: | Height: | Size: 345 B |
Before Width: | Height: | Size: 410 B After Width: | Height: | Size: 397 B |
Before Width: | Height: | Size: 624 B After Width: | Height: | Size: 607 B |
Before Width: | Height: | Size: 383 B After Width: | Height: | Size: 373 B |
Before Width: | Height: | Size: 401 B After Width: | Height: | Size: 391 B |
Before Width: | Height: | Size: 300 B After Width: | Height: | Size: 287 B |
Before Width: | Height: | Size: 198 B After Width: | Height: | Size: 180 B |
Before Width: | Height: | Size: 567 B After Width: | Height: | Size: 558 B |
Before Width: | Height: | Size: 284 B After Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 232 B |
Before Width: | Height: | Size: 292 B After Width: | Height: | Size: 280 B |
Before Width: | Height: | Size: 198 B After Width: | Height: | Size: 181 B |
Before Width: | Height: | Size: 195 B After Width: | Height: | Size: 182 B |
Before Width: | Height: | Size: 288 B After Width: | Height: | Size: 283 B |
Before Width: | Height: | Size: 398 B After Width: | Height: | Size: 397 B |
Before Width: | Height: | Size: 347 B After Width: | Height: | Size: 329 B |
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 252 B |
Before Width: | Height: | Size: 510 B After Width: | Height: | Size: 496 B |
Before Width: | Height: | Size: 333 B After Width: | Height: | Size: 320 B |
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 379 B |
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 176 B |
Before Width: | Height: | Size: 805 B After Width: | Height: | Size: 798 B |