Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2016-07-21 13:28:33 +0300
committerLin Jen-Shin <godfat@godfat.org>2016-07-21 13:28:33 +0300
commit83975914337d1dc05193a83d27be577c5631f801 (patch)
treeaeaf2450cb8a8a1c99b064d7d353e28d682c0b65 /app
parente3ce02300bf90451b98479720d1093afe8b7eea8 (diff)
parent4211f50014faebf027fd2bc80e0cf1d3f012627c (diff)
Merge branch 'artifacts-from-ref-and-build-name-api' into artifacts-from-ref-and-build-name
* artifacts-from-ref-and-build-name-api: (384 commits) Add API documentation for downloading the latest successful build Since it's too hard to use JOIN with Rails... feedback: Workaround MySQL with INNER JOIN: Just put setup directly in the test, feedback: Cleanup the use of let, feedback: Lose unneeded instance variables and variables, feedback: Add link to user profile to commit avatar (!5163) It's not longer than 80 chars Make sure there's a build Use the same logic, it should specify that it's not logged in Use 'when logging as guest' for context, feedback: Cleanup that a bit Refactor service settings view Fix a problem with processing a pipeline where stage only has manual actions Rename user2 to reporter_user Should check against `authorize_read_builds!` A CHANGELOG entry Don't show other actions of the same name Use limit parameter rather than hardcoded value Reuse those two methods ...
Diffstat (limited to 'app')
-rw-r--r--app/assets/images/emoji.pngbin1025831 -> 1087659 bytes
-rw-r--r--app/assets/images/emoji@2x.pngbin2492919 -> 2652225 bytes
-rw-r--r--app/assets/javascripts/gl_dropdown.js.coffee2
-rw-r--r--app/assets/javascripts/graphs/graphs_bundle.js.coffee (renamed from app/assets/javascripts/graphs/application.js.coffee)0
-rw-r--r--app/assets/javascripts/issues-bulk-assignment.js.coffee13
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js.coffee2
-rw-r--r--app/assets/javascripts/network/network_bundle.js.coffee (renamed from app/assets/javascripts/network/application.js.coffee)0
-rw-r--r--app/assets/javascripts/profile/profile_bundle.js.coffee (renamed from app/assets/javascripts/profile/application.js.coffee)0
-rw-r--r--app/assets/javascripts/protected_branches.js.coffee8
-rw-r--r--app/assets/javascripts/subscription_select.js.coffee18
-rw-r--r--app/assets/javascripts/users/users_bundle.js.coffee (renamed from app/assets/javascripts/users/application.js.coffee)0
-rw-r--r--app/assets/stylesheets/framework/blocks.scss4
-rw-r--r--app/assets/stylesheets/framework/buttons.scss18
-rw-r--r--app/assets/stylesheets/framework/files.scss2
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss4
-rw-r--r--app/assets/stylesheets/framework/typography.scss32
-rw-r--r--app/assets/stylesheets/framework/variables.scss2
-rw-r--r--app/assets/stylesheets/pages/emojis.scss2607
-rw-r--r--app/assets/stylesheets/pages/issuable.scss3
-rw-r--r--app/assets/stylesheets/pages/issues.scss10
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss16
-rw-r--r--app/assets/stylesheets/pages/pipelines.scss67
-rw-r--r--app/assets/stylesheets/pages/projects.scss73
-rw-r--r--app/assets/stylesheets/pages/status.scss8
-rw-r--r--app/assets/stylesheets/pages/tags.scss7
-rw-r--r--app/assets/stylesheets/pages/tree.scss2
-rw-r--r--app/controllers/admin/groups_controller.rb2
-rw-r--r--app/controllers/admin/services_controller.rb15
-rw-r--r--app/controllers/concerns/creates_commit.rb3
-rw-r--r--app/controllers/concerns/diff_for_path.rb1
-rw-r--r--app/controllers/concerns/service_params.rb35
-rw-r--r--app/controllers/groups_controller.rb2
-rw-r--r--app/controllers/projects/badges_controller.rb5
-rw-r--r--app/controllers/projects/blob_controller.rb6
-rw-r--r--app/controllers/projects/builds_controller.rb13
-rw-r--r--app/controllers/projects/compare_controller.rb1
-rw-r--r--app/controllers/projects/issues_controller.rb1
-rw-r--r--app/controllers/projects/pipelines_settings_controller.rb30
-rw-r--r--app/controllers/projects/protected_branches_controller.rb2
-rw-r--r--app/controllers/projects/refs_controller.rb2
-rw-r--r--app/controllers/projects/services_controller.rb30
-rw-r--r--app/controllers/projects_controller.rb4
-rw-r--r--app/helpers/avatars_helper.rb30
-rw-r--r--app/helpers/branches_helper.rb2
-rw-r--r--app/helpers/ci_status_helper.rb14
-rw-r--r--app/helpers/commits_helper.rb10
-rw-r--r--app/helpers/diff_helper.rb9
-rw-r--r--app/helpers/external_wiki_helper.rb5
-rw-r--r--app/helpers/services_helper.rb25
-rw-r--r--app/helpers/time_helper.rb26
-rw-r--r--app/mailers/emails/builds.rb1
-rw-r--r--app/models/ability.rb4
-rw-r--r--app/models/ci/build.rb91
-rw-r--r--app/models/ci/pipeline.rb24
-rw-r--r--app/models/ci/runner.rb8
-rw-r--r--app/models/ci/trigger_request.rb8
-rw-r--r--app/models/commit_status.rb10
-rw-r--r--app/models/concerns/statuseable.rb6
-rw-r--r--app/models/deployment.rb4
-rw-r--r--app/models/merge_request.rb8
-rw-r--r--app/models/merge_request_diff.rb9
-rw-r--r--app/models/project.rb68
-rw-r--r--app/models/project_services/builds_email_service.rb27
-rw-r--r--app/models/project_services/slack_service.rb51
-rw-r--r--app/models/repository.rb114
-rw-r--r--app/models/service.rb29
-rw-r--r--app/models/user.rb2
-rw-r--r--app/services/ci/create_builds_service.rb6
-rw-r--r--app/services/commits/change_service.rb4
-rw-r--r--app/services/create_branch_service.rb28
-rw-r--r--app/services/files/base_service.rb4
-rw-r--r--app/services/files/update_service.rb5
-rw-r--r--app/services/git_push_service.rb3
-rw-r--r--app/services/issuable_base_service.rb10
-rw-r--r--app/services/issues/bulk_update_service.rb2
-rw-r--r--app/services/merge_requests/merge_service.rb4
-rw-r--r--app/services/merge_requests/refresh_service.rb2
-rw-r--r--app/services/projects/import_export/export_service.rb6
-rw-r--r--app/uploaders/avatar_uploader.rb4
-rw-r--r--app/views/admin/groups/_form.html.haml4
-rw-r--r--app/views/emojis/index.html.haml2
-rw-r--r--app/views/events/_event.html.haml6
-rw-r--r--app/views/groups/edit.html.haml4
-rw-r--r--app/views/layouts/_init_auto_complete.html.haml10
-rw-r--r--app/views/layouts/nav/_explore.html.haml4
-rw-r--r--app/views/layouts/nav/_project_settings.html.haml6
-rw-r--r--app/views/profiles/_head.html.haml2
-rw-r--r--app/views/projects/_builds_settings.html.haml65
-rw-r--r--app/views/projects/badges/index.html.haml23
-rw-r--r--app/views/projects/blob/_editor.html.haml4
-rw-r--r--app/views/projects/branches/_branch.html.haml4
-rw-r--r--app/views/projects/builds/_sidebar.html.haml6
-rw-r--r--app/views/projects/buttons/_download.html.haml4
-rw-r--r--app/views/projects/buttons/_fork.html.haml4
-rw-r--r--app/views/projects/ci/builds/_build.html.haml13
-rw-r--r--app/views/projects/ci/pipelines/_pipeline.html.haml50
-rw-r--r--app/views/projects/commits/_commit.html.haml3
-rw-r--r--app/views/projects/deployments/_actions.haml22
-rw-r--r--app/views/projects/deployments/_deployment.html.haml10
-rw-r--r--app/views/projects/diffs/_content.html.haml10
-rw-r--r--app/views/projects/diffs/_diffs.html.haml2
-rw-r--r--app/views/projects/edit.html.haml6
-rw-r--r--app/views/projects/environments/_environment.html.haml3
-rw-r--r--app/views/projects/environments/index.html.haml1
-rw-r--r--app/views/projects/environments/show.html.haml2
-rw-r--r--app/views/projects/forks/index.html.haml4
-rw-r--r--app/views/projects/forks/new.html.haml91
-rw-r--r--app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml2
-rw-r--r--app/views/projects/graphs/_head.html.haml2
-rw-r--r--app/views/projects/merge_requests/widget/open/_conflicts.html.haml2
-rw-r--r--app/views/projects/network/show.html.haml2
-rw-r--r--app/views/projects/notes/_notes_with_form.html.haml4
-rw-r--r--app/views/projects/pipelines_settings/show.html.haml103
-rw-r--r--app/views/projects/protected_branches/_branches_list.html.haml2
-rw-r--r--app/views/projects/protected_branches/_protected_branch.html.haml2
-rw-r--r--app/views/projects/protected_branches/index.html.haml8
-rw-r--r--app/views/projects/repositories/_download_archive.html.haml4
-rw-r--r--app/views/projects/services/_form.html.haml3
-rw-r--r--app/views/projects/tags/_download.html.haml4
-rw-r--r--app/views/projects/tags/show.html.haml67
-rw-r--r--app/views/shared/_allow_request_access.html.haml6
-rw-r--r--app/views/shared/_service_settings.html.haml81
-rw-r--r--app/views/shared/icons/_icon_fork.svg1
-rw-r--r--app/views/shared/icons/_icon_status_cancel.svg12
-rw-r--r--app/views/shared/icons/_icon_status_failed.svg12
-rw-r--r--app/views/shared/icons/_icon_status_pending.svg13
-rw-r--r--app/views/shared/icons/_icon_status_running.svg12
-rw-r--r--app/views/shared/icons/_icon_status_success.svg15
-rw-r--r--app/views/shared/icons/_icon_status_warning.svg15
-rw-r--r--app/views/shared/issuable/_filter.html.haml9
-rw-r--r--app/views/users/show.html.haml2
131 files changed, 2604 insertions, 1857 deletions
diff --git a/app/assets/images/emoji.png b/app/assets/images/emoji.png
index 6bacb0e92b6..6f1a34a5591 100644
--- a/app/assets/images/emoji.png
+++ b/app/assets/images/emoji.png
Binary files differ
diff --git a/app/assets/images/emoji@2x.png b/app/assets/images/emoji@2x.png
index 99588b56616..dc9cae1d44c 100644
--- a/app/assets/images/emoji@2x.png
+++ b/app/assets/images/emoji@2x.png
Binary files differ
diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee
index 1b0d0db8954..951530e03a5 100644
--- a/app/assets/javascripts/gl_dropdown.js.coffee
+++ b/app/assets/javascripts/gl_dropdown.js.coffee
@@ -250,6 +250,8 @@ class GitLabDropdown
if self.options.clicked
self.options.clicked(selected, $el, e)
+ $el.trigger('blur')
+
# Finds an element inside wrapper element
getElement: (selector) ->
@dropdown.find selector
diff --git a/app/assets/javascripts/graphs/application.js.coffee b/app/assets/javascripts/graphs/graphs_bundle.js.coffee
index e0f681acf0b..e0f681acf0b 100644
--- a/app/assets/javascripts/graphs/application.js.coffee
+++ b/app/assets/javascripts/graphs/graphs_bundle.js.coffee
diff --git a/app/assets/javascripts/issues-bulk-assignment.js.coffee b/app/assets/javascripts/issues-bulk-assignment.js.coffee
index 6b0e69dbae7..3d09ea08e3b 100644
--- a/app/assets/javascripts/issues-bulk-assignment.js.coffee
+++ b/app/assets/javascripts/issues-bulk-assignment.js.coffee
@@ -85,12 +85,13 @@ class @IssuableBulkActions
getFormDataAsObject: ->
formData =
update:
- state_event : @form.find('input[name="update[state_event]"]').val()
- assignee_id : @form.find('input[name="update[assignee_id]"]').val()
- milestone_id : @form.find('input[name="update[milestone_id]"]').val()
- issues_ids : @form.find('input[name="update[issues_ids]"]').val()
- add_label_ids : []
- remove_label_ids : []
+ state_event : @form.find('input[name="update[state_event]"]').val()
+ assignee_id : @form.find('input[name="update[assignee_id]"]').val()
+ milestone_id : @form.find('input[name="update[milestone_id]"]').val()
+ issues_ids : @form.find('input[name="update[issues_ids]"]').val()
+ subscription_event : @form.find('input[name="update[subscription_event]"]').val()
+ add_label_ids : []
+ remove_label_ids : []
if @willUpdateLabels
@getLabelsToApply().map (id) ->
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js.coffee b/app/assets/javascripts/lib/utils/datetime_utility.js.coffee
index 178963fe0aa..2371e913844 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js.coffee
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js.coffee
@@ -2,7 +2,7 @@
w.gl ?= {}
w.gl.utils ?= {}
- w.gl.utils.days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
+ w.gl.utils.days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
w.gl.utils.formatDate = (datetime) ->
dateFormat(datetime, 'mmm d, yyyy h:MMtt Z')
diff --git a/app/assets/javascripts/network/application.js.coffee b/app/assets/javascripts/network/network_bundle.js.coffee
index f75f63869c5..f75f63869c5 100644
--- a/app/assets/javascripts/network/application.js.coffee
+++ b/app/assets/javascripts/network/network_bundle.js.coffee
diff --git a/app/assets/javascripts/profile/application.js.coffee b/app/assets/javascripts/profile/profile_bundle.js.coffee
index 91cacfece46..91cacfece46 100644
--- a/app/assets/javascripts/profile/application.js.coffee
+++ b/app/assets/javascripts/profile/profile_bundle.js.coffee
diff --git a/app/assets/javascripts/protected_branches.js.coffee b/app/assets/javascripts/protected_branches.js.coffee
index 79c2306e4d2..14afef2e2ee 100644
--- a/app/assets/javascripts/protected_branches.js.coffee
+++ b/app/assets/javascripts/protected_branches.js.coffee
@@ -1,18 +1,18 @@
$ ->
$(".protected-branches-list :checkbox").change (e) ->
name = $(this).attr("name")
- if name == "developers_can_push"
+ if name == "developers_can_push" || name == "developers_can_merge"
id = $(this).val()
- checked = $(this).is(":checked")
+ can_push = $(this).is(":checked")
url = $(this).data("url")
$.ajax
- type: "PUT"
+ type: "PATCH"
url: url
dataType: "json"
data:
id: id
protected_branch:
- developers_can_push: checked
+ "#{name}": can_push
success: ->
row = $(e.target)
diff --git a/app/assets/javascripts/subscription_select.js.coffee b/app/assets/javascripts/subscription_select.js.coffee
new file mode 100644
index 00000000000..e5eb7a50d80
--- /dev/null
+++ b/app/assets/javascripts/subscription_select.js.coffee
@@ -0,0 +1,18 @@
+class @SubscriptionSelect
+ constructor: ->
+ $('.js-subscription-event').each (i, el) ->
+ fieldName = $(el).data("field-name")
+
+ $(el).glDropdown(
+ selectable: true
+ fieldName: fieldName
+ toggleLabel: (selected, el, instance) =>
+ label = 'Subscription'
+ $item = instance.dropdown.find('.is-active')
+ label = $item.text() if $item.length
+ label
+ clicked: (item, $el, e)->
+ e.preventDefault()
+ id: (obj, el) ->
+ $(el).data("id")
+ )
diff --git a/app/assets/javascripts/users/application.js.coffee b/app/assets/javascripts/users/users_bundle.js.coffee
index 91cacfece46..91cacfece46 100644
--- a/app/assets/javascripts/users/application.js.coffee
+++ b/app/assets/javascripts/users/users_bundle.js.coffee
diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss
index ad94e457cfd..7ce203d2ec7 100644
--- a/app/assets/stylesheets/framework/blocks.scss
+++ b/app/assets/stylesheets/framework/blocks.scss
@@ -232,7 +232,9 @@
.nav-block {
.controls {
float: right;
- margin-top: 11px;
+ margin-top: 8px;
+ padding-bottom: 7px;
+ border-bottom: 1px solid $border-color;
}
}
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index 590b8f54363..f87b8a2ad1c 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -49,6 +49,17 @@
border-color: $border-dark;
color: $color;
}
+
+ svg {
+
+ path {
+ fill: $color;
+ }
+
+ use {
+ stroke: $color;
+ }
+ }
}
@mixin btn-green {
@@ -173,6 +184,13 @@
.caret {
margin-left: 5px;
}
+
+ svg {
+ height: 15px;
+ width: auto;
+ position: relative;
+ top: 2px;
+ }
}
.btn-lg {
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index 71e4b50f2af..407f1873431 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -70,7 +70,7 @@
}
&.wiki {
- padding: $gl-padding;
+ padding: 30px $gl-padding;
.highlight {
margin-bottom: 9px;
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index d52e8f00172..3fa4a22258d 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -198,6 +198,10 @@ header.header-pinned-nav {
.sidebar-collapsed-icon {
cursor: pointer;
+
+ .btn {
+ background-color: $gray-light;
+ }
}
}
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index 3575984b229..8659604cb8b 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -37,39 +37,41 @@
}
h1 {
- font-size: 1.3em;
+ font-size: 2em;
font-weight: 600;
- margin: 24px 0 12px;
- padding: 0 0 10px;
- border-bottom: 1px solid #e7e9ed;
+ margin: 1em 0 10px;
+ padding: 0 0 0.3em;
+ border-bottom: 1px solid $btn-default-border;
color: $gl-gray-dark;
}
h2 {
- font-size: 1.2em;
+ font-size: 1.6em;
font-weight: 600;
- margin: 24px 0 12px;
+ margin: 1em 0 10px;
+ padding-bottom: 0.3em;
+ border-bottom: 1px solid $btn-default-border;
color: $gl-gray-dark;
}
h3 {
- margin: 24px 0 12px;
- font-size: 1.1em;
+ margin: 1em 0 10px;
+ font-size: 1.4em;
}
h4 {
- margin: 24px 0 12px;
- font-size: 0.98em;
+ margin: 1em 0 10px;
+ font-size: 1.25em;
}
h5 {
- margin: 24px 0 12px;
- font-size: 0.95em;
+ margin: 1em 0 10px;
+ font-size: 1em;
}
h6 {
- margin: 24px 0 12px;
- font-size: 0.90em;
+ margin: 1em 0 10px;
+ font-size: 0.95em;
}
blockquote {
@@ -115,7 +117,7 @@
ul, ol {
padding: 0;
- margin: 6px 0 6px 28px !important;
+ margin: 3px 0 3px 28px !important;
}
li {
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index f0e7002e4cd..1882d4e888d 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -16,7 +16,7 @@ $border-color: #e5e5e5;
$focus-border-color: #3aabf0;
$table-border-color: #f0f0f0;
$background-color: #fafafa;
-$dark-background-color: #f7f7f7;
+$dark-background-color: #f5f5f5;
$table-text-gray: #8f8f8f;
/*
diff --git a/app/assets/stylesheets/pages/emojis.scss b/app/assets/stylesheets/pages/emojis.scss
index b731abc7450..f17797b2381 100644
--- a/app/assets/stylesheets/pages/emojis.scss
+++ b/app/assets/stylesheets/pages/emojis.scss
@@ -1,4 +1,4 @@
-.emoji-0023-20E3 { background-position: 0 0; }
+.emoji-0023-20E3 { background-position: 0 0px; }
.emoji-002A-20E3 { background-position: -20px 0; }
.emoji-0030-20E3 { background-position: 0 -20px; }
.emoji-0031-20E3 { background-position: -20px -20px; }
@@ -452,1271 +452,1344 @@
.emoji-1F391 { background-position: -420px -200px; }
.emoji-1F392 { background-position: -420px -220px; }
.emoji-1F393 { background-position: -420px -240px; }
-.emoji-1F394 { background-position: -420px -260px; }
-.emoji-1F395 { background-position: -420px -280px; }
-.emoji-1F396 { background-position: -420px -300px; }
-.emoji-1F397 { background-position: -420px -320px; }
-.emoji-1F398 { background-position: -420px -340px; }
-.emoji-1F399 { background-position: -420px -360px; }
-.emoji-1F39A { background-position: -420px -380px; }
-.emoji-1F39B { background-position: -420px -400px; }
-.emoji-1F39C { background-position: 0 -420px; }
-.emoji-1F39D { background-position: -20px -420px; }
-.emoji-1F39E { background-position: -40px -420px; }
-.emoji-1F39F { background-position: -60px -420px; }
-.emoji-1F3A0 { background-position: -80px -420px; }
-.emoji-1F3A1 { background-position: -100px -420px; }
-.emoji-1F3A2 { background-position: -120px -420px; }
-.emoji-1F3A3 { background-position: -140px -420px; }
-.emoji-1F3A4 { background-position: -160px -420px; }
-.emoji-1F3A5 { background-position: -180px -420px; }
-.emoji-1F3A6 { background-position: -200px -420px; }
-.emoji-1F3A7 { background-position: -220px -420px; }
-.emoji-1F3A8 { background-position: -240px -420px; }
-.emoji-1F3A9 { background-position: -260px -420px; }
-.emoji-1F3AA { background-position: -280px -420px; }
-.emoji-1F3AB { background-position: -300px -420px; }
-.emoji-1F3AC { background-position: -320px -420px; }
-.emoji-1F3AD { background-position: -340px -420px; }
-.emoji-1F3AE { background-position: -360px -420px; }
-.emoji-1F3AF { background-position: -380px -420px; }
-.emoji-1F3B0 { background-position: -400px -420px; }
-.emoji-1F3B1 { background-position: -420px -420px; }
-.emoji-1F3B2 { background-position: -440px 0; }
-.emoji-1F3B3 { background-position: -440px -20px; }
-.emoji-1F3B4 { background-position: -440px -40px; }
-.emoji-1F3B5 { background-position: -440px -60px; }
-.emoji-1F3B6 { background-position: -440px -80px; }
-.emoji-1F3B7 { background-position: -440px -100px; }
-.emoji-1F3B8 { background-position: -440px -120px; }
-.emoji-1F3B9 { background-position: -440px -140px; }
-.emoji-1F3BA { background-position: -440px -160px; }
-.emoji-1F3BB { background-position: -440px -180px; }
-.emoji-1F3BC { background-position: -440px -200px; }
-.emoji-1F3BD { background-position: -440px -220px; }
-.emoji-1F3BE { background-position: -440px -240px; }
-.emoji-1F3BF { background-position: -440px -260px; }
-.emoji-1F3C0 { background-position: -440px -280px; }
-.emoji-1F3C1 { background-position: -440px -300px; }
-.emoji-1F3C2 { background-position: -440px -320px; }
-.emoji-1F3C3 { background-position: -440px -340px; }
-.emoji-1F3C3-1F3FB { background-position: -440px -360px; }
-.emoji-1F3C3-1F3FC { background-position: -440px -380px; }
-.emoji-1F3C3-1F3FD { background-position: -440px -400px; }
-.emoji-1F3C3-1F3FE { background-position: -440px -420px; }
-.emoji-1F3C3-1F3FF { background-position: 0 -440px; }
-.emoji-1F3C4 { background-position: -20px -440px; }
-.emoji-1F3C4-1F3FB { background-position: -40px -440px; }
-.emoji-1F3C4-1F3FC { background-position: -60px -440px; }
-.emoji-1F3C4-1F3FD { background-position: -80px -440px; }
-.emoji-1F3C4-1F3FE { background-position: -100px -440px; }
-.emoji-1F3C4-1F3FF { background-position: -120px -440px; }
-.emoji-1F3C5 { background-position: -140px -440px; }
-.emoji-1F3C6 { background-position: -160px -440px; }
-.emoji-1F3C7 { background-position: -180px -440px; }
-.emoji-1F3C7-1F3FB { background-position: -200px -440px; }
-.emoji-1F3C7-1F3FC { background-position: -220px -440px; }
-.emoji-1F3C7-1F3FD { background-position: -240px -440px; }
-.emoji-1F3C7-1F3FE { background-position: -260px -440px; }
-.emoji-1F3C7-1F3FF { background-position: -280px -440px; }
-.emoji-1F3C8 { background-position: -300px -440px; }
-.emoji-1F3C9 { background-position: -320px -440px; }
-.emoji-1F3CA { background-position: -340px -440px; }
-.emoji-1F3CA-1F3FB { background-position: -360px -440px; }
-.emoji-1F3CA-1F3FC { background-position: -380px -440px; }
-.emoji-1F3CA-1F3FD { background-position: -400px -440px; }
-.emoji-1F3CA-1F3FE { background-position: -420px -440px; }
-.emoji-1F3CA-1F3FF { background-position: -440px -440px; }
-.emoji-1F3CB { background-position: -460px 0; }
-.emoji-1F3CB-1F3FB { background-position: -460px -20px; }
-.emoji-1F3CB-1F3FC { background-position: -460px -40px; }
-.emoji-1F3CB-1F3FD { background-position: -460px -60px; }
-.emoji-1F3CB-1F3FE { background-position: -460px -80px; }
-.emoji-1F3CB-1F3FF { background-position: -460px -100px; }
-.emoji-1F3CC { background-position: -460px -120px; }
-.emoji-1F3CD { background-position: -460px -140px; }
-.emoji-1F3CE { background-position: -460px -160px; }
-.emoji-1F3CF { background-position: -460px -180px; }
-.emoji-1F3D0 { background-position: -460px -200px; }
-.emoji-1F3D1 { background-position: -460px -220px; }
-.emoji-1F3D2 { background-position: -460px -240px; }
-.emoji-1F3D3 { background-position: -460px -260px; }
-.emoji-1F3D4 { background-position: -460px -280px; }
-.emoji-1F3D5 { background-position: -460px -300px; }
-.emoji-1F3D6 { background-position: -460px -320px; }
-.emoji-1F3D7 { background-position: -460px -340px; }
-.emoji-1F3D8 { background-position: -460px -360px; }
-.emoji-1F3D9 { background-position: -460px -380px; }
-.emoji-1F3DA { background-position: -460px -400px; }
-.emoji-1F3DB { background-position: -460px -420px; }
-.emoji-1F3DC { background-position: -460px -440px; }
-.emoji-1F3DD { background-position: 0 -460px; }
-.emoji-1F3DE { background-position: -20px -460px; }
-.emoji-1F3DF { background-position: -40px -460px; }
-.emoji-1F3E0 { background-position: -60px -460px; }
-.emoji-1F3E1 { background-position: -80px -460px; }
-.emoji-1F3E2 { background-position: -100px -460px; }
-.emoji-1F3E3 { background-position: -120px -460px; }
-.emoji-1F3E4 { background-position: -140px -460px; }
-.emoji-1F3E5 { background-position: -160px -460px; }
-.emoji-1F3E6 { background-position: -180px -460px; }
-.emoji-1F3E7 { background-position: -200px -460px; }
-.emoji-1F3E8 { background-position: -220px -460px; }
-.emoji-1F3E9 { background-position: -240px -460px; }
-.emoji-1F3EA { background-position: -260px -460px; }
-.emoji-1F3EB { background-position: -280px -460px; }
-.emoji-1F3EC { background-position: -300px -460px; }
-.emoji-1F3ED { background-position: -320px -460px; }
-.emoji-1F3EE { background-position: -340px -460px; }
-.emoji-1F3EF { background-position: -360px -460px; }
-.emoji-1F3F0 { background-position: -380px -460px; }
-.emoji-1F3F1 { background-position: -400px -460px; }
-.emoji-1F3F2 { background-position: -420px -460px; }
-.emoji-1F3F3 { background-position: -440px -460px; }
-.emoji-1F3F4 { background-position: -460px -460px; }
-.emoji-1F3F5 { background-position: -480px 0; }
-.emoji-1F3F6 { background-position: -480px -20px; }
-.emoji-1F3F7 { background-position: -480px -40px; }
-.emoji-1F3F8 { background-position: -480px -60px; }
-.emoji-1F3F9 { background-position: -480px -80px; }
-.emoji-1F3FA { background-position: -480px -100px; }
-.emoji-1F3FB { background-position: -480px -120px; }
-.emoji-1F3FC { background-position: -480px -140px; }
-.emoji-1F3FD { background-position: -480px -160px; }
-.emoji-1F3FE { background-position: -480px -180px; }
-.emoji-1F3FF { background-position: -480px -200px; }
-.emoji-1F400 { background-position: -480px -220px; }
-.emoji-1F401 { background-position: -480px -240px; }
-.emoji-1F402 { background-position: -480px -260px; }
-.emoji-1F403 { background-position: -480px -280px; }
-.emoji-1F404 { background-position: -480px -300px; }
-.emoji-1F405 { background-position: -480px -320px; }
-.emoji-1F406 { background-position: -480px -340px; }
-.emoji-1F407 { background-position: -480px -360px; }
-.emoji-1F408 { background-position: -480px -380px; }
-.emoji-1F409 { background-position: -480px -400px; }
-.emoji-1F40A { background-position: -480px -420px; }
-.emoji-1F40B { background-position: -480px -440px; }
-.emoji-1F40C { background-position: -480px -460px; }
-.emoji-1F40D { background-position: 0 -480px; }
-.emoji-1F40E { background-position: -20px -480px; }
-.emoji-1F40F { background-position: -40px -480px; }
-.emoji-1F410 { background-position: -60px -480px; }
-.emoji-1F411 { background-position: -80px -480px; }
-.emoji-1F412 { background-position: -100px -480px; }
-.emoji-1F413 { background-position: -120px -480px; }
-.emoji-1F414 { background-position: -140px -480px; }
-.emoji-1F415 { background-position: -160px -480px; }
-.emoji-1F416 { background-position: -180px -480px; }
-.emoji-1F417 { background-position: -200px -480px; }
-.emoji-1F418 { background-position: -220px -480px; }
-.emoji-1F419 { background-position: -240px -480px; }
-.emoji-1F41A { background-position: -260px -480px; }
-.emoji-1F41B { background-position: -280px -480px; }
-.emoji-1F41C { background-position: -300px -480px; }
-.emoji-1F41D { background-position: -320px -480px; }
-.emoji-1F41E { background-position: -340px -480px; }
-.emoji-1F41F { background-position: -360px -480px; }
-.emoji-1F420 { background-position: -380px -480px; }
-.emoji-1F421 { background-position: -400px -480px; }
-.emoji-1F422 { background-position: -420px -480px; }
-.emoji-1F423 { background-position: -440px -480px; }
-.emoji-1F424 { background-position: -460px -480px; }
-.emoji-1F425 { background-position: -480px -480px; }
-.emoji-1F426 { background-position: -500px 0; }
-.emoji-1F427 { background-position: -500px -20px; }
-.emoji-1F428 { background-position: -500px -40px; }
-.emoji-1F429 { background-position: -500px -60px; }
-.emoji-1F42A { background-position: -500px -80px; }
-.emoji-1F42B { background-position: -500px -100px; }
-.emoji-1F42C { background-position: -500px -120px; }
-.emoji-1F42D { background-position: -500px -140px; }
-.emoji-1F42E { background-position: -500px -160px; }
-.emoji-1F42F { background-position: -500px -180px; }
-.emoji-1F430 { background-position: -500px -200px; }
-.emoji-1F431 { background-position: -500px -220px; }
-.emoji-1F432 { background-position: -500px -240px; }
-.emoji-1F433 { background-position: -500px -260px; }
-.emoji-1F434 { background-position: -500px -280px; }
-.emoji-1F435 { background-position: -500px -300px; }
-.emoji-1F436 { background-position: -500px -320px; }
-.emoji-1F437 { background-position: -500px -340px; }
-.emoji-1F438 { background-position: -500px -360px; }
-.emoji-1F439 { background-position: -500px -380px; }
-.emoji-1F43A { background-position: -500px -400px; }
-.emoji-1F43B { background-position: -500px -420px; }
-.emoji-1F43C { background-position: -500px -440px; }
-.emoji-1F43D { background-position: -500px -460px; }
-.emoji-1F43E { background-position: -500px -480px; }
-.emoji-1F43F { background-position: 0 -500px; }
-.emoji-1F440 { background-position: -20px -500px; }
-.emoji-1F441 { background-position: -40px -500px; }
-.emoji-1F441-1F5E8 { background-position: -60px -500px; }
-.emoji-1F442 { background-position: -80px -500px; }
-.emoji-1F442-1F3FB { background-position: -100px -500px; }
-.emoji-1F442-1F3FC { background-position: -120px -500px; }
-.emoji-1F442-1F3FD { background-position: -140px -500px; }
-.emoji-1F442-1F3FE { background-position: -160px -500px; }
-.emoji-1F442-1F3FF { background-position: -180px -500px; }
-.emoji-1F443 { background-position: -200px -500px; }
-.emoji-1F443-1F3FB { background-position: -220px -500px; }
-.emoji-1F443-1F3FC { background-position: -240px -500px; }
-.emoji-1F443-1F3FD { background-position: -260px -500px; }
-.emoji-1F443-1F3FE { background-position: -280px -500px; }
-.emoji-1F443-1F3FF { background-position: -300px -500px; }
-.emoji-1F444 { background-position: -320px -500px; }
-.emoji-1F445 { background-position: -340px -500px; }
-.emoji-1F446 { background-position: -360px -500px; }
-.emoji-1F446-1F3FB { background-position: -380px -500px; }
-.emoji-1F446-1F3FC { background-position: -400px -500px; }
-.emoji-1F446-1F3FD { background-position: -420px -500px; }
-.emoji-1F446-1F3FE { background-position: -440px -500px; }
-.emoji-1F446-1F3FF { background-position: -460px -500px; }
-.emoji-1F447 { background-position: -480px -500px; }
-.emoji-1F447-1F3FB { background-position: -500px -500px; }
-.emoji-1F447-1F3FC { background-position: -520px 0; }
-.emoji-1F447-1F3FD { background-position: -520px -20px; }
-.emoji-1F447-1F3FE { background-position: -520px -40px; }
-.emoji-1F447-1F3FF { background-position: -520px -60px; }
-.emoji-1F448 { background-position: -520px -80px; }
-.emoji-1F448-1F3FB { background-position: -520px -100px; }
-.emoji-1F448-1F3FC { background-position: -520px -120px; }
-.emoji-1F448-1F3FD { background-position: -520px -140px; }
-.emoji-1F448-1F3FE { background-position: -520px -160px; }
-.emoji-1F448-1F3FF { background-position: -520px -180px; }
-.emoji-1F449 { background-position: -520px -200px; }
-.emoji-1F449-1F3FB { background-position: -520px -220px; }
-.emoji-1F449-1F3FC { background-position: -520px -240px; }
-.emoji-1F449-1F3FD { background-position: -520px -260px; }
-.emoji-1F449-1F3FE { background-position: -520px -280px; }
-.emoji-1F449-1F3FF { background-position: -520px -300px; }
-.emoji-1F44A { background-position: -520px -320px; }
-.emoji-1F44A-1F3FB { background-position: -520px -340px; }
-.emoji-1F44A-1F3FC { background-position: -520px -360px; }
-.emoji-1F44A-1F3FD { background-position: -520px -380px; }
-.emoji-1F44A-1F3FE { background-position: -520px -400px; }
-.emoji-1F44A-1F3FF { background-position: -520px -420px; }
-.emoji-1F44B { background-position: -520px -440px; }
-.emoji-1F44B-1F3FB { background-position: -520px -460px; }
-.emoji-1F44B-1F3FC { background-position: -520px -480px; }
-.emoji-1F44B-1F3FD { background-position: -520px -500px; }
-.emoji-1F44B-1F3FE { background-position: 0 -520px; }
-.emoji-1F44B-1F3FF { background-position: -20px -520px; }
-.emoji-1F44C { background-position: -40px -520px; }
-.emoji-1F44C-1F3FB { background-position: -60px -520px; }
-.emoji-1F44C-1F3FC { background-position: -80px -520px; }
-.emoji-1F44C-1F3FD { background-position: -100px -520px; }
-.emoji-1F44C-1F3FE { background-position: -120px -520px; }
-.emoji-1F44C-1F3FF { background-position: -140px -520px; }
-.emoji-1F44D { background-position: -160px -520px; }
-.emoji-1F44D-1F3FB { background-position: -180px -520px; }
-.emoji-1F44D-1F3FC { background-position: -200px -520px; }
-.emoji-1F44D-1F3FD { background-position: -220px -520px; }
-.emoji-1F44D-1F3FE { background-position: -240px -520px; }
-.emoji-1F44D-1F3FF { background-position: -260px -520px; }
-.emoji-1F44E { background-position: -280px -520px; }
-.emoji-1F44E-1F3FB { background-position: -300px -520px; }
-.emoji-1F44E-1F3FC { background-position: -320px -520px; }
-.emoji-1F44E-1F3FD { background-position: -340px -520px; }
-.emoji-1F44E-1F3FE { background-position: -360px -520px; }
-.emoji-1F44E-1F3FF { background-position: -380px -520px; }
-.emoji-1F44F { background-position: -400px -520px; }
-.emoji-1F44F-1F3FB { background-position: -420px -520px; }
-.emoji-1F44F-1F3FC { background-position: -440px -520px; }
-.emoji-1F44F-1F3FD { background-position: -460px -520px; }
-.emoji-1F44F-1F3FE { background-position: -480px -520px; }
-.emoji-1F44F-1F3FF { background-position: -500px -520px; }
-.emoji-1F450 { background-position: -520px -520px; }
-.emoji-1F450-1F3FB { background-position: -540px 0; }
-.emoji-1F450-1F3FC { background-position: -540px -20px; }
-.emoji-1F450-1F3FD { background-position: -540px -40px; }
-.emoji-1F450-1F3FE { background-position: -540px -60px; }
-.emoji-1F450-1F3FF { background-position: -540px -80px; }
-.emoji-1F451 { background-position: -540px -100px; }
-.emoji-1F452 { background-position: -540px -120px; }
-.emoji-1F453 { background-position: -540px -140px; }
-.emoji-1F454 { background-position: -540px -160px; }
-.emoji-1F455 { background-position: -540px -180px; }
-.emoji-1F456 { background-position: -540px -200px; }
-.emoji-1F457 { background-position: -540px -220px; }
-.emoji-1F458 { background-position: -540px -240px; }
-.emoji-1F459 { background-position: -540px -260px; }
-.emoji-1F45A { background-position: -540px -280px; }
-.emoji-1F45B { background-position: -540px -300px; }
-.emoji-1F45C { background-position: -540px -320px; }
-.emoji-1F45D { background-position: -540px -340px; }
-.emoji-1F45E { background-position: -540px -360px; }
-.emoji-1F45F { background-position: -540px -380px; }
-.emoji-1F460 { background-position: -540px -400px; }
-.emoji-1F461 { background-position: -540px -420px; }
-.emoji-1F462 { background-position: -540px -440px; }
-.emoji-1F463 { background-position: -540px -460px; }
-.emoji-1F464 { background-position: -540px -480px; }
-.emoji-1F465 { background-position: -540px -500px; }
-.emoji-1F466 { background-position: -540px -520px; }
-.emoji-1F466-1F3FB { background-position: 0 -540px; }
-.emoji-1F466-1F3FC { background-position: -20px -540px; }
-.emoji-1F466-1F3FD { background-position: -40px -540px; }
-.emoji-1F466-1F3FE { background-position: -60px -540px; }
-.emoji-1F466-1F3FF { background-position: -80px -540px; }
-.emoji-1F467 { background-position: -100px -540px; }
-.emoji-1F467-1F3FB { background-position: -120px -540px; }
-.emoji-1F467-1F3FC { background-position: -140px -540px; }
-.emoji-1F467-1F3FD { background-position: -160px -540px; }
-.emoji-1F467-1F3FE { background-position: -180px -540px; }
-.emoji-1F467-1F3FF { background-position: -200px -540px; }
-.emoji-1F468 { background-position: -220px -540px; }
-.emoji-1F468-1F3FB { background-position: -240px -540px; }
-.emoji-1F468-1F3FC { background-position: -260px -540px; }
-.emoji-1F468-1F3FD { background-position: -280px -540px; }
-.emoji-1F468-1F3FE { background-position: -300px -540px; }
-.emoji-1F468-1F3FF { background-position: -320px -540px; }
-.emoji-1F468-1F468-1F466 { background-position: -340px -540px; }
-.emoji-1F468-1F468-1F466-1F466 { background-position: -360px -540px; }
-.emoji-1F468-1F468-1F467 { background-position: -380px -540px; }
-.emoji-1F468-1F468-1F467-1F466 { background-position: -400px -540px; }
-.emoji-1F468-1F468-1F467-1F467 { background-position: -420px -540px; }
-.emoji-1F468-1F469-1F466-1F466 { background-position: -440px -540px; }
-.emoji-1F468-1F469-1F467 { background-position: -460px -540px; }
-.emoji-1F468-1F469-1F467-1F466 { background-position: -480px -540px; }
-.emoji-1F468-1F469-1F467-1F467 { background-position: -500px -540px; }
-.emoji-1F468-2764-1F468 { background-position: -520px -540px; }
-.emoji-1F468-2764-1F48B-1F468 { background-position: -540px -540px; }
-.emoji-1F469 { background-position: -560px 0; }
-.emoji-1F469-1F3FB { background-position: -560px -20px; }
-.emoji-1F469-1F3FC { background-position: -560px -40px; }
-.emoji-1F469-1F3FD { background-position: -560px -60px; }
-.emoji-1F469-1F3FE { background-position: -560px -80px; }
-.emoji-1F469-1F3FF { background-position: -560px -100px; }
-.emoji-1F469-1F469-1F466 { background-position: -560px -120px; }
-.emoji-1F469-1F469-1F466-1F466 { background-position: -560px -140px; }
-.emoji-1F469-1F469-1F467 { background-position: -560px -160px; }
-.emoji-1F469-1F469-1F467-1F466 { background-position: -560px -180px; }
-.emoji-1F469-1F469-1F467-1F467 { background-position: -560px -200px; }
-.emoji-1F469-2764-1F469 { background-position: -560px -220px; }
-.emoji-1F469-2764-1F48B-1F469 { background-position: -560px -240px; }
-.emoji-1F46A { background-position: -560px -260px; }
-.emoji-1F46B { background-position: -560px -280px; }
-.emoji-1F46C { background-position: -560px -300px; }
-.emoji-1F46D { background-position: -560px -320px; }
-.emoji-1F46E { background-position: -560px -340px; }
-.emoji-1F46E-1F3FB { background-position: -560px -360px; }
-.emoji-1F46E-1F3FC { background-position: -560px -380px; }
-.emoji-1F46E-1F3FD { background-position: -560px -400px; }
-.emoji-1F46E-1F3FE { background-position: -560px -420px; }
-.emoji-1F46E-1F3FF { background-position: -560px -440px; }
-.emoji-1F46F { background-position: -560px -460px; }
-.emoji-1F470 { background-position: -560px -480px; }
-.emoji-1F470-1F3FB { background-position: -560px -500px; }
-.emoji-1F470-1F3FC { background-position: -560px -520px; }
-.emoji-1F470-1F3FD { background-position: -560px -540px; }
-.emoji-1F470-1F3FE { background-position: 0 -560px; }
-.emoji-1F470-1F3FF { background-position: -20px -560px; }
-.emoji-1F471 { background-position: -40px -560px; }
-.emoji-1F471-1F3FB { background-position: -60px -560px; }
-.emoji-1F471-1F3FC { background-position: -80px -560px; }
-.emoji-1F471-1F3FD { background-position: -100px -560px; }
-.emoji-1F471-1F3FE { background-position: -120px -560px; }
-.emoji-1F471-1F3FF { background-position: -140px -560px; }
-.emoji-1F472 { background-position: -160px -560px; }
-.emoji-1F472-1F3FB { background-position: -180px -560px; }
-.emoji-1F472-1F3FC { background-position: -200px -560px; }
-.emoji-1F472-1F3FD { background-position: -220px -560px; }
-.emoji-1F472-1F3FE { background-position: -240px -560px; }
-.emoji-1F472-1F3FF { background-position: -260px -560px; }
-.emoji-1F473 { background-position: -280px -560px; }
-.emoji-1F473-1F3FB { background-position: -300px -560px; }
-.emoji-1F473-1F3FC { background-position: -320px -560px; }
-.emoji-1F473-1F3FD { background-position: -340px -560px; }
-.emoji-1F473-1F3FE { background-position: -360px -560px; }
-.emoji-1F473-1F3FF { background-position: -380px -560px; }
-.emoji-1F474 { background-position: -400px -560px; }
-.emoji-1F474-1F3FB { background-position: -420px -560px; }
-.emoji-1F474-1F3FC { background-position: -440px -560px; }
-.emoji-1F474-1F3FD { background-position: -460px -560px; }
-.emoji-1F474-1F3FE { background-position: -480px -560px; }
-.emoji-1F474-1F3FF { background-position: -500px -560px; }
-.emoji-1F475 { background-position: -520px -560px; }
-.emoji-1F475-1F3FB { background-position: -540px -560px; }
-.emoji-1F475-1F3FC { background-position: -560px -560px; }
-.emoji-1F475-1F3FD { background-position: -580px 0; }
-.emoji-1F475-1F3FE { background-position: -580px -20px; }
-.emoji-1F475-1F3FF { background-position: -580px -40px; }
-.emoji-1F476 { background-position: -580px -60px; }
-.emoji-1F476-1F3FB { background-position: -580px -80px; }
-.emoji-1F476-1F3FC { background-position: -580px -100px; }
-.emoji-1F476-1F3FD { background-position: -580px -120px; }
-.emoji-1F476-1F3FE { background-position: -580px -140px; }
-.emoji-1F476-1F3FF { background-position: -580px -160px; }
-.emoji-1F477 { background-position: -580px -180px; }
-.emoji-1F477-1F3FB { background-position: -580px -200px; }
-.emoji-1F477-1F3FC { background-position: -580px -220px; }
-.emoji-1F477-1F3FD { background-position: -580px -240px; }
-.emoji-1F477-1F3FE { background-position: -580px -260px; }
-.emoji-1F477-1F3FF { background-position: -580px -280px; }
-.emoji-1F478 { background-position: -580px -300px; }
-.emoji-1F478-1F3FB { background-position: -580px -320px; }
-.emoji-1F478-1F3FC { background-position: -580px -340px; }
-.emoji-1F478-1F3FD { background-position: -580px -360px; }
-.emoji-1F478-1F3FE { background-position: -580px -380px; }
-.emoji-1F478-1F3FF { background-position: -580px -400px; }
-.emoji-1F479 { background-position: -580px -420px; }
-.emoji-1F47A { background-position: -580px -440px; }
-.emoji-1F47B { background-position: -580px -460px; }
-.emoji-1F47C { background-position: -580px -480px; }
-.emoji-1F47C-1F3FB { background-position: -580px -500px; }
-.emoji-1F47C-1F3FC { background-position: -580px -520px; }
-.emoji-1F47C-1F3FD { background-position: -580px -540px; }
-.emoji-1F47C-1F3FE { background-position: -580px -560px; }
-.emoji-1F47C-1F3FF { background-position: 0 -580px; }
-.emoji-1F47D { background-position: -20px -580px; }
-.emoji-1F47E { background-position: -40px -580px; }
-.emoji-1F47F { background-position: -60px -580px; }
-.emoji-1F480 { background-position: -80px -580px; }
-.emoji-1F481 { background-position: -100px -580px; }
-.emoji-1F481-1F3FB { background-position: -120px -580px; }
-.emoji-1F481-1F3FC { background-position: -140px -580px; }
-.emoji-1F481-1F3FD { background-position: -160px -580px; }
-.emoji-1F481-1F3FE { background-position: -180px -580px; }
-.emoji-1F481-1F3FF { background-position: -200px -580px; }
-.emoji-1F482 { background-position: -220px -580px; }
-.emoji-1F482-1F3FB { background-position: -240px -580px; }
-.emoji-1F482-1F3FC { background-position: -260px -580px; }
-.emoji-1F482-1F3FD { background-position: -280px -580px; }
-.emoji-1F482-1F3FE { background-position: -300px -580px; }
-.emoji-1F482-1F3FF { background-position: -320px -580px; }
-.emoji-1F483 { background-position: -340px -580px; }
-.emoji-1F483-1F3FB { background-position: -360px -580px; }
-.emoji-1F483-1F3FC { background-position: -380px -580px; }
-.emoji-1F483-1F3FD { background-position: -400px -580px; }
-.emoji-1F483-1F3FE { background-position: -420px -580px; }
-.emoji-1F483-1F3FF { background-position: -440px -580px; }
-.emoji-1F484 { background-position: -460px -580px; }
-.emoji-1F485 { background-position: -480px -580px; }
-.emoji-1F485-1F3FB { background-position: -500px -580px; }
-.emoji-1F485-1F3FC { background-position: -520px -580px; }
-.emoji-1F485-1F3FD { background-position: -540px -580px; }
-.emoji-1F485-1F3FE { background-position: -560px -580px; }
-.emoji-1F485-1F3FF { background-position: -580px -580px; }
-.emoji-1F486 { background-position: -600px 0; }
-.emoji-1F486-1F3FB { background-position: -600px -20px; }
-.emoji-1F486-1F3FC { background-position: -600px -40px; }
-.emoji-1F486-1F3FD { background-position: -600px -60px; }
-.emoji-1F486-1F3FE { background-position: -600px -80px; }
-.emoji-1F486-1F3FF { background-position: -600px -100px; }
-.emoji-1F487 { background-position: -600px -120px; }
-.emoji-1F487-1F3FB { background-position: -600px -140px; }
-.emoji-1F487-1F3FC { background-position: -600px -160px; }
-.emoji-1F487-1F3FD { background-position: -600px -180px; }
-.emoji-1F487-1F3FE { background-position: -600px -200px; }
-.emoji-1F487-1F3FF { background-position: -600px -220px; }
-.emoji-1F488 { background-position: -600px -240px; }
-.emoji-1F489 { background-position: -600px -260px; }
-.emoji-1F48A { background-position: -600px -280px; }
-.emoji-1F48B { background-position: -600px -300px; }
-.emoji-1F48C { background-position: -600px -320px; }
-.emoji-1F48D { background-position: -600px -340px; }
-.emoji-1F48E { background-position: -600px -360px; }
-.emoji-1F48F { background-position: -600px -380px; }
-.emoji-1F490 { background-position: -600px -400px; }
-.emoji-1F491 { background-position: -600px -420px; }
-.emoji-1F492 { background-position: -600px -440px; }
-.emoji-1F493 { background-position: -600px -460px; }
-.emoji-1F494 { background-position: -600px -480px; }
-.emoji-1F495 { background-position: -600px -500px; }
-.emoji-1F496 { background-position: -600px -520px; }
-.emoji-1F497 { background-position: -600px -540px; }
-.emoji-1F498 { background-position: -600px -560px; }
-.emoji-1F499 { background-position: -600px -580px; }
-.emoji-1F49A { background-position: 0 -600px; }
-.emoji-1F49B { background-position: -20px -600px; }
-.emoji-1F49C { background-position: -40px -600px; }
-.emoji-1F49D { background-position: -60px -600px; }
-.emoji-1F49E { background-position: -80px -600px; }
-.emoji-1F49F { background-position: -100px -600px; }
-.emoji-1F4A0 { background-position: -120px -600px; }
-.emoji-1F4A1 { background-position: -140px -600px; }
-.emoji-1F4A2 { background-position: -160px -600px; }
-.emoji-1F4A3 { background-position: -180px -600px; }
-.emoji-1F4A4 { background-position: -200px -600px; }
-.emoji-1F4A5 { background-position: -220px -600px; }
-.emoji-1F4A6 { background-position: -240px -600px; }
-.emoji-1F4A7 { background-position: -260px -600px; }
-.emoji-1F4A8 { background-position: -280px -600px; }
-.emoji-1F4A9 { background-position: -300px -600px; }
-.emoji-1F4AA { background-position: -320px -600px; }
-.emoji-1F4AA-1F3FB { background-position: -340px -600px; }
-.emoji-1F4AA-1F3FC { background-position: -360px -600px; }
-.emoji-1F4AA-1F3FD { background-position: -380px -600px; }
-.emoji-1F4AA-1F3FE { background-position: -400px -600px; }
-.emoji-1F4AA-1F3FF { background-position: -420px -600px; }
-.emoji-1F4AB { background-position: -440px -600px; }
-.emoji-1F4AC { background-position: -460px -600px; }
-.emoji-1F4AD { background-position: -480px -600px; }
-.emoji-1F4AE { background-position: -500px -600px; }
-.emoji-1F4AF { background-position: -520px -600px; }
-.emoji-1F4B0 { background-position: -540px -600px; }
-.emoji-1F4B1 { background-position: -560px -600px; }
-.emoji-1F4B2 { background-position: -580px -600px; }
-.emoji-1F4B3 { background-position: -600px -600px; }
-.emoji-1F4B4 { background-position: -620px 0; }
-.emoji-1F4B5 { background-position: -620px -20px; }
-.emoji-1F4B6 { background-position: -620px -40px; }
-.emoji-1F4B7 { background-position: -620px -60px; }
-.emoji-1F4B8 { background-position: -620px -80px; }
-.emoji-1F4B9 { background-position: -620px -100px; }
-.emoji-1F4BA { background-position: -620px -120px; }
-.emoji-1F4BB { background-position: -620px -140px; }
-.emoji-1F4BC { background-position: -620px -160px; }
-.emoji-1F4BD { background-position: -620px -180px; }
-.emoji-1F4BE { background-position: -620px -200px; }
-.emoji-1F4BF { background-position: -620px -220px; }
-.emoji-1F4C0 { background-position: -620px -240px; }
-.emoji-1F4C1 { background-position: -620px -260px; }
-.emoji-1F4C2 { background-position: -620px -280px; }
-.emoji-1F4C3 { background-position: -620px -300px; }
-.emoji-1F4C4 { background-position: -620px -320px; }
-.emoji-1F4C5 { background-position: -620px -340px; }
-.emoji-1F4C6 { background-position: -620px -360px; }
-.emoji-1F4C7 { background-position: -620px -380px; }
-.emoji-1F4C8 { background-position: -620px -400px; }
-.emoji-1F4C9 { background-position: -620px -420px; }
-.emoji-1F4CA { background-position: -620px -440px; }
-.emoji-1F4CB { background-position: -620px -460px; }
-.emoji-1F4CC { background-position: -620px -480px; }
-.emoji-1F4CD { background-position: -620px -500px; }
-.emoji-1F4CE { background-position: -620px -520px; }
-.emoji-1F4CF { background-position: -620px -540px; }
-.emoji-1F4D0 { background-position: -620px -560px; }
-.emoji-1F4D1 { background-position: -620px -580px; }
-.emoji-1F4D2 { background-position: -620px -600px; }
-.emoji-1F4D3 { background-position: 0 -620px; }
-.emoji-1F4D4 { background-position: -20px -620px; }
-.emoji-1F4D5 { background-position: -40px -620px; }
-.emoji-1F4D6 { background-position: -60px -620px; }
-.emoji-1F4D7 { background-position: -80px -620px; }
-.emoji-1F4D8 { background-position: -100px -620px; }
-.emoji-1F4D9 { background-position: -120px -620px; }
-.emoji-1F4DA { background-position: -140px -620px; }
-.emoji-1F4DB { background-position: -160px -620px; }
-.emoji-1F4DC { background-position: -180px -620px; }
-.emoji-1F4DD { background-position: -200px -620px; }
-.emoji-1F4DE { background-position: -220px -620px; }
-.emoji-1F4DF { background-position: -240px -620px; }
-.emoji-1F4E0 { background-position: -260px -620px; }
-.emoji-1F4E1 { background-position: -280px -620px; }
-.emoji-1F4E2 { background-position: -300px -620px; }
-.emoji-1F4E3 { background-position: -320px -620px; }
-.emoji-1F4E4 { background-position: -340px -620px; }
-.emoji-1F4E5 { background-position: -360px -620px; }
-.emoji-1F4E6 { background-position: -380px -620px; }
-.emoji-1F4E7 { background-position: -400px -620px; }
-.emoji-1F4E8 { background-position: -420px -620px; }
-.emoji-1F4E9 { background-position: -440px -620px; }
-.emoji-1F4EA { background-position: -460px -620px; }
-.emoji-1F4EB { background-position: -480px -620px; }
-.emoji-1F4EC { background-position: -500px -620px; }
-.emoji-1F4ED { background-position: -520px -620px; }
-.emoji-1F4EE { background-position: -540px -620px; }
-.emoji-1F4EF { background-position: -560px -620px; }
-.emoji-1F4F0 { background-position: -580px -620px; }
-.emoji-1F4F1 { background-position: -600px -620px; }
-.emoji-1F4F2 { background-position: -620px -620px; }
-.emoji-1F4F3 { background-position: -640px 0; }
-.emoji-1F4F4 { background-position: -640px -20px; }
-.emoji-1F4F5 { background-position: -640px -40px; }
-.emoji-1F4F6 { background-position: -640px -60px; }
-.emoji-1F4F7 { background-position: -640px -80px; }
-.emoji-1F4F8 { background-position: -640px -100px; }
-.emoji-1F4F9 { background-position: -640px -120px; }
-.emoji-1F4FA { background-position: -640px -140px; }
-.emoji-1F4FB { background-position: -640px -160px; }
-.emoji-1F4FC { background-position: -640px -180px; }
-.emoji-1F4FD { background-position: -640px -200px; }
-.emoji-1F4FE { background-position: -640px -220px; }
-.emoji-1F4FF { background-position: -640px -240px; }
-.emoji-1F500 { background-position: -640px -260px; }
-.emoji-1F501 { background-position: -640px -280px; }
-.emoji-1F502 { background-position: -640px -300px; }
-.emoji-1F503 { background-position: -640px -320px; }
-.emoji-1F504 { background-position: -640px -340px; }
-.emoji-1F505 { background-position: -640px -360px; }
-.emoji-1F506 { background-position: -640px -380px; }
-.emoji-1F507 { background-position: -640px -400px; }
-.emoji-1F508 { background-position: -640px -420px; }
-.emoji-1F509 { background-position: -640px -440px; }
-.emoji-1F50A { background-position: -640px -460px; }
-.emoji-1F50B { background-position: -640px -480px; }
-.emoji-1F50C { background-position: -640px -500px; }
-.emoji-1F50D { background-position: -640px -520px; }
-.emoji-1F50E { background-position: -640px -540px; }
-.emoji-1F50F { background-position: -640px -560px; }
-.emoji-1F510 { background-position: -640px -580px; }
-.emoji-1F511 { background-position: -640px -600px; }
-.emoji-1F512 { background-position: -640px -620px; }
-.emoji-1F513 { background-position: 0 -640px; }
-.emoji-1F514 { background-position: -20px -640px; }
-.emoji-1F515 { background-position: -40px -640px; }
-.emoji-1F516 { background-position: -60px -640px; }
-.emoji-1F517 { background-position: -80px -640px; }
-.emoji-1F518 { background-position: -100px -640px; }
-.emoji-1F519 { background-position: -120px -640px; }
-.emoji-1F51A { background-position: -140px -640px; }
-.emoji-1F51B { background-position: -160px -640px; }
-.emoji-1F51C { background-position: -180px -640px; }
-.emoji-1F51D { background-position: -200px -640px; }
-.emoji-1F51E { background-position: -220px -640px; }
-.emoji-1F51F { background-position: -240px -640px; }
-.emoji-1F520 { background-position: -260px -640px; }
-.emoji-1F521 { background-position: -280px -640px; }
-.emoji-1F522 { background-position: -300px -640px; }
-.emoji-1F523 { background-position: -320px -640px; }
-.emoji-1F524 { background-position: -340px -640px; }
-.emoji-1F525 { background-position: -360px -640px; }
-.emoji-1F526 { background-position: -380px -640px; }
-.emoji-1F527 { background-position: -400px -640px; }
-.emoji-1F528 { background-position: -420px -640px; }
-.emoji-1F529 { background-position: -440px -640px; }
-.emoji-1F52A { background-position: -460px -640px; }
-.emoji-1F52B { background-position: -480px -640px; }
-.emoji-1F52C { background-position: -500px -640px; }
-.emoji-1F52D { background-position: -520px -640px; }
-.emoji-1F52E { background-position: -540px -640px; }
-.emoji-1F52F { background-position: -560px -640px; }
-.emoji-1F530 { background-position: -580px -640px; }
-.emoji-1F531 { background-position: -600px -640px; }
-.emoji-1F532 { background-position: -620px -640px; }
-.emoji-1F533 { background-position: -640px -640px; }
-.emoji-1F534 { background-position: -660px 0; }
-.emoji-1F535 { background-position: -660px -20px; }
-.emoji-1F536 { background-position: -660px -40px; }
-.emoji-1F537 { background-position: -660px -60px; }
-.emoji-1F538 { background-position: -660px -80px; }
-.emoji-1F539 { background-position: -660px -100px; }
-.emoji-1F53A { background-position: -660px -120px; }
-.emoji-1F53B { background-position: -660px -140px; }
-.emoji-1F53C { background-position: -660px -160px; }
-.emoji-1F53D { background-position: -660px -180px; }
-.emoji-1F546 { background-position: -660px -200px; }
-.emoji-1F547 { background-position: -660px -220px; }
-.emoji-1F548 { background-position: -660px -240px; }
-.emoji-1F549 { background-position: -660px -260px; }
-.emoji-1F54A { background-position: -660px -280px; }
-.emoji-1F54B { background-position: -660px -300px; }
-.emoji-1F54C { background-position: -660px -320px; }
-.emoji-1F54D { background-position: -660px -340px; }
-.emoji-1F54E { background-position: -660px -360px; }
-.emoji-1F550 { background-position: -660px -380px; }
-.emoji-1F551 { background-position: -660px -400px; }
-.emoji-1F552 { background-position: -660px -420px; }
-.emoji-1F553 { background-position: -660px -440px; }
-.emoji-1F554 { background-position: -660px -460px; }
-.emoji-1F555 { background-position: -660px -480px; }
-.emoji-1F556 { background-position: -660px -500px; }
-.emoji-1F557 { background-position: -660px -520px; }
-.emoji-1F558 { background-position: -660px -540px; }
-.emoji-1F559 { background-position: -660px -560px; }
-.emoji-1F55A { background-position: -660px -580px; }
-.emoji-1F55B { background-position: -660px -600px; }
-.emoji-1F55C { background-position: -660px -620px; }
-.emoji-1F55D { background-position: -660px -640px; }
-.emoji-1F55E { background-position: 0 -660px; }
-.emoji-1F55F { background-position: -20px -660px; }
-.emoji-1F560 { background-position: -40px -660px; }
-.emoji-1F561 { background-position: -60px -660px; }
-.emoji-1F562 { background-position: -80px -660px; }
-.emoji-1F563 { background-position: -100px -660px; }
-.emoji-1F564 { background-position: -120px -660px; }
-.emoji-1F565 { background-position: -140px -660px; }
-.emoji-1F566 { background-position: -160px -660px; }
-.emoji-1F567 { background-position: -180px -660px; }
-.emoji-1F568 { background-position: -200px -660px; }
-.emoji-1F569 { background-position: -220px -660px; }
-.emoji-1F56A { background-position: -240px -660px; }
-.emoji-1F56B { background-position: -260px -660px; }
-.emoji-1F56C { background-position: -280px -660px; }
-.emoji-1F56D { background-position: -300px -660px; }
-.emoji-1F56E { background-position: -320px -660px; }
-.emoji-1F56F { background-position: -340px -660px; }
-.emoji-1F570 { background-position: -360px -660px; }
-.emoji-1F571 { background-position: -380px -660px; }
-.emoji-1F572 { background-position: -400px -660px; }
-.emoji-1F573 { background-position: -420px -660px; }
-.emoji-1F574 { background-position: -440px -660px; }
-.emoji-1F575 { background-position: -460px -660px; }
-.emoji-1F575-1F3FB { background-position: -480px -660px; }
-.emoji-1F575-1F3FC { background-position: -500px -660px; }
-.emoji-1F575-1F3FD { background-position: -520px -660px; }
-.emoji-1F575-1F3FE { background-position: -540px -660px; }
-.emoji-1F575-1F3FF { background-position: -560px -660px; }
-.emoji-1F576 { background-position: -580px -660px; }
-.emoji-1F577 { background-position: -600px -660px; }
-.emoji-1F578 { background-position: -620px -660px; }
-.emoji-1F579 { background-position: -640px -660px; }
-.emoji-1F57B { background-position: -660px -660px; }
-.emoji-1F57E { background-position: -680px 0; }
-.emoji-1F57F { background-position: -680px -20px; }
-.emoji-1F581 { background-position: -680px -40px; }
-.emoji-1F582 { background-position: -680px -60px; }
-.emoji-1F583 { background-position: -680px -80px; }
-.emoji-1F585 { background-position: -680px -100px; }
-.emoji-1F586 { background-position: -680px -120px; }
-.emoji-1F587 { background-position: -680px -140px; }
-.emoji-1F588 { background-position: -680px -160px; }
-.emoji-1F589 { background-position: -680px -180px; }
-.emoji-1F58A { background-position: -680px -200px; }
-.emoji-1F58B { background-position: -680px -220px; }
-.emoji-1F58C { background-position: -680px -240px; }
-.emoji-1F58D { background-position: -680px -260px; }
-.emoji-1F58E { background-position: -680px -280px; }
-.emoji-1F58F { background-position: -680px -300px; }
-.emoji-1F590 { background-position: -680px -320px; }
-.emoji-1F590-1F3FB { background-position: -680px -340px; }
-.emoji-1F590-1F3FC { background-position: -680px -360px; }
-.emoji-1F590-1F3FD { background-position: -680px -380px; }
-.emoji-1F590-1F3FE { background-position: -680px -400px; }
-.emoji-1F590-1F3FF { background-position: -680px -420px; }
-.emoji-1F591 { background-position: -680px -440px; }
-.emoji-1F592 { background-position: -680px -460px; }
-.emoji-1F593 { background-position: -680px -480px; }
-.emoji-1F594 { background-position: -680px -500px; }
-.emoji-1F595 { background-position: -680px -520px; }
-.emoji-1F595-1F3FB { background-position: -680px -540px; }
-.emoji-1F595-1F3FC { background-position: -680px -560px; }
-.emoji-1F595-1F3FD { background-position: -680px -580px; }
-.emoji-1F595-1F3FE { background-position: -680px -600px; }
-.emoji-1F595-1F3FF { background-position: -680px -620px; }
-.emoji-1F596 { background-position: -680px -640px; }
-.emoji-1F596-1F3FB { background-position: -680px -660px; }
-.emoji-1F596-1F3FC { background-position: 0 -680px; }
-.emoji-1F596-1F3FD { background-position: -20px -680px; }
-.emoji-1F596-1F3FE { background-position: -40px -680px; }
-.emoji-1F596-1F3FF { background-position: -60px -680px; }
-.emoji-1F597 { background-position: -80px -680px; }
-.emoji-1F598 { background-position: -100px -680px; }
-.emoji-1F599 { background-position: -120px -680px; }
-.emoji-1F59E { background-position: -140px -680px; }
-.emoji-1F59F { background-position: -160px -680px; }
-.emoji-1F5A5 { background-position: -180px -680px; }
-.emoji-1F5A6 { background-position: -200px -680px; }
-.emoji-1F5A7 { background-position: -220px -680px; }
-.emoji-1F5A8 { background-position: -240px -680px; }
-.emoji-1F5A9 { background-position: -260px -680px; }
-.emoji-1F5AA { background-position: -280px -680px; }
-.emoji-1F5AB { background-position: -300px -680px; }
-.emoji-1F5AD { background-position: -320px -680px; }
-.emoji-1F5AE { background-position: -340px -680px; }
-.emoji-1F5AF { background-position: -360px -680px; }
-.emoji-1F5B1 { background-position: -380px -680px; }
-.emoji-1F5B2 { background-position: -400px -680px; }
-.emoji-1F5B3 { background-position: -420px -680px; }
-.emoji-1F5B4 { background-position: -440px -680px; }
-.emoji-1F5B8 { background-position: -460px -680px; }
-.emoji-1F5B9 { background-position: -480px -680px; }
-.emoji-1F5BC { background-position: -500px -680px; }
-.emoji-1F5BD { background-position: -520px -680px; }
-.emoji-1F5BE { background-position: -540px -680px; }
-.emoji-1F5C0 { background-position: -560px -680px; }
-.emoji-1F5C1 { background-position: -580px -680px; }
-.emoji-1F5C2 { background-position: -600px -680px; }
-.emoji-1F5C3 { background-position: -620px -680px; }
-.emoji-1F5C4 { background-position: -640px -680px; }
-.emoji-1F5C6 { background-position: -660px -680px; }
-.emoji-1F5C7 { background-position: -680px -680px; }
-.emoji-1F5C9 { background-position: -700px 0; }
-.emoji-1F5CA { background-position: -700px -20px; }
-.emoji-1F5CE { background-position: -700px -40px; }
-.emoji-1F5CF { background-position: -700px -60px; }
-.emoji-1F5D0 { background-position: -700px -80px; }
-.emoji-1F5D1 { background-position: -700px -100px; }
-.emoji-1F5D2 { background-position: -700px -120px; }
-.emoji-1F5D3 { background-position: -700px -140px; }
-.emoji-1F5D4 { background-position: -700px -160px; }
-.emoji-1F5D8 { background-position: -700px -180px; }
-.emoji-1F5D9 { background-position: -700px -200px; }
-.emoji-1F5DC { background-position: -700px -220px; }
-.emoji-1F5DD { background-position: -700px -240px; }
-.emoji-1F5DE { background-position: -700px -260px; }
-.emoji-1F5E0 { background-position: -700px -280px; }
-.emoji-1F5E1 { background-position: -700px -300px; }
-.emoji-1F5E2 { background-position: -700px -320px; }
-.emoji-1F5E3 { background-position: -700px -340px; }
-.emoji-1F5E8 { background-position: -700px -360px; }
-.emoji-1F5E9 { background-position: -700px -380px; }
-.emoji-1F5EA { background-position: -700px -400px; }
-.emoji-1F5EB { background-position: -700px -420px; }
-.emoji-1F5EC { background-position: -700px -440px; }
-.emoji-1F5ED { background-position: -700px -460px; }
-.emoji-1F5EE { background-position: -700px -480px; }
-.emoji-1F5EF { background-position: -700px -500px; }
-.emoji-1F5F0 { background-position: -700px -520px; }
-.emoji-1F5F1 { background-position: -700px -540px; }
-.emoji-1F5F2 { background-position: -700px -560px; }
-.emoji-1F5F3 { background-position: -700px -580px; }
-.emoji-1F5F4 { background-position: -700px -600px; }
-.emoji-1F5F5 { background-position: -700px -620px; }
-.emoji-1F5F8 { background-position: -700px -640px; }
-.emoji-1F5F9 { background-position: -700px -660px; }
-.emoji-1F5FA { background-position: -700px -680px; }
-.emoji-1F5FB { background-position: 0 -700px; }
-.emoji-1F5FC { background-position: -20px -700px; }
-.emoji-1F5FD { background-position: -40px -700px; }
-.emoji-1F5FE { background-position: -60px -700px; }
-.emoji-1F5FF { background-position: -80px -700px; }
-.emoji-1F600 { background-position: -100px -700px; }
-.emoji-1F601 { background-position: -120px -700px; }
-.emoji-1F602 { background-position: -140px -700px; }
-.emoji-1F603 { background-position: -160px -700px; }
-.emoji-1F604 { background-position: -180px -700px; }
-.emoji-1F605 { background-position: -200px -700px; }
-.emoji-1F606 { background-position: -220px -700px; }
-.emoji-1F607 { background-position: -240px -700px; }
-.emoji-1F608 { background-position: -260px -700px; }
-.emoji-1F609 { background-position: -280px -700px; }
-.emoji-1F60A { background-position: -300px -700px; }
-.emoji-1F60B { background-position: -320px -700px; }
-.emoji-1F60C { background-position: -340px -700px; }
-.emoji-1F60D { background-position: -360px -700px; }
-.emoji-1F60E { background-position: -380px -700px; }
-.emoji-1F60F { background-position: -400px -700px; }
-.emoji-1F610 { background-position: -420px -700px; }
-.emoji-1F611 { background-position: -440px -700px; }
-.emoji-1F612 { background-position: -460px -700px; }
-.emoji-1F613 { background-position: -480px -700px; }
-.emoji-1F614 { background-position: -500px -700px; }
-.emoji-1F615 { background-position: -520px -700px; }
-.emoji-1F616 { background-position: -540px -700px; }
-.emoji-1F617 { background-position: -560px -700px; }
-.emoji-1F618 { background-position: -580px -700px; }
-.emoji-1F619 { background-position: -600px -700px; }
-.emoji-1F61A { background-position: -620px -700px; }
-.emoji-1F61B { background-position: -640px -700px; }
-.emoji-1F61C { background-position: -660px -700px; }
-.emoji-1F61D { background-position: -680px -700px; }
-.emoji-1F61E { background-position: -700px -700px; }
-.emoji-1F61F { background-position: -720px 0; }
-.emoji-1F620 { background-position: -720px -20px; }
-.emoji-1F621 { background-position: -720px -40px; }
-.emoji-1F622 { background-position: -720px -60px; }
-.emoji-1F623 { background-position: -720px -80px; }
-.emoji-1F624 { background-position: -720px -100px; }
-.emoji-1F625 { background-position: -720px -120px; }
-.emoji-1F626 { background-position: -720px -140px; }
-.emoji-1F627 { background-position: -720px -160px; }
-.emoji-1F628 { background-position: -720px -180px; }
-.emoji-1F629 { background-position: -720px -200px; }
-.emoji-1F62A { background-position: -720px -220px; }
-.emoji-1F62B { background-position: -720px -240px; }
-.emoji-1F62C { background-position: -720px -260px; }
-.emoji-1F62D { background-position: -720px -280px; }
-.emoji-1F62E { background-position: -720px -300px; }
-.emoji-1F62F { background-position: -720px -320px; }
-.emoji-1F630 { background-position: -720px -340px; }
-.emoji-1F631 { background-position: -720px -360px; }
-.emoji-1F632 { background-position: -720px -380px; }
-.emoji-1F633 { background-position: -720px -400px; }
-.emoji-1F634 { background-position: -720px -420px; }
-.emoji-1F635 { background-position: -720px -440px; }
-.emoji-1F636 { background-position: -720px -460px; }
-.emoji-1F637 { background-position: -720px -480px; }
-.emoji-1F638 { background-position: -720px -500px; }
-.emoji-1F639 { background-position: -720px -520px; }
-.emoji-1F63A { background-position: -720px -540px; }
-.emoji-1F63B { background-position: -720px -560px; }
-.emoji-1F63C { background-position: -720px -580px; }
-.emoji-1F63D { background-position: -720px -600px; }
-.emoji-1F63E { background-position: -720px -620px; }
-.emoji-1F63F { background-position: -720px -640px; }
-.emoji-1F640 { background-position: -720px -660px; }
-.emoji-1F641 { background-position: -720px -680px; }
-.emoji-1F642 { background-position: -720px -700px; }
-.emoji-1F643 { background-position: 0 -720px; }
-.emoji-1F644 { background-position: -20px -720px; }
-.emoji-1F645 { background-position: -40px -720px; }
-.emoji-1F645-1F3FB { background-position: -60px -720px; }
-.emoji-1F645-1F3FC { background-position: -80px -720px; }
-.emoji-1F645-1F3FD { background-position: -100px -720px; }
-.emoji-1F645-1F3FE { background-position: -120px -720px; }
-.emoji-1F645-1F3FF { background-position: -140px -720px; }
-.emoji-1F646 { background-position: -160px -720px; }
-.emoji-1F646-1F3FB { background-position: -180px -720px; }
-.emoji-1F646-1F3FC { background-position: -200px -720px; }
-.emoji-1F646-1F3FD { background-position: -220px -720px; }
-.emoji-1F646-1F3FE { background-position: -240px -720px; }
-.emoji-1F646-1F3FF { background-position: -260px -720px; }
-.emoji-1F647 { background-position: -280px -720px; }
-.emoji-1F647-1F3FB { background-position: -300px -720px; }
-.emoji-1F647-1F3FC { background-position: -320px -720px; }
-.emoji-1F647-1F3FD { background-position: -340px -720px; }
-.emoji-1F647-1F3FE { background-position: -360px -720px; }
-.emoji-1F647-1F3FF { background-position: -380px -720px; }
-.emoji-1F648 { background-position: -400px -720px; }
-.emoji-1F649 { background-position: -420px -720px; }
-.emoji-1F64A { background-position: -440px -720px; }
-.emoji-1F64B { background-position: -460px -720px; }
-.emoji-1F64B-1F3FB { background-position: -480px -720px; }
-.emoji-1F64B-1F3FC { background-position: -500px -720px; }
-.emoji-1F64B-1F3FD { background-position: -520px -720px; }
-.emoji-1F64B-1F3FE { background-position: -540px -720px; }
-.emoji-1F64B-1F3FF { background-position: -560px -720px; }
-.emoji-1F64C { background-position: -580px -720px; }
-.emoji-1F64C-1F3FB { background-position: -600px -720px; }
-.emoji-1F64C-1F3FC { background-position: -620px -720px; }
-.emoji-1F64C-1F3FD { background-position: -640px -720px; }
-.emoji-1F64C-1F3FE { background-position: -660px -720px; }
-.emoji-1F64C-1F3FF { background-position: -680px -720px; }
-.emoji-1F64D { background-position: -700px -720px; }
-.emoji-1F64D-1F3FB { background-position: -720px -720px; }
-.emoji-1F64D-1F3FC { background-position: -740px 0; }
-.emoji-1F64D-1F3FD { background-position: -740px -20px; }
-.emoji-1F64D-1F3FE { background-position: -740px -40px; }
-.emoji-1F64D-1F3FF { background-position: -740px -60px; }
-.emoji-1F64E { background-position: -740px -80px; }
-.emoji-1F64E-1F3FB { background-position: -740px -100px; }
-.emoji-1F64E-1F3FC { background-position: -740px -120px; }
-.emoji-1F64E-1F3FD { background-position: -740px -140px; }
-.emoji-1F64E-1F3FE { background-position: -740px -160px; }
-.emoji-1F64E-1F3FF { background-position: -740px -180px; }
-.emoji-1F64F { background-position: -740px -200px; }
-.emoji-1F64F-1F3FB { background-position: -740px -220px; }
-.emoji-1F64F-1F3FC { background-position: -740px -240px; }
-.emoji-1F64F-1F3FD { background-position: -740px -260px; }
-.emoji-1F64F-1F3FE { background-position: -740px -280px; }
-.emoji-1F64F-1F3FF { background-position: -740px -300px; }
-.emoji-1F680 { background-position: -740px -320px; }
-.emoji-1F681 { background-position: -740px -340px; }
-.emoji-1F682 { background-position: -740px -360px; }
-.emoji-1F683 { background-position: -740px -380px; }
-.emoji-1F684 { background-position: -740px -400px; }
-.emoji-1F685 { background-position: -740px -420px; }
-.emoji-1F686 { background-position: -740px -440px; }
-.emoji-1F687 { background-position: -740px -460px; }
-.emoji-1F688 { background-position: -740px -480px; }
-.emoji-1F689 { background-position: -740px -500px; }
-.emoji-1F68A { background-position: -740px -520px; }
-.emoji-1F68B { background-position: -740px -540px; }
-.emoji-1F68C { background-position: -740px -560px; }
-.emoji-1F68D { background-position: -740px -580px; }
-.emoji-1F68E { background-position: -740px -600px; }
-.emoji-1F68F { background-position: -740px -620px; }
-.emoji-1F690 { background-position: -740px -640px; }
-.emoji-1F691 { background-position: -740px -660px; }
-.emoji-1F692 { background-position: -740px -680px; }
-.emoji-1F693 { background-position: -740px -700px; }
-.emoji-1F694 { background-position: -740px -720px; }
-.emoji-1F695 { background-position: 0 -740px; }
-.emoji-1F696 { background-position: -20px -740px; }
-.emoji-1F697 { background-position: -40px -740px; }
-.emoji-1F698 { background-position: -60px -740px; }
-.emoji-1F699 { background-position: -80px -740px; }
-.emoji-1F69A { background-position: -100px -740px; }
-.emoji-1F69B { background-position: -120px -740px; }
-.emoji-1F69C { background-position: -140px -740px; }
-.emoji-1F69D { background-position: -160px -740px; }
-.emoji-1F69E { background-position: -180px -740px; }
-.emoji-1F69F { background-position: -200px -740px; }
-.emoji-1F6A0 { background-position: -220px -740px; }
-.emoji-1F6A1 { background-position: -240px -740px; }
-.emoji-1F6A2 { background-position: -260px -740px; }
-.emoji-1F6A3 { background-position: -280px -740px; }
-.emoji-1F6A3-1F3FB { background-position: -300px -740px; }
-.emoji-1F6A3-1F3FC { background-position: -320px -740px; }
-.emoji-1F6A3-1F3FD { background-position: -340px -740px; }
-.emoji-1F6A3-1F3FE { background-position: -360px -740px; }
-.emoji-1F6A3-1F3FF { background-position: -380px -740px; }
-.emoji-1F6A4 { background-position: -400px -740px; }
-.emoji-1F6A5 { background-position: -420px -740px; }
-.emoji-1F6A6 { background-position: -440px -740px; }
-.emoji-1F6A7 { background-position: -460px -740px; }
-.emoji-1F6A8 { background-position: -480px -740px; }
-.emoji-1F6A9 { background-position: -500px -740px; }
-.emoji-1F6AA { background-position: -520px -740px; }
-.emoji-1F6AB { background-position: -540px -740px; }
-.emoji-1F6AC { background-position: -560px -740px; }
-.emoji-1F6AD { background-position: -580px -740px; }
-.emoji-1F6AE { background-position: -600px -740px; }
-.emoji-1F6AF { background-position: -620px -740px; }
-.emoji-1F6B0 { background-position: -640px -740px; }
-.emoji-1F6B1 { background-position: -660px -740px; }
-.emoji-1F6B2 { background-position: -680px -740px; }
-.emoji-1F6B3 { background-position: -700px -740px; }
-.emoji-1F6B4 { background-position: -720px -740px; }
-.emoji-1F6B4-1F3FB { background-position: -740px -740px; }
-.emoji-1F6B4-1F3FC { background-position: -760px 0; }
-.emoji-1F6B4-1F3FD { background-position: -760px -20px; }
-.emoji-1F6B4-1F3FE { background-position: -760px -40px; }
-.emoji-1F6B4-1F3FF { background-position: -760px -60px; }
-.emoji-1F6B5 { background-position: -760px -80px; }
-.emoji-1F6B5-1F3FB { background-position: -760px -100px; }
-.emoji-1F6B5-1F3FC { background-position: -760px -120px; }
-.emoji-1F6B5-1F3FD { background-position: -760px -140px; }
-.emoji-1F6B5-1F3FE { background-position: -760px -160px; }
-.emoji-1F6B5-1F3FF { background-position: -760px -180px; }
-.emoji-1F6B6 { background-position: -760px -200px; }
-.emoji-1F6B6-1F3FB { background-position: -760px -220px; }
-.emoji-1F6B6-1F3FC { background-position: -760px -240px; }
-.emoji-1F6B6-1F3FD { background-position: -760px -260px; }
-.emoji-1F6B6-1F3FE { background-position: -760px -280px; }
-.emoji-1F6B6-1F3FF { background-position: -760px -300px; }
-.emoji-1F6B7 { background-position: -760px -320px; }
-.emoji-1F6B8 { background-position: -760px -340px; }
-.emoji-1F6B9 { background-position: -760px -360px; }
-.emoji-1F6BA { background-position: -760px -380px; }
-.emoji-1F6BB { background-position: -760px -400px; }
-.emoji-1F6BC { background-position: -760px -420px; }
-.emoji-1F6BD { background-position: -760px -440px; }
-.emoji-1F6BE { background-position: -760px -460px; }
-.emoji-1F6BF { background-position: -760px -480px; }
-.emoji-1F6C0 { background-position: -760px -500px; }
-.emoji-1F6C0-1F3FB { background-position: -760px -520px; }
-.emoji-1F6C0-1F3FC { background-position: -760px -540px; }
-.emoji-1F6C0-1F3FD { background-position: -760px -560px; }
-.emoji-1F6C0-1F3FE { background-position: -760px -580px; }
-.emoji-1F6C0-1F3FF { background-position: -760px -600px; }
-.emoji-1F6C1 { background-position: -760px -620px; }
-.emoji-1F6C2 { background-position: -760px -640px; }
-.emoji-1F6C3 { background-position: -760px -660px; }
-.emoji-1F6C4 { background-position: -760px -680px; }
-.emoji-1F6C5 { background-position: -760px -700px; }
-.emoji-1F6C6 { background-position: -760px -720px; }
-.emoji-1F6C7 { background-position: -760px -740px; }
-.emoji-1F6C8 { background-position: 0 -760px; }
-.emoji-1F6C9 { background-position: -20px -760px; }
-.emoji-1F6CA { background-position: -40px -760px; }
-.emoji-1F6CB { background-position: -60px -760px; }
-.emoji-1F6CC { background-position: -80px -760px; }
-.emoji-1F6CD { background-position: -100px -760px; }
-.emoji-1F6CE { background-position: -120px -760px; }
-.emoji-1F6CF { background-position: -140px -760px; }
-.emoji-1F6D0 { background-position: -160px -760px; }
-.emoji-1F6E0 { background-position: -180px -760px; }
-.emoji-1F6E1 { background-position: -200px -760px; }
-.emoji-1F6E2 { background-position: -220px -760px; }
-.emoji-1F6E3 { background-position: -240px -760px; }
-.emoji-1F6E4 { background-position: -260px -760px; }
-.emoji-1F6E5 { background-position: -280px -760px; }
-.emoji-1F6E6 { background-position: -300px -760px; }
-.emoji-1F6E7 { background-position: -320px -760px; }
-.emoji-1F6E8 { background-position: -340px -760px; }
-.emoji-1F6E9 { background-position: -360px -760px; }
-.emoji-1F6EA { background-position: -380px -760px; }
-.emoji-1F6EB { background-position: -400px -760px; }
-.emoji-1F6EC { background-position: -420px -760px; }
-.emoji-1F6F0 { background-position: -440px -760px; }
-.emoji-1F6F1 { background-position: -460px -760px; }
-.emoji-1F6F2 { background-position: -480px -760px; }
-.emoji-1F6F3 { background-position: -500px -760px; }
-.emoji-1F910 { background-position: -520px -760px; }
-.emoji-1F911 { background-position: -540px -760px; }
-.emoji-1F912 { background-position: -560px -760px; }
-.emoji-1F913 { background-position: -580px -760px; }
-.emoji-1F914 { background-position: -600px -760px; }
-.emoji-1F915 { background-position: -620px -760px; }
-.emoji-1F916 { background-position: -640px -760px; }
-.emoji-1F917 { background-position: -660px -760px; }
-.emoji-1F918 { background-position: -680px -760px; }
-.emoji-1F918-1F3FB { background-position: -700px -760px; }
-.emoji-1F918-1F3FC { background-position: -720px -760px; }
-.emoji-1F918-1F3FD { background-position: -740px -760px; }
-.emoji-1F918-1F3FE { background-position: -760px -760px; }
-.emoji-1F918-1F3FF { background-position: -780px 0; }
-.emoji-1F980 { background-position: -780px -20px; }
-.emoji-1F981 { background-position: -780px -40px; }
-.emoji-1F982 { background-position: -780px -60px; }
-.emoji-1F983 { background-position: -780px -80px; }
-.emoji-1F984 { background-position: -780px -100px; }
-.emoji-1F9C0 { background-position: -780px -120px; }
-.emoji-203C { background-position: -780px -140px; }
-.emoji-2049 { background-position: -780px -160px; }
-.emoji-2122 { background-position: -780px -180px; }
-.emoji-2139 { background-position: -780px -200px; }
-.emoji-2194 { background-position: -780px -220px; }
-.emoji-2195 { background-position: -780px -240px; }
-.emoji-2196 { background-position: -780px -260px; }
-.emoji-2197 { background-position: -780px -280px; }
-.emoji-2198 { background-position: -780px -300px; }
-.emoji-2199 { background-position: -780px -320px; }
-.emoji-21A9 { background-position: -780px -340px; }
-.emoji-21AA { background-position: -780px -360px; }
-.emoji-231A { background-position: -780px -380px; }
-.emoji-231B { background-position: -780px -400px; }
-.emoji-2328 { background-position: -780px -420px; }
-.emoji-23E9 { background-position: -780px -440px; }
-.emoji-23EA { background-position: -780px -460px; }
-.emoji-23EB { background-position: -780px -480px; }
-.emoji-23EC { background-position: -780px -500px; }
-.emoji-23ED { background-position: -780px -520px; }
-.emoji-23EE { background-position: -780px -540px; }
-.emoji-23EF { background-position: -780px -560px; }
-.emoji-23F0 { background-position: -780px -580px; }
-.emoji-23F1 { background-position: -780px -600px; }
-.emoji-23F2 { background-position: -780px -620px; }
-.emoji-23F3 { background-position: -780px -640px; }
-.emoji-23F8 { background-position: -780px -660px; }
-.emoji-23F9 { background-position: -780px -680px; }
-.emoji-23FA { background-position: -780px -700px; }
-.emoji-24C2 { background-position: -780px -720px; }
-.emoji-25AA { background-position: -780px -740px; }
-.emoji-25AB { background-position: -780px -760px; }
-.emoji-25B6 { background-position: 0 -780px; }
-.emoji-25C0 { background-position: -20px -780px; }
-.emoji-25FB { background-position: -40px -780px; }
-.emoji-25FC { background-position: -60px -780px; }
-.emoji-25FD { background-position: -80px -780px; }
-.emoji-25FE { background-position: -100px -780px; }
-.emoji-2600 { background-position: -120px -780px; }
-.emoji-2601 { background-position: -140px -780px; }
-.emoji-2602 { background-position: -160px -780px; }
-.emoji-2603 { background-position: -180px -780px; }
-.emoji-2604 { background-position: -200px -780px; }
-.emoji-260E { background-position: -220px -780px; }
-.emoji-2611 { background-position: -240px -780px; }
-.emoji-2614 { background-position: -260px -780px; }
-.emoji-2615 { background-position: -280px -780px; }
-.emoji-2618 { background-position: -300px -780px; }
-.emoji-261D { background-position: -320px -780px; }
-.emoji-261D-1F3FB { background-position: -340px -780px; }
-.emoji-261D-1F3FC { background-position: -360px -780px; }
-.emoji-261D-1F3FD { background-position: -380px -780px; }
-.emoji-261D-1F3FE { background-position: -400px -780px; }
-.emoji-261D-1F3FF { background-position: -420px -780px; }
-.emoji-2620 { background-position: -440px -780px; }
-.emoji-2622 { background-position: -460px -780px; }
-.emoji-2623 { background-position: -480px -780px; }
-.emoji-2626 { background-position: -500px -780px; }
-.emoji-262A { background-position: -520px -780px; }
-.emoji-262E { background-position: -540px -780px; }
-.emoji-262F { background-position: -560px -780px; }
-.emoji-2638 { background-position: -580px -780px; }
-.emoji-2639 { background-position: -600px -780px; }
-.emoji-263A { background-position: -620px -780px; }
-.emoji-2648 { background-position: -640px -780px; }
-.emoji-2649 { background-position: -660px -780px; }
-.emoji-264A { background-position: -680px -780px; }
-.emoji-264B { background-position: -700px -780px; }
-.emoji-264C { background-position: -720px -780px; }
-.emoji-264D { background-position: -740px -780px; }
-.emoji-264E { background-position: -760px -780px; }
-.emoji-264F { background-position: -780px -780px; }
-.emoji-2650 { background-position: -800px 0; }
-.emoji-2651 { background-position: -800px -20px; }
-.emoji-2652 { background-position: -800px -40px; }
-.emoji-2653 { background-position: -800px -60px; }
-.emoji-2660 { background-position: -800px -80px; }
-.emoji-2663 { background-position: -800px -100px; }
-.emoji-2665 { background-position: -800px -120px; }
-.emoji-2666 { background-position: -800px -140px; }
-.emoji-2668 { background-position: -800px -160px; }
-.emoji-267B { background-position: -800px -180px; }
-.emoji-267F { background-position: -800px -200px; }
-.emoji-2692 { background-position: -800px -220px; }
-.emoji-2693 { background-position: -800px -240px; }
-.emoji-2694 { background-position: -800px -260px; }
-.emoji-2696 { background-position: -800px -280px; }
-.emoji-2697 { background-position: -800px -300px; }
-.emoji-2699 { background-position: -800px -320px; }
-.emoji-269B { background-position: -800px -340px; }
-.emoji-269C { background-position: -800px -360px; }
-.emoji-26A0 { background-position: -800px -380px; }
-.emoji-26A1 { background-position: -800px -400px; }
-.emoji-26AA { background-position: -800px -420px; }
-.emoji-26AB { background-position: -800px -440px; }
-.emoji-26B0 { background-position: -800px -460px; }
-.emoji-26B1 { background-position: -800px -480px; }
-.emoji-26BD { background-position: -800px -500px; }
-.emoji-26BE { background-position: -800px -520px; }
-.emoji-26C4 { background-position: -800px -540px; }
-.emoji-26C5 { background-position: -800px -560px; }
-.emoji-26C8 { background-position: -800px -580px; }
-.emoji-26CE { background-position: -800px -600px; }
-.emoji-26CF { background-position: -800px -620px; }
-.emoji-26D1 { background-position: -800px -640px; }
-.emoji-26D3 { background-position: -800px -660px; }
-.emoji-26D4 { background-position: -800px -680px; }
-.emoji-26E9 { background-position: -800px -700px; }
-.emoji-26EA { background-position: -800px -720px; }
-.emoji-26F0 { background-position: -800px -740px; }
-.emoji-26F1 { background-position: -800px -760px; }
-.emoji-26F2 { background-position: -800px -780px; }
-.emoji-26F3 { background-position: 0 -800px; }
-.emoji-26F4 { background-position: -20px -800px; }
-.emoji-26F5 { background-position: -40px -800px; }
-.emoji-26F7 { background-position: -60px -800px; }
-.emoji-26F8 { background-position: -80px -800px; }
-.emoji-26F9 { background-position: -100px -800px; }
-.emoji-26F9-1F3FB { background-position: -120px -800px; }
-.emoji-26F9-1F3FC { background-position: -140px -800px; }
-.emoji-26F9-1F3FD { background-position: -160px -800px; }
-.emoji-26F9-1F3FE { background-position: -180px -800px; }
-.emoji-26F9-1F3FF { background-position: -200px -800px; }
-.emoji-26FA { background-position: -220px -800px; }
-.emoji-26FD { background-position: -240px -800px; }
-.emoji-2702 { background-position: -260px -800px; }
-.emoji-2705 { background-position: -280px -800px; }
-.emoji-2708 { background-position: -300px -800px; }
-.emoji-2709 { background-position: -320px -800px; }
-.emoji-270A { background-position: -340px -800px; }
-.emoji-270A-1F3FB { background-position: -360px -800px; }
-.emoji-270A-1F3FC { background-position: -380px -800px; }
-.emoji-270A-1F3FD { background-position: -400px -800px; }
-.emoji-270A-1F3FE { background-position: -420px -800px; }
-.emoji-270A-1F3FF { background-position: -440px -800px; }
-.emoji-270B { background-position: -460px -800px; }
-.emoji-270B-1F3FB { background-position: -480px -800px; }
-.emoji-270B-1F3FC { background-position: -500px -800px; }
-.emoji-270B-1F3FD { background-position: -520px -800px; }
-.emoji-270B-1F3FE { background-position: -540px -800px; }
-.emoji-270B-1F3FF { background-position: -560px -800px; }
-.emoji-270C { background-position: -580px -800px; }
-.emoji-270C-1F3FB { background-position: -600px -800px; }
-.emoji-270C-1F3FC { background-position: -620px -800px; }
-.emoji-270C-1F3FD { background-position: -640px -800px; }
-.emoji-270C-1F3FE { background-position: -660px -800px; }
-.emoji-270C-1F3FF { background-position: -680px -800px; }
-.emoji-270D { background-position: -700px -800px; }
-.emoji-270D-1F3FB { background-position: -720px -800px; }
-.emoji-270D-1F3FC { background-position: -740px -800px; }
-.emoji-270D-1F3FD { background-position: -760px -800px; }
-.emoji-270D-1F3FE { background-position: -780px -800px; }
-.emoji-270D-1F3FF { background-position: -800px -800px; }
-.emoji-270F { background-position: -820px 0; }
-.emoji-2712 { background-position: -820px -20px; }
-.emoji-2714 { background-position: -820px -40px; }
-.emoji-2716 { background-position: -820px -60px; }
-.emoji-271D { background-position: -820px -80px; }
-.emoji-2721 { background-position: -820px -100px; }
-.emoji-2728 { background-position: -820px -120px; }
-.emoji-2733 { background-position: -820px -140px; }
-.emoji-2734 { background-position: -820px -160px; }
-.emoji-2744 { background-position: -820px -180px; }
-.emoji-2747 { background-position: -820px -200px; }
-.emoji-274C { background-position: -820px -220px; }
-.emoji-274E { background-position: -820px -240px; }
-.emoji-2753 { background-position: -820px -260px; }
-.emoji-2754 { background-position: -820px -280px; }
-.emoji-2755 { background-position: -820px -300px; }
-.emoji-2757 { background-position: -820px -320px; }
-.emoji-2763 { background-position: -820px -340px; }
-.emoji-2764 { background-position: -820px -360px; }
-.emoji-2795 { background-position: -820px -380px; }
-.emoji-2796 { background-position: -820px -400px; }
-.emoji-2797 { background-position: -820px -420px; }
-.emoji-27A1 { background-position: -820px -440px; }
-.emoji-27B0 { background-position: -820px -460px; }
-.emoji-27BF { background-position: -820px -480px; }
-.emoji-2934 { background-position: -820px -500px; }
-.emoji-2935 { background-position: -820px -520px; }
-.emoji-2B05 { background-position: -820px -540px; }
-.emoji-2B06 { background-position: -820px -560px; }
-.emoji-2B07 { background-position: -820px -580px; }
-.emoji-2B1B { background-position: -820px -600px; }
-.emoji-2B1C { background-position: -820px -620px; }
-.emoji-2B50 { background-position: -820px -640px; }
-.emoji-2B55 { background-position: -820px -660px; }
-.emoji-3030 { background-position: -820px -680px; }
-.emoji-303D { background-position: -820px -700px; }
-.emoji-3297 { background-position: -820px -720px; }
-.emoji-3299 { background-position: -820px -740px; }
+.emoji-1F396 { background-position: -420px -260px; }
+.emoji-1F397 { background-position: -420px -280px; }
+.emoji-1F399 { background-position: -420px -300px; }
+.emoji-1F39A { background-position: -420px -320px; }
+.emoji-1F39B { background-position: -420px -340px; }
+.emoji-1F39E { background-position: -420px -360px; }
+.emoji-1F39F { background-position: -420px -380px; }
+.emoji-1F3A0 { background-position: -420px -400px; }
+.emoji-1F3A1 { background-position: 0 -420px; }
+.emoji-1F3A2 { background-position: -20px -420px; }
+.emoji-1F3A3 { background-position: -40px -420px; }
+.emoji-1F3A4 { background-position: -60px -420px; }
+.emoji-1F3A5 { background-position: -80px -420px; }
+.emoji-1F3A6 { background-position: -100px -420px; }
+.emoji-1F3A7 { background-position: -120px -420px; }
+.emoji-1F3A8 { background-position: -140px -420px; }
+.emoji-1F3A9 { background-position: -160px -420px; }
+.emoji-1F3AA { background-position: -180px -420px; }
+.emoji-1F3AB { background-position: -200px -420px; }
+.emoji-1F3AC { background-position: -220px -420px; }
+.emoji-1F3AD { background-position: -240px -420px; }
+.emoji-1F3AE { background-position: -260px -420px; }
+.emoji-1F3AF { background-position: -280px -420px; }
+.emoji-1F3B0 { background-position: -300px -420px; }
+.emoji-1F3B1 { background-position: -320px -420px; }
+.emoji-1F3B2 { background-position: -340px -420px; }
+.emoji-1F3B3 { background-position: -360px -420px; }
+.emoji-1F3B4 { background-position: -380px -420px; }
+.emoji-1F3B5 { background-position: -400px -420px; }
+.emoji-1F3B6 { background-position: -420px -420px; }
+.emoji-1F3B7 { background-position: -440px 0; }
+.emoji-1F3B8 { background-position: -440px -20px; }
+.emoji-1F3B9 { background-position: -440px -40px; }
+.emoji-1F3BA { background-position: -440px -60px; }
+.emoji-1F3BB { background-position: -440px -80px; }
+.emoji-1F3BC { background-position: -440px -100px; }
+.emoji-1F3BD { background-position: -440px -120px; }
+.emoji-1F3BE { background-position: -440px -140px; }
+.emoji-1F3BF { background-position: -440px -160px; }
+.emoji-1F3C0 { background-position: -440px -180px; }
+.emoji-1F3C1 { background-position: -440px -200px; }
+.emoji-1F3C2 { background-position: -440px -220px; }
+.emoji-1F3C3 { background-position: -440px -240px; }
+.emoji-1F3C3-1F3FB { background-position: -440px -260px; }
+.emoji-1F3C3-1F3FC { background-position: -440px -280px; }
+.emoji-1F3C3-1F3FD { background-position: -440px -300px; }
+.emoji-1F3C3-1F3FE { background-position: -440px -320px; }
+.emoji-1F3C3-1F3FF { background-position: -440px -340px; }
+.emoji-1F3C4 { background-position: -440px -360px; }
+.emoji-1F3C4-1F3FB { background-position: -440px -380px; }
+.emoji-1F3C4-1F3FC { background-position: -440px -400px; }
+.emoji-1F3C4-1F3FD { background-position: -440px -420px; }
+.emoji-1F3C4-1F3FE { background-position: 0 -440px; }
+.emoji-1F3C4-1F3FF { background-position: -20px -440px; }
+.emoji-1F3C5 { background-position: -40px -440px; }
+.emoji-1F3C6 { background-position: -60px -440px; }
+.emoji-1F3C7 { background-position: -80px -440px; }
+.emoji-1F3C7-1F3FB { background-position: -100px -440px; }
+.emoji-1F3C7-1F3FC { background-position: -120px -440px; }
+.emoji-1F3C7-1F3FD { background-position: -140px -440px; }
+.emoji-1F3C7-1F3FE { background-position: -160px -440px; }
+.emoji-1F3C7-1F3FF { background-position: -180px -440px; }
+.emoji-1F3C8 { background-position: -200px -440px; }
+.emoji-1F3C9 { background-position: -220px -440px; }
+.emoji-1F3CA { background-position: -240px -440px; }
+.emoji-1F3CA-1F3FB { background-position: -260px -440px; }
+.emoji-1F3CA-1F3FC { background-position: -280px -440px; }
+.emoji-1F3CA-1F3FD { background-position: -300px -440px; }
+.emoji-1F3CA-1F3FE { background-position: -320px -440px; }
+.emoji-1F3CA-1F3FF { background-position: -340px -440px; }
+.emoji-1F3CB { background-position: -360px -440px; }
+.emoji-1F3CB-1F3FB { background-position: -380px -440px; }
+.emoji-1F3CB-1F3FC { background-position: -400px -440px; }
+.emoji-1F3CB-1F3FD { background-position: -420px -440px; }
+.emoji-1F3CB-1F3FE { background-position: -440px -440px; }
+.emoji-1F3CB-1F3FF { background-position: -460px 0; }
+.emoji-1F3CC { background-position: -460px -20px; }
+.emoji-1F3CD { background-position: -460px -40px; }
+.emoji-1F3CE { background-position: -460px -60px; }
+.emoji-1F3CF { background-position: -460px -80px; }
+.emoji-1F3D0 { background-position: -460px -100px; }
+.emoji-1F3D1 { background-position: -460px -120px; }
+.emoji-1F3D2 { background-position: -460px -140px; }
+.emoji-1F3D3 { background-position: -460px -160px; }
+.emoji-1F3D4 { background-position: -460px -180px; }
+.emoji-1F3D5 { background-position: -460px -200px; }
+.emoji-1F3D6 { background-position: -460px -220px; }
+.emoji-1F3D7 { background-position: -460px -240px; }
+.emoji-1F3D8 { background-position: -460px -260px; }
+.emoji-1F3D9 { background-position: -460px -280px; }
+.emoji-1F3DA { background-position: -460px -300px; }
+.emoji-1F3DB { background-position: -460px -320px; }
+.emoji-1F3DC { background-position: -460px -340px; }
+.emoji-1F3DD { background-position: -460px -360px; }
+.emoji-1F3DE { background-position: -460px -380px; }
+.emoji-1F3DF { background-position: -460px -400px; }
+.emoji-1F3E0 { background-position: -460px -420px; }
+.emoji-1F3E1 { background-position: -460px -440px; }
+.emoji-1F3E2 { background-position: 0 -460px; }
+.emoji-1F3E3 { background-position: -20px -460px; }
+.emoji-1F3E4 { background-position: -40px -460px; }
+.emoji-1F3E5 { background-position: -60px -460px; }
+.emoji-1F3E6 { background-position: -80px -460px; }
+.emoji-1F3E7 { background-position: -100px -460px; }
+.emoji-1F3E8 { background-position: -120px -460px; }
+.emoji-1F3E9 { background-position: -140px -460px; }
+.emoji-1F3EA { background-position: -160px -460px; }
+.emoji-1F3EB { background-position: -180px -460px; }
+.emoji-1F3EC { background-position: -200px -460px; }
+.emoji-1F3ED { background-position: -220px -460px; }
+.emoji-1F3EE { background-position: -240px -460px; }
+.emoji-1F3EF { background-position: -260px -460px; }
+.emoji-1F3F0 { background-position: -280px -460px; }
+.emoji-1F3F3 { background-position: -300px -460px; }
+.emoji-1F3F4 { background-position: -320px -460px; }
+.emoji-1F3F5 { background-position: -340px -460px; }
+.emoji-1F3F7 { background-position: -360px -460px; }
+.emoji-1F3F8 { background-position: -380px -460px; }
+.emoji-1F3F9 { background-position: -400px -460px; }
+.emoji-1F3FA { background-position: -420px -460px; }
+.emoji-1F3FB { background-position: -440px -460px; }
+.emoji-1F3FC { background-position: -460px -460px; }
+.emoji-1F3FD { background-position: -480px 0; }
+.emoji-1F3FE { background-position: -480px -20px; }
+.emoji-1F3FF { background-position: -480px -40px; }
+.emoji-1F400 { background-position: -480px -60px; }
+.emoji-1F401 { background-position: -480px -80px; }
+.emoji-1F402 { background-position: -480px -100px; }
+.emoji-1F403 { background-position: -480px -120px; }
+.emoji-1F404 { background-position: -480px -140px; }
+.emoji-1F405 { background-position: -480px -160px; }
+.emoji-1F406 { background-position: -480px -180px; }
+.emoji-1F407 { background-position: -480px -200px; }
+.emoji-1F408 { background-position: -480px -220px; }
+.emoji-1F409 { background-position: -480px -240px; }
+.emoji-1F40A { background-position: -480px -260px; }
+.emoji-1F40B { background-position: -480px -280px; }
+.emoji-1F40C { background-position: -480px -300px; }
+.emoji-1F40D { background-position: -480px -320px; }
+.emoji-1F40E { background-position: -480px -340px; }
+.emoji-1F40F { background-position: -480px -360px; }
+.emoji-1F410 { background-position: -480px -380px; }
+.emoji-1F411 { background-position: -480px -400px; }
+.emoji-1F412 { background-position: -480px -420px; }
+.emoji-1F413 { background-position: -480px -440px; }
+.emoji-1F414 { background-position: -480px -460px; }
+.emoji-1F415 { background-position: 0 -480px; }
+.emoji-1F416 { background-position: -20px -480px; }
+.emoji-1F417 { background-position: -40px -480px; }
+.emoji-1F418 { background-position: -60px -480px; }
+.emoji-1F419 { background-position: -80px -480px; }
+.emoji-1F41A { background-position: -100px -480px; }
+.emoji-1F41B { background-position: -120px -480px; }
+.emoji-1F41C { background-position: -140px -480px; }
+.emoji-1F41D { background-position: -160px -480px; }
+.emoji-1F41E { background-position: -180px -480px; }
+.emoji-1F41F { background-position: -200px -480px; }
+.emoji-1F420 { background-position: -220px -480px; }
+.emoji-1F421 { background-position: -240px -480px; }
+.emoji-1F422 { background-position: -260px -480px; }
+.emoji-1F423 { background-position: -280px -480px; }
+.emoji-1F424 { background-position: -300px -480px; }
+.emoji-1F425 { background-position: -320px -480px; }
+.emoji-1F426 { background-position: -340px -480px; }
+.emoji-1F427 { background-position: -360px -480px; }
+.emoji-1F428 { background-position: -380px -480px; }
+.emoji-1F429 { background-position: -400px -480px; }
+.emoji-1F42A { background-position: -420px -480px; }
+.emoji-1F42B { background-position: -440px -480px; }
+.emoji-1F42C { background-position: -460px -480px; }
+.emoji-1F42D { background-position: -480px -480px; }
+.emoji-1F42E { background-position: -500px 0; }
+.emoji-1F42F { background-position: -500px -20px; }
+.emoji-1F430 { background-position: -500px -40px; }
+.emoji-1F431 { background-position: -500px -60px; }
+.emoji-1F432 { background-position: -500px -80px; }
+.emoji-1F433 { background-position: -500px -100px; }
+.emoji-1F434 { background-position: -500px -120px; }
+.emoji-1F435 { background-position: -500px -140px; }
+.emoji-1F436 { background-position: -500px -160px; }
+.emoji-1F437 { background-position: -500px -180px; }
+.emoji-1F438 { background-position: -500px -200px; }
+.emoji-1F439 { background-position: -500px -220px; }
+.emoji-1F43A { background-position: -500px -240px; }
+.emoji-1F43B { background-position: -500px -260px; }
+.emoji-1F43C { background-position: -500px -280px; }
+.emoji-1F43D { background-position: -500px -300px; }
+.emoji-1F43E { background-position: -500px -320px; }
+.emoji-1F43F { background-position: -500px -340px; }
+.emoji-1F440 { background-position: -500px -360px; }
+.emoji-1F441 { background-position: -500px -380px; }
+.emoji-1F441-1F5E8 { background-position: -500px -400px; }
+.emoji-1F442 { background-position: -500px -420px; }
+.emoji-1F442-1F3FB { background-position: -500px -440px; }
+.emoji-1F442-1F3FC { background-position: -500px -460px; }
+.emoji-1F442-1F3FD { background-position: -500px -480px; }
+.emoji-1F442-1F3FE { background-position: 0 -500px; }
+.emoji-1F442-1F3FF { background-position: -20px -500px; }
+.emoji-1F443 { background-position: -40px -500px; }
+.emoji-1F443-1F3FB { background-position: -60px -500px; }
+.emoji-1F443-1F3FC { background-position: -80px -500px; }
+.emoji-1F443-1F3FD { background-position: -100px -500px; }
+.emoji-1F443-1F3FE { background-position: -120px -500px; }
+.emoji-1F443-1F3FF { background-position: -140px -500px; }
+.emoji-1F444 { background-position: -160px -500px; }
+.emoji-1F445 { background-position: -180px -500px; }
+.emoji-1F446 { background-position: -200px -500px; }
+.emoji-1F446-1F3FB { background-position: -220px -500px; }
+.emoji-1F446-1F3FC { background-position: -240px -500px; }
+.emoji-1F446-1F3FD { background-position: -260px -500px; }
+.emoji-1F446-1F3FE { background-position: -280px -500px; }
+.emoji-1F446-1F3FF { background-position: -300px -500px; }
+.emoji-1F447 { background-position: -320px -500px; }
+.emoji-1F447-1F3FB { background-position: -340px -500px; }
+.emoji-1F447-1F3FC { background-position: -360px -500px; }
+.emoji-1F447-1F3FD { background-position: -380px -500px; }
+.emoji-1F447-1F3FE { background-position: -400px -500px; }
+.emoji-1F447-1F3FF { background-position: -420px -500px; }
+.emoji-1F448 { background-position: -440px -500px; }
+.emoji-1F448-1F3FB { background-position: -460px -500px; }
+.emoji-1F448-1F3FC { background-position: -480px -500px; }
+.emoji-1F448-1F3FD { background-position: -500px -500px; }
+.emoji-1F448-1F3FE { background-position: -520px 0; }
+.emoji-1F448-1F3FF { background-position: -520px -20px; }
+.emoji-1F449 { background-position: -520px -40px; }
+.emoji-1F449-1F3FB { background-position: -520px -60px; }
+.emoji-1F449-1F3FC { background-position: -520px -80px; }
+.emoji-1F449-1F3FD { background-position: -520px -100px; }
+.emoji-1F449-1F3FE { background-position: -520px -120px; }
+.emoji-1F449-1F3FF { background-position: -520px -140px; }
+.emoji-1F44A { background-position: -520px -160px; }
+.emoji-1F44A-1F3FB { background-position: -520px -180px; }
+.emoji-1F44A-1F3FC { background-position: -520px -200px; }
+.emoji-1F44A-1F3FD { background-position: -520px -220px; }
+.emoji-1F44A-1F3FE { background-position: -520px -240px; }
+.emoji-1F44A-1F3FF { background-position: -520px -260px; }
+.emoji-1F44B { background-position: -520px -280px; }
+.emoji-1F44B-1F3FB { background-position: -520px -300px; }
+.emoji-1F44B-1F3FC { background-position: -520px -320px; }
+.emoji-1F44B-1F3FD { background-position: -520px -340px; }
+.emoji-1F44B-1F3FE { background-position: -520px -360px; }
+.emoji-1F44B-1F3FF { background-position: -520px -380px; }
+.emoji-1F44C { background-position: -520px -400px; }
+.emoji-1F44C-1F3FB { background-position: -520px -420px; }
+.emoji-1F44C-1F3FC { background-position: -520px -440px; }
+.emoji-1F44C-1F3FD { background-position: -520px -460px; }
+.emoji-1F44C-1F3FE { background-position: -520px -480px; }
+.emoji-1F44C-1F3FF { background-position: -520px -500px; }
+.emoji-1F44D { background-position: 0 -520px; }
+.emoji-1F44D-1F3FB { background-position: -20px -520px; }
+.emoji-1F44D-1F3FC { background-position: -40px -520px; }
+.emoji-1F44D-1F3FD { background-position: -60px -520px; }
+.emoji-1F44D-1F3FE { background-position: -80px -520px; }
+.emoji-1F44D-1F3FF { background-position: -100px -520px; }
+.emoji-1F44E { background-position: -120px -520px; }
+.emoji-1F44E-1F3FB { background-position: -140px -520px; }
+.emoji-1F44E-1F3FC { background-position: -160px -520px; }
+.emoji-1F44E-1F3FD { background-position: -180px -520px; }
+.emoji-1F44E-1F3FE { background-position: -200px -520px; }
+.emoji-1F44E-1F3FF { background-position: -220px -520px; }
+.emoji-1F44F { background-position: -240px -520px; }
+.emoji-1F44F-1F3FB { background-position: -260px -520px; }
+.emoji-1F44F-1F3FC { background-position: -280px -520px; }
+.emoji-1F44F-1F3FD { background-position: -300px -520px; }
+.emoji-1F44F-1F3FE { background-position: -320px -520px; }
+.emoji-1F44F-1F3FF { background-position: -340px -520px; }
+.emoji-1F450 { background-position: -360px -520px; }
+.emoji-1F450-1F3FB { background-position: -380px -520px; }
+.emoji-1F450-1F3FC { background-position: -400px -520px; }
+.emoji-1F450-1F3FD { background-position: -420px -520px; }
+.emoji-1F450-1F3FE { background-position: -440px -520px; }
+.emoji-1F450-1F3FF { background-position: -460px -520px; }
+.emoji-1F451 { background-position: -480px -520px; }
+.emoji-1F452 { background-position: -500px -520px; }
+.emoji-1F453 { background-position: -520px -520px; }
+.emoji-1F454 { background-position: -540px 0; }
+.emoji-1F455 { background-position: -540px -20px; }
+.emoji-1F456 { background-position: -540px -40px; }
+.emoji-1F457 { background-position: -540px -60px; }
+.emoji-1F458 { background-position: -540px -80px; }
+.emoji-1F459 { background-position: -540px -100px; }
+.emoji-1F45A { background-position: -540px -120px; }
+.emoji-1F45B { background-position: -540px -140px; }
+.emoji-1F45C { background-position: -540px -160px; }
+.emoji-1F45D { background-position: -540px -180px; }
+.emoji-1F45E { background-position: -540px -200px; }
+.emoji-1F45F { background-position: -540px -220px; }
+.emoji-1F460 { background-position: -540px -240px; }
+.emoji-1F461 { background-position: -540px -260px; }
+.emoji-1F462 { background-position: -540px -280px; }
+.emoji-1F463 { background-position: -540px -300px; }
+.emoji-1F464 { background-position: -540px -320px; }
+.emoji-1F465 { background-position: -540px -340px; }
+.emoji-1F466 { background-position: -540px -360px; }
+.emoji-1F466-1F3FB { background-position: -540px -380px; }
+.emoji-1F466-1F3FC { background-position: -540px -400px; }
+.emoji-1F466-1F3FD { background-position: -540px -420px; }
+.emoji-1F466-1F3FE { background-position: -540px -440px; }
+.emoji-1F466-1F3FF { background-position: -540px -460px; }
+.emoji-1F467 { background-position: -540px -480px; }
+.emoji-1F467-1F3FB { background-position: -540px -500px; }
+.emoji-1F467-1F3FC { background-position: -540px -520px; }
+.emoji-1F467-1F3FD { background-position: 0 -540px; }
+.emoji-1F467-1F3FE { background-position: -20px -540px; }
+.emoji-1F467-1F3FF { background-position: -40px -540px; }
+.emoji-1F468 { background-position: -60px -540px; }
+.emoji-1F468-1F3FB { background-position: -80px -540px; }
+.emoji-1F468-1F3FC { background-position: -100px -540px; }
+.emoji-1F468-1F3FD { background-position: -120px -540px; }
+.emoji-1F468-1F3FE { background-position: -140px -540px; }
+.emoji-1F468-1F3FF { background-position: -160px -540px; }
+.emoji-1F468-1F468-1F466 { background-position: -180px -540px; }
+.emoji-1F468-1F468-1F466-1F466 { background-position: -200px -540px; }
+.emoji-1F468-1F468-1F467 { background-position: -220px -540px; }
+.emoji-1F468-1F468-1F467-1F466 { background-position: -240px -540px; }
+.emoji-1F468-1F468-1F467-1F467 { background-position: -260px -540px; }
+.emoji-1F468-1F469-1F466-1F466 { background-position: -280px -540px; }
+.emoji-1F468-1F469-1F467 { background-position: -300px -540px; }
+.emoji-1F468-1F469-1F467-1F466 { background-position: -320px -540px; }
+.emoji-1F468-1F469-1F467-1F467 { background-position: -340px -540px; }
+.emoji-1F468-2764-1F468 { background-position: -360px -540px; }
+.emoji-1F468-2764-1F48B-1F468 { background-position: -380px -540px; }
+.emoji-1F469 { background-position: -400px -540px; }
+.emoji-1F469-1F3FB { background-position: -420px -540px; }
+.emoji-1F469-1F3FC { background-position: -440px -540px; }
+.emoji-1F469-1F3FD { background-position: -460px -540px; }
+.emoji-1F469-1F3FE { background-position: -480px -540px; }
+.emoji-1F469-1F3FF { background-position: -500px -540px; }
+.emoji-1F469-1F469-1F466 { background-position: -520px -540px; }
+.emoji-1F469-1F469-1F466-1F466 { background-position: -540px -540px; }
+.emoji-1F469-1F469-1F467 { background-position: -560px 0; }
+.emoji-1F469-1F469-1F467-1F466 { background-position: -560px -20px; }
+.emoji-1F469-1F469-1F467-1F467 { background-position: -560px -40px; }
+.emoji-1F469-2764-1F469 { background-position: -560px -60px; }
+.emoji-1F469-2764-1F48B-1F469 { background-position: -560px -80px; }
+.emoji-1F46A { background-position: -560px -100px; }
+.emoji-1F46B { background-position: -560px -120px; }
+.emoji-1F46C { background-position: -560px -140px; }
+.emoji-1F46D { background-position: -560px -160px; }
+.emoji-1F46E { background-position: -560px -180px; }
+.emoji-1F46E-1F3FB { background-position: -560px -200px; }
+.emoji-1F46E-1F3FC { background-position: -560px -220px; }
+.emoji-1F46E-1F3FD { background-position: -560px -240px; }
+.emoji-1F46E-1F3FE { background-position: -560px -260px; }
+.emoji-1F46E-1F3FF { background-position: -560px -280px; }
+.emoji-1F46F { background-position: -560px -300px; }
+.emoji-1F470 { background-position: -560px -320px; }
+.emoji-1F470-1F3FB { background-position: -560px -340px; }
+.emoji-1F470-1F3FC { background-position: -560px -360px; }
+.emoji-1F470-1F3FD { background-position: -560px -380px; }
+.emoji-1F470-1F3FE { background-position: -560px -400px; }
+.emoji-1F470-1F3FF { background-position: -560px -420px; }
+.emoji-1F471 { background-position: -560px -440px; }
+.emoji-1F471-1F3FB { background-position: -560px -460px; }
+.emoji-1F471-1F3FC { background-position: -560px -480px; }
+.emoji-1F471-1F3FD { background-position: -560px -500px; }
+.emoji-1F471-1F3FE { background-position: -560px -520px; }
+.emoji-1F471-1F3FF { background-position: -560px -540px; }
+.emoji-1F472 { background-position: 0 -560px; }
+.emoji-1F472-1F3FB { background-position: -20px -560px; }
+.emoji-1F472-1F3FC { background-position: -40px -560px; }
+.emoji-1F472-1F3FD { background-position: -60px -560px; }
+.emoji-1F472-1F3FE { background-position: -80px -560px; }
+.emoji-1F472-1F3FF { background-position: -100px -560px; }
+.emoji-1F473 { background-position: -120px -560px; }
+.emoji-1F473-1F3FB { background-position: -140px -560px; }
+.emoji-1F473-1F3FC { background-position: -160px -560px; }
+.emoji-1F473-1F3FD { background-position: -180px -560px; }
+.emoji-1F473-1F3FE { background-position: -200px -560px; }
+.emoji-1F473-1F3FF { background-position: -220px -560px; }
+.emoji-1F474 { background-position: -240px -560px; }
+.emoji-1F474-1F3FB { background-position: -260px -560px; }
+.emoji-1F474-1F3FC { background-position: -280px -560px; }
+.emoji-1F474-1F3FD { background-position: -300px -560px; }
+.emoji-1F474-1F3FE { background-position: -320px -560px; }
+.emoji-1F474-1F3FF { background-position: -340px -560px; }
+.emoji-1F475 { background-position: -360px -560px; }
+.emoji-1F475-1F3FB { background-position: -380px -560px; }
+.emoji-1F475-1F3FC { background-position: -400px -560px; }
+.emoji-1F475-1F3FD { background-position: -420px -560px; }
+.emoji-1F475-1F3FE { background-position: -440px -560px; }
+.emoji-1F475-1F3FF { background-position: -460px -560px; }
+.emoji-1F476 { background-position: -480px -560px; }
+.emoji-1F476-1F3FB { background-position: -500px -560px; }
+.emoji-1F476-1F3FC { background-position: -520px -560px; }
+.emoji-1F476-1F3FD { background-position: -540px -560px; }
+.emoji-1F476-1F3FE { background-position: -560px -560px; }
+.emoji-1F476-1F3FF { background-position: -580px 0; }
+.emoji-1F477 { background-position: -580px -20px; }
+.emoji-1F477-1F3FB { background-position: -580px -40px; }
+.emoji-1F477-1F3FC { background-position: -580px -60px; }
+.emoji-1F477-1F3FD { background-position: -580px -80px; }
+.emoji-1F477-1F3FE { background-position: -580px -100px; }
+.emoji-1F477-1F3FF { background-position: -580px -120px; }
+.emoji-1F478 { background-position: -580px -140px; }
+.emoji-1F478-1F3FB { background-position: -580px -160px; }
+.emoji-1F478-1F3FC { background-position: -580px -180px; }
+.emoji-1F478-1F3FD { background-position: -580px -200px; }
+.emoji-1F478-1F3FE { background-position: -580px -220px; }
+.emoji-1F478-1F3FF { background-position: -580px -240px; }
+.emoji-1F479 { background-position: -580px -260px; }
+.emoji-1F47A { background-position: -580px -280px; }
+.emoji-1F47B { background-position: -580px -300px; }
+.emoji-1F47C { background-position: -580px -320px; }
+.emoji-1F47C-1F3FB { background-position: -580px -340px; }
+.emoji-1F47C-1F3FC { background-position: -580px -360px; }
+.emoji-1F47C-1F3FD { background-position: -580px -380px; }
+.emoji-1F47C-1F3FE { background-position: -580px -400px; }
+.emoji-1F47C-1F3FF { background-position: -580px -420px; }
+.emoji-1F47D { background-position: -580px -440px; }
+.emoji-1F47E { background-position: -580px -460px; }
+.emoji-1F47F { background-position: -580px -480px; }
+.emoji-1F480 { background-position: -580px -500px; }
+.emoji-1F481 { background-position: -580px -520px; }
+.emoji-1F481-1F3FB { background-position: -580px -540px; }
+.emoji-1F481-1F3FC { background-position: -580px -560px; }
+.emoji-1F481-1F3FD { background-position: 0 -580px; }
+.emoji-1F481-1F3FE { background-position: -20px -580px; }
+.emoji-1F481-1F3FF { background-position: -40px -580px; }
+.emoji-1F482 { background-position: -60px -580px; }
+.emoji-1F482-1F3FB { background-position: -80px -580px; }
+.emoji-1F482-1F3FC { background-position: -100px -580px; }
+.emoji-1F482-1F3FD { background-position: -120px -580px; }
+.emoji-1F482-1F3FE { background-position: -140px -580px; }
+.emoji-1F482-1F3FF { background-position: -160px -580px; }
+.emoji-1F483 { background-position: -180px -580px; }
+.emoji-1F483-1F3FB { background-position: -200px -580px; }
+.emoji-1F483-1F3FC { background-position: -220px -580px; }
+.emoji-1F483-1F3FD { background-position: -240px -580px; }
+.emoji-1F483-1F3FE { background-position: -260px -580px; }
+.emoji-1F483-1F3FF { background-position: -280px -580px; }
+.emoji-1F484 { background-position: -300px -580px; }
+.emoji-1F485 { background-position: -320px -580px; }
+.emoji-1F485-1F3FB { background-position: -340px -580px; }
+.emoji-1F485-1F3FC { background-position: -360px -580px; }
+.emoji-1F485-1F3FD { background-position: -380px -580px; }
+.emoji-1F485-1F3FE { background-position: -400px -580px; }
+.emoji-1F485-1F3FF { background-position: -420px -580px; }
+.emoji-1F486 { background-position: -440px -580px; }
+.emoji-1F486-1F3FB { background-position: -460px -580px; }
+.emoji-1F486-1F3FC { background-position: -480px -580px; }
+.emoji-1F486-1F3FD { background-position: -500px -580px; }
+.emoji-1F486-1F3FE { background-position: -520px -580px; }
+.emoji-1F486-1F3FF { background-position: -540px -580px; }
+.emoji-1F487 { background-position: -560px -580px; }
+.emoji-1F487-1F3FB { background-position: -580px -580px; }
+.emoji-1F487-1F3FC { background-position: -600px 0; }
+.emoji-1F487-1F3FD { background-position: -600px -20px; }
+.emoji-1F487-1F3FE { background-position: -600px -40px; }
+.emoji-1F487-1F3FF { background-position: -600px -60px; }
+.emoji-1F488 { background-position: -600px -80px; }
+.emoji-1F489 { background-position: -600px -100px; }
+.emoji-1F48A { background-position: -600px -120px; }
+.emoji-1F48B { background-position: -600px -140px; }
+.emoji-1F48C { background-position: -600px -160px; }
+.emoji-1F48D { background-position: -600px -180px; }
+.emoji-1F48E { background-position: -600px -200px; }
+.emoji-1F48F { background-position: -600px -220px; }
+.emoji-1F490 { background-position: -600px -240px; }
+.emoji-1F491 { background-position: -600px -260px; }
+.emoji-1F492 { background-position: -600px -280px; }
+.emoji-1F493 { background-position: -600px -300px; }
+.emoji-1F494 { background-position: -600px -320px; }
+.emoji-1F495 { background-position: -600px -340px; }
+.emoji-1F496 { background-position: -600px -360px; }
+.emoji-1F497 { background-position: -600px -380px; }
+.emoji-1F498 { background-position: -600px -400px; }
+.emoji-1F499 { background-position: -600px -420px; }
+.emoji-1F49A { background-position: -600px -440px; }
+.emoji-1F49B { background-position: -600px -460px; }
+.emoji-1F49C { background-position: -600px -480px; }
+.emoji-1F49D { background-position: -600px -500px; }
+.emoji-1F49E { background-position: -600px -520px; }
+.emoji-1F49F { background-position: -600px -540px; }
+.emoji-1F4A0 { background-position: -600px -560px; }
+.emoji-1F4A1 { background-position: -600px -580px; }
+.emoji-1F4A2 { background-position: 0 -600px; }
+.emoji-1F4A3 { background-position: -20px -600px; }
+.emoji-1F4A4 { background-position: -40px -600px; }
+.emoji-1F4A5 { background-position: -60px -600px; }
+.emoji-1F4A6 { background-position: -80px -600px; }
+.emoji-1F4A7 { background-position: -100px -600px; }
+.emoji-1F4A8 { background-position: -120px -600px; }
+.emoji-1F4A9 { background-position: -140px -600px; }
+.emoji-1F4AA { background-position: -160px -600px; }
+.emoji-1F4AA-1F3FB { background-position: -180px -600px; }
+.emoji-1F4AA-1F3FC { background-position: -200px -600px; }
+.emoji-1F4AA-1F3FD { background-position: -220px -600px; }
+.emoji-1F4AA-1F3FE { background-position: -240px -600px; }
+.emoji-1F4AA-1F3FF { background-position: -260px -600px; }
+.emoji-1F4AB { background-position: -280px -600px; }
+.emoji-1F4AC { background-position: -300px -600px; }
+.emoji-1F4AD { background-position: -320px -600px; }
+.emoji-1F4AE { background-position: -340px -600px; }
+.emoji-1F4AF { background-position: -360px -600px; }
+.emoji-1F4B0 { background-position: -380px -600px; }
+.emoji-1F4B1 { background-position: -400px -600px; }
+.emoji-1F4B2 { background-position: -420px -600px; }
+.emoji-1F4B3 { background-position: -440px -600px; }
+.emoji-1F4B4 { background-position: -460px -600px; }
+.emoji-1F4B5 { background-position: -480px -600px; }
+.emoji-1F4B6 { background-position: -500px -600px; }
+.emoji-1F4B7 { background-position: -520px -600px; }
+.emoji-1F4B8 { background-position: -540px -600px; }
+.emoji-1F4B9 { background-position: -560px -600px; }
+.emoji-1F4BA { background-position: -580px -600px; }
+.emoji-1F4BB { background-position: -600px -600px; }
+.emoji-1F4BC { background-position: -620px 0; }
+.emoji-1F4BD { background-position: -620px -20px; }
+.emoji-1F4BE { background-position: -620px -40px; }
+.emoji-1F4BF { background-position: -620px -60px; }
+.emoji-1F4C0 { background-position: -620px -80px; }
+.emoji-1F4C1 { background-position: -620px -100px; }
+.emoji-1F4C2 { background-position: -620px -120px; }
+.emoji-1F4C3 { background-position: -620px -140px; }
+.emoji-1F4C4 { background-position: -620px -160px; }
+.emoji-1F4C5 { background-position: -620px -180px; }
+.emoji-1F4C6 { background-position: -620px -200px; }
+.emoji-1F4C7 { background-position: -620px -220px; }
+.emoji-1F4C8 { background-position: -620px -240px; }
+.emoji-1F4C9 { background-position: -620px -260px; }
+.emoji-1F4CA { background-position: -620px -280px; }
+.emoji-1F4CB { background-position: -620px -300px; }
+.emoji-1F4CC { background-position: -620px -320px; }
+.emoji-1F4CD { background-position: -620px -340px; }
+.emoji-1F4CE { background-position: -620px -360px; }
+.emoji-1F4CF { background-position: -620px -380px; }
+.emoji-1F4D0 { background-position: -620px -400px; }
+.emoji-1F4D1 { background-position: -620px -420px; }
+.emoji-1F4D2 { background-position: -620px -440px; }
+.emoji-1F4D3 { background-position: -620px -460px; }
+.emoji-1F4D4 { background-position: -620px -480px; }
+.emoji-1F4D5 { background-position: -620px -500px; }
+.emoji-1F4D6 { background-position: -620px -520px; }
+.emoji-1F4D7 { background-position: -620px -540px; }
+.emoji-1F4D8 { background-position: -620px -560px; }
+.emoji-1F4D9 { background-position: -620px -580px; }
+.emoji-1F4DA { background-position: -620px -600px; }
+.emoji-1F4DB { background-position: 0 -620px; }
+.emoji-1F4DC { background-position: -20px -620px; }
+.emoji-1F4DD { background-position: -40px -620px; }
+.emoji-1F4DE { background-position: -60px -620px; }
+.emoji-1F4DF { background-position: -80px -620px; }
+.emoji-1F4E0 { background-position: -100px -620px; }
+.emoji-1F4E1 { background-position: -120px -620px; }
+.emoji-1F4E2 { background-position: -140px -620px; }
+.emoji-1F4E3 { background-position: -160px -620px; }
+.emoji-1F4E4 { background-position: -180px -620px; }
+.emoji-1F4E5 { background-position: -200px -620px; }
+.emoji-1F4E6 { background-position: -220px -620px; }
+.emoji-1F4E7 { background-position: -240px -620px; }
+.emoji-1F4E8 { background-position: -260px -620px; }
+.emoji-1F4E9 { background-position: -280px -620px; }
+.emoji-1F4EA { background-position: -300px -620px; }
+.emoji-1F4EB { background-position: -320px -620px; }
+.emoji-1F4EC { background-position: -340px -620px; }
+.emoji-1F4ED { background-position: -360px -620px; }
+.emoji-1F4EE { background-position: -380px -620px; }
+.emoji-1F4EF { background-position: -400px -620px; }
+.emoji-1F4F0 { background-position: -420px -620px; }
+.emoji-1F4F1 { background-position: -440px -620px; }
+.emoji-1F4F2 { background-position: -460px -620px; }
+.emoji-1F4F3 { background-position: -480px -620px; }
+.emoji-1F4F4 { background-position: -500px -620px; }
+.emoji-1F4F5 { background-position: -520px -620px; }
+.emoji-1F4F6 { background-position: -540px -620px; }
+.emoji-1F4F7 { background-position: -560px -620px; }
+.emoji-1F4F8 { background-position: -580px -620px; }
+.emoji-1F4F9 { background-position: -600px -620px; }
+.emoji-1F4FA { background-position: -620px -620px; }
+.emoji-1F4FB { background-position: -640px 0; }
+.emoji-1F4FC { background-position: -640px -20px; }
+.emoji-1F4FD { background-position: -640px -40px; }
+.emoji-1F4FF { background-position: -640px -60px; }
+.emoji-1F500 { background-position: -640px -80px; }
+.emoji-1F501 { background-position: -640px -100px; }
+.emoji-1F502 { background-position: -640px -120px; }
+.emoji-1F503 { background-position: -640px -140px; }
+.emoji-1F504 { background-position: -640px -160px; }
+.emoji-1F505 { background-position: -640px -180px; }
+.emoji-1F506 { background-position: -640px -200px; }
+.emoji-1F507 { background-position: -640px -220px; }
+.emoji-1F508 { background-position: -640px -240px; }
+.emoji-1F509 { background-position: -640px -260px; }
+.emoji-1F50A { background-position: -640px -280px; }
+.emoji-1F50B { background-position: -640px -300px; }
+.emoji-1F50C { background-position: -640px -320px; }
+.emoji-1F50D { background-position: -640px -340px; }
+.emoji-1F50E { background-position: -640px -360px; }
+.emoji-1F50F { background-position: -640px -380px; }
+.emoji-1F510 { background-position: -640px -400px; }
+.emoji-1F511 { background-position: -640px -420px; }
+.emoji-1F512 { background-position: -640px -440px; }
+.emoji-1F513 { background-position: -640px -460px; }
+.emoji-1F514 { background-position: -640px -480px; }
+.emoji-1F515 { background-position: -640px -500px; }
+.emoji-1F516 { background-position: -640px -520px; }
+.emoji-1F517 { background-position: -640px -540px; }
+.emoji-1F518 { background-position: -640px -560px; }
+.emoji-1F519 { background-position: -640px -580px; }
+.emoji-1F51A { background-position: -640px -600px; }
+.emoji-1F51B { background-position: -640px -620px; }
+.emoji-1F51C { background-position: 0 -640px; }
+.emoji-1F51D { background-position: -20px -640px; }
+.emoji-1F51E { background-position: -40px -640px; }
+.emoji-1F51F { background-position: -60px -640px; }
+.emoji-1F520 { background-position: -80px -640px; }
+.emoji-1F521 { background-position: -100px -640px; }
+.emoji-1F522 { background-position: -120px -640px; }
+.emoji-1F523 { background-position: -140px -640px; }
+.emoji-1F524 { background-position: -160px -640px; }
+.emoji-1F525 { background-position: -180px -640px; }
+.emoji-1F526 { background-position: -200px -640px; }
+.emoji-1F527 { background-position: -220px -640px; }
+.emoji-1F528 { background-position: -240px -640px; }
+.emoji-1F529 { background-position: -260px -640px; }
+.emoji-1F52A { background-position: -280px -640px; }
+.emoji-1F52B { background-position: -300px -640px; }
+.emoji-1F52C { background-position: -320px -640px; }
+.emoji-1F52D { background-position: -340px -640px; }
+.emoji-1F52E { background-position: -360px -640px; }
+.emoji-1F52F { background-position: -380px -640px; }
+.emoji-1F530 { background-position: -400px -640px; }
+.emoji-1F531 { background-position: -420px -640px; }
+.emoji-1F532 { background-position: -440px -640px; }
+.emoji-1F533 { background-position: -460px -640px; }
+.emoji-1F534 { background-position: -480px -640px; }
+.emoji-1F535 { background-position: -500px -640px; }
+.emoji-1F536 { background-position: -520px -640px; }
+.emoji-1F537 { background-position: -540px -640px; }
+.emoji-1F538 { background-position: -560px -640px; }
+.emoji-1F539 { background-position: -580px -640px; }
+.emoji-1F53A { background-position: -600px -640px; }
+.emoji-1F53B { background-position: -620px -640px; }
+.emoji-1F53C { background-position: -640px -640px; }
+.emoji-1F53D { background-position: -660px 0; }
+.emoji-1F549 { background-position: -660px -20px; }
+.emoji-1F54A { background-position: -660px -40px; }
+.emoji-1F54B { background-position: -660px -60px; }
+.emoji-1F54C { background-position: -660px -80px; }
+.emoji-1F54D { background-position: -660px -100px; }
+.emoji-1F54E { background-position: -660px -120px; }
+.emoji-1F550 { background-position: -660px -140px; }
+.emoji-1F551 { background-position: -660px -160px; }
+.emoji-1F552 { background-position: -660px -180px; }
+.emoji-1F553 { background-position: -660px -200px; }
+.emoji-1F554 { background-position: -660px -220px; }
+.emoji-1F555 { background-position: -660px -240px; }
+.emoji-1F556 { background-position: -660px -260px; }
+.emoji-1F557 { background-position: -660px -280px; }
+.emoji-1F558 { background-position: -660px -300px; }
+.emoji-1F559 { background-position: -660px -320px; }
+.emoji-1F55A { background-position: -660px -340px; }
+.emoji-1F55B { background-position: -660px -360px; }
+.emoji-1F55C { background-position: -660px -380px; }
+.emoji-1F55D { background-position: -660px -400px; }
+.emoji-1F55E { background-position: -660px -420px; }
+.emoji-1F55F { background-position: -660px -440px; }
+.emoji-1F560 { background-position: -660px -460px; }
+.emoji-1F561 { background-position: -660px -480px; }
+.emoji-1F562 { background-position: -660px -500px; }
+.emoji-1F563 { background-position: -660px -520px; }
+.emoji-1F564 { background-position: -660px -540px; }
+.emoji-1F565 { background-position: -660px -560px; }
+.emoji-1F566 { background-position: -660px -580px; }
+.emoji-1F567 { background-position: -660px -600px; }
+.emoji-1F56F { background-position: -660px -620px; }
+.emoji-1F570 { background-position: -660px -640px; }
+.emoji-1F573 { background-position: 0 -660px; }
+.emoji-1F574 { background-position: -20px -660px; }
+.emoji-1F575 { background-position: -40px -660px; }
+.emoji-1F575-1F3FB { background-position: -60px -660px; }
+.emoji-1F575-1F3FC { background-position: -80px -660px; }
+.emoji-1F575-1F3FD { background-position: -100px -660px; }
+.emoji-1F575-1F3FE { background-position: -120px -660px; }
+.emoji-1F575-1F3FF { background-position: -140px -660px; }
+.emoji-1F576 { background-position: -160px -660px; }
+.emoji-1F577 { background-position: -180px -660px; }
+.emoji-1F578 { background-position: -200px -660px; }
+.emoji-1F579 { background-position: -220px -660px; }
+.emoji-1F57A { background-position: -240px -660px; }
+.emoji-1F57A-1F3FB { background-position: -260px -660px; }
+.emoji-1F57A-1F3FC { background-position: -280px -660px; }
+.emoji-1F57A-1F3FD { background-position: -300px -660px; }
+.emoji-1F57A-1F3FE { background-position: -320px -660px; }
+.emoji-1F57A-1F3FF { background-position: -340px -660px; }
+.emoji-1F587 { background-position: -360px -660px; }
+.emoji-1F58A { background-position: -380px -660px; }
+.emoji-1F58B { background-position: -400px -660px; }
+.emoji-1F58C { background-position: -420px -660px; }
+.emoji-1F58D { background-position: -440px -660px; }
+.emoji-1F590 { background-position: -460px -660px; }
+.emoji-1F590-1F3FB { background-position: -480px -660px; }
+.emoji-1F590-1F3FC { background-position: -500px -660px; }
+.emoji-1F590-1F3FD { background-position: -520px -660px; }
+.emoji-1F590-1F3FE { background-position: -540px -660px; }
+.emoji-1F590-1F3FF { background-position: -560px -660px; }
+.emoji-1F595 { background-position: -580px -660px; }
+.emoji-1F595-1F3FB { background-position: -600px -660px; }
+.emoji-1F595-1F3FC { background-position: -620px -660px; }
+.emoji-1F595-1F3FD { background-position: -640px -660px; }
+.emoji-1F595-1F3FE { background-position: -660px -660px; }
+.emoji-1F595-1F3FF { background-position: -680px 0; }
+.emoji-1F596 { background-position: -680px -20px; }
+.emoji-1F596-1F3FB { background-position: -680px -40px; }
+.emoji-1F596-1F3FC { background-position: -680px -60px; }
+.emoji-1F596-1F3FD { background-position: -680px -80px; }
+.emoji-1F596-1F3FE { background-position: -680px -100px; }
+.emoji-1F596-1F3FF { background-position: -680px -120px; }
+.emoji-1F5A4 { background-position: -680px -140px; }
+.emoji-1F5A5 { background-position: -680px -160px; }
+.emoji-1F5A8 { background-position: -680px -180px; }
+.emoji-1F5B1 { background-position: -680px -200px; }
+.emoji-1F5B2 { background-position: -680px -220px; }
+.emoji-1F5BC { background-position: -680px -240px; }
+.emoji-1F5C2 { background-position: -680px -260px; }
+.emoji-1F5C3 { background-position: -680px -280px; }
+.emoji-1F5C4 { background-position: -680px -300px; }
+.emoji-1F5D1 { background-position: -680px -320px; }
+.emoji-1F5D2 { background-position: -680px -340px; }
+.emoji-1F5D3 { background-position: -680px -360px; }
+.emoji-1F5DC { background-position: -680px -380px; }
+.emoji-1F5DD { background-position: -680px -400px; }
+.emoji-1F5DE { background-position: -680px -420px; }
+.emoji-1F5E1 { background-position: -680px -440px; }
+.emoji-1F5E3 { background-position: -680px -460px; }
+.emoji-1F5EF { background-position: -680px -480px; }
+.emoji-1F5F3 { background-position: -680px -500px; }
+.emoji-1F5FA { background-position: -680px -520px; }
+.emoji-1F5FB { background-position: -680px -540px; }
+.emoji-1F5FC { background-position: -680px -560px; }
+.emoji-1F5FD { background-position: -680px -580px; }
+.emoji-1F5FE { background-position: -680px -600px; }
+.emoji-1F5FF { background-position: -680px -620px; }
+.emoji-1F600 { background-position: -680px -640px; }
+.emoji-1F601 { background-position: -680px -660px; }
+.emoji-1F602 { background-position: 0 -680px; }
+.emoji-1F603 { background-position: -20px -680px; }
+.emoji-1F604 { background-position: -40px -680px; }
+.emoji-1F605 { background-position: -60px -680px; }
+.emoji-1F606 { background-position: -80px -680px; }
+.emoji-1F607 { background-position: -100px -680px; }
+.emoji-1F608 { background-position: -120px -680px; }
+.emoji-1F609 { background-position: -140px -680px; }
+.emoji-1F60A { background-position: -160px -680px; }
+.emoji-1F60B { background-position: -180px -680px; }
+.emoji-1F60C { background-position: -200px -680px; }
+.emoji-1F60D { background-position: -220px -680px; }
+.emoji-1F60E { background-position: -240px -680px; }
+.emoji-1F60F { background-position: -260px -680px; }
+.emoji-1F610 { background-position: -280px -680px; }
+.emoji-1F611 { background-position: -300px -680px; }
+.emoji-1F612 { background-position: -320px -680px; }
+.emoji-1F613 { background-position: -340px -680px; }
+.emoji-1F614 { background-position: -360px -680px; }
+.emoji-1F615 { background-position: -380px -680px; }
+.emoji-1F616 { background-position: -400px -680px; }
+.emoji-1F617 { background-position: -420px -680px; }
+.emoji-1F618 { background-position: -440px -680px; }
+.emoji-1F619 { background-position: -460px -680px; }
+.emoji-1F61A { background-position: -480px -680px; }
+.emoji-1F61B { background-position: -500px -680px; }
+.emoji-1F61C { background-position: -520px -680px; }
+.emoji-1F61D { background-position: -540px -680px; }
+.emoji-1F61E { background-position: -560px -680px; }
+.emoji-1F61F { background-position: -580px -680px; }
+.emoji-1F620 { background-position: -600px -680px; }
+.emoji-1F621 { background-position: -620px -680px; }
+.emoji-1F622 { background-position: -640px -680px; }
+.emoji-1F623 { background-position: -660px -680px; }
+.emoji-1F624 { background-position: -680px -680px; }
+.emoji-1F625 { background-position: -700px 0; }
+.emoji-1F626 { background-position: -700px -20px; }
+.emoji-1F627 { background-position: -700px -40px; }
+.emoji-1F628 { background-position: -700px -60px; }
+.emoji-1F629 { background-position: -700px -80px; }
+.emoji-1F62A { background-position: -700px -100px; }
+.emoji-1F62B { background-position: -700px -120px; }
+.emoji-1F62C { background-position: -700px -140px; }
+.emoji-1F62D { background-position: -700px -160px; }
+.emoji-1F62E { background-position: -700px -180px; }
+.emoji-1F62F { background-position: -700px -200px; }
+.emoji-1F630 { background-position: -700px -220px; }
+.emoji-1F631 { background-position: -700px -240px; }
+.emoji-1F632 { background-position: -700px -260px; }
+.emoji-1F633 { background-position: -700px -280px; }
+.emoji-1F634 { background-position: -700px -300px; }
+.emoji-1F635 { background-position: -700px -320px; }
+.emoji-1F636 { background-position: -700px -340px; }
+.emoji-1F637 { background-position: -700px -360px; }
+.emoji-1F638 { background-position: -700px -380px; }
+.emoji-1F639 { background-position: -700px -400px; }
+.emoji-1F63A { background-position: -700px -420px; }
+.emoji-1F63B { background-position: -700px -440px; }
+.emoji-1F63C { background-position: -700px -460px; }
+.emoji-1F63D { background-position: -700px -480px; }
+.emoji-1F63E { background-position: -700px -500px; }
+.emoji-1F63F { background-position: -700px -520px; }
+.emoji-1F640 { background-position: -700px -540px; }
+.emoji-1F641 { background-position: -700px -560px; }
+.emoji-1F642 { background-position: -700px -580px; }
+.emoji-1F643 { background-position: -700px -600px; }
+.emoji-1F644 { background-position: -700px -620px; }
+.emoji-1F645 { background-position: -700px -640px; }
+.emoji-1F645-1F3FB { background-position: -700px -660px; }
+.emoji-1F645-1F3FC { background-position: -700px -680px; }
+.emoji-1F645-1F3FD { background-position: 0 -700px; }
+.emoji-1F645-1F3FE { background-position: -20px -700px; }
+.emoji-1F645-1F3FF { background-position: -40px -700px; }
+.emoji-1F646 { background-position: -60px -700px; }
+.emoji-1F646-1F3FB { background-position: -80px -700px; }
+.emoji-1F646-1F3FC { background-position: -100px -700px; }
+.emoji-1F646-1F3FD { background-position: -120px -700px; }
+.emoji-1F646-1F3FE { background-position: -140px -700px; }
+.emoji-1F646-1F3FF { background-position: -160px -700px; }
+.emoji-1F647 { background-position: -180px -700px; }
+.emoji-1F647-1F3FB { background-position: -200px -700px; }
+.emoji-1F647-1F3FC { background-position: -220px -700px; }
+.emoji-1F647-1F3FD { background-position: -240px -700px; }
+.emoji-1F647-1F3FE { background-position: -260px -700px; }
+.emoji-1F647-1F3FF { background-position: -280px -700px; }
+.emoji-1F648 { background-position: -300px -700px; }
+.emoji-1F649 { background-position: -320px -700px; }
+.emoji-1F64A { background-position: -340px -700px; }
+.emoji-1F64B { background-position: -360px -700px; }
+.emoji-1F64B-1F3FB { background-position: -380px -700px; }
+.emoji-1F64B-1F3FC { background-position: -400px -700px; }
+.emoji-1F64B-1F3FD { background-position: -420px -700px; }
+.emoji-1F64B-1F3FE { background-position: -440px -700px; }
+.emoji-1F64B-1F3FF { background-position: -460px -700px; }
+.emoji-1F64C { background-position: -480px -700px; }
+.emoji-1F64C-1F3FB { background-position: -500px -700px; }
+.emoji-1F64C-1F3FC { background-position: -520px -700px; }
+.emoji-1F64C-1F3FD { background-position: -540px -700px; }
+.emoji-1F64C-1F3FE { background-position: -560px -700px; }
+.emoji-1F64C-1F3FF { background-position: -580px -700px; }
+.emoji-1F64D { background-position: -600px -700px; }
+.emoji-1F64D-1F3FB { background-position: -620px -700px; }
+.emoji-1F64D-1F3FC { background-position: -640px -700px; }
+.emoji-1F64D-1F3FD { background-position: -660px -700px; }
+.emoji-1F64D-1F3FE { background-position: -680px -700px; }
+.emoji-1F64D-1F3FF { background-position: -700px -700px; }
+.emoji-1F64E { background-position: -720px 0; }
+.emoji-1F64E-1F3FB { background-position: -720px -20px; }
+.emoji-1F64E-1F3FC { background-position: -720px -40px; }
+.emoji-1F64E-1F3FD { background-position: -720px -60px; }
+.emoji-1F64E-1F3FE { background-position: -720px -80px; }
+.emoji-1F64E-1F3FF { background-position: -720px -100px; }
+.emoji-1F64F { background-position: -720px -120px; }
+.emoji-1F64F-1F3FB { background-position: -720px -140px; }
+.emoji-1F64F-1F3FC { background-position: -720px -160px; }
+.emoji-1F64F-1F3FD { background-position: -720px -180px; }
+.emoji-1F64F-1F3FE { background-position: -720px -200px; }
+.emoji-1F64F-1F3FF { background-position: -720px -220px; }
+.emoji-1F680 { background-position: -720px -240px; }
+.emoji-1F681 { background-position: -720px -260px; }
+.emoji-1F682 { background-position: -720px -280px; }
+.emoji-1F683 { background-position: -720px -300px; }
+.emoji-1F684 { background-position: -720px -320px; }
+.emoji-1F685 { background-position: -720px -340px; }
+.emoji-1F686 { background-position: -720px -360px; }
+.emoji-1F687 { background-position: -720px -380px; }
+.emoji-1F688 { background-position: -720px -400px; }
+.emoji-1F689 { background-position: -720px -420px; }
+.emoji-1F68A { background-position: -720px -440px; }
+.emoji-1F68B { background-position: -720px -460px; }
+.emoji-1F68C { background-position: -720px -480px; }
+.emoji-1F68D { background-position: -720px -500px; }
+.emoji-1F68E { background-position: -720px -520px; }
+.emoji-1F68F { background-position: -720px -540px; }
+.emoji-1F690 { background-position: -720px -560px; }
+.emoji-1F691 { background-position: -720px -580px; }
+.emoji-1F692 { background-position: -720px -600px; }
+.emoji-1F693 { background-position: -720px -620px; }
+.emoji-1F694 { background-position: -720px -640px; }
+.emoji-1F695 { background-position: -720px -660px; }
+.emoji-1F696 { background-position: -720px -680px; }
+.emoji-1F697 { background-position: -720px -700px; }
+.emoji-1F698 { background-position: 0 -720px; }
+.emoji-1F699 { background-position: -20px -720px; }
+.emoji-1F69A { background-position: -40px -720px; }
+.emoji-1F69B { background-position: -60px -720px; }
+.emoji-1F69C { background-position: -80px -720px; }
+.emoji-1F69D { background-position: -100px -720px; }
+.emoji-1F69E { background-position: -120px -720px; }
+.emoji-1F69F { background-position: -140px -720px; }
+.emoji-1F6A0 { background-position: -160px -720px; }
+.emoji-1F6A1 { background-position: -180px -720px; }
+.emoji-1F6A2 { background-position: -200px -720px; }
+.emoji-1F6A3 { background-position: -220px -720px; }
+.emoji-1F6A3-1F3FB { background-position: -240px -720px; }
+.emoji-1F6A3-1F3FC { background-position: -260px -720px; }
+.emoji-1F6A3-1F3FD { background-position: -280px -720px; }
+.emoji-1F6A3-1F3FE { background-position: -300px -720px; }
+.emoji-1F6A3-1F3FF { background-position: -320px -720px; }
+.emoji-1F6A4 { background-position: -340px -720px; }
+.emoji-1F6A5 { background-position: -360px -720px; }
+.emoji-1F6A6 { background-position: -380px -720px; }
+.emoji-1F6A7 { background-position: -400px -720px; }
+.emoji-1F6A8 { background-position: -420px -720px; }
+.emoji-1F6A9 { background-position: -440px -720px; }
+.emoji-1F6AA { background-position: -460px -720px; }
+.emoji-1F6AB { background-position: -480px -720px; }
+.emoji-1F6AC { background-position: -500px -720px; }
+.emoji-1F6AD { background-position: -520px -720px; }
+.emoji-1F6AE { background-position: -540px -720px; }
+.emoji-1F6AF { background-position: -560px -720px; }
+.emoji-1F6B0 { background-position: -580px -720px; }
+.emoji-1F6B1 { background-position: -600px -720px; }
+.emoji-1F6B2 { background-position: -620px -720px; }
+.emoji-1F6B3 { background-position: -640px -720px; }
+.emoji-1F6B4 { background-position: -660px -720px; }
+.emoji-1F6B4-1F3FB { background-position: -680px -720px; }
+.emoji-1F6B4-1F3FC { background-position: -700px -720px; }
+.emoji-1F6B4-1F3FD { background-position: -720px -720px; }
+.emoji-1F6B4-1F3FE { background-position: -740px 0; }
+.emoji-1F6B4-1F3FF { background-position: -740px -20px; }
+.emoji-1F6B5 { background-position: -740px -40px; }
+.emoji-1F6B5-1F3FB { background-position: -740px -60px; }
+.emoji-1F6B5-1F3FC { background-position: -740px -80px; }
+.emoji-1F6B5-1F3FD { background-position: -740px -100px; }
+.emoji-1F6B5-1F3FE { background-position: -740px -120px; }
+.emoji-1F6B5-1F3FF { background-position: -740px -140px; }
+.emoji-1F6B6 { background-position: -740px -160px; }
+.emoji-1F6B6-1F3FB { background-position: -740px -180px; }
+.emoji-1F6B6-1F3FC { background-position: -740px -200px; }
+.emoji-1F6B6-1F3FD { background-position: -740px -220px; }
+.emoji-1F6B6-1F3FE { background-position: -740px -240px; }
+.emoji-1F6B6-1F3FF { background-position: -740px -260px; }
+.emoji-1F6B7 { background-position: -740px -280px; }
+.emoji-1F6B8 { background-position: -740px -300px; }
+.emoji-1F6B9 { background-position: -740px -320px; }
+.emoji-1F6BA { background-position: -740px -340px; }
+.emoji-1F6BB { background-position: -740px -360px; }
+.emoji-1F6BC { background-position: -740px -380px; }
+.emoji-1F6BD { background-position: -740px -400px; }
+.emoji-1F6BE { background-position: -740px -420px; }
+.emoji-1F6BF { background-position: -740px -440px; }
+.emoji-1F6C0 { background-position: -740px -460px; }
+.emoji-1F6C0-1F3FB { background-position: -740px -480px; }
+.emoji-1F6C0-1F3FC { background-position: -740px -500px; }
+.emoji-1F6C0-1F3FD { background-position: -740px -520px; }
+.emoji-1F6C0-1F3FE { background-position: -740px -540px; }
+.emoji-1F6C0-1F3FF { background-position: -740px -560px; }
+.emoji-1F6C1 { background-position: -740px -580px; }
+.emoji-1F6C2 { background-position: -740px -600px; }
+.emoji-1F6C3 { background-position: -740px -620px; }
+.emoji-1F6C4 { background-position: -740px -640px; }
+.emoji-1F6C5 { background-position: -740px -660px; }
+.emoji-1F6CB { background-position: -740px -680px; }
+.emoji-1F6CC { background-position: -740px -700px; }
+.emoji-1F6CD { background-position: -740px -720px; }
+.emoji-1F6CE { background-position: 0 -740px; }
+.emoji-1F6CF { background-position: -20px -740px; }
+.emoji-1F6D0 { background-position: -40px -740px; }
+.emoji-1F6D1 { background-position: -60px -740px; }
+.emoji-1F6D2 { background-position: -80px -740px; }
+.emoji-1F6E0 { background-position: -100px -740px; }
+.emoji-1F6E1 { background-position: -120px -740px; }
+.emoji-1F6E2 { background-position: -140px -740px; }
+.emoji-1F6E3 { background-position: -160px -740px; }
+.emoji-1F6E4 { background-position: -180px -740px; }
+.emoji-1F6E5 { background-position: -200px -740px; }
+.emoji-1F6E9 { background-position: -220px -740px; }
+.emoji-1F6EB { background-position: -240px -740px; }
+.emoji-1F6EC { background-position: -260px -740px; }
+.emoji-1F6F0 { background-position: -280px -740px; }
+.emoji-1F6F3 { background-position: -300px -740px; }
+.emoji-1F6F4 { background-position: -320px -740px; }
+.emoji-1F6F5 { background-position: -340px -740px; }
+.emoji-1F6F6 { background-position: -360px -740px; }
+.emoji-1F910 { background-position: -380px -740px; }
+.emoji-1F911 { background-position: -400px -740px; }
+.emoji-1F912 { background-position: -420px -740px; }
+.emoji-1F913 { background-position: -440px -740px; }
+.emoji-1F914 { background-position: -460px -740px; }
+.emoji-1F915 { background-position: -480px -740px; }
+.emoji-1F916 { background-position: -500px -740px; }
+.emoji-1F917 { background-position: -520px -740px; }
+.emoji-1F918 { background-position: -540px -740px; }
+.emoji-1F918-1F3FB { background-position: -560px -740px; }
+.emoji-1F918-1F3FC { background-position: -580px -740px; }
+.emoji-1F918-1F3FD { background-position: -600px -740px; }
+.emoji-1F918-1F3FE { background-position: -620px -740px; }
+.emoji-1F918-1F3FF { background-position: -640px -740px; }
+.emoji-1F919 { background-position: -660px -740px; }
+.emoji-1F919-1F3FB { background-position: -680px -740px; }
+.emoji-1F919-1F3FC { background-position: -700px -740px; }
+.emoji-1F919-1F3FD { background-position: -720px -740px; }
+.emoji-1F919-1F3FE { background-position: -740px -740px; }
+.emoji-1F919-1F3FF { background-position: -760px 0; }
+.emoji-1F91A { background-position: -760px -20px; }
+.emoji-1F91A-1F3FB { background-position: -760px -40px; }
+.emoji-1F91A-1F3FC { background-position: -760px -60px; }
+.emoji-1F91A-1F3FD { background-position: -760px -80px; }
+.emoji-1F91A-1F3FE { background-position: -760px -100px; }
+.emoji-1F91A-1F3FF { background-position: -760px -120px; }
+.emoji-1F91B { background-position: -760px -140px; }
+.emoji-1F91B-1F3FB { background-position: -760px -160px; }
+.emoji-1F91B-1F3FC { background-position: -760px -180px; }
+.emoji-1F91B-1F3FD { background-position: -760px -200px; }
+.emoji-1F91B-1F3FE { background-position: -760px -220px; }
+.emoji-1F91B-1F3FF { background-position: -760px -240px; }
+.emoji-1F91C { background-position: -760px -260px; }
+.emoji-1F91C-1F3FB { background-position: -760px -280px; }
+.emoji-1F91C-1F3FC { background-position: -760px -300px; }
+.emoji-1F91C-1F3FD { background-position: -760px -320px; }
+.emoji-1F91C-1F3FE { background-position: -760px -340px; }
+.emoji-1F91C-1F3FF { background-position: -760px -360px; }
+.emoji-1F91D { background-position: -760px -380px; }
+.emoji-1F91D-1F3FB { background-position: -760px -400px; }
+.emoji-1F91D-1F3FC { background-position: -760px -420px; }
+.emoji-1F91D-1F3FD { background-position: -760px -440px; }
+.emoji-1F91D-1F3FE { background-position: -760px -460px; }
+.emoji-1F91D-1F3FF { background-position: -760px -480px; }
+.emoji-1F91E { background-position: -760px -500px; }
+.emoji-1F91E-1F3FB { background-position: -760px -520px; }
+.emoji-1F91E-1F3FC { background-position: -760px -540px; }
+.emoji-1F91E-1F3FD { background-position: -760px -560px; }
+.emoji-1F91E-1F3FE { background-position: -760px -580px; }
+.emoji-1F91E-1F3FF { background-position: -760px -600px; }
+.emoji-1F920 { background-position: -760px -620px; }
+.emoji-1F921 { background-position: -760px -640px; }
+.emoji-1F922 { background-position: -760px -660px; }
+.emoji-1F923 { background-position: -760px -680px; }
+.emoji-1F924 { background-position: -760px -700px; }
+.emoji-1F925 { background-position: -760px -720px; }
+.emoji-1F926 { background-position: -760px -740px; }
+.emoji-1F926-1F3FB { background-position: 0 -760px; }
+.emoji-1F926-1F3FC { background-position: -20px -760px; }
+.emoji-1F926-1F3FD { background-position: -40px -760px; }
+.emoji-1F926-1F3FE { background-position: -60px -760px; }
+.emoji-1F926-1F3FF { background-position: -80px -760px; }
+.emoji-1F927 { background-position: -100px -760px; }
+.emoji-1F930 { background-position: -120px -760px; }
+.emoji-1F930-1F3FB { background-position: -140px -760px; }
+.emoji-1F930-1F3FC { background-position: -160px -760px; }
+.emoji-1F930-1F3FD { background-position: -180px -760px; }
+.emoji-1F930-1F3FE { background-position: -200px -760px; }
+.emoji-1F930-1F3FF { background-position: -220px -760px; }
+.emoji-1F933 { background-position: -240px -760px; }
+.emoji-1F933-1F3FB { background-position: -260px -760px; }
+.emoji-1F933-1F3FC { background-position: -280px -760px; }
+.emoji-1F933-1F3FD { background-position: -300px -760px; }
+.emoji-1F933-1F3FE { background-position: -320px -760px; }
+.emoji-1F933-1F3FF { background-position: -340px -760px; }
+.emoji-1F934 { background-position: -360px -760px; }
+.emoji-1F934-1F3FB { background-position: -380px -760px; }
+.emoji-1F934-1F3FC { background-position: -400px -760px; }
+.emoji-1F934-1F3FD { background-position: -420px -760px; }
+.emoji-1F934-1F3FE { background-position: -440px -760px; }
+.emoji-1F934-1F3FF { background-position: -460px -760px; }
+.emoji-1F935 { background-position: -480px -760px; }
+.emoji-1F935-1F3FB { background-position: -500px -760px; }
+.emoji-1F935-1F3FC { background-position: -520px -760px; }
+.emoji-1F935-1F3FD { background-position: -540px -760px; }
+.emoji-1F935-1F3FE { background-position: -560px -760px; }
+.emoji-1F935-1F3FF { background-position: -580px -760px; }
+.emoji-1F936 { background-position: -600px -760px; }
+.emoji-1F936-1F3FB { background-position: -620px -760px; }
+.emoji-1F936-1F3FC { background-position: -640px -760px; }
+.emoji-1F936-1F3FD { background-position: -660px -760px; }
+.emoji-1F936-1F3FE { background-position: -680px -760px; }
+.emoji-1F936-1F3FF { background-position: -700px -760px; }
+.emoji-1F937 { background-position: -720px -760px; }
+.emoji-1F937-1F3FB { background-position: -740px -760px; }
+.emoji-1F937-1F3FC { background-position: -760px -760px; }
+.emoji-1F937-1F3FD { background-position: -780px 0; }
+.emoji-1F937-1F3FE { background-position: -780px -20px; }
+.emoji-1F937-1F3FF { background-position: -780px -40px; }
+.emoji-1F938 { background-position: -780px -60px; }
+.emoji-1F938-1F3FB { background-position: -780px -80px; }
+.emoji-1F938-1F3FC { background-position: -780px -100px; }
+.emoji-1F938-1F3FD { background-position: -780px -120px; }
+.emoji-1F938-1F3FE { background-position: -780px -140px; }
+.emoji-1F938-1F3FF { background-position: -780px -160px; }
+.emoji-1F939 { background-position: -780px -180px; }
+.emoji-1F939-1F3FB { background-position: -780px -200px; }
+.emoji-1F939-1F3FC { background-position: -780px -220px; }
+.emoji-1F939-1F3FD { background-position: -780px -240px; }
+.emoji-1F939-1F3FE { background-position: -780px -260px; }
+.emoji-1F939-1F3FF { background-position: -780px -280px; }
+.emoji-1F93A { background-position: -780px -300px; }
+.emoji-1F93C { background-position: -780px -320px; }
+.emoji-1F93C-1F3FB { background-position: -780px -340px; }
+.emoji-1F93C-1F3FC { background-position: -780px -360px; }
+.emoji-1F93C-1F3FD { background-position: -780px -380px; }
+.emoji-1F93C-1F3FE { background-position: -780px -400px; }
+.emoji-1F93C-1F3FF { background-position: -780px -420px; }
+.emoji-1F93D { background-position: -780px -440px; }
+.emoji-1F93D-1F3FB { background-position: -780px -460px; }
+.emoji-1F93D-1F3FC { background-position: -780px -480px; }
+.emoji-1F93D-1F3FD { background-position: -780px -500px; }
+.emoji-1F93D-1F3FE { background-position: -780px -520px; }
+.emoji-1F93D-1F3FF { background-position: -780px -540px; }
+.emoji-1F93E { background-position: -780px -560px; }
+.emoji-1F93E-1F3FB { background-position: -780px -580px; }
+.emoji-1F93E-1F3FC { background-position: -780px -600px; }
+.emoji-1F93E-1F3FD { background-position: -780px -620px; }
+.emoji-1F93E-1F3FE { background-position: -780px -640px; }
+.emoji-1F93E-1F3FF { background-position: -780px -660px; }
+.emoji-1F940 { background-position: -780px -680px; }
+.emoji-1F941 { background-position: -780px -700px; }
+.emoji-1F942 { background-position: -780px -720px; }
+.emoji-1F943 { background-position: -780px -740px; }
+.emoji-1F944 { background-position: -780px -760px; }
+.emoji-1F945 { background-position: 0 -780px; }
+.emoji-1F947 { background-position: -20px -780px; }
+.emoji-1F948 { background-position: -40px -780px; }
+.emoji-1F949 { background-position: -60px -780px; }
+.emoji-1F94A { background-position: -80px -780px; }
+.emoji-1F94B { background-position: -100px -780px; }
+.emoji-1F950 { background-position: -120px -780px; }
+.emoji-1F951 { background-position: -140px -780px; }
+.emoji-1F952 { background-position: -160px -780px; }
+.emoji-1F953 { background-position: -180px -780px; }
+.emoji-1F954 { background-position: -200px -780px; }
+.emoji-1F955 { background-position: -220px -780px; }
+.emoji-1F956 { background-position: -240px -780px; }
+.emoji-1F957 { background-position: -260px -780px; }
+.emoji-1F958 { background-position: -280px -780px; }
+.emoji-1F959 { background-position: -300px -780px; }
+.emoji-1F95A { background-position: -320px -780px; }
+.emoji-1F95B { background-position: -340px -780px; }
+.emoji-1F95C { background-position: -360px -780px; }
+.emoji-1F95D { background-position: -380px -780px; }
+.emoji-1F95E { background-position: -400px -780px; }
+.emoji-1F980 { background-position: -420px -780px; }
+.emoji-1F981 { background-position: -440px -780px; }
+.emoji-1F982 { background-position: -460px -780px; }
+.emoji-1F983 { background-position: -480px -780px; }
+.emoji-1F984 { background-position: -500px -780px; }
+.emoji-1F985 { background-position: -520px -780px; }
+.emoji-1F986 { background-position: -540px -780px; }
+.emoji-1F987 { background-position: -560px -780px; }
+.emoji-1F988 { background-position: -580px -780px; }
+.emoji-1F989 { background-position: -600px -780px; }
+.emoji-1F98A { background-position: -620px -780px; }
+.emoji-1F98B { background-position: -640px -780px; }
+.emoji-1F98C { background-position: -660px -780px; }
+.emoji-1F98D { background-position: -680px -780px; }
+.emoji-1F98E { background-position: -700px -780px; }
+.emoji-1F98F { background-position: -720px -780px; }
+.emoji-1F990 { background-position: -740px -780px; }
+.emoji-1F991 { background-position: -760px -780px; }
+.emoji-1F9C0 { background-position: -780px -780px; }
+.emoji-203C { background-position: -800px 0; }
+.emoji-2049 { background-position: -800px -20px; }
+.emoji-2122 { background-position: -800px -40px; }
+.emoji-2139 { background-position: -800px -60px; }
+.emoji-2194 { background-position: -800px -80px; }
+.emoji-2195 { background-position: -800px -100px; }
+.emoji-2196 { background-position: -800px -120px; }
+.emoji-2197 { background-position: -800px -140px; }
+.emoji-2198 { background-position: -800px -160px; }
+.emoji-2199 { background-position: -800px -180px; }
+.emoji-21A9 { background-position: -800px -200px; }
+.emoji-21AA { background-position: -800px -220px; }
+.emoji-231A { background-position: -800px -240px; }
+.emoji-231B { background-position: -800px -260px; }
+.emoji-2328 { background-position: -800px -280px; }
+.emoji-23CF { background-position: -800px -300px; }
+.emoji-23E9 { background-position: -800px -320px; }
+.emoji-23EA { background-position: -800px -340px; }
+.emoji-23EB { background-position: -800px -360px; }
+.emoji-23EC { background-position: -800px -380px; }
+.emoji-23ED { background-position: -800px -400px; }
+.emoji-23EE { background-position: -800px -420px; }
+.emoji-23EF { background-position: -800px -440px; }
+.emoji-23F0 { background-position: -800px -460px; }
+.emoji-23F1 { background-position: -800px -480px; }
+.emoji-23F2 { background-position: -800px -500px; }
+.emoji-23F3 { background-position: -800px -520px; }
+.emoji-23F8 { background-position: -800px -540px; }
+.emoji-23F9 { background-position: -800px -560px; }
+.emoji-23FA { background-position: -800px -580px; }
+.emoji-24C2 { background-position: -800px -600px; }
+.emoji-25AA { background-position: -800px -620px; }
+.emoji-25AB { background-position: -800px -640px; }
+.emoji-25B6 { background-position: -800px -660px; }
+.emoji-25C0 { background-position: -800px -680px; }
+.emoji-25FB { background-position: -800px -700px; }
+.emoji-25FC { background-position: -800px -720px; }
+.emoji-25FD { background-position: -800px -740px; }
+.emoji-25FE { background-position: -800px -760px; }
+.emoji-2600 { background-position: -800px -780px; }
+.emoji-2601 { background-position: 0 -800px; }
+.emoji-2602 { background-position: -20px -800px; }
+.emoji-2603 { background-position: -40px -800px; }
+.emoji-2604 { background-position: -60px -800px; }
+.emoji-260E { background-position: -80px -800px; }
+.emoji-2611 { background-position: -100px -800px; }
+.emoji-2614 { background-position: -120px -800px; }
+.emoji-2615 { background-position: -140px -800px; }
+.emoji-2618 { background-position: -160px -800px; }
+.emoji-261D { background-position: -180px -800px; }
+.emoji-261D-1F3FB { background-position: -200px -800px; }
+.emoji-261D-1F3FC { background-position: -220px -800px; }
+.emoji-261D-1F3FD { background-position: -240px -800px; }
+.emoji-261D-1F3FE { background-position: -260px -800px; }
+.emoji-261D-1F3FF { background-position: -280px -800px; }
+.emoji-2620 { background-position: -300px -800px; }
+.emoji-2622 { background-position: -320px -800px; }
+.emoji-2623 { background-position: -340px -800px; }
+.emoji-2626 { background-position: -360px -800px; }
+.emoji-262A { background-position: -380px -800px; }
+.emoji-262E { background-position: -400px -800px; }
+.emoji-262F { background-position: -420px -800px; }
+.emoji-2638 { background-position: -440px -800px; }
+.emoji-2639 { background-position: -460px -800px; }
+.emoji-263A { background-position: -480px -800px; }
+.emoji-2648 { background-position: -500px -800px; }
+.emoji-2649 { background-position: -520px -800px; }
+.emoji-264A { background-position: -540px -800px; }
+.emoji-264B { background-position: -560px -800px; }
+.emoji-264C { background-position: -580px -800px; }
+.emoji-264D { background-position: -600px -800px; }
+.emoji-264E { background-position: -620px -800px; }
+.emoji-264F { background-position: -640px -800px; }
+.emoji-2650 { background-position: -660px -800px; }
+.emoji-2651 { background-position: -680px -800px; }
+.emoji-2652 { background-position: -700px -800px; }
+.emoji-2653 { background-position: -720px -800px; }
+.emoji-2660 { background-position: -740px -800px; }
+.emoji-2663 { background-position: -760px -800px; }
+.emoji-2665 { background-position: -780px -800px; }
+.emoji-2666 { background-position: -800px -800px; }
+.emoji-2668 { background-position: -820px 0; }
+.emoji-267B { background-position: -820px -20px; }
+.emoji-267F { background-position: -820px -40px; }
+.emoji-2692 { background-position: -820px -60px; }
+.emoji-2693 { background-position: -820px -80px; }
+.emoji-2694 { background-position: -820px -100px; }
+.emoji-2696 { background-position: -820px -120px; }
+.emoji-2697 { background-position: -820px -140px; }
+.emoji-2699 { background-position: -820px -160px; }
+.emoji-269B { background-position: -820px -180px; }
+.emoji-269C { background-position: -820px -200px; }
+.emoji-26A0 { background-position: -820px -220px; }
+.emoji-26A1 { background-position: -820px -240px; }
+.emoji-26AA { background-position: -820px -260px; }
+.emoji-26AB { background-position: -820px -280px; }
+.emoji-26B0 { background-position: -820px -300px; }
+.emoji-26B1 { background-position: -820px -320px; }
+.emoji-26BD { background-position: -820px -340px; }
+.emoji-26BE { background-position: -820px -360px; }
+.emoji-26C4 { background-position: -820px -380px; }
+.emoji-26C5 { background-position: -820px -400px; }
+.emoji-26C8 { background-position: -820px -420px; }
+.emoji-26CE { background-position: -820px -440px; }
+.emoji-26CF { background-position: -820px -460px; }
+.emoji-26D1 { background-position: -820px -480px; }
+.emoji-26D3 { background-position: -820px -500px; }
+.emoji-26D4 { background-position: -820px -520px; }
+.emoji-26E9 { background-position: -820px -540px; }
+.emoji-26EA { background-position: -820px -560px; }
+.emoji-26F0 { background-position: -820px -580px; }
+.emoji-26F1 { background-position: -820px -600px; }
+.emoji-26F2 { background-position: -820px -620px; }
+.emoji-26F3 { background-position: -820px -640px; }
+.emoji-26F4 { background-position: -820px -660px; }
+.emoji-26F5 { background-position: -820px -680px; }
+.emoji-26F7 { background-position: -820px -700px; }
+.emoji-26F8 { background-position: -820px -720px; }
+.emoji-26F9 { background-position: -820px -740px; }
+.emoji-26F9-1F3FB { background-position: -820px -760px; }
+.emoji-26F9-1F3FC { background-position: -820px -780px; }
+.emoji-26F9-1F3FD { background-position: -820px -800px; }
+.emoji-26F9-1F3FE { background-position: 0 -820px; }
+.emoji-26F9-1F3FF { background-position: -20px -820px; }
+.emoji-26FA { background-position: -40px -820px; }
+.emoji-26FD { background-position: -60px -820px; }
+.emoji-2702 { background-position: -80px -820px; }
+.emoji-2705 { background-position: -100px -820px; }
+.emoji-2708 { background-position: -120px -820px; }
+.emoji-2709 { background-position: -140px -820px; }
+.emoji-270A { background-position: -160px -820px; }
+.emoji-270A-1F3FB { background-position: -180px -820px; }
+.emoji-270A-1F3FC { background-position: -200px -820px; }
+.emoji-270A-1F3FD { background-position: -220px -820px; }
+.emoji-270A-1F3FE { background-position: -240px -820px; }
+.emoji-270A-1F3FF { background-position: -260px -820px; }
+.emoji-270B { background-position: -280px -820px; }
+.emoji-270B-1F3FB { background-position: -300px -820px; }
+.emoji-270B-1F3FC { background-position: -320px -820px; }
+.emoji-270B-1F3FD { background-position: -340px -820px; }
+.emoji-270B-1F3FE { background-position: -360px -820px; }
+.emoji-270B-1F3FF { background-position: -380px -820px; }
+.emoji-270C { background-position: -400px -820px; }
+.emoji-270C-1F3FB { background-position: -420px -820px; }
+.emoji-270C-1F3FC { background-position: -440px -820px; }
+.emoji-270C-1F3FD { background-position: -460px -820px; }
+.emoji-270C-1F3FE { background-position: -480px -820px; }
+.emoji-270C-1F3FF { background-position: -500px -820px; }
+.emoji-270D { background-position: -520px -820px; }
+.emoji-270D-1F3FB { background-position: -540px -820px; }
+.emoji-270D-1F3FC { background-position: -560px -820px; }
+.emoji-270D-1F3FD { background-position: -580px -820px; }
+.emoji-270D-1F3FE { background-position: -600px -820px; }
+.emoji-270D-1F3FF { background-position: -620px -820px; }
+.emoji-270F { background-position: -640px -820px; }
+.emoji-2712 { background-position: -660px -820px; }
+.emoji-2714 { background-position: -680px -820px; }
+.emoji-2716 { background-position: -700px -820px; }
+.emoji-271D { background-position: -720px -820px; }
+.emoji-2721 { background-position: -740px -820px; }
+.emoji-2728 { background-position: -760px -820px; }
+.emoji-2733 { background-position: -780px -820px; }
+.emoji-2734 { background-position: -800px -820px; }
+.emoji-2744 { background-position: -820px -820px; }
+.emoji-2747 { background-position: -840px 0; }
+.emoji-274C { background-position: -840px -20px; }
+.emoji-274E { background-position: -840px -40px; }
+.emoji-2753 { background-position: -840px -60px; }
+.emoji-2754 { background-position: -840px -80px; }
+.emoji-2755 { background-position: -840px -100px; }
+.emoji-2757 { background-position: -840px -120px; }
+.emoji-2763 { background-position: -840px -140px; }
+.emoji-2764 { background-position: -840px -160px; }
+.emoji-2795 { background-position: -840px -180px; }
+.emoji-2796 { background-position: -840px -200px; }
+.emoji-2797 { background-position: -840px -220px; }
+.emoji-27A1 { background-position: -840px -240px; }
+.emoji-27B0 { background-position: -840px -260px; }
+.emoji-27BF { background-position: -840px -280px; }
+.emoji-2934 { background-position: -840px -300px; }
+.emoji-2935 { background-position: -840px -320px; }
+.emoji-2B05 { background-position: -840px -340px; }
+.emoji-2B06 { background-position: -840px -360px; }
+.emoji-2B07 { background-position: -840px -380px; }
+.emoji-2B1B { background-position: -840px -400px; }
+.emoji-2B1C { background-position: -840px -420px; }
+.emoji-2B50 { background-position: -840px -440px; }
+.emoji-2B55 { background-position: -840px -460px; }
+.emoji-3030 { background-position: -840px -480px; }
+.emoji-303D { background-position: -840px -500px; }
+.emoji-3297 { background-position: -840px -520px; }
+.emoji-3299 { background-position: -840px -540px; }
.emoji-icon {
background-image: image-url('emoji.png');
@@ -1731,6 +1804,6 @@
only screen and (min-resolution: 192dpi),
only screen and (min-resolution: 2dppx) {
background-image: image-url('emoji@2x.png');
- background-size: 840px 820px;
+ background-size: 860px 840px;
}
}
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 542fa244689..ded437625ee 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -122,7 +122,8 @@
button {
float: right;
- padding: 3px 5px;
+ padding: 1px 5px;
+ background-color: $gray-light;
}
}
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index 0e4d8c140aa..ee3b2d2b801 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -63,7 +63,7 @@ form.edit-issue {
.merge-request,
.issue {
&.today {
- background: #f8feef;
+ background: #f3fff2;
border-color: #e1e8d5;
}
@@ -78,6 +78,14 @@ form.edit-issue {
}
}
+.merge-request-ci-status {
+ svg {
+ margin-right: 4px;
+ position: relative;
+ top: 1px;
+ }
+}
+
@media (max-width: $screen-xs-max) {
.issue-btn-group {
width: 100%;
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 15c6c9f231a..5254faf723d 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -60,8 +60,10 @@
.ci_widget {
border-bottom: 1px solid #eef0f2;
- i {
+ svg {
margin-right: 4px;
+ position: relative;
+ top: 1px;
}
&.ci-success {
@@ -196,6 +198,16 @@
.merge-request-title {
margin-bottom: 2px;
+
+ .ci-status-link {
+
+ svg {
+ height: 16px;
+ width: 16px;
+ position: relative;
+ top: 3px;
+ }
+ }
}
}
@@ -270,7 +282,7 @@
.item-title {
@media (min-width: $screen-sm-min) {
- width: 49%;
+ width: 45%;
}
}
diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss
index a0334207c68..a404f108dc4 100644
--- a/app/assets/stylesheets/pages/pipelines.scss
+++ b/app/assets/stylesheets/pages/pipelines.scss
@@ -1,7 +1,7 @@
.pipelines {
.stage {
- max-width: 80px;
- width: 80px;
+ max-width: 90px;
+ width: 90px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -30,13 +30,17 @@
}
.table.builds {
- min-width: 1100px;
+ min-width: 1200px;
tr {
th {
- padding: 16px;
+ padding: 16px 8px;
border: none;
}
+
+ td {
+ padding: 10px 8px;
+ }
}
tbody {
@@ -45,6 +49,14 @@
.commit-link {
+ .ci-status {
+
+ svg {
+ top: 1px;
+ margin-right: 0;
+ }
+ }
+
a:hover {
text-decoration: none;
}
@@ -53,9 +65,8 @@
.branch-commit {
.branch-name {
- margin-left: 8px;
font-weight: bold;
- max-width: 180px;
+ max-width: 150px;
overflow: hidden;
display: inline-block;
white-space: nowrap;
@@ -64,10 +75,15 @@
}
svg {
- margin: 0 6px;
height: 14px;
width: auto;
vertical-align: middle;
+ fill: $table-text-gray;
+ }
+
+ .fa {
+ font-size: 12px;
+ color: $table-text-gray;
}
.commit-id {
@@ -100,6 +116,31 @@
}
}
+ .icon-container {
+ display: inline-block;
+ text-align: right;
+ width: 20px;
+
+ .fa {
+ position: relative;
+ right: 3px;
+ }
+
+ svg {
+ position: relative;
+ right: 1px;
+ }
+ }
+
+ .stage-cell {
+
+ svg {
+ height: 18px;
+ width: 18px;
+ vertical-align: middle;
+ }
+ }
+
.duration,
.finished-at {
color: $table-text-gray;
@@ -107,21 +148,19 @@
.fa {
font-size: 12px;
+ margin-right: 4px;
}
svg {
- height: 12px;
- width: auto;
+ width: 12px;
+ height: auto;
vertical-align: middle;
- }
-
- .fa,
- svg {
- margin-right: 5px;
+ margin-right: 4px;
}
}
.pipeline-actions {
+ min-width: 140px;
.btn {
margin: 0;
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index ea9f7cf0540..cc3aef5199e 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -129,6 +129,17 @@
color: $layout-link-gray;
}
+ svg {
+
+ path {
+ fill: $layout-link-gray;
+ }
+
+ use {
+ stroke: $layout-link-gray;
+ }
+ }
+
.fa-caret-down {
margin-left: 3px;
}
@@ -322,18 +333,53 @@ a.deploy-project-label {
}
.fork-namespaces {
- .fork-thumbnail {
- text-align: center;
- margin-bottom: $gl-padding;
-
- .caption {
- padding: $gl-padding 0;
- min-height: 30px;
- }
+ .row {
+ -webkit-flex-wrap: wrap;
+ display: -webkit-flex;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+
+ .fork-thumbnail {
+ @include border-radius($border-radius-base);
+ background-color: $white-light;
+ border: 1px solid $border-white-light;
+ height: 202px;
+ margin: $gl-padding;
+ text-align: center;
+ width: 169px;
+ &:hover, &.forked {
+ background-color: $row-hover;
+ border-color: $row-hover-border;
+ }
+ .no-avatar {
+ width: 100px;
+ height: 100px;
+ background-color: $gray-light;
+ border: 1px solid $gray-dark;
+ margin: 0 auto;
+ @include border-radius(50%);
+ i {
+ font-size: 100px;
+ color: $gray-dark;
+ }
+ }
+ a {
+ display: block;
+ width: 100%;
+ height: 100%;
+ padding-top: $gl-padding;
+ color: $gl-gray;
+ .caption {
+ min-height: 30px;
+ padding: $gl-padding 0;
+ }
+ }
- img {
- @include border-radius(50%);
- max-width: 100px;
+ img {
+ @include border-radius(50%);
+ max-width: 100px;
+ }
}
}
}
@@ -486,6 +532,11 @@ pre.light-well {
> span {
margin-left: 10px;
}
+
+ svg {
+ position: relative;
+ top: 2px;
+ }
}
}
diff --git a/app/assets/stylesheets/pages/status.scss b/app/assets/stylesheets/pages/status.scss
index c6b053150be..a22d4b6f6be 100644
--- a/app/assets/stylesheets/pages/status.scss
+++ b/app/assets/stylesheets/pages/status.scss
@@ -41,6 +41,14 @@
color: $blue-normal;
border-color: $blue-normal;
}
+
+ svg {
+ height: 13px;
+ width: 13px;
+ position: relative;
+ top: 1px;
+ margin: 0 3px;
+ }
}
.ci-status-icon-success {
diff --git a/app/assets/stylesheets/pages/tags.scss b/app/assets/stylesheets/pages/tags.scss
new file mode 100644
index 00000000000..24ebd3e7cfa
--- /dev/null
+++ b/app/assets/stylesheets/pages/tags.scss
@@ -0,0 +1,7 @@
+.tag-buttons {
+ line-height: 40px;
+
+ .btn:not(.dropdown-toggle) {
+ margin-left: 10px;
+ }
+}
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index 42a20e9775f..390977297fb 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -19,7 +19,7 @@
border-top: 1px solid $table-border-gray;
td, th {
- line-height: 23px;
+ line-height: 21px;
}
&:hover {
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index 94b5aaa71d0..f3a88a8e6c8 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -60,6 +60,6 @@ class Admin::GroupsController < Admin::ApplicationController
end
def group_params
- params.require(:group).permit(:name, :description, :path, :avatar, :visibility_level)
+ params.require(:group).permit(:name, :description, :path, :avatar, :visibility_level, :request_access_enabled)
end
end
diff --git a/app/controllers/admin/services_controller.rb b/app/controllers/admin/services_controller.rb
index 46133588332..7c37f3155da 100644
--- a/app/controllers/admin/services_controller.rb
+++ b/app/controllers/admin/services_controller.rb
@@ -1,4 +1,6 @@
class Admin::ServicesController < Admin::ApplicationController
+ include ServiceParams
+
before_action :service, only: [:edit, :update]
def index
@@ -13,7 +15,7 @@ class Admin::ServicesController < Admin::ApplicationController
end
def update
- if service.update_attributes(application_services_params[:service])
+ if service.update_attributes(service_params[:service])
redirect_to admin_application_settings_services_path,
notice: 'Application settings saved successfully'
else
@@ -37,15 +39,4 @@ class Admin::ServicesController < Admin::ApplicationController
def service
@service ||= Service.where(id: params[:id], template: true).first
end
-
- def application_services_params
- application_services_params = params.permit(:id,
- service: Projects::ServicesController::ALLOWED_PARAMS)
- if application_services_params[:service].is_a?(Hash)
- Projects::ServicesController::FILTER_BLANK_PARAMS.each do |param|
- application_services_params[:service].delete(param) if application_services_params[:service][param].blank?
- end
- end
- application_services_params
- end
end
diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb
index dacb5679dd3..f2b8f297bc2 100644
--- a/app/controllers/concerns/creates_commit.rb
+++ b/app/controllers/concerns/creates_commit.rb
@@ -7,7 +7,8 @@ module CreatesCommit
commit_params = @commit_params.merge(
source_project: @project,
source_branch: @ref,
- target_branch: @target_branch
+ target_branch: @target_branch,
+ previous_path: @previous_path
)
result = service.new(@tree_edit_project, current_user, commit_params).execute
diff --git a/app/controllers/concerns/diff_for_path.rb b/app/controllers/concerns/diff_for_path.rb
index e09b8789eb2..026d8b2e1e0 100644
--- a/app/controllers/concerns/diff_for_path.rb
+++ b/app/controllers/concerns/diff_for_path.rb
@@ -10,7 +10,6 @@ module DiffForPath
diff_commit = commit_for_diff(diff_file)
blob = diff_file.blob(diff_commit)
- @expand_all_diffs = true
locals = {
diff_file: diff_file,
diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb
new file mode 100644
index 00000000000..471d15af913
--- /dev/null
+++ b/app/controllers/concerns/service_params.rb
@@ -0,0 +1,35 @@
+module ServiceParams
+ extend ActiveSupport::Concern
+
+ ALLOWED_PARAMS = [:title, :token, :type, :active, :api_key, :api_url, :api_version, :subdomain,
+ :room, :recipients, :project_url, :webhook,
+ :user_key, :device, :priority, :sound, :bamboo_url, :username, :password,
+ :build_key, :server, :teamcity_url, :drone_url, :build_type,
+ :description, :issues_url, :new_issue_url, :restrict_to_branch, :channel,
+ :colorize_messages, :channels,
+ :push_events, :issues_events, :merge_requests_events, :tag_push_events,
+ :note_events, :build_events, :wiki_page_events,
+ :notify_only_broken_builds, :add_pusher,
+ :send_from_committer_email, :disable_diffs, :external_wiki_url,
+ :notify, :color,
+ :server_host, :server_port, :default_irc_uri, :enable_ssl_verification,
+ :jira_issue_transition_id]
+
+ # Parameters to ignore if no value is specified
+ FILTER_BLANK_PARAMS = [:password]
+
+ def service_params
+ dynamic_params = []
+ dynamic_params.concat(@service.event_channel_names)
+
+ service_params = params.permit(:id, service: ALLOWED_PARAMS + dynamic_params)
+
+ if service_params[:service].is_a?(Hash)
+ FILTER_BLANK_PARAMS.each do |param|
+ service_params[:service].delete(param) if service_params[:service][param].blank?
+ end
+ end
+
+ service_params
+ end
+end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index a04bf7df722..6780a6d4d87 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -121,7 +121,7 @@ class GroupsController < Groups::ApplicationController
end
def group_params
- params.require(:group).permit(:name, :description, :path, :avatar, :public, :visibility_level, :share_with_group_lock)
+ params.require(:group).permit(:name, :description, :path, :avatar, :public, :visibility_level, :share_with_group_lock, :request_access_enabled)
end
def load_events
diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb
index 824aa41db51..a9f482c8787 100644
--- a/app/controllers/projects/badges_controller.rb
+++ b/app/controllers/projects/badges_controller.rb
@@ -3,11 +3,6 @@ class Projects::BadgesController < Projects::ApplicationController
before_action :authorize_admin_project!, only: [:index]
before_action :no_cache_headers, except: [:index]
- def index
- @ref = params[:ref] || @project.default_branch || 'master'
- @build_badge = Gitlab::Badge::Build.new(@project, @ref)
- end
-
def build
badge = Gitlab::Badge::Build.new(project, params[:ref])
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 5356fdf010d..eda3727a28d 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -38,6 +38,12 @@ class Projects::BlobController < Projects::ApplicationController
end
def update
+ if params[:file_path].present?
+ @previous_path = @path
+ @path = params[:file_path]
+ @commit_params[:file_path] = @path
+ end
+
after_edit_path =
if from_merge_request && @target_branch == @ref
diffs_namespace_project_merge_request_path(from_merge_request.target_project.namespace, from_merge_request.target_project, from_merge_request) +
diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb
index d7513d75f01..553b62741a5 100644
--- a/app/controllers/projects/builds_controller.rb
+++ b/app/controllers/projects/builds_controller.rb
@@ -1,6 +1,6 @@
class Projects::BuildsController < Projects::ApplicationController
before_action :build, except: [:index, :cancel_all]
- before_action :authorize_read_build!, except: [:cancel, :cancel_all, :retry]
+ before_action :authorize_read_build!, except: [:cancel, :cancel_all, :retry, :play]
before_action :authorize_update_build!, except: [:index, :show, :status, :raw]
layout 'project'
@@ -49,14 +49,19 @@ class Projects::BuildsController < Projects::ApplicationController
end
def retry
- unless @build.retryable?
- return render_404
- end
+ return render_404 unless @build.retryable?
build = Ci::Build.retry(@build, current_user)
redirect_to build_path(build)
end
+ def play
+ return render_404 unless @build.playable?
+
+ build = @build.play(current_user)
+ redirect_to build_path(build)
+ end
+
def cancel
@build.cancel
redirect_to build_path(@build)
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index 5f3ee71444d..10749d0fef8 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -15,6 +15,7 @@ class Projects::CompareController < Projects::ApplicationController
end
def show
+ apply_diff_view_cookie!
end
def diff_for_path
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index b6e80762e3c..fa663c9bda4 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -226,6 +226,7 @@ class Projects::IssuesController < Projects::ApplicationController
:assignee_id,
:milestone_id,
:state_event,
+ :subscription_event,
label_ids: [],
add_label_ids: [],
remove_label_ids: []
diff --git a/app/controllers/projects/pipelines_settings_controller.rb b/app/controllers/projects/pipelines_settings_controller.rb
new file mode 100644
index 00000000000..85ba706e5cd
--- /dev/null
+++ b/app/controllers/projects/pipelines_settings_controller.rb
@@ -0,0 +1,30 @@
+class Projects::PipelinesSettingsController < Projects::ApplicationController
+ before_action :authorize_admin_pipeline!
+
+ def show
+ @ref = params[:ref] || @project.default_branch || 'master'
+ @build_badge = Gitlab::Badge::Build.new(@project, @ref)
+ end
+
+ def update
+ if @project.update_attributes(update_params)
+ flash[:notice] = "CI/CD Pipelines settings for '#{@project.name}' were successfully updated."
+ redirect_to namespace_project_pipelines_settings_path(@project.namespace, @project)
+ else
+ render 'index'
+ end
+ end
+
+ private
+
+ def create_params
+ params.require(:pipeline).permit(:ref)
+ end
+
+ def update_params
+ params.require(:project).permit(
+ :runners_token, :builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
+ :public_builds
+ )
+ end
+end
diff --git a/app/controllers/projects/protected_branches_controller.rb b/app/controllers/projects/protected_branches_controller.rb
index 80dad758afa..10dca47fded 100644
--- a/app/controllers/projects/protected_branches_controller.rb
+++ b/app/controllers/projects/protected_branches_controller.rb
@@ -50,6 +50,6 @@ class Projects::ProtectedBranchesController < Projects::ApplicationController
end
def protected_branch_params
- params.require(:protected_branch).permit(:name, :developers_can_push)
+ params.require(:protected_branch).permit(:name, :developers_can_push, :developers_can_merge)
end
end
diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb
index d79f16e6a5a..3602b3d5e58 100644
--- a/app/controllers/projects/refs_controller.rb
+++ b/app/controllers/projects/refs_controller.rb
@@ -25,7 +25,7 @@ class Projects::RefsController < Projects::ApplicationController
when "graphs_commits"
commits_namespace_project_graph_path(@project.namespace, @project, @id)
when "badges"
- namespace_project_badges_path(@project.namespace, @project, ref: @id)
+ namespace_project_pipelines_settings_path(@project.namespace, @project, ref: @id)
else
namespace_project_commits_path(@project.namespace, @project, @id)
end
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 739681f4085..6a227d85f6f 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -1,20 +1,5 @@
class Projects::ServicesController < Projects::ApplicationController
- ALLOWED_PARAMS = [:title, :token, :type, :active, :api_key, :api_url, :api_version, :subdomain,
- :room, :recipients, :project_url, :webhook,
- :user_key, :device, :priority, :sound, :bamboo_url, :username, :password,
- :build_key, :server, :teamcity_url, :drone_url, :build_type,
- :description, :issues_url, :new_issue_url, :restrict_to_branch, :channel,
- :colorize_messages, :channels,
- :push_events, :issues_events, :merge_requests_events, :tag_push_events,
- :note_events, :build_events, :wiki_page_events,
- :notify_only_broken_builds, :add_pusher,
- :send_from_committer_email, :disable_diffs, :external_wiki_url,
- :notify, :color,
- :server_host, :server_port, :default_irc_uri, :enable_ssl_verification,
- :jira_issue_transition_id]
-
- # Parameters to ignore if no value is specified
- FILTER_BLANK_PARAMS = [:password]
+ include ServiceParams
# Authorize
before_action :authorize_admin_project!
@@ -33,7 +18,7 @@ class Projects::ServicesController < Projects::ApplicationController
end
def update
- if @service.update_attributes(service_params)
+ if @service.update_attributes(service_params[:service])
redirect_to(
edit_namespace_project_service_path(@project.namespace, @project,
@service.to_param, notice:
@@ -45,8 +30,9 @@ class Projects::ServicesController < Projects::ApplicationController
end
def test
- data = Gitlab::PushDataBuilder.build_sample(project, current_user)
+ data = @service.test_data(project, current_user)
outcome = @service.test(data)
+
if outcome[:success]
message = { notice: 'We sent a request to the provided URL' }
else
@@ -63,12 +49,4 @@ class Projects::ServicesController < Projects::ApplicationController
def service
@service ||= @project.services.find { |service| service.to_param == params[:id] }
end
-
- def service_params
- service_params = params.require(:service).permit(ALLOWED_PARAMS)
- FILTER_BLANK_PARAMS.each do |param|
- service_params.delete(param) if service_params[param].blank?
- end
- service_params
- end
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 1803aa8eab4..ec7a2e63b9a 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -5,7 +5,7 @@ class ProjectsController < Projects::ApplicationController
before_action :project, except: [:new, :create]
before_action :repository, except: [:new, :create]
before_action :assign_ref_vars, only: [:show], if: :repo_exists?
- before_action :tree, only: [:show], if: :project_view_files?
+ before_action :tree, only: [:show], if: [:repo_exists?, :project_view_files?]
# Authorize
before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping, :download_export, :export, :remove_export, :generate_new_export]
@@ -296,7 +296,7 @@ class ProjectsController < Projects::ApplicationController
:issues_tracker_id, :default_branch,
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar,
:builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
- :public_builds, :only_allow_merge_if_build_succeeds
+ :public_builds, :only_allow_merge_if_build_succeeds, :request_access_enabled
)
end
diff --git a/app/helpers/avatars_helper.rb b/app/helpers/avatars_helper.rb
new file mode 100644
index 00000000000..6ff40c6b461
--- /dev/null
+++ b/app/helpers/avatars_helper.rb
@@ -0,0 +1,30 @@
+module AvatarsHelper
+
+ def author_avatar(commit_or_event, options = {})
+ user_avatar(options.merge({
+ user: commit_or_event.author,
+ user_name: commit_or_event.author_name,
+ user_email: commit_or_event.author_email,
+ }))
+ end
+
+ private
+
+ def user_avatar(options = {})
+ avatar_size = options[:size] || 16
+ user_name = options[:user].try(:name) || options[:user_name]
+ avatar = image_tag(
+ avatar_icon(options[:user] || options[:user_email], avatar_size),
+ class: "avatar has-tooltip hidden-xs s#{avatar_size}",
+ alt: "#{user_name}'s avatar",
+ title: user_name
+ )
+
+ if options[:user]
+ link_to(avatar, user_path(options[:user]))
+ elsif options[:user_email]
+ mail_to(options[:user_email], avatar)
+ end
+ end
+
+end
diff --git a/app/helpers/branches_helper.rb b/app/helpers/branches_helper.rb
index 601df5c18df..bfd23aa4e04 100644
--- a/app/helpers/branches_helper.rb
+++ b/app/helpers/branches_helper.rb
@@ -12,7 +12,7 @@ module BranchesHelper
def can_push_branch?(project, branch_name)
return false unless project.repository.branch_exists?(branch_name)
- ::Gitlab::GitAccess.new(current_user, project, 'web').can_push_to_branch?(branch_name)
+ ::Gitlab::UserAccess.new(current_user, project: project).can_push_to_branch?(branch_name)
end
def project_branches
diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb
index e6c99c9959e..59a8365d60b 100644
--- a/app/helpers/ci_status_helper.rb
+++ b/app/helpers/ci_status_helper.rb
@@ -26,18 +26,20 @@ module CiStatusHelper
icon_name =
case status
when 'success'
- 'check'
+ 'icon_status_success'
+ when 'success_with_warnings'
+ 'icon_status_warning'
when 'failed'
- 'close'
+ 'icon_status_failed'
when 'pending'
- 'clock-o'
+ 'icon_status_pending'
when 'running'
- 'spinner'
+ 'icon_status_running'
else
- 'circle'
+ 'icon_status_cancel'
end
- icon(icon_name + ' fw')
+ custom_icon(icon_name)
end
def render_commit_status(commit, tooltip_placement: 'auto left', cssclass: '')
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index 474041eccbb..052ce56809e 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -16,16 +16,6 @@ module CommitsHelper
commit_person_link(commit, options.merge(source: :committer))
end
- def commit_author_avatar(commit, options = {})
- options = options.merge(source: :author)
- user = commit.send(options[:source])
-
- source_email = clean(commit.send "#{options[:source]}_email".to_sym)
- person_email = user.try(:email) || source_email
-
- image_tag(avatar_icon(person_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]} hidden-xs", width: options[:size], alt: "")
- end
-
def image_diff_class(diff)
if diff.deleted_file
"deleted"
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index adab901700c..75b029365f9 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -9,7 +9,7 @@ module DiffHelper
end
def expand_all_diffs?
- @expand_all_diffs || params[:expand_all_diffs].present?
+ params[:expand_all_diffs].present?
end
def diff_view
@@ -23,13 +23,14 @@ module DiffHelper
end
def diff_options
- default_options = Commit.max_diff_options
+ options = { ignore_whitespace_change: hide_whitespace?, no_collapse: expand_all_diffs? }
if action_name == 'diff_for_path'
- default_options[:paths] = params.values_at(:old_path, :new_path)
+ options[:no_collapse] = true
+ options[:paths] = params.values_at(:old_path, :new_path)
end
- default_options.merge(ignore_whitespace_change: hide_whitespace?)
+ Commit.max_diff_options.merge(options)
end
def safe_diff_files(diffs, diff_refs: nil, repository: nil)
diff --git a/app/helpers/external_wiki_helper.rb b/app/helpers/external_wiki_helper.rb
index 1f3401f2906..defd87d6bbe 100644
--- a/app/helpers/external_wiki_helper.rb
+++ b/app/helpers/external_wiki_helper.rb
@@ -1,8 +1,7 @@
module ExternalWikiHelper
def get_project_wiki_path(project)
- external_wiki_service = project.services.
- find { |service| service.to_param == 'external_wiki' }
- if external_wiki_service.present? && external_wiki_service.active?
+ external_wiki_service = project.external_wiki
+ if external_wiki_service
external_wiki_service.properties['external_wiki_url']
else
namespace_project_wiki_path(project.namespace, project, :home)
diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb
new file mode 100644
index 00000000000..2dd0bf5d71e
--- /dev/null
+++ b/app/helpers/services_helper.rb
@@ -0,0 +1,25 @@
+module ServicesHelper
+ def service_event_description(event)
+ case event
+ when "push"
+ "Event will be triggered by a push to the repository"
+ when "tag_push"
+ "Event will be triggered when a new tag is pushed to the repository"
+ when "note"
+ "Event will be triggered when someone adds a comment"
+ when "issue"
+ "Event will be triggered when an issue is created/updated/merged"
+ when "merge_request"
+ "Event will be triggered when a merge request is created/updated/merged"
+ when "build"
+ "Event will be triggered when a build status changes"
+ when "wiki_page"
+ "Event will be triggered when a wiki page is created/updated"
+ end
+ end
+
+ def service_event_field_name(event)
+ event = event.pluralize if %w[merge_request issue].include?(event)
+ "#{event}_events"
+ end
+end
diff --git a/app/helpers/time_helper.rb b/app/helpers/time_helper.rb
index 8cb82c2d5cc..1926f03af07 100644
--- a/app/helpers/time_helper.rb
+++ b/app/helpers/time_helper.rb
@@ -1,14 +1,4 @@
module TimeHelper
- def duration_in_words(finished_at, started_at)
- if finished_at && started_at
- interval_in_seconds = finished_at.to_i - started_at.to_i
- elsif started_at
- interval_in_seconds = Time.now.to_i - started_at.to_i
- end
-
- time_interval_in_words(interval_in_seconds)
- end
-
def time_interval_in_words(interval_in_seconds)
minutes = interval_in_seconds / 60
seconds = interval_in_seconds - minutes * 60
@@ -25,9 +15,19 @@ module TimeHelper
end
def duration_in_numbers(finished_at, started_at)
- diff_in_seconds = finished_at.to_i - started_at.to_i
- time_format = diff_in_seconds < 1.hour ? "%M:%S" : "%H:%M:%S"
+ interval = interval_in_seconds(started_at, finished_at)
+ time_format = interval < 1.hour ? "%M:%S" : "%H:%M:%S"
- Time.at(diff_in_seconds).utc.strftime(time_format)
+ Time.at(interval).utc.strftime(time_format)
+ end
+
+ private
+
+ def interval_in_seconds(started_at, finished_at = nil)
+ if started_at && finished_at
+ finished_at.to_i - started_at.to_i
+ elsif started_at
+ Time.now.to_i - started_at.to_i
+ end
end
end
diff --git a/app/mailers/emails/builds.rb b/app/mailers/emails/builds.rb
index 2f86d1be576..3853af6201a 100644
--- a/app/mailers/emails/builds.rb
+++ b/app/mailers/emails/builds.rb
@@ -6,6 +6,7 @@ module Emails
add_project_headers
add_build_headers('failed')
+
mail(to: to, subject: subject("Build failed for #{@project.name}", @build.short_sha))
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 6fd18f2ee24..f33c8d61d3f 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -172,7 +172,7 @@ class Ability
rules << :read_build if project.public_builds?
unless owner || project.team.member?(user) || project_group_member?(project, user)
- rules << :request_access
+ rules << :request_access if project.request_access_enabled
end
end
@@ -373,7 +373,7 @@ class Ability
end
if group.public? || (group.internal? && !user.external?)
- rules << :request_access unless group.users.include?(user)
+ rules << :request_access if group.request_access_enabled && group.users.exclude?(user)
end
rules.flatten
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 65dfe4f0190..58a813f35ef 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -12,12 +12,10 @@ module Ci
scope :unstarted, ->() { where(runner_id: nil) }
scope :ignore_failures, ->() { where(allow_failure: false) }
- scope :with_artifacts, ->() { where.not(artifacts_file: nil) }
+ scope :with_artifacts, ->() { where.not(artifacts_file: [nil, '']) }
scope :with_expired_artifacts, ->() { with_artifacts.where('artifacts_expire_at < ?', Time.now) }
scope :last_month, ->() { where('created_at > ?', Date.today - 1.month) }
- scope :latest_successful_with_artifacts, ->() do
- with_artifacts.success.order(id: :desc)
- end
+ scope :manual_actions, ->() { where(when: :manual) }
mount_uploader :artifacts_file, ArtifactUploader
mount_uploader :artifacts_metadata, ArtifactUploader
@@ -94,6 +92,29 @@ module Ci
end
end
+ def manual?
+ self.when == 'manual'
+ end
+
+ def other_actions
+ pipeline.manual_actions.where.not(name: name)
+ end
+
+ def playable?
+ project.builds_enabled? && commands.present? && manual?
+ end
+
+ def play(current_user = nil)
+ # Try to queue a current build
+ if self.queue
+ self.update(user: current_user)
+ self
+ else
+ # Otherwise we need to create a duplicate
+ Ci::Build.retry(self, current_user)
+ end
+ end
+
def retryable?
project.builds_enabled? && commands.present? && complete?
end
@@ -124,11 +145,14 @@ module Ci
end
def variables
- variables = []
- variables += predefined_variables
- variables += yaml_variables if yaml_variables
- variables += project_variables
- variables += trigger_variables
+ variables = predefined_variables
+ variables += project.predefined_variables
+ variables += pipeline.predefined_variables
+ variables += runner.predefined_variables if runner
+ variables += project.container_registry_variables
+ variables += yaml_variables
+ variables += project.secret_variables
+ variables += trigger_request.user_variables if trigger_request
variables
end
@@ -388,6 +412,14 @@ module Ci
self.update(artifacts_expire_at: nil)
end
+ def when
+ read_attribute(:when) || build_attributes_from_config[:when] || 'on_success'
+ end
+
+ def yaml_variables
+ read_attribute(:yaml_variables) || build_attributes_from_config[:yaml_variables] || []
+ end
+
private
def update_artifacts_size
@@ -406,29 +438,30 @@ module Ci
self.update(erased_by: user, erased_at: Time.now, artifacts_expire_at: nil)
end
- def project_variables
- project.variables.map do |variable|
- { key: variable.key, value: variable.value, public: false }
- end
+ def predefined_variables
+ variables = [
+ { key: 'CI', value: 'true', public: true },
+ { key: 'GITLAB_CI', value: 'true', public: true },
+ { key: 'CI_BUILD_ID', value: id.to_s, public: true },
+ { key: 'CI_BUILD_TOKEN', value: token, public: false },
+ { key: 'CI_BUILD_REF', value: sha, public: true },
+ { key: 'CI_BUILD_BEFORE_SHA', value: before_sha, public: true },
+ { key: 'CI_BUILD_REF_NAME', value: ref, public: true },
+ { key: 'CI_BUILD_NAME', value: name, public: true },
+ { key: 'CI_BUILD_STAGE', value: stage, public: true },
+ { key: 'CI_SERVER_NAME', value: 'GitLab', public: true },
+ { key: 'CI_SERVER_VERSION', value: Gitlab::VERSION, public: true },
+ { key: 'CI_SERVER_REVISION', value: Gitlab::REVISION, public: true }
+ ]
+ variables << { key: 'CI_BUILD_TAG', value: ref, public: true } if tag?
+ variables << { key: 'CI_BUILD_TRIGGERED', value: 'true', public: true } if trigger_request
+ variables
end
- def trigger_variables
- if trigger_request && trigger_request.variables
- trigger_request.variables.map do |key, value|
- { key: key, value: value, public: false }
- end
- else
- []
- end
- end
+ def build_attributes_from_config
+ return {} unless pipeline.config_processor
- def predefined_variables
- variables = []
- variables << { key: :CI_BUILD_TAG, value: ref, public: true } if tag?
- variables << { key: :CI_BUILD_NAME, value: name, public: true }
- variables << { key: :CI_BUILD_STAGE, value: stage, public: true }
- variables << { key: :CI_BUILD_TRIGGERED, value: 'true', public: true } if trigger_request
- variables
+ pipeline.config_processor.build_attributes(name)
end
end
end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 148b056789a..f0edf3e2731 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -20,6 +20,11 @@ module Ci
after_touch :update_state
after_save :keep_around_commits
+ # ref can't be HEAD or SHA, can only be branch/tag name
+ scope :latest_successful_for, ->(ref = default_branch) do
+ where(ref: ref).success.order(id: :desc).limit(1)
+ end
+
def self.truncate_sha(sha)
sha[0...8]
end
@@ -51,6 +56,10 @@ module Ci
commit.try(:message)
end
+ def git_commit_title
+ commit.try(:title)
+ end
+
def short_sha
Ci::Pipeline.truncate_sha(sha)
end
@@ -65,6 +74,10 @@ module Ci
!tag?
end
+ def manual_actions
+ builds.latest.manual_actions
+ end
+
def retryable?
builds.latest.any? do |build|
build.failed? && build.retryable?
@@ -190,6 +203,12 @@ module Ci
Note.for_commit_id(sha)
end
+ def predefined_variables
+ [
+ { key: 'CI_PIPELINE_ID', value: id.to_s, public: true }
+ ]
+ end
+
private
def build_builds_for_stages(stages, user, status, trigger_request)
@@ -198,8 +217,9 @@ module Ci
# build builds only for the first stage that has builds available.
#
stages.any? do |stage|
- CreateBuildsService.new(self)
- .execute(stage, user, status, trigger_request).present?
+ CreateBuildsService.new(self).
+ execute(stage, user, status, trigger_request).
+ any?(&:active?)
end
end
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index b64ec79ec2b..49f05f881a2 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -114,6 +114,14 @@ module Ci
tag_list.any?
end
+ def predefined_variables
+ [
+ { key: 'CI_RUNNER_ID', value: id.to_s, public: true },
+ { key: 'CI_RUNNER_DESCRIPTION', value: description, public: true },
+ { key: 'CI_RUNNER_TAGS', value: tag_list.to_s, public: true }
+ ]
+ end
+
private
def tag_constraints
diff --git a/app/models/ci/trigger_request.rb b/app/models/ci/trigger_request.rb
index fcf2b6dc5e2..fc674871743 100644
--- a/app/models/ci/trigger_request.rb
+++ b/app/models/ci/trigger_request.rb
@@ -7,5 +7,13 @@ module Ci
has_many :builds, class_name: 'Ci::Build'
serialize :variables
+
+ def user_variables
+ return [] unless variables
+
+ variables.map do |key, value|
+ { key: key, value: value, public: false }
+ end
+ end
end
end
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index 3e97fe68d4b..2d185c28809 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -17,17 +17,19 @@ class CommitStatus < ActiveRecord::Base
alias_attribute :author, :user
scope :latest, -> do
- max_id = unscope(:select).
- select("max(#{table_name}.id)").
- group(:name, :commit_id)
+ max_id = unscope(:select).select("max(#{quoted_table_name}.id)")
- where(id: max_id)
+ where(id: max_id.group(:name, :commit_id))
end
scope :retried, -> { where.not(id: latest) }
scope :ordered, -> { order(:name) }
scope :ignored, -> { where(allow_failure: true, status: [:failed, :canceled]) }
state_machine :status, initial: :pending do
+ event :queue do
+ transition skipped: :pending
+ end
+
event :run do
transition pending: :running
end
diff --git a/app/models/concerns/statuseable.rb b/app/models/concerns/statuseable.rb
index 3ef91caad47..44c6b30f278 100644
--- a/app/models/concerns/statuseable.rb
+++ b/app/models/concerns/statuseable.rb
@@ -16,10 +16,10 @@ module Statuseable
deduce_status = "(CASE
WHEN (#{builds})=0 THEN NULL
- WHEN (#{builds})=(#{success})+(#{ignored}) THEN 'success'
- WHEN (#{builds})=(#{pending}) THEN 'pending'
- WHEN (#{builds})=(#{canceled})+(#{success})+(#{ignored}) THEN 'canceled'
WHEN (#{builds})=(#{skipped}) THEN 'skipped'
+ WHEN (#{builds})=(#{success})+(#{ignored})+(#{skipped}) THEN 'success'
+ WHEN (#{builds})=(#{pending})+(#{skipped}) THEN 'pending'
+ WHEN (#{builds})=(#{canceled})+(#{success})+(#{ignored})+(#{skipped}) THEN 'canceled'
WHEN (#{running})+(#{pending})>0 THEN 'running'
ELSE 'failed'
END)"
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index 520026c18dd..1a7cd60817e 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -32,4 +32,8 @@ class Deployment < ActiveRecord::Base
def keep_around_commit
project.repository.keep_around(self.sha)
end
+
+ def manual_actions
+ deployable.try(:other_actions)
+ end
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 157901378d3..471e32f3b60 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -552,7 +552,13 @@ class MergeRequest < ActiveRecord::Base
end
def can_be_merged_by?(user)
- ::Gitlab::GitAccess.new(user, project, 'web').can_push_to_branch?(target_branch)
+ access = ::Gitlab::UserAccess.new(user, project: project)
+ access.can_push_to_branch?(target_branch) || access.can_merge_to_branch?(target_branch)
+ end
+
+ def can_be_merged_via_command_line_by?(user)
+ access = ::Gitlab::UserAccess.new(user, project: project)
+ access.can_push_to_branch?(target_branch)
end
def mergeable_ci_state?
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index feaba925bad..3f520c8f3ff 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -1,6 +1,7 @@
class MergeRequestDiff < ActiveRecord::Base
include Sortable
include Importable
+ include EncodingHelper
# Prevent store of diff if commits amount more then 500
COMMITS_SAFE_SIZE = 100
@@ -211,6 +212,14 @@ class MergeRequestDiff < ActiveRecord::Base
branch_base_commit.try(:sha)
end
+ def utf8_st_diffs
+ st_diffs.map do |diff|
+ diff.each do |k, v|
+ diff[k] = encode_utf8(v) if v.respond_to?(:encoding)
+ end
+ end
+ end
+
#
# #save or #update_attributes providing changes on serialized attributes do a lot of
# serialization and deserialization calls resulting in bad performance.
diff --git a/app/models/project.rb b/app/models/project.rb
index 60928bf9922..d14d15fdc5c 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -430,18 +430,14 @@ class Project < ActiveRecord::Base
end
# ref can't be HEAD, can only be branch/tag name or SHA
- def latest_successful_pipeline_for(ref = 'master')
- table = Ci::Pipeline.quoted_table_name
- # TODO: Use `where(ref: ref).or(sha: ref)` in Rails 5
- pipelines.where("#{table}.ref = ? OR #{table}.sha = ?", ref, ref).
- success.order(id: :desc)
- end
+ def latest_successful_builds_for(ref = default_branch)
+ latest_pipeline = pipelines.latest_successful_for(ref).first
- # ref can't be HEAD, can only be branch/tag name or SHA
- def latest_successful_builds_for(ref = 'master')
- Ci::Build.joins(:pipeline).
- merge(latest_successful_pipeline_for(ref)).
- latest_successful_with_artifacts
+ if latest_pipeline
+ latest_pipeline.builds.latest.with_artifacts
+ else
+ builds.none
+ end
end
def merge_base_commit(first_commit_id, second_commit_id)
@@ -665,6 +661,22 @@ class Project < ActiveRecord::Base
update_column(:has_external_issue_tracker, services.external_issue_trackers.any?)
end
+ def external_wiki
+ if has_external_wiki.nil?
+ cache_has_external_wiki # Populate
+ end
+
+ if has_external_wiki
+ @external_wiki ||= services.external_wikis.first
+ else
+ nil
+ end
+ end
+
+ def cache_has_external_wiki
+ update_column(:has_external_wiki, services.external_wikis.any?)
+ end
+
def build_missing_services
services_templates = Service.where(template: true)
@@ -853,6 +865,10 @@ class Project < ActiveRecord::Base
protected_branches.matching(branch_name).any?(&:developers_can_push)
end
+ def developers_can_merge_to_protected_branch?(branch_name)
+ protected_branches.matching(branch_name).any?(&:developers_can_merge)
+ end
+
def forked?
!(forked_project_link.nil? || forked_project_link.forked_from_project.nil?)
end
@@ -1175,4 +1191,34 @@ class Project < ActiveRecord::Base
def ensure_dir_exist
gitlab_shell.add_namespace(repository_storage_path, namespace.path)
end
+
+ def predefined_variables
+ [
+ { key: 'CI_PROJECT_ID', value: id.to_s, public: true },
+ { key: 'CI_PROJECT_NAME', value: path, public: true },
+ { key: 'CI_PROJECT_PATH', value: path_with_namespace, public: true },
+ { key: 'CI_PROJECT_NAMESPACE', value: namespace.path, public: true },
+ { key: 'CI_PROJECT_URL', value: web_url, public: true }
+ ]
+ end
+
+ def container_registry_variables
+ return [] unless Gitlab.config.registry.enabled
+
+ variables = [
+ { key: 'CI_REGISTRY', value: Gitlab.config.registry.host_port, public: true }
+ ]
+
+ if container_registry_enabled?
+ variables << { key: 'CI_REGISTRY_IMAGE', value: container_registry_repository_url, public: true }
+ end
+
+ variables
+ end
+
+ def secret_variables
+ variables.map do |variable|
+ { key: variable.key, value: variable.value, public: false }
+ end
+ end
end
diff --git a/app/models/project_services/builds_email_service.rb b/app/models/project_services/builds_email_service.rb
index 54da4d74fc5..5e166471077 100644
--- a/app/models/project_services/builds_email_service.rb
+++ b/app/models/project_services/builds_email_service.rb
@@ -42,6 +42,19 @@ class BuildsEmailService < Service
end
end
+ def can_test?
+ project.builds.count > 0
+ end
+
+ def disabled_title
+ "Please setup a build on your repository."
+ end
+
+ def test_data(project = nil, user = nil)
+ build = project.builds.last
+ Gitlab::BuildDataBuilder.build(build)
+ end
+
def fields
[
{ type: 'textarea', name: 'recipients', placeholder: 'Emails separated by comma' },
@@ -50,6 +63,20 @@ class BuildsEmailService < Service
]
end
+ def test(data)
+ begin
+ # bypass build status verification when testing
+ data[:build_status] = "failed"
+ data[:build_allow_failure] = false
+
+ result = execute(data)
+ rescue StandardError => error
+ return { success: false, result: error }
+ end
+
+ { success: true, result: result }
+ end
+
def should_build_be_notified?(data)
case data[:build_status]
when 'success'
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
index cf9e4d5a8b6..abbc780dc1a 100644
--- a/app/models/project_services/slack_service.rb
+++ b/app/models/project_services/slack_service.rb
@@ -4,6 +4,9 @@ class SlackService < Service
validates :webhook, presence: true, url: true, if: :activated?
def initialize_properties
+ # Custom serialized properties initialization
+ self.supported_events.each { |event| self.class.prop_accessor(event_channel_name(event)) }
+
if properties.nil?
self.properties = {}
self.notify_only_broken_builds = true
@@ -29,13 +32,15 @@ class SlackService < Service
end
def fields
- [
- { type: 'text', name: 'webhook',
- placeholder: 'https://hooks.slack.com/services/...' },
- { type: 'text', name: 'username', placeholder: 'username' },
- { type: 'text', name: 'channel', placeholder: '#channel' },
- { type: 'checkbox', name: 'notify_only_broken_builds' },
- ]
+ default_fields =
+ [
+ { type: 'text', name: 'webhook', placeholder: 'https://hooks.slack.com/services/...' },
+ { type: 'text', name: 'username', placeholder: 'username' },
+ { type: 'text', name: 'channel', placeholder: "#general" },
+ { type: 'checkbox', name: 'notify_only_broken_builds' },
+ ]
+
+ default_fields + build_event_channels
end
def supported_events
@@ -74,7 +79,10 @@ class SlackService < Service
end
opt = {}
- opt[:channel] = channel if channel
+
+ event_channel = get_channel_field(object_kind) || channel
+
+ opt[:channel] = event_channel if event_channel
opt[:username] = username if username
if message
@@ -83,8 +91,35 @@ class SlackService < Service
end
end
+ def event_channel_names
+ supported_events.map { |event| event_channel_name(event) }
+ end
+
+ def event_field(event)
+ fields.find { |field| field[:name] == event_channel_name(event) }
+ end
+
+ def global_fields
+ fields.reject { |field| field[:name].end_with?('channel') }
+ end
+
private
+ def get_channel_field(event)
+ field_name = event_channel_name(event)
+ self.public_send(field_name)
+ end
+
+ def build_event_channels
+ supported_events.reduce([]) do |channels, event|
+ channels << { type: 'text', name: event_channel_name(event), placeholder: "#general" }
+ end
+ end
+
+ def event_channel_name(event)
+ "#{event}_channel"
+ end
+
def project_name
project.name_with_namespace.gsub(/\s/, '')
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 5b670cb4b8f..511df2d67c6 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -392,6 +392,11 @@ class Repository
expire_cache if exists?
+ # expire cache that don't depend on repository data (when expiring)
+ expire_tags_cache
+ expire_tag_count_cache
+ expire_branches_cache
+ expire_branch_count_cache
expire_root_ref_cache
expire_emptiness_caches
expire_exists_cache
@@ -704,6 +709,7 @@ class Repository
options[:commit] = {
message: message,
branch: ref,
+ update_ref: false,
}
raw_repository.mkdir(path, options)
@@ -719,6 +725,7 @@ class Repository
options[:commit] = {
message: message,
branch: ref,
+ update_ref: false,
}
options[:file] = {
@@ -731,6 +738,33 @@ class Repository
end
end
+ def update_file(user, path, content, branch:, previous_path:, message:)
+ commit_with_hooks(user, branch) do |ref|
+ committer = user_to_committer(user)
+ options = {}
+ options[:committer] = committer
+ options[:author] = committer
+ options[:commit] = {
+ message: message,
+ branch: ref,
+ update_ref: false
+ }
+
+ options[:file] = {
+ content: content,
+ path: path,
+ update: true
+ }
+
+ if previous_path
+ options[:file][:previous_path] = previous_path
+ Gitlab::Git::Blob.rename(raw_repository, options)
+ else
+ Gitlab::Git::Blob.commit(raw_repository, options)
+ end
+ end
+ end
+
def remove_file(user, path, message, branch)
commit_with_hooks(user, branch) do |ref|
committer = user_to_committer(user)
@@ -739,7 +773,8 @@ class Repository
options[:author] = committer
options[:commit] = {
message: message,
- branch: ref
+ branch: ref,
+ update_ref: false,
}
options[:file] = {
@@ -769,9 +804,9 @@ class Repository
end
end
- def merge(user, source_sha, target_branch, options = {})
- our_commit = rugged.branches[target_branch].target
- their_commit = rugged.lookup(source_sha)
+ def merge(user, merge_request, options = {})
+ our_commit = rugged.branches[merge_request.target_branch].target
+ their_commit = rugged.lookup(merge_request.diff_head_sha)
raise "Invalid merge target" if our_commit.nil?
raise "Invalid merge source" if their_commit.nil?
@@ -779,14 +814,15 @@ class Repository
merge_index = rugged.merge_commits(our_commit, their_commit)
return false if merge_index.conflicts?
- commit_with_hooks(user, target_branch) do |ref|
+ commit_with_hooks(user, merge_request.target_branch) do
actual_options = options.merge(
parents: [our_commit, their_commit],
tree: merge_index.write_tree(rugged),
- update_ref: ref
)
- Rugged::Commit.create(rugged, actual_options)
+ commit_id = Rugged::Commit.create(rugged, actual_options)
+ merge_request.update(in_progress_merge_commit_sha: commit_id)
+ commit_id
end
end
@@ -796,15 +832,14 @@ class Repository
return false unless revert_tree_id
- commit_with_hooks(user, base_branch) do |ref|
+ commit_with_hooks(user, base_branch) do
committer = user_to_committer(user)
source_sha = Rugged::Commit.create(rugged,
message: commit.revert_message,
author: committer,
committer: committer,
tree: revert_tree_id,
- parents: [rugged.lookup(source_sha)],
- update_ref: ref)
+ parents: [rugged.lookup(source_sha)])
end
end
@@ -814,7 +849,7 @@ class Repository
return false unless cherry_pick_tree_id
- commit_with_hooks(user, base_branch) do |ref|
+ commit_with_hooks(user, base_branch) do
committer = user_to_committer(user)
source_sha = Rugged::Commit.create(rugged,
message: commit.message,
@@ -825,8 +860,7 @@ class Repository
},
committer: committer,
tree: cherry_pick_tree_id,
- parents: [rugged.lookup(source_sha)],
- update_ref: ref)
+ parents: [rugged.lookup(source_sha)])
end
end
@@ -927,20 +961,6 @@ class Repository
Gitlab::Popen.popen(args, path_to_repo)
end
- def with_tmp_ref(oldrev = nil)
- random_string = SecureRandom.hex
- tmp_ref = "refs/tmp/#{random_string}/head"
-
- if oldrev && !Gitlab::Git.blank_ref?(oldrev)
- rugged.references.create(tmp_ref, oldrev)
- end
-
- # Make commit in tmp ref
- yield(tmp_ref)
- ensure
- rugged.references.delete(tmp_ref) rescue nil
- end
-
def commit_with_hooks(current_user, branch)
update_autocrlf_option
@@ -953,33 +973,31 @@ class Repository
oldrev = target_branch.target
end
- with_tmp_ref(oldrev) do |tmp_ref|
- # Make commit in tmp ref
- newrev = yield(tmp_ref)
+ # Make commit
+ newrev = yield(ref)
- unless newrev
- raise CommitError.new('Failed to create commit')
- end
+ unless newrev
+ raise CommitError.new('Failed to create commit')
+ end
- GitHooksService.new.execute(current_user, path_to_repo, oldrev, newrev, ref) do
- if was_empty || !target_branch
- # Create branch
- rugged.references.create(ref, newrev)
+ GitHooksService.new.execute(current_user, path_to_repo, oldrev, newrev, ref) do
+ if was_empty || !target_branch
+ # Create branch
+ rugged.references.create(ref, newrev)
+ else
+ # Update head
+ current_head = find_branch(branch).target
+
+ # Make sure target branch was not changed during pre-receive hook
+ if current_head == oldrev
+ rugged.references.update(ref, newrev)
else
- # Update head
- current_head = find_branch(branch).target
-
- # Make sure target branch was not changed during pre-receive hook
- if current_head == oldrev
- rugged.references.update(ref, newrev)
- else
- raise CommitError.new('Commit was rejected because branch received new push')
- end
+ raise CommitError.new('Commit was rejected because branch received new push')
end
end
-
- newrev
end
+
+ newrev
end
def ls_files(ref)
diff --git a/app/models/service.rb b/app/models/service.rb
index d7a32c28267..a8e1cc2f422 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -17,6 +17,7 @@ class Service < ActiveRecord::Base
after_commit :reset_updated_properties
after_commit :cache_project_has_external_issue_tracker
+ after_commit :cache_project_has_external_wiki
belongs_to :project, inverse_of: :services
has_one :service_hook
@@ -25,6 +26,7 @@ class Service < ActiveRecord::Base
scope :visible, -> { where.not(type: ['GitlabIssueTrackerService', 'GitlabCiService']) }
scope :issue_trackers, -> { where(category: 'issue_tracker') }
+ scope :external_wikis, -> { where(type: 'ExternalWikiService') }
scope :active, -> { where(active: true) }
scope :without_defaults, -> { where(default: false) }
@@ -76,6 +78,22 @@ class Service < ActiveRecord::Base
[]
end
+ def test_data(project, user)
+ Gitlab::PushDataBuilder.build_sample(project, user)
+ end
+
+ def event_channel_names
+ []
+ end
+
+ def event_field(event)
+ nil
+ end
+
+ def global_fields
+ fields
+ end
+
def supported_events
%w(push tag_push issue merge_request wiki_page)
end
@@ -94,6 +112,11 @@ class Service < ActiveRecord::Base
!project.empty_repo?
end
+ # reason why service cannot be tested
+ def disabled_title
+ "Please setup a project repository."
+ end
+
# Provide convenient accessor methods
# for each serialized property.
# Also keep track of updated properties in a similar way as ActiveModel::Dirty
@@ -203,4 +226,10 @@ class Service < ActiveRecord::Base
project.cache_has_external_issue_tracker
end
end
+
+ def cache_project_has_external_wiki
+ if project && !project.destroyed?
+ project.cache_has_external_wiki
+ end
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 3d0a033785c..975e935fa20 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -854,7 +854,7 @@ class User < ActiveRecord::Base
groups.joins(:shared_projects).select(:project_id)]
if min_access_level
- scope = { access_level: Gitlab::Access.values.select { |access| access >= min_access_level } }
+ scope = { access_level: Gitlab::Access.all_values.select { |access| access >= min_access_level } }
relations = [relations.shift] + relations.map { |relation| relation.where(members: scope) }
end
diff --git a/app/services/ci/create_builds_service.rb b/app/services/ci/create_builds_service.rb
index 3b21f0acb96..4946f7076fd 100644
--- a/app/services/ci/create_builds_service.rb
+++ b/app/services/ci/create_builds_service.rb
@@ -15,7 +15,7 @@ module Ci
status == 'success'
when 'on_failure'
status == 'failed'
- when 'always'
+ when 'always', 'manual'
%w(success failed).include?(status)
end
end
@@ -47,6 +47,10 @@ module Ci
user: user,
project: @pipeline.project)
+ # TODO: The proper implementation for this is in
+ # https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/5295
+ build_attrs[:status] = 'skipped' if build_attrs[:when] == 'manual'
+
##
# We do not persist new builds here.
# Those will be persisted when @pipeline is saved.
diff --git a/app/services/commits/change_service.rb b/app/services/commits/change_service.rb
index c578097376a..ed73d8cb8c2 100644
--- a/app/services/commits/change_service.rb
+++ b/app/services/commits/change_service.rb
@@ -23,7 +23,7 @@ module Commits
private
def check_push_permissions
- allowed = ::Gitlab::GitAccess.new(current_user, project, 'web').can_push_to_branch?(@target_branch)
+ allowed = ::Gitlab::UserAccess.new(current_user, project: project).can_push_to_branch?(@target_branch)
unless allowed
raise ValidationError.new('You are not allowed to push into this branch')
@@ -31,7 +31,7 @@ module Commits
true
end
-
+
def create_target_branch(new_branch)
# Temporary branch exists and contains the change commit
return success if repository.find_branch(new_branch)
diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb
index d874582d54f..757fc35a78f 100644
--- a/app/services/create_branch_service.rb
+++ b/app/services/create_branch_service.rb
@@ -15,21 +15,19 @@ class CreateBranchService < BaseService
return error('Branch already exists')
end
- new_branch = nil
-
- if source_project != @project
- repository.with_tmp_ref do |tmp_ref|
- repository.fetch_ref(
- source_project.repository.path_to_repo,
- "refs/heads/#{ref}",
- tmp_ref
- )
-
- new_branch = repository.add_branch(current_user, branch_name, tmp_ref)
- end
- else
- new_branch = repository.add_branch(current_user, branch_name, ref)
- end
+ new_branch = if source_project != @project
+ repository.fetch_ref(
+ source_project.repository.path_to_repo,
+ "refs/heads/#{ref}",
+ "refs/heads/#{branch_name}"
+ )
+
+ repository.after_create_branch
+
+ repository.find_branch(branch_name)
+ else
+ repository.add_branch(current_user, branch_name, ref)
+ end
if new_branch
success(new_branch)
diff --git a/app/services/files/base_service.rb b/app/services/files/base_service.rb
index 37c5e321b39..c4a206f785e 100644
--- a/app/services/files/base_service.rb
+++ b/app/services/files/base_service.rb
@@ -9,12 +9,14 @@ module Files
@commit_message = params[:commit_message]
@file_path = params[:file_path]
+ @previous_path = params[:previous_path]
@file_content = if params[:file_content_encoding] == 'base64'
Base64.decode64(params[:file_content])
else
params[:file_content]
end
+ # Validate parameters
validate
# Create new branch if it different from source_branch
@@ -42,7 +44,7 @@ module Files
end
def validate
- allowed = ::Gitlab::GitAccess.new(current_user, project, 'web').can_push_to_branch?(@target_branch)
+ allowed = ::Gitlab::UserAccess.new(current_user, project: project).can_push_to_branch?(@target_branch)
unless allowed
raise_error("You are not allowed to push into this branch")
diff --git a/app/services/files/update_service.rb b/app/services/files/update_service.rb
index 1960dc7d949..8d2b5083179 100644
--- a/app/services/files/update_service.rb
+++ b/app/services/files/update_service.rb
@@ -3,7 +3,10 @@ require_relative "base_service"
module Files
class UpdateService < Files::BaseService
def commit
- repository.commit_file(current_user, @file_path, @file_content, @commit_message, @target_branch, true)
+ repository.update_file(current_user, @file_path, @file_content,
+ branch: @target_branch,
+ previous_path: @previous_path,
+ message: @commit_message)
end
end
end
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index a886f35981f..e02b50ff9a2 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -89,7 +89,8 @@ class GitPushService < BaseService
# Set protection on the default branch if configured
if current_application_settings.default_branch_protection != PROTECTION_NONE
developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false
- @project.protected_branches.create({ name: @project.default_branch, developers_can_push: developers_can_push })
+ developers_can_merge = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_MERGE ? true : false
+ @project.protected_branches.create({ name: @project.default_branch, developers_can_push: developers_can_push, developers_can_merge: developers_can_merge })
end
end
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index e3dc569152c..2d96efe1042 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -101,6 +101,7 @@ class IssuableBaseService < BaseService
def update(issuable)
change_state(issuable)
+ change_subscription(issuable)
filter_params
old_labels = issuable.labels.to_a
@@ -124,6 +125,15 @@ class IssuableBaseService < BaseService
end
end
+ def change_subscription(issuable)
+ case params.delete(:subscription_event)
+ when 'subscribe'
+ issuable.subscribe(current_user)
+ when 'unsubscribe'
+ issuable.unsubscribe(current_user)
+ end
+ end
+
def has_changes?(issuable, old_labels: [])
valid_attrs = [:title, :description, :assignee_id, :milestone_id, :target_branch]
diff --git a/app/services/issues/bulk_update_service.rb b/app/services/issues/bulk_update_service.rb
index cd08c3a0cb9..7e19a73f71a 100644
--- a/app/services/issues/bulk_update_service.rb
+++ b/app/services/issues/bulk_update_service.rb
@@ -4,7 +4,7 @@ module Issues
issues_ids = params.delete(:issues_ids).split(",")
issue_params = params
- %i(state_event milestone_id assignee_id add_label_ids remove_label_ids).each do |key|
+ %i(state_event milestone_id assignee_id add_label_ids remove_label_ids subscription_event).each do |key|
issue_params.delete(key) unless issue_params[key].present?
end
diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb
index f1b1d90c457..0dac0614141 100644
--- a/app/services/merge_requests/merge_service.rb
+++ b/app/services/merge_requests/merge_service.rb
@@ -34,7 +34,7 @@ module MergeRequests
committer: committer
}
- commit_id = repository.merge(current_user, merge_request.diff_head_sha, merge_request.target_branch, options)
+ commit_id = repository.merge(current_user, merge_request, options)
merge_request.update(merge_commit_sha: commit_id)
rescue GitHooksService::PreReceiveError => e
merge_request.update(merge_error: e.message)
@@ -43,6 +43,8 @@ module MergeRequests
merge_request.update(merge_error: "Something went wrong during merge")
Rails.logger.error(e.message)
false
+ ensure
+ merge_request.update(in_progress_merge_commit_sha: nil)
end
def after_merge
diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb
index b11ecd97a57..1daf6bbf553 100644
--- a/app/services/merge_requests/refresh_service.rb
+++ b/app/services/merge_requests/refresh_service.rb
@@ -48,7 +48,7 @@ module MergeRequests
end
def force_push?
- Gitlab::ForcePushCheck.force_push?(@project, @oldrev, @newrev)
+ Gitlab::Checks::ForcePush.force_push?(@project, @oldrev, @newrev)
end
# Refresh merge request diff if we push to source or target branch of merge request
diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb
index 998789d64d2..06252c7b625 100644
--- a/app/services/projects/import_export/export_service.rb
+++ b/app/services/projects/import_export/export_service.rb
@@ -9,7 +9,7 @@ module Projects
private
def save_all
- if [version_saver, project_tree_saver, uploads_saver, repo_saver, wiki_repo_saver].all?(&:save)
+ if [version_saver, avatar_saver, project_tree_saver, uploads_saver, repo_saver, wiki_repo_saver].all?(&:save)
Gitlab::ImportExport::Saver.save(project: project, shared: @shared)
notify_success
else
@@ -21,6 +21,10 @@ module Projects
Gitlab::ImportExport::VersionSaver.new(shared: @shared)
end
+ def avatar_saver
+ Gitlab::ImportExport::AvatarSaver.new(project: project, shared: @shared)
+ end
+
def project_tree_saver
Gitlab::ImportExport::ProjectTreeSaver.new(project: project, shared: @shared)
end
diff --git a/app/uploaders/avatar_uploader.rb b/app/uploaders/avatar_uploader.rb
index 6135c3ad96f..03d9329a14e 100644
--- a/app/uploaders/avatar_uploader.rb
+++ b/app/uploaders/avatar_uploader.rb
@@ -14,4 +14,8 @@ class AvatarUploader < CarrierWave::Uploader::Base
def reset_events_cache(file)
model.reset_events_cache if model.is_a?(User)
end
+
+ def exists?
+ model.avatar.file && model.avatar.file.exists?
+ end
end
diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml
index 0cc405401cf..5f7fdfdb011 100644
--- a/app/views/admin/groups/_form.html.haml
+++ b/app/views/admin/groups/_form.html.haml
@@ -9,6 +9,10 @@
= render 'shared/visibility_level', f: f, visibility_level: @group.visibility_level, can_change_visibility_level: can_change_group_visibility_level?(@group), form_model: @group
+ .form-group
+ .col-sm-offset-2.col-sm-10
+ = render 'shared/allow_request_access', form: f
+
- if @group.new_record?
.form-group
.col-sm-offset-2.col-sm-10
diff --git a/app/views/emojis/index.html.haml b/app/views/emojis/index.html.haml
index 8b38b4c2bd4..790d90ad3ee 100644
--- a/app/views/emojis/index.html.haml
+++ b/app/views/emojis/index.html.haml
@@ -1,5 +1,5 @@
.emoji-menu
- = text_field_tag :emoji_search, "", class: "emoji-search search-input form-control", placeholder: "Seach emojis"
+ = text_field_tag :emoji_search, "", class: "emoji-search search-input form-control", placeholder: "Search emoji"
.emoji-menu-content
- Gitlab::AwardEmoji.emoji_by_category.each do |category, emojis|
%h5.emoji-menu-title
diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml
index e4629bae0e6..5c318cd3b8b 100644
--- a/app/views/events/_event.html.haml
+++ b/app/views/events/_event.html.haml
@@ -4,11 +4,7 @@
#{time_ago_with_tooltip(event.created_at)}
= cache [event, current_application_settings, "v2.2"] do
- - if event.author
- = link_to user_path(event.author) do
- = image_tag avatar_icon(event.author_email, 40), class: "avatar s40", alt:''
- - else
- = image_tag avatar_icon(event.author_email, 40), class: "avatar s40", alt:''
+ = author_avatar(event, size: 40)
- if event.created_project?
= render "events/event/created_project", event: event
diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml
index 92cd4c553d0..decb89b2fd6 100644
--- a/app/views/groups/edit.html.haml
+++ b/app/views/groups/edit.html.haml
@@ -22,6 +22,10 @@
= render 'shared/visibility_level', f: f, visibility_level: @group.visibility_level, can_change_visibility_level: can_change_group_visibility_level?(@group), form_model: @group
.form-group
+ .col-sm-offset-2.col-sm-10
+ = render 'shared/allow_request_access', form: f
+
+ .form-group
%hr
= f.label :share_with_group_lock, class: 'control-label' do
Share with group lock
diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml
index 12e7ed0e792..351100f3523 100644
--- a/app/views/layouts/_init_auto_complete.html.haml
+++ b/app/views/layouts/_init_auto_complete.html.haml
@@ -1,7 +1,7 @@
- project = @target_project || @project
+- noteable_class = @noteable.class if @noteable.present?
-- if @noteable
- :javascript
- GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_namespace_project_path(project.namespace, project, type: @noteable.class, type_id: params[:id])}"
- GitLab.GfmAutoComplete.cachedData = undefined;
- GitLab.GfmAutoComplete.setup();
+:javascript
+ GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_namespace_project_path(project.namespace, project, type: noteable_class, type_id: params[:id])}"
+ GitLab.GfmAutoComplete.cachedData = undefined;
+ GitLab.GfmAutoComplete.setup();
diff --git a/app/views/layouts/nav/_explore.html.haml b/app/views/layouts/nav/_explore.html.haml
index 3b40006a0cc..e5bda7b3a6f 100644
--- a/app/views/layouts/nav/_explore.html.haml
+++ b/app/views/layouts/nav/_explore.html.haml
@@ -1,21 +1,17 @@
%ul.nav.nav-sidebar
= nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
= link_to explore_root_path, title: 'Projects' do
- = icon('bookmark fw')
%span
Projects
= nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do
= link_to explore_groups_path, title: 'Groups' do
- = icon('group fw')
%span
Groups
= nav_link(controller: :snippets) do
= link_to explore_snippets_path, title: 'Snippets' do
- = icon('clipboard fw')
%span
Snippets
= nav_link(controller: :help) do
= link_to help_path, title: 'Help' do
- = icon('question-circle fw')
%span
Help
diff --git a/app/views/layouts/nav/_project_settings.html.haml b/app/views/layouts/nav/_project_settings.html.haml
index 51a54b4f262..52a5bdc1a1b 100644
--- a/app/views/layouts/nav/_project_settings.html.haml
+++ b/app/views/layouts/nav/_project_settings.html.haml
@@ -39,7 +39,7 @@
= link_to namespace_project_triggers_path(@project.namespace, @project), title: 'Triggers' do
%span
Triggers
- = nav_link(controller: :badges) do
- = link_to namespace_project_badges_path(@project.namespace, @project), title: 'Badges' do
+ = nav_link(controller: :pipelines_settings) do
+ = link_to namespace_project_pipelines_settings_path(@project.namespace, @project), title: 'CI/CD Pipelines' do
%span
- Badges
+ CI/CD Pipelines
diff --git a/app/views/profiles/_head.html.haml b/app/views/profiles/_head.html.haml
index 003884a5bd9..943ebdaeffe 100644
--- a/app/views/profiles/_head.html.haml
+++ b/app/views/profiles/_head.html.haml
@@ -1,3 +1,3 @@
- content_for :page_specific_javascripts do
= page_specific_javascript_tag('lib/cropper.js')
- = page_specific_javascript_tag('profile/application.js')
+ = page_specific_javascript_tag('profile/profile_bundle.js')
diff --git a/app/views/projects/_builds_settings.html.haml b/app/views/projects/_builds_settings.html.haml
deleted file mode 100644
index fff30f11d82..00000000000
--- a/app/views/projects/_builds_settings.html.haml
+++ /dev/null
@@ -1,65 +0,0 @@
-%fieldset.builds-feature
- %h5.prepend-top-0
- Builds
- - unless @repository.gitlab_ci_yml
- .form-group
- %p Builds need to be configured before you can begin using Continuous Integration.
- = link_to 'Get started with Builds', help_page_path('ci/quick_start/README'), class: 'btn btn-info'
- .form-group
- %p Get recent application code using the following command:
- .radio
- = f.label :build_allow_git_fetch_false do
- = f.radio_button :build_allow_git_fetch, 'false'
- %strong git clone
- %br
- %span.descr Slower but makes sure you have a clean dir before every build
- .radio
- = f.label :build_allow_git_fetch_true do
- = f.radio_button :build_allow_git_fetch, 'true'
- %strong git fetch
- %br
- %span.descr Faster
-
- .form-group
- = f.label :build_timeout_in_minutes, 'Timeout', class: 'label-light'
- = f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0'
- %p.help-block per build in minutes
- .form-group
- = f.label :build_coverage_regex, "Test coverage parsing", class: 'label-light'
- .input-group
- %span.input-group-addon /
- = f.text_field :build_coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered'
- %span.input-group-addon /
- %p.help-block
- We will use this regular expression to find test coverage output in build trace.
- Leave blank if you want to disable this feature
- .bs-callout.bs-callout-info
- %p Below are examples of regex for existing tools:
- %ul
- %li
- Simplecov (Ruby) -
- %code \(\d+.\d+\%\) covered
- %li
- pytest-cov (Python) -
- %code \d+\%\s*$
- %li
- phpunit --coverage-text --colors=never (PHP) -
- %code ^\s*Lines:\s*\d+.\d+\%
- %li
- gcovr (C/C++) -
- %code ^TOTAL.*\s+(\d+\%)$
- %li
- tap --coverage-report=text-summary (Node.js) -
- %code ^Statements\s*:\s*([^%]+)
-
- .form-group
- .checkbox
- = f.label :public_builds do
- = f.check_box :public_builds
- %strong Public builds
- .help-block Allow everyone to access builds for Public and Internal projects
-
- .form-group.append-bottom-0
- = f.label :runners_token, "Runners token", class: 'label-light'
- = f.text_field :runners_token, class: "form-control", placeholder: 'xEeFCaDAB89'
- %p.help-block The secure token used to checkout project.
diff --git a/app/views/projects/badges/index.html.haml b/app/views/projects/badges/index.html.haml
deleted file mode 100644
index ac80951dd4f..00000000000
--- a/app/views/projects/badges/index.html.haml
+++ /dev/null
@@ -1,23 +0,0 @@
-- page_title 'Badges'
-- badges_path = namespace_project_badges_path(@project.namespace, @project)
-
-.prepend-top-10
- .panel.panel-default
- .panel-heading
- %b Builds badge &middot;
- = @build_badge.to_html
- .pull-right
- = render 'shared/ref_switcher', destination: 'badges', align_right: true
- .panel-body
- .row
- .col-md-2.text-center
- Markdown
- .col-md-10.code.js-syntax-highlight
- = highlight('.md', @build_badge.to_markdown)
- .row
- %hr
- .row
- .col-md-2.text-center
- HTML
- .col-md-10.code.js-syntax-highlight
- = highlight('.html', @build_badge.to_html)
diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml
index 29c7d45074a..ff379bafb26 100644
--- a/app/views/projects/blob/_editor.html.haml
+++ b/app/views/projects/blob/_editor.html.haml
@@ -4,7 +4,9 @@
= icon('code-fork')
= ref
%span.editor-file-name
- = @path
+ - if current_action?(:edit) || current_action?(:update)
+ = text_field_tag 'file_path', (params[:file_path] || @path),
+ class: 'form-control new-file-path'
- if current_action?(:new) || current_action?(:create)
%span.editor-file-name
diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml
index e48b78f9eef..b096516c627 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -27,9 +27,9 @@
= link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: branch.name), class: 'btn btn-default', method: :post, title: "Compare" do
Compare
- - pipeline = @project.latest_successful_pipeline_for(branch.name).first
+ - pipeline = @project.pipelines.latest_successful_for(branch.name).first
- if pipeline
- - artifacts = pipeline.builds.latest_successful_with_artifacts
+ - artifacts = pipeline.builds.latest.with_artifacts
- if artifacts.any?
.dropdown.inline.artifacts-btn
%a.btn.dropdown-toggle{ 'data-toggle' => 'dropdown' }
diff --git a/app/views/projects/builds/_sidebar.html.haml b/app/views/projects/builds/_sidebar.html.haml
index cab21f0cf19..dc57b49f27a 100644
--- a/app/views/projects/builds/_sidebar.html.haml
+++ b/app/views/projects/builds/_sidebar.html.haml
@@ -49,7 +49,7 @@
- if @build.duration
%p.build-detail-row
%span.build-light-text Duration:
- #{duration_in_words(@build.finished_at, @build.started_at)}
+ = time_interval_in_words(@build.duration)
- if @build.finished_at
%p.build-detail-row
%span.build-light-text Finished:
@@ -94,9 +94,9 @@
.block
.title
- Commit message
+ Commit title
%p.build-light-text.append-bottom-0
- #{@build.pipeline.git_commit_message}
+ #{@build.pipeline.git_commit_title}
- if @build.tags.any?
.block
diff --git a/app/views/projects/buttons/_download.html.haml b/app/views/projects/buttons/_download.html.haml
index 32f911f6b31..d135b448dd7 100644
--- a/app/views/projects/buttons/_download.html.haml
+++ b/app/views/projects/buttons/_download.html.haml
@@ -14,9 +14,9 @@
%li
= link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: @ref, format: 'tar.gz'), rel: 'nofollow' do
%span Download tar.gz
- - pipeline = @project.latest_successful_pipeline_for(@ref).first
+ - pipeline = @project.pipelines.latest_successful_for(@ref).first
- if pipeline
- - artifacts = pipeline.builds.latest_successful_with_artifacts
+ - artifacts = pipeline.builds.latest.with_artifacts
- if artifacts.any?
%li.dropdown-header Artifacts
- unless pipeline.latest?
diff --git a/app/views/projects/buttons/_fork.html.haml b/app/views/projects/buttons/_fork.html.haml
index a9eaed4c5f6..a098a082854 100644
--- a/app/views/projects/buttons/_fork.html.haml
+++ b/app/views/projects/buttons/_fork.html.haml
@@ -2,7 +2,7 @@
- if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn has-tooltip' do
- = icon('code-fork fw')
+ = custom_icon('icon_fork')
Fork
%div.count-with-arrow
%span.arrow
@@ -10,7 +10,7 @@
= @project.forks_count
- else
= link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn has-tooltip' do
- = icon('code-fork fw')
+ = custom_icon('icon_fork')
Fork
%div.count-with-arrow
%span.arrow
diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml
index e1b42b2cfa5..9264289987d 100644
--- a/app/views/projects/ci/builds/_build.html.haml
+++ b/app/views/projects/ci/builds/_build.html.haml
@@ -39,6 +39,8 @@
%span.label.label-danger allowed to fail
- if defined?(retried) && retried
%span.label.label-warning retried
+ - if build.manual?
+ %span.label.label-info manual
- if defined?(runner) && runner
@@ -79,6 +81,11 @@
- if build.active?
= link_to cancel_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Cancel', class: 'btn btn-build' do
= icon('remove', class: 'cred')
- - elsif defined?(allow_retry) && allow_retry && build.retryable?
- = link_to retry_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do
- = icon('repeat')
+ - elsif defined?(allow_retry) && allow_retry
+ - if build.retryable?
+ = link_to retry_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do
+ = icon('repeat')
+ - elsif build.playable?
+ = link_to play_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Play', class: 'btn btn-build' do
+ = icon('play')
+
diff --git a/app/views/projects/ci/pipelines/_pipeline.html.haml b/app/views/projects/ci/pipelines/_pipeline.html.haml
index 0557d384e33..2f7d54f0bdd 100644
--- a/app/views/projects/ci/pipelines/_pipeline.html.haml
+++ b/app/views/projects/ci/pipelines/_pipeline.html.haml
@@ -10,12 +10,13 @@
= link_to namespace_project_pipeline_path(@project.namespace, @project, pipeline.id) do
%span ##{pipeline.id}
- if pipeline.ref
+ .icon-container
+ = pipeline.tag? ? icon('tag') : icon('code-fork')
= link_to pipeline.ref, namespace_project_commits_path(@project.namespace, @project, pipeline.ref), class: "monospace branch-name"
- = custom_icon("icon_commit")
+ .icon-container
+ = custom_icon("icon_commit")
= link_to pipeline.short_sha, namespace_project_commit_path(@project.namespace, @project, pipeline.sha), class: "commit-id monospace"
- - if pipeline.tag?
- %span.label.label-primary tag
- - elsif pipeline.latest?
+ - if pipeline.latest?
%span.label.label-success.has-tooltip{ title: 'Latest build for this branch' } latest
- if pipeline.triggered?
%span.label.label-primary triggered
@@ -26,7 +27,7 @@
%p.commit-title
- if commit = pipeline.commit
- = commit_author_avatar(commit, size: 20)
+ = author_avatar(commit, size: 20)
= link_to_gfm truncate(commit.title, length: 60), namespace_project_commit_path(@project.namespace, @project, commit.id), class: "commit-row-message"
- else
Cant find HEAD commit for this branch
@@ -34,7 +35,7 @@
- stages_status = pipeline.statuses.latest.stages_status
- stages.each do |stage|
- %td
+ %td.stage-cell
- status = stages_status[stage]
- tooltip = "#{stage.titleize}: #{status || 'not found'}"
- if status
@@ -57,18 +58,31 @@
%td.pipeline-actions
.controls.hidden-xs.pull-right
- artifacts = pipeline.builds.latest.select { |b| b.artifacts? }
- - if artifacts.present?
- .inline
- .btn-group
- %a.dropdown-toggle.btn.btn-default.build-artifacts{type: 'button', 'data-toggle' => 'dropdown'}
- = icon("download")
- %b.caret
- %ul.dropdown-menu.dropdown-menu-align-right
- - artifacts.each do |build|
- %li
- = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, build), rel: 'nofollow' do
- = icon("download")
- %span Download '#{build.name}' artifacts
+ - actions = pipeline.manual_actions
+ - if artifacts.present? || actions.any?
+ .btn-group.inline
+ - if actions.any?
+ .btn-group
+ %a.dropdown-toggle.btn.btn-default{type: 'button', 'data-toggle' => 'dropdown'}
+ = icon("play")
+ %b.caret
+ %ul.dropdown-menu.dropdown-menu-align-right
+ - actions.each do |build|
+ %li
+ = link_to play_namespace_project_build_path(@project.namespace, @project, build), method: :post, rel: 'nofollow' do
+ = icon("play")
+ %span= build.name.humanize
+ - if artifacts.present?
+ .btn-group
+ %a.dropdown-toggle.btn.btn-default.build-artifacts{type: 'button', 'data-toggle' => 'dropdown'}
+ = icon("download")
+ %b.caret
+ %ul.dropdown-menu.dropdown-menu-align-right
+ - artifacts.each do |build|
+ %li
+ = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, build), rel: 'nofollow' do
+ = icon("download")
+ %span Download '#{build.name}' artifacts
- if can?(current_user, :update_pipeline, @project)
.cancel-retry-btns.inline
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index c8c7b858baa..ab9afb06afb 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -9,7 +9,8 @@
= cache(cache_key) do
%li.commit.js-toggle-container{ id: "commit-#{commit.short_id}" }
- = commit_author_avatar(commit, size: 36)
+ = author_avatar(commit, size: 36)
+
.commit-info-block
.commit-row-title
%span.item-title
diff --git a/app/views/projects/deployments/_actions.haml b/app/views/projects/deployments/_actions.haml
new file mode 100644
index 00000000000..65d68aa2985
--- /dev/null
+++ b/app/views/projects/deployments/_actions.haml
@@ -0,0 +1,22 @@
+- if can?(current_user, :create_deployment, deployment) && deployment.deployable
+ .pull-right
+ - actions = deployment.manual_actions
+ - if actions.present?
+ .btn-group.inline
+ .btn-group
+ %a.dropdown-toggle.btn.btn-default{type: 'button', 'data-toggle' => 'dropdown'}
+ = icon("play")
+ %b.caret
+ %ul.dropdown-menu.dropdown-menu-align-right
+ - actions.each do |action|
+ %li
+ = link_to [:play, @project.namespace.becomes(Namespace), @project, action], method: :post, rel: 'nofollow' do
+ = icon("play")
+ %span= action.name.humanize
+
+ - if local_assigns.fetch(:allow_rollback, false)
+ = link_to [:retry, @project.namespace.becomes(Namespace), @project, deployment.deployable], method: :post, class: 'btn btn-build' do
+ - if deployment.last?
+ Retry
+ - else
+ Rollback
diff --git a/app/views/projects/deployments/_deployment.html.haml b/app/views/projects/deployments/_deployment.html.haml
index d08dd92f1f6..baf02f1e6a0 100644
--- a/app/views/projects/deployments/_deployment.html.haml
+++ b/app/views/projects/deployments/_deployment.html.haml
@@ -7,17 +7,11 @@
%td
- if deployment.deployable
- = link_to namespace_project_build_path(@project.namespace, @project, deployment.deployable) do
+ = link_to [@project.namespace.becomes(Namespace), @project, deployment.deployable] do
= "#{deployment.deployable.name} (##{deployment.deployable.id})"
%td
#{time_ago_with_tooltip(deployment.created_at)}
%td
- - if can?(current_user, :create_deployment, deployment) && deployment.deployable
- .pull-right
- = link_to retry_namespace_project_build_path(@project.namespace, @project, deployment.deployable), method: :post, class: 'btn btn-build' do
- - if deployment.last?
- Retry
- - else
- Rollback
+ = render 'projects/deployments/actions', deployment: deployment, allow_rollback: true
diff --git a/app/views/projects/diffs/_content.html.haml b/app/views/projects/diffs/_content.html.haml
index 0c0424edffd..a1b071f130c 100644
--- a/app/views/projects/diffs/_content.html.haml
+++ b/app/views/projects/diffs/_content.html.haml
@@ -8,12 +8,12 @@
- elsif blob_text_viewable?(blob)
- if !project.repository.diffable?(blob)
.nothing-here-block This diff was suppressed by a .gitattributes entry.
+ - elsif diff_file.collapsed?
+ - url = url_for(params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path))
+ .nothing-here-block.diff-collapsed{data: { diff_for_path: url } }
+ This diff is collapsed. Click to expand it.
- elsif diff_file.diff_lines.length > 0
- - if diff_file.collapsed_by_default? && !expand_all_diffs?
- - url = url_for(params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path))
- .nothing-here-block.diff-collapsed{data: { diff_for_path: url } }
- This diff is collapsed. Click to expand it.
- - elsif diff_view == 'parallel'
+ - if diff_view == 'parallel'
= render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob
- else
= render "projects/diffs/text_file", diff_file: diff_file
diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml
index 20aaab5accf..8ae433b4823 100644
--- a/app/views/projects/diffs/_diffs.html.haml
+++ b/app/views/projects/diffs/_diffs.html.haml
@@ -6,7 +6,7 @@
.content-block.oneline-block.files-changed
.inline-parallel-buttons
- - unless expand_all_diffs?
+ - if !expand_all_diffs? && diff_files.any? { |diff_file| diff_file.collapsed? }
= link_to 'Expand all', url_for(params.merge(expand_all_diffs: 1, format: 'html')), class: 'btn btn-default'
- if show_whitespace_toggle
- if current_controller?(:commit)
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 57af167180b..921155e970b 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -32,6 +32,10 @@
%strong
= visibility_level_label(@project.visibility_level)
.light= visibility_level_description(@project.visibility_level, @project)
+
+ .form-group
+ = render 'shared/allow_request_access', form: f
+
.form-group
= f.label :tag_list, "Tags", class: 'label-light'
= f.text_field :tag_list, value: @project.tag_list.to_s, maxlength: 2000, class: "form-control"
@@ -86,8 +90,6 @@
%hr
= render 'merge_request_settings', f: f
%hr
- = render 'builds_settings', f: f
- %hr
%fieldset.features.append-bottom-default
%h5.prepend-top-0
Project avatar
diff --git a/app/views/projects/environments/_environment.html.haml b/app/views/projects/environments/_environment.html.haml
index eafa246d05f..e2453395602 100644
--- a/app/views/projects/environments/_environment.html.haml
+++ b/app/views/projects/environments/_environment.html.haml
@@ -15,3 +15,6 @@
%td
- if last_deployment
#{time_ago_with_tooltip(last_deployment.created_at)}
+
+ %td
+ = render 'projects/deployments/actions', deployment: last_deployment
diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml
index 303d7c23d01..a6dd34653ab 100644
--- a/app/views/projects/environments/index.html.haml
+++ b/app/views/projects/environments/index.html.haml
@@ -28,4 +28,5 @@
%th Environment
%th Last deployment
%th Date
+ %th
= render @environments
diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml
index b17aba2431f..b8b1ce52a91 100644
--- a/app/views/projects/environments/show.html.haml
+++ b/app/views/projects/environments/show.html.haml
@@ -5,7 +5,7 @@
%div{ class: container_class }
.top-area
.col-md-9
- %h3.page-title= @environment.name.titleize
+ %h3.page-title= @environment.name.capitalize
.col-md-3
.nav-controls
diff --git a/app/views/projects/forks/index.html.haml b/app/views/projects/forks/index.html.haml
index dbe9ddfde2f..a1d79bdabda 100644
--- a/app/views/projects/forks/index.html.haml
+++ b/app/views/projects/forks/index.html.haml
@@ -31,11 +31,11 @@
- if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn btn-new' do
- = icon('code-fork fw')
+ = custom_icon('icon_fork')
Fork
- else
= link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn btn-new' do
- = icon('code-fork fw')
+ = custom_icon('icon_fork')
Fork
diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml
index 73a7fc0e1ac..5242bc72b71 100644
--- a/app/views/projects/forks/new.html.haml
+++ b/app/views/projects/forks/new.html.haml
@@ -1,45 +1,54 @@
- page_title "Fork project"
-- if @namespaces.present?
- %h3.page-title Fork project
- %p.lead
- Click to fork the project to a user or group
- %hr
- .fork-namespaces
- - @namespaces.in_groups_of(6, false) do |group|
- .row
- - group.each do |namespace|
- .col-md-2.col-sm-3
- - if fork = namespace.find_fork_of(@project)
- .fork-thumbnail
- = link_to project_path(fork), title: "Visit project fork", class: 'has-tooltip' do
- = image_tag namespace_icon(namespace, 100)
- .caption
- %strong
- = namespace.human_name
- %div.text-primary
- Already forked
-
- - else
- .fork-thumbnail
- = link_to namespace_project_forks_path(@project.namespace, @project, namespace_key: namespace.id), title: "Fork here", method: "POST", class: 'has-tooltip' do
- = image_tag namespace_icon(namespace, 100)
- .caption
- %strong
- = namespace.human_name
-
- %p.light
- Fork is a copy of a project repository.
+.row.prepend-top-default
+ .col-lg-3
+ %h4.prepend-top-0
+ Fork project
+ %p
+ A fork is a copy of a project.
%br
- Forking a repository allows you to do changes without affecting the original project.
-- else
- %h3 No available namespaces to fork the project
- %p.slead
- You must have permission to create a project in a namespace before forking.
+ Forking a repository allows you to make changes without affecting the original project.
+ .col-lg-9
+ .fork-namespaces
+ - if @namespaces.present?
+ %label.label-light
+ %span
+ Click to fork the project to a user or group
+ - @namespaces.in_groups_of(6, false) do |group|
+ .row
+ - group.each do |namespace|
+ - avatar = namespace_icon(namespace, 100)
+ - if fork = namespace.find_fork_of(@project)
+ .fork-thumbnail.forked
+ = link_to project_path(fork) do
+ - if /no_((\w*)_)*avatar/.match(avatar)
+ .no-avatar
+ = icon 'question'
+ - else
+ = image_tag avatar
+ .caption
+ = namespace.human_name
+ - else
+ .fork-thumbnail
+ = link_to namespace_project_forks_path(@project.namespace, @project, namespace_key: namespace.id), method: "POST" do
+ - if /no_((\w*)_)*avatar/.match(avatar)
+ .no-avatar
+ = icon 'question'
+ - else
+ = image_tag avatar
+ .caption
+ = namespace.human_name
+ - else
+ %label.label-light
+ %span
+ No available namespaces to fork the project.
+ %br
+ %small
+ You must have permission to create a project in a namespace before forking.
-.save-project-loader.hide
- .center
- %h2
- %i.fa.fa-spinner.fa-spin
- Forking repository
- %p Please wait a moment, this page will automatically refresh when ready.
+ .save-project-loader.hide
+ .center
+ %h2
+ %i.fa.fa-spinner.fa-spin
+ Forking repository
+ %p Please wait a moment, this page will automatically refresh when ready.
diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
index 542827b2f15..331dc1fcc29 100644
--- a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
+++ b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
@@ -51,7 +51,7 @@
%td.duration
- if generic_commit_status.duration
= icon("clock-o")
- #{duration_in_words(generic_commit_status.finished_at, generic_commit_status.started_at)}
+ = time_interval_in_words(generic_commit_status.duration)
%td.timestamp
- if generic_commit_status.finished_at
diff --git a/app/views/projects/graphs/_head.html.haml b/app/views/projects/graphs/_head.html.haml
index ca347406dfe..45e51389c00 100644
--- a/app/views/projects/graphs/_head.html.haml
+++ b/app/views/projects/graphs/_head.html.haml
@@ -3,7 +3,7 @@
- content_for :page_specific_javascripts do
= page_specific_javascript_tag('lib/chart.js')
- = page_specific_javascript_tag('graphs/application.js')
+ = page_specific_javascript_tag('graphs/graphs_bundle.js')
= nav_link(action: :show) do
= link_to 'Contributors', namespace_project_graph_path
= nav_link(action: :commits) do
diff --git a/app/views/projects/merge_requests/widget/open/_conflicts.html.haml b/app/views/projects/merge_requests/widget/open/_conflicts.html.haml
index 06ab0a3fa00..f000cc38a65 100644
--- a/app/views/projects/merge_requests/widget/open/_conflicts.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_conflicts.html.haml
@@ -4,7 +4,7 @@
%p
Please resolve these conflicts or
- - if @merge_request.can_be_merged_by?(current_user)
+ - if @merge_request.can_be_merged_via_command_line_by?(current_user)
#{link_to "merge this request manually", "#modal_merge_info", class: "how_to_merge_link vlink", "data-toggle" => "modal"}.
- else
ask someone with write access to this repository to merge this request manually.
diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml
index 091af4df4a1..b2ece44d966 100644
--- a/app/views/projects/network/show.html.haml
+++ b/app/views/projects/network/show.html.haml
@@ -1,7 +1,7 @@
- page_title "Network", @ref
- content_for :page_specific_javascripts do
= page_specific_javascript_tag('lib/raphael.js')
- = page_specific_javascript_tag('network/application.js')
+ = page_specific_javascript_tag('network/network_bundle.js')
= render "projects/commits/head"
= render "head"
%div{ class: container_class }
diff --git a/app/views/projects/notes/_notes_with_form.html.haml b/app/views/projects/notes/_notes_with_form.html.haml
index 56d302fab82..74538a9723e 100644
--- a/app/views/projects/notes/_notes_with_form.html.haml
+++ b/app/views/projects/notes/_notes_with_form.html.haml
@@ -14,9 +14,9 @@
.disabled-comment.text-center
.disabled-comment-text.inline
Please
- = link_to "register",new_user_session_path
+ = link_to "register", new_session_path(:user, redirect_to_referer: 'yes')
or
- = link_to "login",new_user_session_path
+ = link_to "login", new_session_path(:user, redirect_to_referer: 'yes')
to post a comment
:javascript
diff --git a/app/views/projects/pipelines_settings/show.html.haml b/app/views/projects/pipelines_settings/show.html.haml
new file mode 100644
index 00000000000..228bad36ebd
--- /dev/null
+++ b/app/views/projects/pipelines_settings/show.html.haml
@@ -0,0 +1,103 @@
+- page_title "CI/CD Pipelines"
+
+.row.prepend-top-default
+ .col-lg-3.profile-settings-sidebar
+ %h4.prepend-top-0
+ = page_title
+ .col-lg-9
+ %h5.prepend-top-0
+ Pipelines
+ = form_for @project, url: namespace_project_pipelines_settings_path(@project.namespace.becomes(Namespace), @project), remote: true, authenticity_token: true do |f|
+ %fieldset.builds-feature
+ - unless @repository.gitlab_ci_yml
+ .form-group
+ %p Pipelines need to be configured before you can begin using Continuous Integration.
+ = link_to 'Get started with CI/CD Pipelines', help_page_path('ci/quick_start/README'), class: 'btn btn-info'
+ .form-group
+ %p Get recent application code using the following command:
+ .radio
+ = f.label :build_allow_git_fetch_false do
+ = f.radio_button :build_allow_git_fetch, 'false'
+ %strong git clone
+ %br
+ %span.descr Slower but makes sure you have a clean dir before every build
+ .radio
+ = f.label :build_allow_git_fetch_true do
+ = f.radio_button :build_allow_git_fetch, 'true'
+ %strong git fetch
+ %br
+ %span.descr Faster
+
+ .form-group
+ = f.label :build_timeout_in_minutes, 'Timeout', class: 'label-light'
+ = f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0'
+ %p.help-block per build in minutes
+ .form-group
+ = f.label :build_coverage_regex, "Test coverage parsing", class: 'label-light'
+ .input-group
+ %span.input-group-addon /
+ = f.text_field :build_coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered'
+ %span.input-group-addon /
+ %p.help-block
+ We will use this regular expression to find test coverage output in build trace.
+ Leave blank if you want to disable this feature
+ .bs-callout.bs-callout-info
+ %p Below are examples of regex for existing tools:
+ %ul
+ %li
+ Simplecov (Ruby) -
+ %code \(\d+.\d+\%\) covered
+ %li
+ pytest-cov (Python) -
+ %code \d+\%\s*$
+ %li
+ phpunit --coverage-text --colors=never (PHP) -
+ %code ^\s*Lines:\s*\d+.\d+\%
+ %li
+ gcovr (C/C++) -
+ %code ^TOTAL.*\s+(\d+\%)$
+ %li
+ tap --coverage-report=text-summary (Node.js) -
+ %code ^Statements\s*:\s*([^%]+)
+
+ .form-group
+ .checkbox
+ = f.label :public_builds do
+ = f.check_box :public_builds
+ %strong Public pipelines
+ .help-block Allow everyone to access pipelines for Public and Internal projects
+
+ .form-group.append-bottom-default
+ = f.label :runners_token, "Runners token", class: 'label-light'
+ = f.text_field :runners_token, class: "form-control", placeholder: 'xEeFCaDAB89'
+ %p.help-block The secure token used to checkout project.
+
+ = f.submit 'Save changes', class: "btn btn-save"
+
+%hr
+
+.row.prepend-top-default
+ .col-lg-3.profile-settings-sidebar
+ %h4.prepend-top-0
+ Builds Badge
+ .col-lg-9
+ .prepend-top-10
+ .panel.panel-default
+ .panel-heading
+ %b Builds badge &middot;
+ = @build_badge.to_html
+ .pull-right
+ = render 'shared/ref_switcher', destination: 'badges', align_right: true
+ .panel-body
+ .row
+ .col-md-2.text-center
+ Markdown
+ .col-md-10.code.js-syntax-highlight
+ = highlight('.md', @build_badge.to_markdown)
+ .row
+ %hr
+ .row
+ .col-md-2.text-center
+ HTML
+ .col-md-10.code.js-syntax-highlight
+ = highlight('.html', @build_badge.to_html)
diff --git a/app/views/projects/protected_branches/_branches_list.html.haml b/app/views/projects/protected_branches/_branches_list.html.haml
index 97cb1a9052b..720d67dff7c 100644
--- a/app/views/projects/protected_branches/_branches_list.html.haml
+++ b/app/views/projects/protected_branches/_branches_list.html.haml
@@ -8,6 +8,7 @@
.table-responsive
%table.table.protected-branches-list
%colgroup
+ %col{ width: "20%" }
%col{ width: "30%" }
%col{ width: "25%" }
%col{ width: "25%" }
@@ -18,6 +19,7 @@
%th Protected Branch
%th Commit
%th Developers Can Push
+ %th Developers Can Merge
- if can_admin_project
%th
%tbody
diff --git a/app/views/projects/protected_branches/_protected_branch.html.haml b/app/views/projects/protected_branches/_protected_branch.html.haml
index 474aec3a97c..7fda7f96047 100644
--- a/app/views/projects/protected_branches/_protected_branch.html.haml
+++ b/app/views/projects/protected_branches/_protected_branch.html.haml
@@ -16,6 +16,8 @@
(branch was removed from repository)
%td
= check_box_tag("developers_can_push", protected_branch.id, protected_branch.developers_can_push, data: { url: url })
+ %td
+ = check_box_tag("developers_can_merge", protected_branch.id, protected_branch.developers_can_merge, data: { url: url })
- if can_admin_project
%td
= link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, protected_branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-warning btn-sm pull-right"
diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml
index 883d3e3af1e..151e1d64851 100644
--- a/app/views/projects/protected_branches/index.html.haml
+++ b/app/views/projects/protected_branches/index.html.haml
@@ -36,6 +36,14 @@
= f.label :developers_can_push, "Developers can push", class: "label-light append-bottom-0"
%p.light.append-bottom-0
Allow developers to push to this branch
+
+ .form-group
+ = f.check_box :developers_can_merge, class: "pull-left"
+ .prepend-left-20
+ = f.label :developers_can_merge, "Developers can merge", class: "label-light append-bottom-0"
+ %p.light.append-bottom-0
+ Allow developers to accept merge requests to this branch
= f.submit "Protect", class: "btn-create btn protect-branch-btn", disabled: true
+
%hr
= render "branches_list"
diff --git a/app/views/projects/repositories/_download_archive.html.haml b/app/views/projects/repositories/_download_archive.html.haml
index e29d99371c8..183daebfc3a 100644
--- a/app/views/projects/repositories/_download_archive.html.haml
+++ b/app/views/projects/repositories/_download_archive.html.haml
@@ -25,9 +25,9 @@
= link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'tar'), rel: 'nofollow' do
%i.fa.fa-download
%span Download tar
- - pipeline = @project.latest_successful_pipeline_for(ref).first
+ - pipeline = @project.pipelines.latest_successful_for(ref).first
- if pipeline
- - artifacts = pipeline.builds.latest_successful_with_artifacts
+ - artifacts = pipeline.builds.latest.with_artifacts
- if artifacts.any?
%li.dropdown-header Artifacts
- unless pipeline.latest?
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index 1f13ea28b4e..752fbc21a11 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -8,9 +8,10 @@
.col-lg-9
= form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |form|
= render 'shared/service_settings', form: form
+
= form.submit 'Save changes', class: 'btn btn-save'
&nbsp;
- if @service.valid? && @service.activated?
- disabled = @service.can_test? ? '':'disabled'
- = link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service.to_param), class: "btn #{disabled}"
+ = link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service), class: "btn #{disabled}", title: @service.disabled_title
= link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel"
diff --git a/app/views/projects/tags/_download.html.haml b/app/views/projects/tags/_download.html.haml
index 8acf145049a..bb2e5224306 100644
--- a/app/views/projects/tags/_download.html.haml
+++ b/app/views/projects/tags/_download.html.haml
@@ -12,9 +12,9 @@
%li
= link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar.gz'), rel: 'nofollow' do
%span Download tar.gz
- - pipeline = project.latest_successful_pipeline_for(ref).first
+ - pipeline = project.pipelines.latest_successful_for(ref).first
- if pipeline
- - artifacts = pipeline.builds.latest_successful_with_artifacts
+ - artifacts = pipeline.builds.latest.with_artifacts
- if artifacts.any?
%li.dropdown-header Artifacts
- unless pipeline.latest?
diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml
index b7d7d5c5382..395d7af6cbb 100644
--- a/app/views/projects/tags/show.html.haml
+++ b/app/views/projects/tags/show.html.haml
@@ -1,36 +1,39 @@
+- @no_container = true
- page_title @tag.name, "Tags"
= render "projects/commits/head"
-.row-content-block
- .pull-right
- - if can?(current_user, :push_code, @project)
- = link_to edit_namespace_project_tag_release_path(@project.namespace, @project, @tag.name), class: 'btn-grouped btn has-tooltip', title: 'Edit release notes' do
- = icon("pencil")
- = link_to namespace_project_tree_path(@project.namespace, @project, @tag.name), class: 'btn btn-grouped has-tooltip', title: 'Browse files' do
- = icon('files-o')
- = link_to namespace_project_commits_path(@project.namespace, @project, @tag.name), class: 'btn btn-grouped has-tooltip', title: 'Browse commits' do
- = icon('history')
- - if can? current_user, :download_code, @project
- = render 'projects/tags/download', ref: @tag.name, project: @project
- - if can?(current_user, :admin_project, @project)
- .pull-right
- = link_to namespace_project_tag_path(@project.namespace, @project, @tag.name), class: 'btn btn-remove remove-row grouped has-tooltip', title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{@tag.name}' tag cannot be undone. Are you sure?" } do
- %i.fa.fa-trash-o
- .title
- %span.item-title= @tag.name
- - if @commit
- = render 'projects/branches/commit', commit: @commit, project: @project
- - else
- Cant find HEAD commit for this tag
- - if @tag.message.present?
- %pre.body
- = strip_gpg_signature(@tag.message)
+%div{ class: container_class }
+ .sub-header-block
+ .pull-right.tag-buttons
+ - if can?(current_user, :push_code, @project)
+ = link_to edit_namespace_project_tag_release_path(@project.namespace, @project, @tag.name), class: 'btn has-tooltip', title: 'Edit release notes' do
+ = icon("pencil")
+ = link_to namespace_project_tree_path(@project.namespace, @project, @tag.name), class: 'btn has-tooltip', title: 'Browse files' do
+ = icon('files-o')
+ = link_to namespace_project_commits_path(@project.namespace, @project, @tag.name), class: 'btn has-tooltip', title: 'Browse commits' do
+ = icon('history')
+ - if can? current_user, :download_code, @project
+ = render 'projects/tags/download', ref: @tag.name, project: @project
+ - if can?(current_user, :admin_project, @project)
+ .pull-right
+ = link_to namespace_project_tag_path(@project.namespace, @project, @tag.name), class: 'btn btn-remove remove-row grouped has-tooltip', title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{@tag.name}' tag cannot be undone. Are you sure?" } do
+ %i.fa.fa-trash-o
+ .tag-info.append-bottom-10
+ .title
+ %span.item-title= @tag.name
+ - if @commit
+ = render 'projects/branches/commit', commit: @commit, project: @project
+ - else
+ Cant find HEAD commit for this tag
+ - if @tag.message.present?
+ %pre.body
+ = strip_gpg_signature(@tag.message)
-.append-bottom-default.prepend-top-default
- - if @release.description.present?
- .description
- .wiki
- = preserve do
- = markdown @release.description
- - else
- This tag has no release notes.
+ .append-bottom-default.prepend-top-default
+ - if @release.description.present?
+ .description
+ .wiki
+ = preserve do
+ = markdown @release.description
+ - else
+ This tag has no release notes.
diff --git a/app/views/shared/_allow_request_access.html.haml b/app/views/shared/_allow_request_access.html.haml
new file mode 100644
index 00000000000..53a99a736c0
--- /dev/null
+++ b/app/views/shared/_allow_request_access.html.haml
@@ -0,0 +1,6 @@
+.checkbox
+ = form.label :request_access_enabled do
+ = form.check_box :request_access_enabled
+ %strong Allow users to request access
+ %br
+ %span.descr Allow users to request access if visibility is public or internal.
diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml
index 4eaf7c2a025..5254d265918 100644
--- a/app/views/shared/_service_settings.html.haml
+++ b/app/views/shared/_service_settings.html.haml
@@ -10,69 +10,28 @@
.col-sm-10
= form.check_box :active
-- if @service.supported_events.length > 1
- .form-group
- = form.label :url, "Trigger", class: 'control-label'
- .col-sm-10
- - if @service.supported_events.include?("push")
- %div
- = form.check_box :push_events, class: 'pull-left'
- .prepend-left-20
- = form.label :push_events, class: 'list-label' do
- %strong Push events
- %p.light
- This url will be triggered by a push to the repository
- - if @service.supported_events.include?("tag_push")
- %div
- = form.check_box :tag_push_events, class: 'pull-left'
- .prepend-left-20
- = form.label :tag_push_events, class: 'list-label' do
- %strong Tag push events
- %p.light
- This url will be triggered when a new tag is pushed to the repository
- - if @service.supported_events.include?("note")
- %div
- = form.check_box :note_events, class: 'pull-left'
- .prepend-left-20
- = form.label :note_events, class: 'list-label' do
- %strong Comments
- %p.light
- This url will be triggered when someone adds a comment
- - if @service.supported_events.include?("issue")
- %div
- = form.check_box :issues_events, class: 'pull-left'
- .prepend-left-20
- = form.label :issues_events, class: 'list-label' do
- %strong Issues events
- %p.light
- This url will be triggered when an issue is created/updated/merged
- - if @service.supported_events.include?("merge_request")
- %div
- = form.check_box :merge_requests_events, class: 'pull-left'
- .prepend-left-20
- = form.label :merge_requests_events, class: 'list-label' do
- %strong Merge Request events
- %p.light
- This url will be triggered when a merge request is created/updated/merged
- - if @service.supported_events.include?("build")
- %div
- = form.check_box :build_events, class: 'pull-left'
- .prepend-left-20
- = form.label :build_events, class: 'list-label' do
- %strong Build events
- %p.light
- This url will be triggered when a build status changes
- - if @service.supported_events.include?("wiki_page")
- %div
- = form.check_box :wiki_page_events, class: 'pull-left'
- .prepend-left-20
- = form.label :wiki_page_events, class: 'list-label' do
- %strong Wiki Page events
- %p.light
- This url will be triggered when a wiki page is created/updated
+.form-group
+ = form.label :url, "Trigger", class: 'control-label'
+
+ .col-sm-10
+ - @service.supported_events.each do |event|
+ %div
+ = form.check_box service_event_field_name(event), class: 'pull-left'
+ .prepend-left-20
+ = form.label service_event_field_name(event), class: 'list-label' do
+ %strong
+ = event.humanize
+
+ - field = @service.event_field(event)
+
+ - if field
+ %p
+ = form.text_field field[:name], class: "form-control", placeholder: field[:placeholder]
+ %p.light
+ = service_event_description(event)
-- @service.fields.each do |field|
+- @service.global_fields.each do |field|
- type = field[:type]
- if type == 'fieldset'
diff --git a/app/views/shared/icons/_icon_fork.svg b/app/views/shared/icons/_icon_fork.svg
new file mode 100644
index 00000000000..420ffe3a55b
--- /dev/null
+++ b/app/views/shared/icons/_icon_fork.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><circle id="a" cx="4" cy="4" r="4"/><mask id="d" width="8" height="8" x="0" y="0" fill="#fff"><use xlink:href="#a"/></mask><circle id="b" cx="20" cy="4" r="4"/><mask id="e" width="8" height="8" x="0" y="0" fill="#fff"><use xlink:href="#b"/></mask><circle id="c" cx="12" cy="30" r="4"/><mask id="f" width="8" height="8" x="0" y="0" fill="#fff"><use xlink:href="#c"/></mask></defs><g fill="none" fill-rule="evenodd" transform="translate(8 3)"><path fill="#7E7E7E" d="M10 19.667c-4.14-1.29-7.389-5.878-7.389-5.878C2.274 13.353 2 12.545 2 12.01V6h4v5.509c0 .276.166.65.367.831 0 0 1.136 1.028 1.746 1.574C9.617 15.261 11.048 16 12.09 16c1.028 0 2.41-.723 3.858-2.048.588-.54 1.84-1.742 1.84-1.742a.784.784 0 0 0 .211-.502V6h4v6.008c0 .548-.259 1.349-.601 1.795 0 0-3.21 4.707-7.399 5.916V27h-4v-7.333z"/><use stroke="#7E7E7E" stroke-width="4" mask="url(#d)" xlink:href="#a"/><use stroke="#7E7E7E" stroke-width="4" mask="url(#e)" xlink:href="#b"/><use stroke="#7E7E7E" stroke-width="4" mask="url(#f)" xlink:href="#c"/></g></svg> \ No newline at end of file
diff --git a/app/views/shared/icons/_icon_status_cancel.svg b/app/views/shared/icons/_icon_status_cancel.svg
new file mode 100644
index 00000000000..6a0bc1490c4
--- /dev/null
+++ b/app/views/shared/icons/_icon_status_cancel.svg
@@ -0,0 +1,12 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <circle id="a" cx="7" cy="7" r="7"/>
+ <mask id="b" width="14" height="14" x="0" y="0" fill="white">
+ <use xlink:href="#a"/>
+ </mask>
+ </defs>
+ <g fill="none" fill-rule="evenodd">
+ <use stroke="#5C5C5C" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
+ <rect width="10" height="1" x="2" y="6.5" fill="#5C5C5C" transform="rotate(45 7 7)" rx=".3"/>
+ </g>
+</svg>
diff --git a/app/views/shared/icons/_icon_status_failed.svg b/app/views/shared/icons/_icon_status_failed.svg
new file mode 100644
index 00000000000..c41ca18cae7
--- /dev/null
+++ b/app/views/shared/icons/_icon_status_failed.svg
@@ -0,0 +1,12 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <circle id="a" cx="7" cy="7" r="7"/>
+ <mask id="b" width="14" height="14" x="0" y="0" fill="white">
+ <use xlink:href="#a"/>
+ </mask>
+ </defs>
+ <g fill="none" fill-rule="evenodd">
+ <use stroke="#D22852" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
+ <path fill="#D22852" d="M7.5,6.5 L7.5,4.30578971 C7.5,4.12531853 7.36809219,4 7.20537567,4 L6.79462433,4 C6.63904572,4 6.5,4.13690672 6.5,4.30578971 L6.5,6.5 L4.30578971,6.5 C4.12531853,6.5 4,6.63190781 4,6.79462433 L4,7.20537567 C4,7.36095428 4.13690672,7.5 4.30578971,7.5 L6.5,7.5 L6.5,9.69421029 C6.5,9.87468147 6.63190781,10 6.79462433,10 L7.20537567,10 C7.36095428,10 7.5,9.86309328 7.5,9.69421029 L7.5,7.5 L9.69421029,7.5 C9.87468147,7.5 10,7.36809219 10,7.20537567 L10,6.79462433 C10,6.63904572 9.86309328,6.5 9.69421029,6.5 L7.5,6.5 Z" transform="rotate(45 7 7)"/>
+ </g>
+</svg>
diff --git a/app/views/shared/icons/_icon_status_pending.svg b/app/views/shared/icons/_icon_status_pending.svg
new file mode 100644
index 00000000000..035cd8b4ccc
--- /dev/null
+++ b/app/views/shared/icons/_icon_status_pending.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <circle id="a" cx="7" cy="7" r="7"/>
+ <mask id="b" width="14" height="14" x="0" y="0" fill="white">
+ <use xlink:href="#a"/>
+ </mask>
+ </defs>
+ <g fill="none" fill-rule="evenodd">
+ <use stroke="#E75E40" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
+ <rect width="1" height="4" x="5" y="5" fill="#E75E40" rx=".3"/>
+ <rect width="1" height="4" x="8" y="5" fill="#E75E40" rx=".3"/>
+ </g>
+</svg>
diff --git a/app/views/shared/icons/_icon_status_running.svg b/app/views/shared/icons/_icon_status_running.svg
new file mode 100644
index 00000000000..a48b3a25099
--- /dev/null
+++ b/app/views/shared/icons/_icon_status_running.svg
@@ -0,0 +1,12 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <circle id="a" cx="7" cy="7" r="7"/>
+ <mask id="b" width="14" height="14" x="0" y="0" fill="white">
+ <use xlink:href="#a"/>
+ </mask>
+ </defs>
+ <g fill="none" fill-rule="evenodd">
+ <use stroke="#2D9FD8" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
+ <path fill="#2D9FD8" d="M7,3.00800862 C9.09023405,3.13960661 10.7448145,4.87657932 10.7448145,7 C10.7448145,9.209139 8.95395346,11 6.74481446,11 C5.4560962,11 4.30972054,10.3905589 3.57817301,9.44416214 L7,7 L7,3.00800862 Z"/>
+ </g>
+</svg>
diff --git a/app/views/shared/icons/_icon_status_success.svg b/app/views/shared/icons/_icon_status_success.svg
new file mode 100644
index 00000000000..260eab013a3
--- /dev/null
+++ b/app/views/shared/icons/_icon_status_success.svg
@@ -0,0 +1,15 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <circle id="a" cx="7" cy="7" r="7"/>
+ <mask id="b" width="14" height="14" x="0" y="0" fill="white">
+ <use xlink:href="#a"/>
+ </mask>
+ </defs>
+ <g fill="none" fill-rule="evenodd">
+ <use stroke="#31AF64" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
+ <g fill="#31AF64" transform="rotate(45 -.13 10.953)">
+ <rect width="1" height="5" x="2" rx=".3"/>
+ <rect width="3" height="1" y="4" rx=".3"/>
+ </g>
+ </g>
+</svg>
diff --git a/app/views/shared/icons/_icon_status_warning.svg b/app/views/shared/icons/_icon_status_warning.svg
new file mode 100644
index 00000000000..d47e7a1c93f
--- /dev/null
+++ b/app/views/shared/icons/_icon_status_warning.svg
@@ -0,0 +1,15 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <circle id="a" cx="7" cy="7" r="7"/>
+ <mask id="b" width="14" height="14" x="0" y="0" fill="white">
+ <use xlink:href="#a"/>
+ </mask>
+ </defs>
+ <g fill="none" fill-rule="evenodd">
+ <g fill="#FF8A24" transform="translate(6 3)">
+ <rect width="2" height="5" rx=".5"/>
+ <rect width="2" height="2" y="6" rx=".5"/>
+ </g>
+ <use stroke="#FF8A24" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
+ </g>
+</svg>
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index 094d6636c66..0b7fa8c7d06 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -44,9 +44,15 @@
placeholder: "Search authors", data: { first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: @project.id, field_name: "update[assignee_id]" } })
.filter-item.inline
= dropdown_tag("Milestone", options: { title: "Assign milestone", toggle_class: 'js-milestone-select js-extra-options js-filter-submit js-filter-bulk-update', filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone", placeholder: "Search milestones", data: { show_no: true, field_name: "update[milestone_id]", project_id: @project.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), use_id: true } })
-
.filter-item.inline.labels-filter
= render "shared/issuable/label_dropdown", classes: ['js-filter-bulk-update', 'js-multiselect'], show_create: false, show_footer: false, extra_options: false, filter_submit: false, show_footer: false, data_options: { persist_when_hide: "true", field_name: "update[label_ids][]", show_no: false, show_any: false, use_id: true }
+ .filter-item.inline
+ = dropdown_tag("Subscription", options: { toggle_class: "js-subscription-event", title: "Change subscription", dropdown_class: "dropdown-menu-selectable", data: { field_name: "update[subscription_event]" } } ) do
+ %ul
+ %li
+ %a{href: "#", data: {id: "subscribe"}} Subscribe
+ %li
+ %a{href: "#", data: {id: "unsubscribe"}} Unsubscribe
= hidden_field_tag 'update[issues_ids]', []
= hidden_field_tag :state_event, params[:state_event]
@@ -63,6 +69,7 @@
new LabelsSelect();
new MilestoneSelect();
new IssueStatusSelect();
+ new SubscriptionSelect();
$('form.filter-form').on('submit', function (event) {
event.preventDefault();
Turbolinks.visit(this.action + '&' + $(this).serialize());
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index db2b4885861..c7f39868e71 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -2,7 +2,7 @@
- page_description @user.bio
- content_for :page_specific_javascripts do
= page_specific_javascript_tag('lib/d3.js')
- = page_specific_javascript_tag('users/application.js')
+ = page_specific_javascript_tag('users/users_bundle.js')
- header_title @user.name, user_path(@user)
- @no_container = true