Login Incentives (#8230)

* feat(incentives): login bennies WIP

* feat(content): incentive prize content WIP

* fix(content): placeholders pass tests

* WIP(content): Bard instrument placeholder

* feat(content): Incentives build

* chore(sprites): compile
and fix some strings

* WIP(incentives): quests and backgrounds

* fix(quests): correct buy/launch handling

* [WIP] Incentives rewarding (#8226)

* Added login incentive rewards

* Updated incentive rewards

* Added incentive modal and updated notification structure

* Added analytics to sleeping

* Added login incentives to user analytics

* Fixed unit tests and ensured that prizes are incremented and not replaced

* Updated style of daily login incentive modal

* Added rewards modal

* Added translations

* Added loigin incentive ui elements to profile

* Updated login incentives structure and abstracted to common.content

* Added dynamic display for login incentives on profile

* Added purple potion image

* Updated daily login modal

* Fixed progress calculation

* Added bard gear

* Updated login incentive rewards

* Fixed styles and text

* Added multiple read for notifications

* Fixed lint issues

* Fixed styles and added 50 limit

* Updated quest keys

* Added login incentives reward page

* Fixed tests

* Fixed linting and tests

* Read named notifications route. Add image for backgrounds

* Fixed style issues and added tranlsations to login incentive notification

* Hided abiltiy to purchase incentive backgrounds and added message to detail how to unlock

* Updated awarded message

* Fixed text and updated progress counter to display better

* Fixed purple potion reward text

* Fixed check in backgrouns reward text

* fix(quest): pass tests

* Added display of multiple rewards

* Updated modal styles

* Fixed neagtive 50 issue

* Remvoed total count from daily login incentives modal

* Fixed magic paw display

* fix(awards): give bunnies again

* WIP(incentives): more progress on BG shop

* fix(incentives): actually award backgrounds

* fix(incentives): more BG fixy

* fix(backgrounds): don't gem-buy checkin bgs

* Added dust bunny notification

* fix(incentives): don't redisplay bunny award

* chore(news): Bailey
and different promo sprite
This commit is contained in:
Sabe Jones
2016-11-23 19:34:09 -06:00
committed by GitHub
parent dcc06931cc
commit 25b0ff38c4
180 changed files with 34773 additions and 32923 deletions

View File

@@ -0,0 +1,26 @@
import {
generateUser,
translate as t,
} from '../../../../helpers/api-v3-integration.helper';
import { v4 as generateUUID } from 'uuid';
describe('POST /notifications/:notificationId/read', () => {
let user;
before(async () => {
user = await generateUser();
});
it('errors when notification is not found', async () => {
let dummyId = generateUUID();
await expect(user.post(`/notifications/${dummyId}/read`))
.to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: t('messageNotificationNotFound'),
});
});
xit('removes a notification', async () => {
});
});

View File

@@ -278,6 +278,7 @@ describe('analyticsService', () => {
todos: [{_id: 'todo'}],
rewards: [{_id: 'reward'}],
balance: 12,
loginIncentives: 1,
};
data.user = user;
@@ -302,6 +303,7 @@ describe('analyticsService', () => {
contributorLevel: 1,
subscription: 'foo-plan',
balance: 12,
loginIncentives: 1,
},
});
});

View File

@@ -8,6 +8,7 @@ import { model as User } from '../../../../../website/server/models/user';
import * as Tasks from '../../../../../website/server/models/task';
import { clone } from 'lodash';
import common from '../../../../../website/common';
import analytics from '../../../../../website/server/libs/analyticsService';
// const scoreTask = common.ops.scoreTask;
@@ -17,9 +18,6 @@ describe('cron', () => {
let user;
let tasksByType = {habits: [], dailys: [], todos: [], rewards: []};
let daysMissed = 0;
let analytics = {
track: sinon.spy(),
};
beforeEach(() => {
user = new User({
@@ -34,11 +32,17 @@ describe('cron', () => {
},
});
sinon.spy(analytics, 'track');
user._statsComputed = {
mp: 10,
};
});
afterEach(() => {
analytics.track.restore();
});
it('updates user.preferences.timezoneOffsetAtLastCron', () => {
let timezoneOffsetFromUserPrefs = 1;
@@ -59,6 +63,11 @@ describe('cron', () => {
expect(user.flags.cronCount).to.be.greaterThan(cronCountBefore);
});
it('calls analytics', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(analytics.track.callCount).to.equal(1);
});
describe('end of the month perks', () => {
beforeEach(() => {
user.purchased.plan.customerId = 'subscribedId';
@@ -257,6 +266,11 @@ describe('cron', () => {
user.preferences.sleep = true;
});
it('calls analytics', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(analytics.track.callCount).to.equal(1);
});
it('clears user buffs', () => {
user.stats.buffs = {
str: 1,
@@ -656,9 +670,9 @@ describe('cron', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(user.notifications.length).to.equal(1);
expect(user.notifications[0].type).to.equal('CRON');
expect(user.notifications[0].data).to.eql({
expect(user.notifications.length).to.be.greaterThan(0);
expect(user.notifications[1].type).to.equal('CRON');
expect(user.notifications[1].data).to.eql({
hp: user.stats.hp - hpBefore,
mp: user.stats.mp - mpBefore,
});
@@ -675,13 +689,14 @@ describe('cron', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(user.notifications.length).to.equal(1);
expect(user.notifications[0].type).to.equal('CRON');
expect(user.notifications[0].data).to.eql({
expect(user.notifications.length).to.be.greaterThan(0);
expect(user.notifications[1].type).to.equal('CRON');
expect(user.notifications[1].data).to.eql({
hp: user.stats.hp - hpBefore1,
mp: user.stats.mp - mpBefore1,
});
let notifsBefore2 = user.notifications.length;
let hpBefore2 = user.stats.hp;
let mpBefore2 = user.stats.mp;
@@ -689,12 +704,14 @@ describe('cron', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(user.notifications.length).to.equal(1);
expect(user.notifications[0].type).to.equal('CRON');
expect(user.notifications[0].data).to.eql({
expect(user.notifications.length - notifsBefore2).to.equal(1);
expect(user.notifications[1].type).to.not.equal('CRON');
expect(user.notifications[2].type).to.equal('CRON');
expect(user.notifications[2].data).to.eql({
hp: user.stats.hp - hpBefore2 - (hpBefore2 - hpBefore1),
mp: user.stats.mp - mpBefore2 - (mpBefore2 - mpBefore1),
});
expect(user.notifications[1].type).to.not.equal('CRON');
});
});
@@ -747,6 +764,178 @@ describe('cron', () => {
expect(user.inbox.messages[messageId]).to.not.exist;
});
});
describe('login incentives', () => {
it('increments incentive counter each cron', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(1);
user.lastCron = moment(new Date()).subtract({days: 1});
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(2);
});
it('pushes a notification of the day\'s incentive each cron', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(user.notifications.length).to.be.greaterThan(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('increments loginIncentives by 1 even if days are skipped in between', () => {
daysMissed = 3;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(1);
});
it('increments loginIncentives by 1 even if user has Dailies paused', () => {
user.preferences.sleep = true;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(1);
});
it('awards user bard robes if login incentive is 1', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(1);
expect(user.items.gear.owned.armor_special_bardRobes).to.eql(true);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user incentive backgrounds if login incentive is 2', () => {
user.loginIncentives = 1;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(2);
expect(user.purchased.background.blue).to.eql(true);
expect(user.purchased.background.green).to.eql(true);
expect(user.purchased.background.purple).to.eql(true);
expect(user.purchased.background.red).to.eql(true);
expect(user.purchased.background.yellow).to.eql(true);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user Bard Hat if login incentive is 3', () => {
user.loginIncentives = 2;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(3);
expect(user.items.gear.owned.head_special_bardHat).to.eql(true);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user RoyalPurple Hatching Potion if login incentive is 4', () => {
user.loginIncentives = 3;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(4);
expect(user.items.hatchingPotions.RoyalPurple).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user a Chocolate, Meat and Pink Contton Candy if login incentive is 5', () => {
user.loginIncentives = 4;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(5);
expect(user.items.food.Chocolate).to.eql(1);
expect(user.items.food.Meat).to.eql(1);
expect(user.items.food.CottonCandyPink).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user moon quest if login incentive is 7', () => {
user.loginIncentives = 6;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(7);
expect(user.items.quests.moon1).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user RoyalPurple Hatching Potion if login incentive is 10', () => {
user.loginIncentives = 9;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(10);
expect(user.items.hatchingPotions.RoyalPurple).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user a Strawberry, Patato and Blue Contton Candy if login incentive is 14', () => {
user.loginIncentives = 13;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(14);
expect(user.items.food.Strawberry).to.eql(1);
expect(user.items.food.Potatoe).to.eql(1);
expect(user.items.food.CottonCandyBlue).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user a bard instrument if login incentive is 18', () => {
user.loginIncentives = 17;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(18);
expect(user.items.gear.owned.weapon_special_bardInstrument).to.eql(true);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user second moon quest if login incentive is 22', () => {
user.loginIncentives = 21;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(22);
expect(user.items.quests.moon2).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user a RoyalPurple hatching potion if login incentive is 26', () => {
user.loginIncentives = 25;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(26);
expect(user.items.hatchingPotions.RoyalPurple).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user Fish, Milk, Rotten Meat and Honey if login incentive is 30', () => {
user.loginIncentives = 29;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(30);
expect(user.items.food.Fish).to.eql(1);
expect(user.items.food.Milk).to.eql(1);
expect(user.items.food.RottenMeat).to.eql(1);
expect(user.items.food.Honey).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user a RoyalPurple hatching potion if login incentive is 35', () => {
user.loginIncentives = 34;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(35);
expect(user.items.hatchingPotions.RoyalPurple).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user the third moon quest if login incentive is 40', () => {
user.loginIncentives = 39;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(40);
expect(user.items.quests.moon3).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user a RoyalPurple hatching potion if login incentive is 45', () => {
user.loginIncentives = 44;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(45);
expect(user.items.hatchingPotions.RoyalPurple).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
it('awards user a saddle if login incentive is 50', () => {
user.loginIncentives = 49;
cron({user, tasksByType, daysMissed, analytics});
expect(user.loginIncentives).to.eql(50);
expect(user.items.food.Saddle).to.eql(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
});
});
});
describe('recoverCron', () => {

View File

@@ -14,6 +14,7 @@ describe('Notification Controller', function() {
let User = {
user,
readNotification: function noop () {},
readNotifications: function noop () {},
sync: userSync
};

View File

@@ -1,12 +1,12 @@
.promo_android {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1558px -681px;
background-position: -1377px -151px;
width: 175px;
height: 175px;
}
.promo_backgrounds_armoire_201602 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1299px -573px;
background-position: -306px -220px;
width: 141px;
height: 294px;
}
@@ -66,7 +66,7 @@
}
.promo_backtoschool {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: 0px -1572px;
background-position: -1699px -900px;
width: 150px;
height: 150px;
}
@@ -78,10 +78,16 @@
}
.promo_chairs_glasses {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1805px 0px;
background-position: -1805px -176px;
width: 51px;
height: 210px;
}
.promo_checkin_incentives {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1299px -573px;
width: 141px;
height: 294px;
}
.promo_classes_fall_2014 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -643px -1313px;
@@ -96,25 +102,25 @@
}
.promo_classes_fall_2016 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1558px -332px;
background-position: -1558px -295px;
width: 103px;
height: 348px;
}
.promo_contrib_spotlight_beffymaroo {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1441px -573px;
background-position: -1558px -644px;
width: 114px;
height: 147px;
}
.promo_contrib_spotlight_blade {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1715px -1033px;
background-position: -1441px -661px;
width: 89px;
height: 111px;
}
.promo_contrib_spotlight_cantras {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1709px -1181px;
background-position: -1438px -868px;
width: 87px;
height: 109px;
}
@@ -126,7 +132,7 @@
}
.promo_dilatoryDistress {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -1046px;
background-position: -930px -1627px;
width: 90px;
height: 90px;
}
@@ -144,37 +150,37 @@
}
.promo_enchanted_armoire_201507 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1558px -1332px;
background-position: -1070px -1461px;
width: 217px;
height: 90px;
}
.promo_enchanted_armoire_201508 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -794px -1461px;
background-position: -1506px -1461px;
width: 180px;
height: 90px;
}
.promo_enchanted_armoire_201509 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -864px;
background-position: -748px -1627px;
width: 90px;
height: 90px;
}
.promo_enchanted_armoire_201511 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -734px -1022px;
background-position: -1016px -879px;
width: 122px;
height: 90px;
}
.promo_enchanted_armoire_201601 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -500px;
background-position: -384px -1627px;
width: 90px;
height: 90px;
}
.promo_floral_potions {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1662px -332px;
background-position: -1699px -176px;
width: 105px;
height: 273px;
}
@@ -186,7 +192,7 @@
}
.promo_habitica {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1558px -857px;
background-position: -1699px 0px;
width: 175px;
height: 175px;
}
@@ -204,205 +210,205 @@
}
.promo_haunted_hair {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -734px -884px;
background-position: -1558px -1087px;
width: 100px;
height: 137px;
}
.promo_item_notif {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -326px -1461px;
background-position: -820px -1461px;
width: 249px;
height: 102px;
}
.promo_mystery_201405 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -955px;
background-position: -839px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201406 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -312px;
background-position: -593px -884px;
width: 90px;
height: 96px;
}
.promo_mystery_201407 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1805px -412px;
background-position: -968px -884px;
width: 42px;
height: 62px;
}
.promo_mystery_201408 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1734px -939px;
background-position: -1470px -1210px;
width: 60px;
height: 71px;
}
.promo_mystery_201409 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -591px;
background-position: -475px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201410 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1016px -1027px;
background-position: -1174px -1114px;
width: 72px;
height: 63px;
}
.promo_mystery_201411 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -409px;
background-position: -293px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201412 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1805px -345px;
background-position: -1499px -498px;
width: 42px;
height: 66px;
}
.promo_mystery_201501 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1805px -211px;
background-position: -1819px -1347px;
width: 48px;
height: 63px;
}
.promo_mystery_201502 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -1137px;
background-position: -1021px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201503 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -682px;
background-position: -566px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201504 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -875px -1032px;
background-position: -1637px -1313px;
width: 60px;
height: 69px;
}
.promo_mystery_201505 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -773px;
background-position: -657px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201506 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1805px -275px;
background-position: -1819px -1411px;
width: 42px;
height: 69px;
}
.promo_mystery_201507 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px 0px;
background-position: -875px -988px;
width: 90px;
height: 105px;
}
.promo_mystery_201508 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -459px -1572px;
background-position: -593px -981px;
width: 93px;
height: 90px;
}
.promo_mystery_201509 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -1410px;
background-position: -1294px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201510 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -553px -1572px;
background-position: -452px -884px;
width: 93px;
height: 90px;
}
.promo_mystery_201511 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -1501px;
background-position: -1385px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201512 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1734px -857px;
background-position: -1813px -1495px;
width: 60px;
height: 81px;
}
.promo_mystery_201601 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -452px -884px;
background-position: -1016px -970px;
width: 120px;
height: 90px;
}
.promo_mystery_201602 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -1683px;
background-position: -1567px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201603 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -1228px;
background-position: -1112px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201604 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -647px -1572px;
background-position: -452px -975px;
width: 93px;
height: 90px;
}
.promo_mystery_201605 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -1592px;
background-position: -1476px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201606 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -106px;
background-position: -734px -884px;
width: 90px;
height: 105px;
}
.promo_mystery_201607 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -1319px;
background-position: -1203px -1627px;
width: 90px;
height: 90px;
}
.promo_mystery_201608 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -741px -1572px;
background-position: -1543px -1313px;
width: 93px;
height: 90px;
}
.promo_mystery_201609 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -835px -1572px;
background-position: -199px -1627px;
width: 93px;
height: 90px;
}
.promo_mystery_201610 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1734px -681px;
background-position: -1658px -1627px;
width: 63px;
height: 84px;
}
.promo_mystery_201611 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1857px -212px;
background-position: -734px -990px;
width: 90px;
height: 99px;
}
.promo_mystery_3014 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -576px -1461px;
background-position: -1288px -1461px;
width: 217px;
height: 90px;
}
@@ -414,13 +420,13 @@
}
.promo_orca {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -593px -998px;
background-position: -1428px -392px;
width: 105px;
height: 105px;
}
.promo_partyhats {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1662px -606px;
background-position: -1377px -327px;
width: 115px;
height: 47px;
}
@@ -438,31 +444,31 @@
}
.promo_peppermint_flame {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1016px -879px;
background-position: -1699px -1051px;
width: 140px;
height: 147px;
}
.promo_pet_skins {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -875px -884px;
background-position: -1699px -1199px;
width: 140px;
height: 147px;
}
.customize-option.promo_pet_skins {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -900px -899px;
background-position: -1724px -1214px;
width: 60px;
height: 60px;
}
.promo_pyromancer {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -593px -884px;
background-position: -1699px -1495px;
width: 113px;
height: 113px;
}
.promo_rainbow_armor {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: 0px -1723px;
background-position: -875px -884px;
width: 92px;
height: 103px;
}
@@ -480,19 +486,19 @@
}
.promo_splashyskins {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -151px -1572px;
background-position: 0px -1627px;
width: 198px;
height: 91px;
}
.customize-option.promo_splashyskins {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -176px -1587px;
background-position: -25px -1642px;
width: 60px;
height: 60px;
}
.promo_spooky_sparkles_fall_2016 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -306px -220px;
background-position: -1558px 0px;
width: 140px;
height: 294px;
}
@@ -516,19 +522,19 @@
}
.promo_staff_spotlight_Lemoness {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1441px -721px;
background-position: -1558px -792px;
width: 102px;
height: 146px;
}
.promo_staff_spotlight_Viirus {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1428px -392px;
background-position: -1699px -1347px;
width: 119px;
height: 147px;
}
.promo_staff_spotlight_paglias {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1438px -868px;
background-position: -1558px -939px;
width: 99px;
height: 147px;
}
@@ -552,13 +558,13 @@
}
.promo_takeThis_gear {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -452px -975px;
background-position: -1558px -1225px;
width: 114px;
height: 87px;
}
.promo_takethis_armor {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -975px -1461px;
background-position: -1441px -573px;
width: 114px;
height: 87px;
}
@@ -570,25 +576,25 @@
}
.promo_unconventional_armor {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1089px -1027px;
background-position: -1805px -387px;
width: 60px;
height: 60px;
}
.promo_unconventional_armor2 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1734px -766px;
background-position: -1428px -498px;
width: 70px;
height: 74px;
}
.promo_updos {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1558px -1033px;
background-position: -1699px -450px;
width: 156px;
height: 147px;
}
.promo_veteran_pets {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -874px -1114px;
background-position: -1027px -1114px;
width: 146px;
height: 75px;
}
@@ -600,13 +606,13 @@
}
.promo_winterclasses2015 {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: 0px -1461px;
background-position: -494px -1461px;
width: 325px;
height: 110px;
}
.promo_winteryhair {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1377px -302px;
background-position: -874px -1114px;
width: 152px;
height: 75px;
}
@@ -618,7 +624,7 @@
}
.npc_viirus {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -350px -1572px;
background-position: -1441px -773px;
width: 108px;
height: 90px;
}
@@ -630,19 +636,19 @@
}
.scene_coding {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1377px -151px;
background-position: -1699px -749px;
width: 150px;
height: 150px;
}
.scene_phone_peek {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1558px -1181px;
background-position: -1699px -598px;
width: 150px;
height: 150px;
}
.welcome_basic_avatars {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1558px 0px;
background-position: 0px -1461px;
width: 246px;
height: 165px;
}
@@ -654,7 +660,7 @@
}
.welcome_sample_tasks {
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
background-position: -1558px -166px;
background-position: -247px -1461px;
width: 246px;
height: 165px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 987 KiB

After

Width:  |  Height:  |  Size: 987 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 KiB

After

Width:  |  Height:  |  Size: 443 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 73 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 148 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 157 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

After

Width:  |  Height:  |  Size: 150 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 171 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 99 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 66 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 130 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 138 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 135 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 KiB

After

Width:  |  Height:  |  Size: 385 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 216 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1007 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 927 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

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