<commit_before> define([
    'providers',
    'jquery',
    'gizmo/superdesk',
    config.guiJs('livedesk', 'action'),
    config.guiJs('livedesk', 'views/post'),
    config.guiJs('livedesk', 'models/sync'),
    config.guiJs('livedesk', 'models/sync-collection'),
	'jqueryui/draggable',
    'providers/chain/adaptor',
    config.guiJs('livedesk', 'models/blog'),
    config.guiJs('livedesk', 'models/posts'),
    config.guiJs('livedesk', 'models/autoposts'),
	config.guiJs('livedesk', 'models/source'),
	config.guiJs('livedesk', 'models/sources'),
	config.guiJs('livedesk', 'models/autocollection'),
    'tmpl!livedesk>items/implementors/chain',
    'tmpl!livedesk>providers/chain',
	'tmpl!livedesk>providers/chain/blogs',
	'tmpl!livedesk>providers/chain/blog-link',
	'tmpl!livedesk>providers/chain/blog-content',
	'tmpl!livedesk>providers/chain/timeline',
], function(providers, $, Gizmo, BlogAction, PostView, SyncModel, SyncCollection) {

    var autoSources = new SyncCollection();

    var
    	ChainPostView = PostView.extend({
    		events: {
    			'': { afterRender: 'addDraggable'}
    		},
    		addDraggable: function(){
				var self = this, obj;
				self.el.draggable({
					scroll: true,
					addClasses: false,
					revert: 'invalid',
					helper: 'clone',
					appendTo: 'body',
					zIndex: 2700,
					clone: true,
					start: function(evt, ui) {
					    item = $(evt.currentTarget);
					    $(ui.helper).css('width', item.width());
					    $(this).data('data', providers.chain.adaptor.universal(self.model, { Id: self._parent.sourceId, URI: self._parent.sourceURI } ));
					}
				});
    		}
    	}),
		TimelineView = Gizmo.View.extend({
			init: function(){
				this._views = [];
				this.collection
					.on('read readauto', this.render, this)
					.on('addingsauto', this.addAll, this)
					.xfilter();
			},
			activate: function(){
				var self = this;
			    var data = {thumbSize: 'medium'};
                if (autoSources.isPaused(this.sourceId)) {
                    data['cId.since'] = autoSources.getLastSyncId(this.sourceId);
                }

				this.collection
					.on('read update readauto updateauto', function(){
						self.el.find('.chainblogs').show();
					})
					.auto({
						headers: { 'X-Filter': 'PublishedOn, DeletedOn, Order, Id, CId, Content, CreatedOn, Type,'+
								'AuthorName, Author.Source.Name, Author.Name, Author.Source.Id, Author.Source.IsModifiable, IsModified, Author.User.*, '+
							  	'AuthorPerson.EMail, AuthorPerson.FirstName, AuthorPerson.LastName, AuthorPerson.Id, Meta, IsPublished, Creator.FullName' },
                        data: data
					});
			},
			deactivate: function(){
				this.el.find('.chainblogs').hide();
				this.collection.stop();
			},
			render: function(evt){
				var self = this;
				$.tmpl('livedesk>providers/chain/timeline', {}, function(e, o){
					self.el.html(o);
					self.addAll(evt, self.collection._list);
				});
			},
			removeOne:function(view) {
				var
					self = this,
					pos = self._views.indexOf(view);
				if(pos !== -1 ) {
					self._views.splice(pos,1);
				}
			},
			/*!
			 * Order given view in timeline
			 * If the view is the first one the it's added after #load-more selector
			 * returns the given view.
			 */
			orderOne: function(view) {
				var pos = this._views.indexOf(view);
				/*!
				 * View property order need to be set here
				 *   because could be multiple updates and
				 *   orderOne only works for one update.
				 */
				view.order = parseFloat(view.model.get('Order'));
				/*!
				 * If the view isn't in the _views vector
				 *   add it.
				 */
				if ( pos === -1 ) {
					this._views.push(view);
				}
				/*!
				 * Sort the _view vector descendent by view property order.
				 */
				this._views.sort(function(a,b){
					return b.order - a.order;
				});
				/*!
				 * Search it again in find the new position.
				 */
				 for( var order = [], i = 0, count = this._views.length; i < count; i++ ){
				 	order.push(this._views[i].order);
				 }
				pos = this._views.indexOf(view);
				if( pos === 0 ){
					/*!
					 * If the view is the first one the it's added after #load-more selector.
					 *   else
					 *   Reposition the dom element before the old (postion 1) first element.
					 */
					if( this._views.length === 1) {
						this.el.find('.chainblogs').html(view.el);
					} else {
						view.el.insertBefore(this._views[1].el);
					}
				} else {
					/*!
					 * Reposition the dom element after the previous element.
					 */
					view.el.insertAfter(this._views[pos-1].el);
				}
				return view;
			},
			addOne: function(model) {
				var postView = new ChainPostView({
					_parent: this,
					model: model,
					tmplImplementor: 'implementors/chain'
				});
				this.orderOne(postView);
			},
			addAll: function(evt, data){
				for(var i = 0, count = data.length; i < count; i++) {
					this.addOne(data[i]);
				}
			},
			search: function(what) {
				var self = this;
				if( what !== '') {
					self.el.find('li').css('display','none');
					self.el.find("li:contains('"+what+"')").css('display','block');
				} else {
					self.el.find('li').css('display','block');
				}
			}
		}),
		ChainBlogLinkView = Gizmo.View.extend({
			events: {
				'': { click: 'toggleActive'}
			},
			init: function() {
				this.model.on('read update', this.render, this);
			},

            toggleActive: function(e) {
                if (this.el.hasClass('active')) {
                    this.deactivate(e);
                } else {
                    this.activate(e);
                }
            },

			deactivate: function(e) {
				if(e) e.stopPropagation();
				this.el.removeClass('active');
				this.model.chainBlogContentView.deactivate();
			},

			activate: function() {
				this.active = true;
				this.model.chainBlogContentView.activate();
				this._parent.setActive(this);
			},

			render: function(){
				var self = this;
				$.tmpl('livedesk>providers/chain/blog-link', { Blog: self.model.feed(true)}, function(e,o) {
					self.setElement(o);
				});
			}
		}),
		ChainBlogContentView = Gizmo.View.extend({
			init: function(){
				this.model.on('read', this.render, this );
				this.model.chainBlogContentView = this;
			},
			deactivate: function() {
				this.active = false;
				this.timelineView.deactivate();
			},
			activate: function() {
				this.active = true;
                var isAuto = autoSources.isAuto(this.model.sourceId);
                $('.autopublish input:checkbox').prop('checked', isAuto);
                $('.autopublish .sf-toggle-custom').toggleClass('sf-checked', isAuto);
                $('#automod-info').toggle(isAuto);
                isAuto ? this.timelineView.deactivate() : this.timelineView.activate();
			},
			render: function(){
				var self = this;
				$.tmpl('livedesk>providers/chain/blog-content', { Blog: self.model.feed()}, function(e, o){
					self.setElement(o);
					self.timelineView = new TimelineView({
							el: self.el,
							collection: self.model.get('PostPublished'),
							sourceId: self.model.sourceId,
							sourceURI: self.model.href
					});
				});
			}
		}),
		ChainBlogsView = Gizmo.View.extend({
			events: {
				'.sf-searchbox a': { click: 'removeSearch'},
				'.sf-searchbox input': { keypress: 'checkEnter'},
                '.sf-toggle:checkbox': {change: 'toggleAutopublish'}
			},
			init: function(){
				var self = this;
				self.chainBlogLinkViews = [];
				self.chainBlogContentViews = [];
				if($.type(self.sourceBlogs) === 'undefined') {
					self.sourceBlogs = new Gizmo.Register.Sources();
					self.sourceBlogs.setHref(this.blog.get('Source').href);
					self.sourceBlogs
						.on('read', this.render, this)
						.xfilter('URI,Name,Id')
						.sync();
				}

                autoSources.url = this.blog.get('Sync').href;
                autoSources.fetch({headers: autoSources.xfilter, reset: true});
			},

            getActiveView: function() {
                if (this.activeView) {
                    return this.activeView;
                }
            },

			search: function(what){
                var active = this.getActiveView();
                if (active) {
					active.model.chainBlogContentView.timelineView.search(what);
				}
			},

			removeSearch: function(evt){
				var input = $(evt.target).parents('.sf-searchbox').find('input');
					input.val('');
					this .search('');
			},
			checkEnter: function(evt){
				if(evt.which == 13)
					this.search($(evt.target).val());
			},
			setActive: function(view) {
                this.activeView = view;
				for (var i = 0; i < this.chainBlogLinkViews.length; i++) {
					if (this.chainBlogLinkViews[i] !== this.activeView) {
						this.chainBlogLinkViews[i].deactivate();
					}
				}
			},
			render: function() {
				var self = this;
				$.tmpl('livedesk>providers/chain', {}, function(e,o){
						$(self.el).html(o);
					var chainBlog,
						chainBlogLinkView,
						$linkEl = self.el.find('.feed-info'),
						$contentEl = self.el.find('.chain-header');

					self.sourceBlogs.each(function(id,sourceBlog){
						chainBlog = new Gizmo.Register.Blog();
						chainBlog.defaults.PostPublished = Gizmo.Register.AutoPosts;
						chainBlog.setHref(sourceBlog.get('URI').href);
						chainBlog.sync();
                        chainBlog.sourceId = sourceBlog.get('Id');
						chainBlogLinkView = new ChainBlogLinkView({ model: chainBlog, _parent: self });
						chainBlogContentView = new ChainBlogContentView({ model: chainBlog, _parent: self });
						self.chainBlogLinkViews.push(chainBlogLinkView);
						self.chainBlogContentViews.push(chainBlogContentView);
						$linkEl.prepend(chainBlogLinkView.el);
						chainBlogContentView.el.insertAfter($contentEl);
					});
				});
			},

            toggleAutopublish: function(e) {
                e.preventDefault();
                var autopublish = $(e.target).is(':checked'),
                	view = this.activeView,
                	CId,
                	sync,
                	ret;
                if (view) {
                    sync = autoSources.findSource(view.model.sourceId);
                    CId = autoSources.getLastSyncId(view.model.sourceId);
                    if (sync) {
                        sync.save({Auto: autopublish ? 'True' : 'False', CId: CId}, {patch: true}).done(function(){
                        	view.model.chainBlogContentView.activate();
                        });
                    } else {
                        model = autoSources.create({
                        	Blog: this.blog.get('Id'),
                        	Source: view.model.sourceId,
                        	Auto: autopublish ? 'True' : 'False',
                        	Creator: localStorage.getItem('superdesk.login.id')
                        }, {
                        	wait: true,
                        	headers: autoSources.xfilter,
                        	success: function(){
								view.model.chainBlogContentView.activate();
                        	}
                        });
                    }
                }
            }
		});

	$.extend( providers.chain, { init: function(blogUrl) {
		this.adaptor._parent = this;
		this.adaptor.init();

	    var blog = new Gizmo.Auth(new Gizmo.Register.Blog(blogUrl));
        blog.on('read', function() {
			chain = new ChainBlogsView({el: this.el, blog: blog});
		}.apply(this));
        blog.sync();
	}});

    return providers;
});
<commit_msg>LB-708: Search should work when a chained blog is in autopublish<commit_after> define([
    'providers',
    'jquery',
    'gizmo/superdesk',
    config.guiJs('livedesk', 'action'),
    config.guiJs('livedesk', 'views/post'),
    config.guiJs('livedesk', 'models/sync'),
    config.guiJs('livedesk', 'models/sync-collection'),
	'jqueryui/draggable',
    'providers/chain/adaptor',
    config.guiJs('livedesk', 'models/blog'),
    config.guiJs('livedesk', 'models/posts'),
    config.guiJs('livedesk', 'models/autoposts'),
	config.guiJs('livedesk', 'models/source'),
	config.guiJs('livedesk', 'models/sources'),
	config.guiJs('livedesk', 'models/autocollection'),
    'tmpl!livedesk>items/implementors/chain',
    'tmpl!livedesk>providers/chain',
	'tmpl!livedesk>providers/chain/blogs',
	'tmpl!livedesk>providers/chain/blog-link',
	'tmpl!livedesk>providers/chain/blog-content',
	'tmpl!livedesk>providers/chain/timeline',
], function(providers, $, Gizmo, BlogAction, PostView, SyncModel, SyncCollection) {

    var autoSources = new SyncCollection();

    var
    	ChainPostView = PostView.extend({
    		events: {
    			'': { afterRender: 'addDraggable'}
    		},
    		addDraggable: function(){
				var self = this, obj;
				self.el.draggable({
					scroll: true,
					addClasses: false,
					revert: 'invalid',
					helper: 'clone',
					appendTo: 'body',
					zIndex: 2700,
					clone: true,
					start: function(evt, ui) {
					    item = $(evt.currentTarget);
					    $(ui.helper).css('width', item.width());
					    $(this).data('data', providers.chain.adaptor.universal(self.model, { Id: self._parent.sourceId, URI: self._parent.sourceURI } ));
					}
				});
    		}
    	}),
		TimelineView = Gizmo.View.extend({

			headers: {
                'X-Filter': 'PublishedOn, DeletedOn, Order, Id, CId, Content, CreatedOn, Type,'+
				'AuthorName, Author.Source.Name, Author.Name, Author.Source.Id, Author.Source.IsModifiable, IsModified, Author.User.*, '+
					'AuthorPerson.EMail, AuthorPerson.FirstName, AuthorPerson.LastName, AuthorPerson.Id, Meta, IsPublished, Creator.FullName'
            },

			init: function(){
				this._views = [];
				this.collection
					.on('read readauto', this.render, this)
					.on('addingsauto', this.addAll, this)
					.xfilter();
			},
			activate: function(){
				var self = this;
			    var data = {thumbSize: 'medium'};
                if (autoSources.isPaused(this.sourceId)) {
                    data['cId.since'] = autoSources.getLastSyncId(this.sourceId);
                }

				this.collection
					.on('read update readauto updateauto', function(){
						self.el.find('.chainblogs').show();
					})
					.auto({
						headers: this.headers,
                        data: data
					});
			},
			deactivate: function(){
				this.el.find('.chainblogs').hide();
				this.collection.stop();
			},
			render: function(evt){
				var self = this;
				$.tmpl('livedesk>providers/chain/timeline', {}, function(e, o){
					self.el.html(o);
					self.addAll(evt, self.collection._list);
				});
			},
			removeOne:function(view) {
				var
					self = this,
					pos = self._views.indexOf(view);
				if(pos !== -1 ) {
					self._views.splice(pos,1);
				}
			},
			/*!
			 * Order given view in timeline
			 * If the view is the first one the it's added after #load-more selector
			 * returns the given view.
			 */
			orderOne: function(view) {
				var pos = this._views.indexOf(view);
				/*!
				 * View property order need to be set here
				 *   because could be multiple updates and
				 *   orderOne only works for one update.
				 */
				view.order = parseFloat(view.model.get('Order'));
				/*!
				 * If the view isn't in the _views vector
				 *   add it.
				 */
				if ( pos === -1 ) {
					this._views.push(view);
				}
				/*!
				 * Sort the _view vector descendent by view property order.
				 */
				this._views.sort(function(a,b){
					return b.order - a.order;
				});
				/*!
				 * Search it again in find the new position.
				 */
				 for( var order = [], i = 0, count = this._views.length; i < count; i++ ){
				 	order.push(this._views[i].order);
				 }
				pos = this._views.indexOf(view);
				if( pos === 0 ){
					/*!
					 * If the view is the first one the it's added after #load-more selector.
					 *   else
					 *   Reposition the dom element before the old (postion 1) first element.
					 */
					if( this._views.length === 1) {
						this.el.find('.chainblogs').html(view.el);
					} else {
						view.el.insertBefore(this._views[1].el);
					}
				} else {
					/*!
					 * Reposition the dom element after the previous element.
					 */
					view.el.insertAfter(this._views[pos-1].el);
				}
				return view;
			},
			addOne: function(model) {
				var postView = new ChainPostView({
					_parent: this,
					model: model,
					tmplImplementor: 'implementors/chain'
				});
				this.orderOne(postView);
			},
			addAll: function(evt, data){
				for(var i = 0, count = data.length; i < count; i++) {
					this.addOne(data[i]);
				}
			},
			search: function(what) {
                var view = this;
                this.deactivate();
                this.collection.reset([]);
                this._views = [];
				if (what) {
                    this.collection.sync({data: {search: what}}).done(function() {
				        view.el.find('.chainblogs').show();
                    });
				} else if (!autoSources.isAuto(this.sourceId)) { // reset after
                    this.collection.sync();
                    this.activate();
				}
			}
		}),
		ChainBlogLinkView = Gizmo.View.extend({
			events: {
				'': { click: 'toggleActive'}
			},
			init: function() {
				this.model.on('read update', this.render, this);
			},

            toggleActive: function(e) {
                if (this.el.hasClass('active')) {
                    this.deactivate(e);
                } else {
                    this.activate(e);
                }
            },

			deactivate: function(e) {
				if(e) e.stopPropagation();
				this.el.removeClass('active');
				this.model.chainBlogContentView.deactivate();
			},

			activate: function() {
				this.active = true;
				this.model.chainBlogContentView.activate();
				this._parent.setActive(this);
			},

			render: function(){
				var self = this;
				$.tmpl('livedesk>providers/chain/blog-link', { Blog: self.model.feed(true)}, function(e,o) {
					self.setElement(o);
				});
			}
		}),
		ChainBlogContentView = Gizmo.View.extend({
			init: function(){
				this.model.on('read', this.render, this );
				this.model.chainBlogContentView = this;
			},
			deactivate: function() {
				this.active = false;
				this.timelineView.deactivate();
			},
			activate: function() {
				this.active = true;
                var isAuto = autoSources.isAuto(this.model.sourceId);
                $('.autopublish input:checkbox').prop('checked', isAuto);
                $('.autopublish .sf-toggle-custom').toggleClass('sf-checked', isAuto);
                $('#automod-info').toggle(isAuto);
                isAuto ? this.timelineView.deactivate() : this.timelineView.activate();
			},
			render: function(){
				var self = this;
				$.tmpl('livedesk>providers/chain/blog-content', { Blog: self.model.feed()}, function(e, o){
					self.setElement(o);
					self.timelineView = new TimelineView({
							el: self.el,
							collection: self.model.get('PostPublished'),
							sourceId: self.model.sourceId,
							sourceURI: self.model.href
					});
				});
			}
		}),
		ChainBlogsView = Gizmo.View.extend({
			events: {
				'.sf-searchbox a': {click: 'removeSearch'},
				'.sf-searchbox input': {keypress: 'checkEnter'},
                '.sf-toggle:checkbox': {change: 'toggleAutopublish'}
			},
			init: function(){
				var self = this;
				self.chainBlogLinkViews = [];
				self.chainBlogContentViews = [];
				if($.type(self.sourceBlogs) === 'undefined') {
					self.sourceBlogs = new Gizmo.Register.Sources();
					self.sourceBlogs.setHref(this.blog.get('Source').href);
					self.sourceBlogs
						.on('read', this.render, this)
						.xfilter('URI,Name,Id')
						.sync();
				}

                autoSources.url = this.blog.get('Sync').href;
                autoSources.fetch({headers: autoSources.xfilter, reset: true});
			},

            getActiveView: function() {
                if (this.activeView) {
                    return this.activeView;
                }
            },

			search: function(what){
                var active = this.getActiveView();
                if (active) {
					active.model.chainBlogContentView.timelineView.search(what);
				}
			},

			removeSearch: function(evt){
                evt.preventDefault();
				var input = $(evt.target).parents('.sf-searchbox').find('input');
					input.val('');
					this.search('');
                $(this.el).find('.sf-searchbox a').hide();
			},
			checkEnter: function(evt){
				if (evt.which == 13) {
				    this.search($(evt.target).val());
                }

                if ($(evt.target).val()) {
                    $(this.el).find('.sf-searchbox a').css('display', 'block');
                }
			},
			setActive: function(view) {
                this.activeView = view;
				for (var i = 0; i < this.chainBlogLinkViews.length; i++) {
					if (this.chainBlogLinkViews[i] !== this.activeView) {
						this.chainBlogLinkViews[i].deactivate();
					}
				}
			},
			render: function() {
				var self = this;
				$.tmpl('livedesk>providers/chain', {}, function(e,o){
						$(self.el).html(o);
					var chainBlog,
						chainBlogLinkView,
						$linkEl = self.el.find('.feed-info'),
						$contentEl = self.el.find('.chain-header');

					self.sourceBlogs.each(function(id,sourceBlog){
						chainBlog = new Gizmo.Register.Blog();
						chainBlog.defaults.PostPublished = Gizmo.Register.AutoPosts;
						chainBlog.setHref(sourceBlog.get('URI').href);
						chainBlog.sync();
                        chainBlog.sourceId = sourceBlog.get('Id');
						chainBlogLinkView = new ChainBlogLinkView({ model: chainBlog, _parent: self });
						chainBlogContentView = new ChainBlogContentView({ model: chainBlog, _parent: self });
						self.chainBlogLinkViews.push(chainBlogLinkView);
						self.chainBlogContentViews.push(chainBlogContentView);
						$linkEl.prepend(chainBlogLinkView.el);
						chainBlogContentView.el.insertAfter($contentEl);
					});
				});
			},

            toggleAutopublish: function(e) {
                e.preventDefault();
                var autopublish = $(e.target).is(':checked'),
                	view = this.activeView,
                	CId,
                	sync,
                	ret;
                if (view) {
                    sync = autoSources.findSource(view.model.sourceId);
                    CId = autoSources.getLastSyncId(view.model.sourceId);
                    if (sync) {
                        sync.save({Auto: autopublish ? 'True' : 'False', CId: CId}, {patch: true}).done(function(){
                        	view.model.chainBlogContentView.activate();
                        });
                    } else {
                        model = autoSources.create({
                        	Blog: this.blog.get('Id'),
                        	Source: view.model.sourceId,
                        	Auto: autopublish ? 'True' : 'False',
                        	Creator: localStorage.getItem('superdesk.login.id')
                        }, {
                        	wait: true,
                        	headers: autoSources.xfilter,
                        	success: function(){
								view.model.chainBlogContentView.activate();
                        	}
                        });
                    }
                }
            }
		});

	$.extend( providers.chain, { init: function(blogUrl) {
		this.adaptor._parent = this;
		this.adaptor.init();

	    var blog = new Gizmo.Auth(new Gizmo.Register.Blog(blogUrl));
        blog.on('read', function() {
			chain = new ChainBlogsView({el: this.el, blog: blog});
		}.apply(this));
        blog.sync();
	}});

    return providers;
});
<|endoftext|>


<commit_before>Simplicity.Level1 = function (game) { };

Simplicity.Level1.prototype =
{
  create: function () {

    // Create a group for our tiles.
    isoGroup = game.add.group();

    this.canPlay = false;
    this.winTriggered = false;
    this.dead = false;
    this.steps = 8;
    this.stepcount = 0;

    this.cursors = game.input.keyboard.createCursorKeys();

    this.game.input.keyboard.addKeyCapture([
      Phaser.Keyboard.LEFT,
      Phaser.Keyboard.RIGHT,
      Phaser.Keyboard.UP,
      Phaser.Keyboard.DOWN,
      Phaser.Keyboard.SPACEBAR
    ]);

    this.layout = [[2, 2, 2, 2, 2, 1, 1],
    [0, 0, 0, 0, 2, 0, 1],
    [0, 0, 0, 0, 2, 0, 1],
    [0, 0, 0, 0, 2, 1, 1],
    [0, 0, 0, 0, 3, 1, ],
  ];

  this.bubble = game.world.add(new SpeechBubble(game, 180, 190, 200, "Get me to the green tile"));

    this.spawnTiles();
    this.spawnPlayer();

  },
  update: function () {

    if(!game.tweens.isTweening(this.bubble)){
      game.add.tween(this.bubble).to({ x: this.player.x, y: this.player.y-19}, 140, Phaser.Easing.Linear.None, true);
    }

    if(!game.tweens.isTweening(this.player) && this.canPlay){
      var currentTileX = ((this.player.isoX-50)/38);
      var currentTileY = ((this.player.isoY-50)/38);

      var nextPosX = this.player.isoX, nextPosY = this.player.isoY, moved = false;

      if (this.cursors.down.isDown) {
        nextPosX = this.player.isoX + 38;
        nextPosY = this.player.isoY;
        moved = true;
      } else if (this.cursors.up.isDown) {
        nextPosX = this.player.isoX - 38;
        nextPosY = this.player.isoY;
        moved = true;
      } else if (this.cursors.right.isDown) {
        nextPosX = this.player.isoX;
        nextPosY = this.player.isoY - 38;
        moved = true;
      } else if (this.cursors.left.isDown) {
        nextPosX = this.player.isoX;
        nextPosY = this.player.isoY +  38;
        moved = true;
      }

      if(this.checkTile(currentTileX, currentTileY) === 0) {
        game.iso.simpleSort(isoGroup);
        moved = false;
        if(!this.dead) {
          this.changeBubble(failureStrings[Math.floor(Math.random() * failureStrings.length)]);

          game.time.events.add(Phaser.Timer.SECOND, function() {
            this.changeLevel('Level1')
          }, this);

          this.dropSprite(this.player, 200, -500, function(){this.canPlay = true}.bind(this))
          this.dead = true;
        }
      } else if(this.checkTile(currentTileX, currentTileY) === 3) {
        if(!this.winTriggered) {
          this.complete();
        }
        moved = false;
      }

      if(moved) {
        this.stepcount++;
        game.add.tween(this.player).to({ isoX: nextPosX, isoY: nextPosY}, 200, Phaser.Easing.Quadratic.InOut, true);
        if(this.stepcount > this.steps) {
          this.canPlay = false;
          this.changeLevel('Level1')
        }
      }
    }
  },
  render: function () {
    game.debug.text(game.time.fps || '--', 2, 14, "#a7aebe");
    game.debug.text(this.stepcount + ' / ' + this.steps , 2, 28, "#a7aebe");
  },
  spawnTiles: function () {
  this.tiles = []
  var tile;

  dropTile = function(tile, delay) {
    game.time.events.add(delay, function() {
      game.add.tween(tile).to({ isoZ: 0 }, 150, Phaser.Easing.Linear.None, true);
    }, this);

  }

  this.delay = 0;

  for (var y = 0; y < this.layout.length; y++) {
    this.tiles.push([]);
    for (var x = 0; x < this.layout[y].length; x++) {
      // Create a tile using the new game.add.isoSprite factory method at the specified position.
      // The last parameter is the group you want to add it to (just like game.add.sprite)
      if(this.layout[y][x] > 0) {

        this.tiles[y][x] = game.add.isoSprite((x*38)+50, (y*38)+50, 500, 'tile', 0, isoGroup);
        this.tiles[y][x].anchor.set(0.5, 0);
        this.delay += 100;
        this.dropSprite(this.tiles[y][x], this.delay, 0)
      }
      if(this.layout[y][x] === 2){
        this.tiles[y][x].tint = 0x86bfda;
      }
      if(this.layout[y][x] === 3){
        this.tiles[y][x].tint = 0x00FF00;
      }

    }
  }
},

spawnPlayer: function() {
  this.player = game.add.isoSprite(50, 50, 500, 'cube', 0, isoGroup);
  this.player.tint = 0x86bfda;
  this.player.anchor.set(0.5);
  this.bubble.x = this.player.x;
  this.bubble.y = this.player.y;
  this.dropSprite(this.player, this.delay+100, 0, function(){this.canPlay = true}.bind(this))

},

checkTile: function(x,y) {
  if((x < 0 || y < 0)) {
    return 0;
  }

  if(this.layout[y] !== undefined) {
    if(this.layout[y][x] === undefined) {
      return 0;
    } else if(this.layout[y][x] === 0){
      return 0;
    } else {
      return this.layout[y][x];
    }
  } else {
    return 0;
  }
},
changeBubble: function(text) {
  this.bubble.kill();
  this.bubble = game.world.add(new SpeechBubble(game, 180, 190, 200, text));
  this.bubble.x = this.player.x;
  this.bubble.y = this.player.y;
},
complete: function() {
  this.changeBubble('WE WON')

  this.changeLevel('Level1');

  this.winTriggered = true;
},
changeLevel: function(level){
  var level = level;

  var delay = 0;

  for (var y = 0; y < this.layout.length; y++) {
    for (var x = 0; x < this.layout[y].length; x++) {
      if(this.layout[y][x] > 0) {
        delay += 100;
        this.dropSprite(this.tiles[y][x], delay, -500)
      }

    }
  }

  delay += 200;

  this.dropSprite(this.player, this.delay+200, -500, function(){this.canPlay = true}.bind(this))

  game.time.events.add(delay+1000, function() {
    game.world.removeAll()
    game.state.start(level, false, true);
  }, this);

},
dropSprite: function(sprite, delay, to, cb) {
  game.time.events.add(delay, function() {
    game.add.tween(sprite).to({ isoZ: to }, 150, Phaser.Easing.Linear.None, true);
    if(cb) {
      cb();
    }
  }, this);

}
};

game.state.add('Level1', Simplicity.Level1);
<commit_msg>added timer<commit_after>Simplicity.Level1 = function (game) { };

Simplicity.Level1.prototype =
{
  create: function () {

    // Create a group for our tiles.
    isoGroup = game.add.group();

    this.canPlay = false;
    this.winTriggered = false;
    this.dead = false;
    this.steps = 8;
    this.stepcount = 0;
    this.timer = 2;
    this.cursors = game.input.keyboard.createCursorKeys();
    this.hasStepped = false;
    this.timerStarted = false;
    this.game.input.keyboard.addKeyCapture([
      Phaser.Keyboard.LEFT,
      Phaser.Keyboard.RIGHT,
      Phaser.Keyboard.UP,
      Phaser.Keyboard.DOWN,
      Phaser.Keyboard.SPACEBAR
    ]);

    this.layout = [[2, 2, 2, 2, 2, 1, 1],
    [0, 0, 0, 0, 2, 0, 1],
    [0, 0, 0, 0, 2, 0, 1],
    [0, 0, 0, 0, 2, 1, 1],
    [0, 0, 0, 0, 3, 1, ],
  ];

  this.bubble = game.world.add(new SpeechBubble(game, 180, 190, 200, "Get me to the green tile"));

    this.spawnTiles();
    this.spawnPlayer();

  },
  update: function () {

    if(!game.tweens.isTweening(this.bubble)){
      game.add.tween(this.bubble).to({ x: this.player.x, y: this.player.y-19}, 140, Phaser.Easing.Linear.None, true);
    }

    if(!game.tweens.isTweening(this.player) && this.canPlay){

      if(this.hasStepped && !this.timerStarted) {
        this.timerStarted = true;
        this.timerLoop = game.time.events.loop(100, function() {
          this.timer -= 0.1;
          if(this.timer < 0) {
            game.time.events.remove(this.timerLoop);
            this.canPlay = false;
            this.changeLevel('Level1')
          }
        }, this);
      }
      var currentTileX = ((this.player.isoX-50)/38);
      var currentTileY = ((this.player.isoY-50)/38);

      var nextPosX = this.player.isoX, nextPosY = this.player.isoY, moved = false;

      if (this.cursors.down.isDown) {
        nextPosX = this.player.isoX + 38;
        nextPosY = this.player.isoY;
        moved = true;
      } else if (this.cursors.up.isDown) {
        nextPosX = this.player.isoX - 38;
        nextPosY = this.player.isoY;
        moved = true;
      } else if (this.cursors.right.isDown) {
        nextPosX = this.player.isoX;
        nextPosY = this.player.isoY - 38;
        moved = true;
      } else if (this.cursors.left.isDown) {
        nextPosX = this.player.isoX;
        nextPosY = this.player.isoY +  38;
        moved = true;
      }

      if(this.checkTile(currentTileX, currentTileY) === 0) {
        game.iso.simpleSort(isoGroup);
        moved = false;
        if(!this.dead) {
          this.changeBubble(failureStrings[Math.floor(Math.random() * failureStrings.length)]);

          game.time.events.add(Phaser.Timer.SECOND, function() {
            this.changeLevel('Level1')
          }, this);

          this.dropSprite(this.player, 200, -500, function(){this.canPlay = true}.bind(this))
          game.time.events.remove(this.timerLoop);
          this.dead = true;
        }
      } else if(this.checkTile(currentTileX, currentTileY) === 3) {
        if(!this.winTriggered) {
          game.time.events.remove(this.timerLoop);
          this.complete();
        }
        moved = false;
      }

      if(moved) {
        this.hasStepped = true;
        this.stepcount++;
        this.timer = 2;
        game.add.tween(this.player).to({ isoX: nextPosX, isoY: nextPosY}, 200, Phaser.Easing.Quadratic.InOut, true);
        if(this.stepcount > this.steps) {
          this.canPlay = false;
          this.changeLevel('Level1')
        }
      }
    }
  },
  render: function () {
    game.debug.text(game.time.fps || '--', 2, 14, "#a7aebe");
    game.debug.text(this.stepcount + ' / ' + this.steps , 2, 42, "#a7aebe");
    game.debug.text(Math.round(this.timer*10)/10, 2, 28, "#a7aebe");
  },
  spawnTiles: function () {
  this.tiles = []
  var tile;

  dropTile = function(tile, delay) {
    game.time.events.add(delay, function() {
      game.add.tween(tile).to({ isoZ: 0 }, 150, Phaser.Easing.Linear.None, true);
    }, this);

  }

  this.delay = 0;

  for (var y = 0; y < this.layout.length; y++) {
    this.tiles.push([]);
    for (var x = 0; x < this.layout[y].length; x++) {
      // Create a tile using the new game.add.isoSprite factory method at the specified position.
      // The last parameter is the group you want to add it to (just like game.add.sprite)
      if(this.layout[y][x] > 0) {

        this.tiles[y][x] = game.add.isoSprite((x*38)+50, (y*38)+50, 500, 'tile', 0, isoGroup);
        this.tiles[y][x].anchor.set(0.5, 0);
        this.delay += 100;
        this.dropSprite(this.tiles[y][x], this.delay, 0)
      }
      if(this.layout[y][x] === 2){
        this.tiles[y][x].tint = 0x86bfda;
      }
      if(this.layout[y][x] === 3){
        this.tiles[y][x].tint = 0x00FF00;
      }

    }
  }
},

spawnPlayer: function() {
  this.player = game.add.isoSprite(50, 50, 500, 'cube', 0, isoGroup);
  this.player.tint = 0x86bfda;
  this.player.anchor.set(0.5);
  this.bubble.x = this.player.x;
  this.bubble.y = this.player.y;
  this.dropSprite(this.player, this.delay+100, 0, function(){this.canPlay = true}.bind(this))

},

checkTile: function(x,y) {
  if((x < 0 || y < 0)) {
    return 0;
  }

  if(this.layout[y] !== undefined) {
    if(this.layout[y][x] === undefined) {
      return 0;
    } else if(this.layout[y][x] === 0){
      return 0;
    } else {
      return this.layout[y][x];
    }
  } else {
    return 0;
  }
},
changeBubble: function(text) {
  this.bubble.kill();
  this.bubble = game.world.add(new SpeechBubble(game, 180, 190, 200, text));
  this.bubble.x = this.player.x;
  this.bubble.y = this.player.y;
},
complete: function() {
  this.changeBubble('WE WON')

  this.changeLevel('Level1');

  this.winTriggered = true;
},
changeLevel: function(level){
  var level = level;

  var delay = 0;

  for (var y = 0; y < this.layout.length; y++) {
    for (var x = 0; x < this.layout[y].length; x++) {
      if(this.layout[y][x] > 0) {
        delay += 100;
        this.dropSprite(this.tiles[y][x], delay, -500)
      }

    }
  }

  delay += 200;

  this.dropSprite(this.player, this.delay+200, -500, function(){this.canPlay = true}.bind(this))

  game.time.events.add(delay+1000, function() {
    game.world.removeAll()
    game.state.start(level, false, true);
  }, this);

},
dropSprite: function(sprite, delay, to, cb) {
  game.time.events.add(delay, function() {
    game.add.tween(sprite).to({ isoZ: to }, 150, Phaser.Easing.Linear.None, true);
    if(cb) {
      cb();
    }
  }, this);

}
};

game.state.add('Level1', Simplicity.Level1);
<|endoftext|>


<commit_before>var TBB_UA_REGEX = /Mozilla\/5\.0 \(Windows NT 6\.1; rv:[0-9]{2}\.0\) Gecko\/20100101 Firefox\/([0-9]{2})\.0/;
var ORFOX_UA_REGEX = /Mozilla\/5\.0 \(Android; Mobile; rv:[0-9]{2}\.0\) Gecko\/20100101 Firefox\/([0-9]{2})\.0/;

function is_likely_tor_browser() {
  return window.navigator.userAgent.match(TBB_UA_REGEX) &&
         (window.navigator.mimeTypes &&
          window.navigator.mimeTypes.length === 0);
}

function tbb_version() {
  var ua_match = window.navigator.userAgent.match(TBB_UA_REGEX);
  var major_version = ua_match[1];
  return Number(major_version);
}

function is_likely_orfox() {
  return window.navigator.userAgent.match(ORFOX_UA_REGEX) &&
         (window.navigator.mimeTypes &&
          window.navigator.mimeTypes.length === 0);
}

// Warn about using JavaScript and not using Tor Browser
$(function(){
  if (is_likely_tor_browser()) {
    // If the source is using Tor Browser, we want to encourage them to turn Tor
    // Browser's Security Slider to "Safest", which enables various hardening
    // methods, including disabling JavaScript. Since JS is disabled by turning
    // the Security Slider to "Safest", this code only runs if it set to another
    // (less hardened) setting.
    $('.js-warning').show();
    $('#js-warning-close').click(function(){
      $('.js-warning').hide(200);
    });

    // Display a friendly bubble with step-by-step instructions on how to turn
    // the security slider to Safest.
    var infoBubble = $('#security-slider-info-bubble');
    var fadeDuration = 500; // milliseconds

    $('#disable-js').click(function() {
      infoBubble.fadeIn(fadeDuration);
      return false; // don't follow link
    });

    // If the user clicks outside of the infoBubble while it is visible, hide it.
    $(window).click(function() {
      if (infoBubble.is(':visible')) {
        infoBubble.fadeOut(fadeDuration);
      }
    });

    // If the user clicks inside the infoBubble while it is visible, make sure
    // it stays visible.
    infoBubble.click(function(e) {
      e.stopPropagation();
    });
  } else {
    // If the user is running Orfox, we want to encourage them to use the desktop
    // version of Tor Browser for stronger security and anonymity.
    if(is_likely_orfox()){
      $('.orfox-browser').show();
      $('.hide-if-not-tor-browser').hide();
      $('#orfox-browser-close').click(function(){
        $('.orfox-browser').hide(200);
      });
    } else {
      // If the user is not using neither Tor Browser nor Orfox, we want to encourage them to do so.
      $('.use-tor-browser').show();
      $('.hide-if-not-tor-browser').hide();
      $('#use-tor-browser-close').click(function(){
        $('.use-tor-browser').hide(200);
      });
    }
  }
});
<commit_msg>Update Tor Browser User Agent for 8.0<commit_after>var TBB_UA_REGEX = /Mozilla\/5\.0 \((Windows NT 6\.1|X11; Linux x86_64|Macintosh; Intel Mac OS X 10\.13|Windows NT 6\.1; Win64; x64); rv:[0-9]{2}\.0\) Gecko\/20100101 Firefox\/([0-9]{2})\.0/;
var ORFOX_UA_REGEX = /Mozilla\/5\.0 \(Android; Mobile; rv:[0-9]{2}\.0\) Gecko\/20100101 Firefox\/([0-9]{2})\.0/;

function is_likely_tor_browser() {
  return window.navigator.userAgent.match(TBB_UA_REGEX) &&
         (window.navigator.mimeTypes &&
          window.navigator.mimeTypes.length === 0);
}

function tbb_version() {
  var ua_match = window.navigator.userAgent.match(TBB_UA_REGEX);
  var major_version = ua_match[1];
  return Number(major_version);
}

function is_likely_orfox() {
  return window.navigator.userAgent.match(ORFOX_UA_REGEX) &&
         (window.navigator.mimeTypes &&
          window.navigator.mimeTypes.length === 0);
}

// Warn about using JavaScript and not using Tor Browser
$(function(){
  if (is_likely_tor_browser()) {
    // If the source is using Tor Browser, we want to encourage them to turn Tor
    // Browser's Security Slider to "Safest", which enables various hardening
    // methods, including disabling JavaScript. Since JS is disabled by turning
    // the Security Slider to "Safest", this code only runs if it set to another
    // (less hardened) setting.
    $('.js-warning').show();
    $('#js-warning-close').click(function(){
      $('.js-warning').hide(200);
    });

    // Display a friendly bubble with step-by-step instructions on how to turn
    // the security slider to Safest.
    var infoBubble = $('#security-slider-info-bubble');
    var fadeDuration = 500; // milliseconds

    $('#disable-js').click(function() {
      infoBubble.fadeIn(fadeDuration);
      return false; // don't follow link
    });

    // If the user clicks outside of the infoBubble while it is visible, hide it.
    $(window).click(function() {
      if (infoBubble.is(':visible')) {
        infoBubble.fadeOut(fadeDuration);
      }
    });

    // If the user clicks inside the infoBubble while it is visible, make sure
    // it stays visible.
    infoBubble.click(function(e) {
      e.stopPropagation();
    });
  } else {
    // If the user is running Orfox, we want to encourage them to use the desktop
    // version of Tor Browser for stronger security and anonymity.
    if(is_likely_orfox()){
      $('.orfox-browser').show();
      $('.hide-if-not-tor-browser').hide();
      $('#orfox-browser-close').click(function(){
        $('.orfox-browser').hide(200);
      });
    } else {
      // If the user is not using neither Tor Browser nor Orfox, we want to encourage them to do so.
      $('.use-tor-browser').show();
      $('.hide-if-not-tor-browser').hide();
      $('#use-tor-browser-close').click(function(){
        $('.use-tor-browser').hide(200);
      });
    }
  }
});
<|endoftext|>


<commit_before>/**
 * Copyright 2013-2018 the original author or authors from the JHipster project.
 *
 * This file is part of the JHipster project, see http://www.jhipster.tech/
 * for more information.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const AWS_SSM_VERSION = '1.11.247';
const SPRING_CLOUD_CTX_VERSION = '1.3.0.RELEASE';

const configuration = {
    aws: 'aws'
};

const constants = {
    conf: configuration,
    AWS_SSM_VERSION,
    SPRING_CLOUD_CTX_VERSION
};

module.exports = constants;
<commit_msg>Use the Spring Cloud Context version from jhipster-dependencies<commit_after>/**
 * Copyright 2013-2018 the original author or authors from the JHipster project.
 *
 * This file is part of the JHipster project, see http://www.jhipster.tech/
 * for more information.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const AWS_SSM_VERSION = '1.11.247';

const configuration = {
    aws: 'aws'
};

const constants = {
    conf: configuration,
    AWS_SSM_VERSION
};

module.exports = constants;
<|endoftext|>


<commit_before>// The Tag UI area associated with a post

/*global window, document, setTimeout, $, _, Backbone, Ghost */

(function () {
    "use strict";

    Ghost.View.EditorTagWidget = Ghost.View.extend({

        events: {
            'keyup [data-input-behaviour="tag"]': 'handleKeyup',
            'keydown [data-input-behaviour="tag"]': 'handleKeydown',
            'keypress [data-input-behaviour="tag"]': 'handleKeypress',
            'click ul.suggestions li': 'handleSuggestionClick',
            'click .tags .tag': 'handleTagClick',
            'click .tag-label': 'mobileTags'
        },

        keys: {
            UP: 38,
            DOWN: 40,
            ESC: 27,
            ENTER: 13,
            BACKSPACE: 8
        },

        initialize: function () {
            var self = this,
                tagCollection = new Ghost.Collections.Tags();

            tagCollection.fetch().then(function () {
                self.allGhostTags = tagCollection.toJSON();
            });

            this.listenTo(this.model, 'willSave', this.completeCurrentTag, this);
        },

        render: function () {
            var tags = this.model.get('tags'),
                $tags = $('.tags'),
                tagOffset,
                self = this;

            $tags.empty();

            if (tags) {
                _.forEach(tags, function (tag) {
                    var $tag = $('' + tag.name + '');
                    $tags.append($tag);
                    $("[data-tag-id=" + tag.id + "]")[0].scrollIntoView(true);
                });
            }

            this.$suggestions = $("ul.suggestions").hide(); // Initialise suggestions overlay

            if ($tags.length) {
                tagOffset = $('.tag-input').offset().left;
                $('.tag-blocks').css({'left': tagOffset + 'px'});
            }

            $(window).on('resize', self.resize).trigger('resize');

            $('.tag-label').on('touchstart', function () {
                $(this).addClass('touch');
            });

            return this;
        },

        mobileTags: function () {
            var mq = window.matchMedia("(max-width: 400px)"),
                publishBar = $("#publish-bar");
            if (mq.matches) {

                if (publishBar.hasClass("extended-tags")) {
                    publishBar.css("top", "auto").animate({"height": "40px"}, 300, "swing", function () {
                        $(this).removeClass("extended-tags");
                        $(".tag-input").blur();
                    });
                } else {
                    publishBar.animate({"top": 0, "height": $(window).height()}, 300, "swing", function () {
                        $(this).addClass("extended-tags");
                        $(".tag-input").focus();
                    });
                }

                $(".tag-input").one("blur", function () {

                    if (publishBar.hasClass("extended-tags") && !$(':hover').last().hasClass("tag")) {
                        publishBar.css("top", "auto").animate({"height": "40px"}, 300, "swing", function () {
                            $(this).removeClass("extended-tags");
                            $(document.activeElement).blur();
                            document.documentElement.style.display = "none";
                            setTimeout(function () { document.documentElement.style.display = 'block'; }, 0);
                        });
                    }
                });

                window.scrollTo(0, 1);
            }
        },

        showSuggestions: function ($target, _searchTerm) {
            var searchTerm = _searchTerm.toLowerCase(),
                matchingTags = this.findMatchingTags(searchTerm),
                styles = {
                    left: $target.position().left
                },
                maxSuggestions = 5, // Limit the suggestions number
                regexTerm = searchTerm.replace(/(\s+)/g, "(<[^>]+>)*$1(<[^>]+>)*"),
                regexPattern = new RegExp("(" + regexTerm + ")", "i");

            this.$suggestions.css(styles);
            this.$suggestions.html("");

            matchingTags = _.first(matchingTags, maxSuggestions);
            if (matchingTags.length > 0) {
                this.$suggestions.show();
            }
            _.each(matchingTags, function (matchingTag) {
                var highlightedName,
                    suggestionHTML;

                highlightedName = matchingTag.name.replace(regexPattern, "$1");
                /*jslint regexp: true */ // - would like to remove this
                highlightedName = highlightedName.replace(/([^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/, "$1$2$4");

                suggestionHTML = "
" + highlightedName + "
";
                this.$suggestions.append(suggestionHTML);
            }, this);
        },

        handleKeyup: function (e) {
            var $target = $(e.currentTarget),
                searchTerm = $.trim($target.val());

            if (searchTerm) {
                this.showSuggestions($target, searchTerm);
            } else {
                this.$suggestions.hide();
            }

            if (e.keyCode === this.keys.UP) {
                e.preventDefault();
                if (this.$suggestions.is(":visible")) {
                    if (this.$suggestions.children(".selected").length === 0) {
                        this.$suggestions.find("li:last-child").addClass('selected');
                    } else {
                        this.$suggestions.children(".selected").removeClass('selected').prev().addClass('selected');
                    }
                }
            } else if (e.keyCode === this.keys.DOWN) {
                e.preventDefault();
                if (this.$suggestions.is(":visible")) {
                    if (this.$suggestions.children(".selected").length === 0) {
                        this.$suggestions.find("li:first-child").addClass('selected');
                    } else {
                        this.$suggestions.children(".selected").removeClass('selected').next().addClass('selected');
                    }
                }
            } else if (e.keyCode === this.keys.ESC) {
                this.$suggestions.hide();
            }

            if (e.keyCode === this.keys.UP || e.keyCode === this.keys.DOWN) {
                return false;
            }
        },

        handleKeydown: function (e) {
            var $target = $(e.currentTarget),
                lastBlock,
                tag;
            // Delete character tiggers on Keydown, so needed to check on that event rather than Keyup.
            if (e.keyCode === this.keys.BACKSPACE && !$target.val()) {
                lastBlock = this.$('.tags').find('.tag').last();
                lastBlock.remove();
                tag = {id: lastBlock.data('tag-id'), name: lastBlock.text()};
                this.model.removeTag(tag);
            }
        },

        handleKeypress: function (e) {
            var $target = $(e.currentTarget),
                searchTerm = $.trim($target.val()),
                tag,
                $selectedSuggestion,
                isComma = ",".localeCompare(String.fromCharCode(e.keyCode || e.charCode)) === 0;

            // use localeCompare in case of international keyboard layout
            if ((e.keyCode === this.keys.ENTER || isComma) && searchTerm) {
                // Submit tag using enter or comma key
                e.preventDefault();

                $selectedSuggestion = this.$suggestions.children(".selected");
                if (this.$suggestions.is(":visible") && $selectedSuggestion.length !== 0) {

                    if ($('.tag:containsExact("' + $selectedSuggestion.data('tag-name') + '")').length === 0) {
                        tag = {id: $selectedSuggestion.data('tag-id'), name: $selectedSuggestion.data('tag-name')};
                        this.addTag(tag);
                    }
                } else {
                    if (isComma) {
                        searchTerm = searchTerm.replace(/,/g, "");
                    }  // Remove comma from string if comma is used to submit.
                    if ($('.tag:containsExact("' + searchTerm + '")').length === 0) {
                        this.addTag({id: null, name: searchTerm});
                    }
                }
                $target.val('').focus();
                searchTerm = ""; // Used to reset search term
                this.$suggestions.hide();
            }
        },

        completeCurrentTag: function () {
            var $target = this.$('.tag-input'),
                tagName = $target.val(),
                usedTagNames,
                hasAlreadyBeenAdded;

            usedTagNames = _.map(this.model.get('tags'), function (tag) {
                return tag.name.toUpperCase();
            });
            hasAlreadyBeenAdded = usedTagNames.indexOf(tagName.toUpperCase()) !== -1;

            if (tagName.length > 0 && !hasAlreadyBeenAdded) {
                this.addTag({id: null, name: tagName});
            }
        },

        handleSuggestionClick: function (e) {
            var $target = $(e.currentTarget);
            if (e) { e.preventDefault(); }
            this.addTag({id: $target.data('tag-id'), name: $target.data('tag-name')});
        },

        handleTagClick: function (e) {
            var $tag = $(e.currentTarget),
                tag = {id: $tag.data('tag-id'), name: $tag.text()};
            $tag.remove();
            window.scrollTo(0, 1);
            this.model.removeTag(tag);
        },

        resize: _.throttle(function () {
            var $tags = $('.tags');
            if ($(window).width() > 400) {
                $tags.css("max-width", $("#entry-tags").width() - 320);
            } else {
                $tags.css("max-width", "inherit");
            }
        }, 50),

        findMatchingTags: function (searchTerm) {
            var matchingTagModels,
                self = this;

            if (!this.allGhostTags) {
                return [];
            }

            searchTerm = searchTerm.toUpperCase();
            matchingTagModels = _.filter(this.allGhostTags, function (tag) {
                var tagNameMatches,
                    hasAlreadyBeenAdded;

                tagNameMatches = tag.name.toUpperCase().indexOf(searchTerm) !== -1;

                hasAlreadyBeenAdded = _.some(self.model.get('tags'), function (usedTag) {
                    return tag.name.toUpperCase() === usedTag.name.toUpperCase();
                });
                return tagNameMatches && !hasAlreadyBeenAdded;
            });

            return matchingTagModels;
        },

        addTag: function (tag) {
            var $tag = $('' + tag.name + '');
            this.$('.tags').append($tag);
            $(".tag").last()[0].scrollIntoView(true);
            window.scrollTo(0, 1);
            this.model.addTag(tag);

            this.$('.tag-input').val('').focus();
            this.$suggestions.hide();
        }
    });

}());
<commit_msg>Tag needs escaping. Wrongly call showSuggestions.<commit_after>// The Tag UI area associated with a post

/*global window, document, setTimeout, $, _, Backbone, Ghost */

(function () {
    "use strict";

    Ghost.View.EditorTagWidget = Ghost.View.extend({

        events: {
            'keyup [data-input-behaviour="tag"]': 'handleKeyup',
            'keydown [data-input-behaviour="tag"]': 'handleKeydown',
            'keypress [data-input-behaviour="tag"]': 'handleKeypress',
            'click ul.suggestions li': 'handleSuggestionClick',
            'click .tags .tag': 'handleTagClick',
            'click .tag-label': 'mobileTags'
        },

        keys: {
            UP: 38,
            DOWN: 40,
            ESC: 27,
            ENTER: 13,
            BACKSPACE: 8
        },

        initialize: function () {
            var self = this,
                tagCollection = new Ghost.Collections.Tags();

            tagCollection.fetch().then(function () {
                self.allGhostTags = tagCollection.toJSON();
            });

            this.listenTo(this.model, 'willSave', this.completeCurrentTag, this);
        },

        render: function () {
            var tags = this.model.get('tags'),
                $tags = $('.tags'),
                tagOffset,
                self = this;

            $tags.empty();

            if (tags) {
                _.forEach(tags, function (tag) {
                    var $tag = $('' + tag.name + '');
                    $tags.append($tag);
                    $("[data-tag-id=" + tag.id + "]")[0].scrollIntoView(true);
                });
            }

            this.$suggestions = $("ul.suggestions").hide(); // Initialise suggestions overlay

            if ($tags.length) {
                tagOffset = $('.tag-input').offset().left;
                $('.tag-blocks').css({'left': tagOffset + 'px'});
            }

            $(window).on('resize', self.resize).trigger('resize');

            $('.tag-label').on('touchstart', function () {
                $(this).addClass('touch');
            });

            return this;
        },

        mobileTags: function () {
            var mq = window.matchMedia("(max-width: 400px)"),
                publishBar = $("#publish-bar");
            if (mq.matches) {

                if (publishBar.hasClass("extended-tags")) {
                    publishBar.css("top", "auto").animate({"height": "40px"}, 300, "swing", function () {
                        $(this).removeClass("extended-tags");
                        $(".tag-input").blur();
                    });
                } else {
                    publishBar.animate({"top": 0, "height": $(window).height()}, 300, "swing", function () {
                        $(this).addClass("extended-tags");
                        $(".tag-input").focus();
                    });
                }

                $(".tag-input").one("blur", function () {

                    if (publishBar.hasClass("extended-tags") && !$(':hover').last().hasClass("tag")) {
                        publishBar.css("top", "auto").animate({"height": "40px"}, 300, "swing", function () {
                            $(this).removeClass("extended-tags");
                            $(document.activeElement).blur();
                            document.documentElement.style.display = "none";
                            setTimeout(function () { document.documentElement.style.display = 'block'; }, 0);
                        });
                    }
                });

                window.scrollTo(0, 1);
            }
        },

        showSuggestions: function ($target, _searchTerm) {
            var searchTerm = _searchTerm.toLowerCase(),
                matchingTags = this.findMatchingTags(searchTerm),
                styles = {
                    left: $target.position().left
                },
                maxSuggestions = 5, // Limit the suggestions number
                regexTerm = searchTerm.replace(/(\s+)/g, "(<[^>]+>)*$1(<[^>]+>)*"),
                regexPattern = new RegExp("(" + regexTerm + ")", "i");

            this.$suggestions.css(styles);
            this.$suggestions.html("");

            matchingTags = _.first(matchingTags, maxSuggestions);
            if (matchingTags.length > 0) {
                this.$suggestions.show();
            }
            _.each(matchingTags, function (matchingTag) {
                var highlightedName,
                    suggestionHTML;

                highlightedName = matchingTag.name.replace(regexPattern, "$1");
                /*jslint regexp: true */ // - would like to remove this
                highlightedName = highlightedName.replace(/([^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/, "$1$2$4");

                suggestionHTML = "
" + highlightedName + "
";
                this.$suggestions.append(suggestionHTML);
            }, this);
        },

        handleKeyup: function (e) {
            var $target = $(e.currentTarget),
                searchTerm = $.trim($target.val());

            if (e.keyCode === this.keys.UP) {
                e.preventDefault();
                if (this.$suggestions.is(":visible")) {
                    if (this.$suggestions.children(".selected").length === 0) {
                        this.$suggestions.find("li:last-child").addClass('selected');
                    } else {
                        this.$suggestions.children(".selected").removeClass('selected').prev().addClass('selected');
                    }
                }
            } else if (e.keyCode === this.keys.DOWN) {
                e.preventDefault();
                if (this.$suggestions.is(":visible")) {
                    if (this.$suggestions.children(".selected").length === 0) {
                        this.$suggestions.find("li:first-child").addClass('selected');
                    } else {
                        this.$suggestions.children(".selected").removeClass('selected').next().addClass('selected');
                    }
                }
            } else if (e.keyCode === this.keys.ESC) {
                this.$suggestions.hide();
            } else {
                if (searchTerm) {
                    this.showSuggestions($target, searchTerm);
                } else {
                    this.$suggestions.hide();
                }
            }

            if (e.keyCode === this.keys.UP || e.keyCode === this.keys.DOWN) {
                return false;
            }
        },

        handleKeydown: function (e) {
            var $target = $(e.currentTarget),
                lastBlock,
                tag;
            // Delete character tiggers on Keydown, so needed to check on that event rather than Keyup.
            if (e.keyCode === this.keys.BACKSPACE && !$target.val()) {
                lastBlock = this.$('.tags').find('.tag').last();
                lastBlock.remove();
                tag = {id: lastBlock.data('tag-id'), name: lastBlock.text()};
                this.model.removeTag(tag);
            }
        },

        handleKeypress: function (e) {
            var $target = $(e.currentTarget),
                searchTerm = $.trim($target.val()),
                tag,
                $selectedSuggestion,
                isComma = ",".localeCompare(String.fromCharCode(e.keyCode || e.charCode)) === 0;

            // use localeCompare in case of international keyboard layout
            if ((e.keyCode === this.keys.ENTER || isComma) && searchTerm) {
                // Submit tag using enter or comma key
                e.preventDefault();

                $selectedSuggestion = this.$suggestions.children(".selected");
                if (this.$suggestions.is(":visible") && $selectedSuggestion.length !== 0) {

                    if ($('.tag:containsExact("' + _.unescape($selectedSuggestion.data('tag-name')) + '")').length === 0) {
                        tag = {id: $selectedSuggestion.data('tag-id'), name: _.unescape($selectedSuggestion.data('tag-name'))};
                        this.addTag(tag);
                    }
                } else {
                    if (isComma) {
                        searchTerm = searchTerm.replace(/,/g, "");
                    }  // Remove comma from string if comma is used to submit.
                    if ($('.tag:containsExact("' + searchTerm + '")').length === 0) {
                        this.addTag({id: null, name: searchTerm});
                    }
                }
                $target.val('').focus();
                searchTerm = ""; // Used to reset search term
                this.$suggestions.hide();
            }
        },

        completeCurrentTag: function () {
            var $target = this.$('.tag-input'),
                tagName = $target.val(),
                usedTagNames,
                hasAlreadyBeenAdded;

            usedTagNames = _.map(this.model.get('tags'), function (tag) {
                return tag.name.toUpperCase();
            });
            hasAlreadyBeenAdded = usedTagNames.indexOf(tagName.toUpperCase()) !== -1;

            if (tagName.length > 0 && !hasAlreadyBeenAdded) {
                this.addTag({id: null, name: tagName});
            }
        },

        handleSuggestionClick: function (e) {
            var $target = $(e.currentTarget);
            if (e) { e.preventDefault(); }
            this.addTag({id: $target.data('tag-id'), name: _.unescape($target.data('tag-name'))});
        },

        handleTagClick: function (e) {
            var $tag = $(e.currentTarget),
                tag = {id: $tag.data('tag-id'), name: $tag.text()};
            $tag.remove();
            window.scrollTo(0, 1);
            this.model.removeTag(tag);
        },

        resize: _.throttle(function () {
            var $tags = $('.tags');
            if ($(window).width() > 400) {
                $tags.css("max-width", $("#entry-tags").width() - 320);
            } else {
                $tags.css("max-width", "inherit");
            }
        }, 50),

        findMatchingTags: function (searchTerm) {
            var matchingTagModels,
                self = this;

            if (!this.allGhostTags) {
                return [];
            }

            searchTerm = searchTerm.toUpperCase();
            matchingTagModels = _.filter(this.allGhostTags, function (tag) {
                var tagNameMatches,
                    hasAlreadyBeenAdded;

                tagNameMatches = tag.name.toUpperCase().indexOf(searchTerm) !== -1;

                hasAlreadyBeenAdded = _.some(self.model.get('tags'), function (usedTag) {
                    return tag.name.toUpperCase() === usedTag.name.toUpperCase();
                });
                return tagNameMatches && !hasAlreadyBeenAdded;
            });

            return matchingTagModels;
        },

        addTag: function (tag) {
            var $tag = $('' + tag.name + '');
            this.$('.tags').append($tag);
            $(".tag").last()[0].scrollIntoView(true);
            window.scrollTo(0, 1);
            this.model.addTag(tag);

            this.$('.tag-input').val('').focus();
            this.$suggestions.hide();
        }
    });

}());
<|endoftext|>


<commit_before>// Initialization method
function init(elem, id, opts) {
	var obj, posOptions, attr, config, title,

	// Setup element references
	docBody = $(document.body),

	// Use document body instead of document element if needed
	newTarget = elem[0] === document ? docBody : elem,

	// Grab metadata from element if plugin is present
	metadata = (elem.metadata) ? elem.metadata(opts.metadata) : NULL,

	// If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise
	metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL,

	// Grab data from metadata.name (or data-qtipopts as fallback) using .data() method,
	html5 = elem.data(opts.metadata.name || 'qtipopts');

	// If we don't get an object returned attempt to parse it manualyl without parseJSON
	try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; } catch(e) {}

	// Merge in and sanitize metadata
	config = $.extend(TRUE, {}, QTIP.defaults, opts,
		typeof html5 === 'object' ? sanitizeOptions(html5) : NULL,
		sanitizeOptions(metadata5 || metadata));

	// Re-grab our positioning options now we've merged our metadata and set id to passed value
	posOptions = config.position;
	config.id = id;

	// Setup missing content if none is detected
	if('boolean' === typeof config.content.text) {
		attr = elem.attr(config.content.attr);

		// Grab from supplied attribute if available
		if(config.content.attr !== FALSE && attr) { config.content.text = attr; }

		// No valid content was found, abort render
		else { return FALSE; }
	}

	// Setup target options
	if(!posOptions.container.length) { posOptions.container = docBody; }
	if(posOptions.target === FALSE) { posOptions.target = newTarget; }
	if(config.show.target === FALSE) { config.show.target = newTarget; }
	if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); }
	if(config.hide.target === FALSE) { config.hide.target = newTarget; }
	if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; }

	// Ensure we only use a single container
	posOptions.container = posOptions.container.eq(0);

	// Convert position corner values into x and y strings
	posOptions.at = new CORNER(posOptions.at, TRUE);
	posOptions.my = new CORNER(posOptions.my);

	// Destroy previous tooltip if overwrite is enabled, or skip element if not
	if(elem.data(NAMESPACE)) {
		if(config.overwrite) {
			elem.qtip('destroy', true);
		}
		else if(config.overwrite === FALSE) {
			return FALSE;
		}
	}

	// Add has-qtip attribute
	elem.attr(ATTR_HAS, id);

	// Remove title attribute and store it if present
	if(config.suppress && (title = elem.attr('title'))) {
		// Final attr call fixes event delegatiom and IE default tooltip showing problem
		elem.removeAttr('title').attr(oldtitle, title).attr('title', '');
	}

	// Initialize the tooltip and add API reference
	obj = new QTip(elem, config, id, !!attr);
	elem.data(NAMESPACE, obj);

	// Catch remove/removeqtip events on target element to destroy redundant tooltip
	elem.one('remove.qtip-'+id+' removeqtip.qtip-'+id, function() {
		var api; if((api = $(this).data(NAMESPACE))) { api.destroy(); }
	});

	return obj;
}

// jQuery $.fn extension method
QTIP = $.fn.qtip = function(options, notation, newValue)
{
	var command = ('' + options).toLowerCase(), // Parse command
		returned = NULL,
		args = $.makeArray(arguments).slice(1),
		event = args[args.length - 1],
		opts = this[0] ? $.data(this[0], NAMESPACE) : NULL;

	// Check for API request
	if((!arguments.length && opts) || command === 'api') {
		return opts;
	}

	// Execute API command if present
	else if('string' === typeof options) {
		this.each(function() {
			var api = $.data(this, NAMESPACE);
			if(!api) { return TRUE; }

			// Cache the event if possible
			if(event && event.timeStamp) { api.cache.event = event; }

			// Check for specific API commands
			if(notation && (command === 'option' || command === 'options')) {
				if(newValue !== undefined || $.isPlainObject(notation)) {
					api.set(notation, newValue);
				}
				else {
					returned = api.get(notation);
					return FALSE;
				}
			}

			// Execute API command
			else if(api[command]) {
				api[command].apply(api, args);
			}
		});

		return returned !== NULL ? returned : this;
	}

	// No API commands. validate provided options and setup qTips
	else if('object' === typeof options || !arguments.length) {
		// Sanitize options first
		opts = sanitizeOptions($.extend(TRUE, {}, options));

		return this.each(function(i) {
			var options, targets, events, namespace, api, id;

			// Find next available ID, or use custom ID if provided
			id = $.isArray(opts.id) ? opts.id[i] : opts.id;
			id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ? QTIP.nextid++ : id;

			// Setup events namespace
			namespace = '.qtip-'+id+'-create';

			// Initialize the qTip and re-grab newly sanitized options
			api = init($(this), id, opts);
			if(api === FALSE) { return TRUE; }
			else { QTIP.api[id] = api; }
			options = api.options;

			// Initialize plugins
			$.each(PLUGINS, function() {
				if(this.initialize === 'initialize') { this(api); }
			});

			// Assign initial pre-render events
			api._assignInitialEvents(event);
		});
	}
};

// $.fn.qtip Bind method
QTIP.bind = function(opts, event)
{

};

// Populated in render method
QTIP.api = {};
<commit_msg>Remove redundant method<commit_after>// Initialization method
function init(elem, id, opts) {
	var obj, posOptions, attr, config, title,

	// Setup element references
	docBody = $(document.body),

	// Use document body instead of document element if needed
	newTarget = elem[0] === document ? docBody : elem,

	// Grab metadata from element if plugin is present
	metadata = (elem.metadata) ? elem.metadata(opts.metadata) : NULL,

	// If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise
	metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL,

	// Grab data from metadata.name (or data-qtipopts as fallback) using .data() method,
	html5 = elem.data(opts.metadata.name || 'qtipopts');

	// If we don't get an object returned attempt to parse it manualyl without parseJSON
	try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; } catch(e) {}

	// Merge in and sanitize metadata
	config = $.extend(TRUE, {}, QTIP.defaults, opts,
		typeof html5 === 'object' ? sanitizeOptions(html5) : NULL,
		sanitizeOptions(metadata5 || metadata));

	// Re-grab our positioning options now we've merged our metadata and set id to passed value
	posOptions = config.position;
	config.id = id;

	// Setup missing content if none is detected
	if('boolean' === typeof config.content.text) {
		attr = elem.attr(config.content.attr);

		// Grab from supplied attribute if available
		if(config.content.attr !== FALSE && attr) { config.content.text = attr; }

		// No valid content was found, abort render
		else { return FALSE; }
	}

	// Setup target options
	if(!posOptions.container.length) { posOptions.container = docBody; }
	if(posOptions.target === FALSE) { posOptions.target = newTarget; }
	if(config.show.target === FALSE) { config.show.target = newTarget; }
	if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); }
	if(config.hide.target === FALSE) { config.hide.target = newTarget; }
	if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; }

	// Ensure we only use a single container
	posOptions.container = posOptions.container.eq(0);

	// Convert position corner values into x and y strings
	posOptions.at = new CORNER(posOptions.at, TRUE);
	posOptions.my = new CORNER(posOptions.my);

	// Destroy previous tooltip if overwrite is enabled, or skip element if not
	if(elem.data(NAMESPACE)) {
		if(config.overwrite) {
			elem.qtip('destroy', true);
		}
		else if(config.overwrite === FALSE) {
			return FALSE;
		}
	}

	// Add has-qtip attribute
	elem.attr(ATTR_HAS, id);

	// Remove title attribute and store it if present
	if(config.suppress && (title = elem.attr('title'))) {
		// Final attr call fixes event delegatiom and IE default tooltip showing problem
		elem.removeAttr('title').attr(oldtitle, title).attr('title', '');
	}

	// Initialize the tooltip and add API reference
	obj = new QTip(elem, config, id, !!attr);
	elem.data(NAMESPACE, obj);

	// Catch remove/removeqtip events on target element to destroy redundant tooltip
	elem.one('remove.qtip-'+id+' removeqtip.qtip-'+id, function() {
		var api; if((api = $(this).data(NAMESPACE))) { api.destroy(); }
	});

	return obj;
}

// jQuery $.fn extension method
QTIP = $.fn.qtip = function(options, notation, newValue)
{
	var command = ('' + options).toLowerCase(), // Parse command
		returned = NULL,
		args = $.makeArray(arguments).slice(1),
		event = args[args.length - 1],
		opts = this[0] ? $.data(this[0], NAMESPACE) : NULL;

	// Check for API request
	if((!arguments.length && opts) || command === 'api') {
		return opts;
	}

	// Execute API command if present
	else if('string' === typeof options) {
		this.each(function() {
			var api = $.data(this, NAMESPACE);
			if(!api) { return TRUE; }

			// Cache the event if possible
			if(event && event.timeStamp) { api.cache.event = event; }

			// Check for specific API commands
			if(notation && (command === 'option' || command === 'options')) {
				if(newValue !== undefined || $.isPlainObject(notation)) {
					api.set(notation, newValue);
				}
				else {
					returned = api.get(notation);
					return FALSE;
				}
			}

			// Execute API command
			else if(api[command]) {
				api[command].apply(api, args);
			}
		});

		return returned !== NULL ? returned : this;
	}

	// No API commands. validate provided options and setup qTips
	else if('object' === typeof options || !arguments.length) {
		// Sanitize options first
		opts = sanitizeOptions($.extend(TRUE, {}, options));

		return this.each(function(i) {
			var options, targets, events, namespace, api, id;

			// Find next available ID, or use custom ID if provided
			id = $.isArray(opts.id) ? opts.id[i] : opts.id;
			id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ? QTIP.nextid++ : id;

			// Setup events namespace
			namespace = '.qtip-'+id+'-create';

			// Initialize the qTip and re-grab newly sanitized options
			api = init($(this), id, opts);
			if(api === FALSE) { return TRUE; }
			else { QTIP.api[id] = api; }
			options = api.options;

			// Initialize plugins
			$.each(PLUGINS, function() {
				if(this.initialize === 'initialize') { this(api); }
			});

			// Assign initial pre-render events
			api._assignInitialEvents(event);
		});
	}
};

// Populated in render method
QTIP.api = {};
<|endoftext|>


<commit_before>import { Record } from 'immutable';
import { layoutActions } from './actions';

export const layoutState = new Record({
  layout: 'There is no profile yet'
});

export function layoutReducer(state = new layoutState(), {payload, type}) {
  switch (type) {
    case layoutActions.LAYOUT_MODEL_RECEIVED:
      return state.merge({
        layout: payload
      });
    default:
      return state;
  }
}<commit_msg>fix immutable usage<commit_after>import { Record } from 'immutable';
import { layoutActions } from './actions';

export const layoutState = new Record({
  layout: {}
});

export function layoutReducer(state = new layoutState(), {payload, type}) {
  switch (type) {
    case layoutActions.LAYOUT_MODEL_RECEIVED:
      return state.set('layout', payload);
    default:
      return state;
  }
}<|endoftext|>


<commit_before>(function(angular, $, _) {

  angular.module('statuspage').config(function($routeProvider) {
      $routeProvider.when('/status', {
        controller: 'StatuspageStatusPage',
        templateUrl: '~/statuspage/StatusPage.html',

        // If you need to look up data when opening the page, list it out
        // under "resolve".
        resolve: {
          myContact: function(crmApi) {
            return crmApi('Contact', 'getsingle', {
              id: 'user_contact_id',
              return: ['first_name', 'last_name']
            });
          },
          statuses: function(crmApi) {
            return crmApi('System', 'check')
              .catch(function(obj){console.log(obj)})
              .then(createStatusDisplayTitle)
            ;
          }
        }
      });
    }
  );

 /**
  * add property to results of api.System.check
  * @param {type} apiResults
  * @returns apiResults
  */
  function createStatusDisplayTitle(apiResults){
    _.each(apiResults.values, function(status){
      status.displayTitle = status.name+' - '+status.title+' - '+status.severity.toUpperCase();
    });
    return apiResults;
  }

  angular.module('statuspage').filter('trusted', function($sce){ return $sce.trustAsHtml; });

  angular.module('statuspage').controller('StatuspageStatusPage', function($scope, crmApi, crmStatus, crmUiHelp, myContact, statuses) {
    // The ts() and hs() functions help load strings for this module.
    var ts = $scope.ts = CRM.ts('statuspage');
    var hs = $scope.hs = crmUiHelp({file: 'CRM/statuspage/StatusPage'}); // See: templates/CRM/statuspage/StatusPage.hlp

    // We have myContact available in JS. We also want to reference it in HTML.
    $scope.myContact = myContact;

    $scope.statuses = statuses;

    $scope.hush = function hush(name, severity) {
      return  crmStatus(
        { start: ts('Saving Status Preference...')      , success: ts('Preference Saved') },
        crmApi('StatusPreference', 'create', {
          "sequential": 1,
          "name": name,
          "ignore_severity": severity
        })
      );
    }
  });

})(angular, CRM.$, CRM._);
<commit_msg>update model after hush<commit_after>(function(angular, $, _) {

  angular.module('statuspage').config(function($routeProvider) {
      $routeProvider.when('/status', {
        controller: 'StatuspageStatusPage',
        templateUrl: '~/statuspage/StatusPage.html',

        // If you need to look up data when opening the page, list it out
        // under "resolve".
        resolve: {
          myContact: function(crmApi) {
            return crmApi('Contact', 'getsingle', {
              id: 'user_contact_id',
              return: ['first_name', 'last_name']
            });
          },
          statuses: function(crmApi) {
            return crmApi('System', 'check')
              .catch(function(obj){console.log(obj)})
              .then(createStatusDisplayTitle)
            ;
          }
        }
      });
    }
  );

 /**
  * add property to results of api.System.check
  * @param {type} apiResults
  * @returns apiResults
  */
  function createStatusDisplayTitle(apiResults){
    _.each(apiResults.values, function(status){
      status.displayTitle = status.name+' - '+status.title+' - '+status.severity.toUpperCase();
    });
    return apiResults;
  }

  /**
   * remove a status after it has been hushed/snoozed
   * @param {type} $scope
   * @param {type} statusName
   * @returns void
   */
   function rmStatus($scope, statusName) {
    $scope.statuses.values =  _.reject($scope.statuses.values, function(status) {
      return status.name === statusName; // or some complex logic
    });
  }

  angular.module('statuspage').filter('trusted', function($sce){ return $sce.trustAsHtml; });

  angular.module('statuspage').controller('StatuspageStatusPage', function($scope, crmApi, crmStatus, crmUiHelp, myContact, statuses) {
    // The ts() and hs() functions help load strings for this module.
    var ts = $scope.ts = CRM.ts('statuspage');
    var hs = $scope.hs = crmUiHelp({file: 'CRM/statuspage/StatusPage'}); // See: templates/CRM/statuspage/StatusPage.hlp

    // We have myContact available in JS. We also want to reference it in HTML.
    $scope.myContact = myContact;

    $scope.statuses = statuses;

    $scope.hush = function hush(name, severity) {
      return  crmStatus(
        { start: ts('Saving Status Preference...')      , success: ts('Preference Saved') },
        crmApi('StatusPreference', 'create', {
          "sequential": 1,
          "name": name,
          "ignore_severity": severity
        })
        .then(function(){rmStatus($scope, name);})
      );
    }
  });

})(angular, CRM.$, CRM._);
<|endoftext|>


<commit_before>/*global angular, _, moment, $*/

/**
 * angular-timezone-selector
 *
 * A simple directive that allows a user to pick their timezone
 *
 * Author:  Ashok Fernandez <ashok@mish.guru>
 * Date:    12/06/2015
 * License: MIT
 */

angular.module('angular-timezone-selector', [])
  .constant('_', _)
  .constant('moment', moment)
  .factory('timezones', ['_', 'moment', function (_, moment) {
    var timezoneMap = {}
    _.forEach(moment.tz.names(), function (zoneName) {
      var tz=moment.tz(zoneName);
      timezoneMap[zoneName] = {
        id: zoneName,
        name: zoneName.replace(/_/g, ' '),
        offset: 'UTC' + tz.format('Z'),
        nOffset: tz.utcOffset()
      }
    })
    return timezoneMap
  }])

  // Timezone name to country codemap
  .factory('zoneToCC', ['_', function (_) {
    // Note: zones is populated with the data from 'data/zone.csv' when this file is built
    var zones = []
    var zoneMap = {}
    _.forEach(zones, function (zone) {
      zoneMap[zone.name] = zone.cca2
    })
    return zoneMap

  }])

  // Country code to country name map
  .factory('CCToCountryName', ['_', function (_) {
    // Note: codes is populated with the data from 'data/cca2_to_country_name.csv' when this file is built
    var codes = []
    var codeMap = {}
    _.forEach(codes, function (code) {
      codeMap[code.cca2] = code.name
    })
    return codeMap
  }])

  .directive('timezoneSelector', ['_', 'timezones', 'zoneToCC', 'CCToCountryName', function (_, timezones, zoneToCC, CCToCountryName) {
    return {
      restrict: 'E',
      replace: true,
      template: '<select style="min-width:300px;"></select>',
      scope: {
        ngModel: '='
      },
      link: function ($scope, elem, attrs) {
        var data = []

        // Group the timezones by their country code
        var timezonesGroupedByCC = {}
        _.forEach(timezones, function (timezone) {
          if (_.has(zoneToCC, timezone.id)) {
            var CC = zoneToCC[timezone.id]
            timezonesGroupedByCC[CC] = !timezonesGroupedByCC[CC] ? [] : timezonesGroupedByCC[CC]
            timezonesGroupedByCC[CC].push(timezone)
          }
        })

        // Add the grouped countries to the data array with their country name as the group option
        _.forEach(timezonesGroupedByCC, function (zonesByCountry, CC) {
          var zonesForCountry = {
            text: CCToCountryName[CC] + ': ',
            children: zonesByCountry
            firstNOffset: zonesByCountry[0].nOffset,
            firstOffset: zonesByCountry[0].offset
          }

          data.push(zonesForCountry)
        })

        // Sort by country name
        data = _.sortBy(data, 'text')

        // Construct a select box with the timezones grouped by country
        _.forEach(data, function (group) {
          var $optgroup = $('<optgroup label="' + group.text + '">')
          group.children.forEach(function (option) {
            $optgroup.append('<option value="' + option.id + '">' +
              option.name + '</option>')
          })
          elem.append($optgroup)
        })

        // Initialise the chosen box
        elem.chosen({
          width: '300px',
          include_group_label_in_selected: true,
          search_contains: true,
          no_results_text: 'No results, try searching for the name of your country or nearest major city.',
          placeholder_text_single: 'Choose a timezone'
        })

        // Update the box if ngModel changes
        $scope.$watch('ngModel', function () {
          elem.val($scope.ngModel)
          elem.trigger('chosen:updated')
        })
      }
    }
  }])
<commit_msg>Added options for primary & local timezones, and show and sort by offset<commit_after>/*global angular, _, moment, $*/

/**
 * angular-timezone-selector
 *
 * A simple directive that allows a user to pick their timezone
 *
 * Author:  Ashok Fernandez <ashok@mish.guru>
 * Date:    12/06/2015
 * License: MIT
 */

angular.module('angular-timezone-selector', [])
  .constant('_', _)
  .constant('moment', moment)
  .factory('timezones', ['_', 'moment', function (_, moment) {
    var timezoneMap = {}
    _.forEach(moment.tz.names(), function (zoneName) {
      var tz=moment.tz(zoneName);
      timezoneMap[zoneName] = {
        id: zoneName,
        name: zoneName.replace(/_/g, ' '),
        offset: 'UTC' + tz.format('Z'),
        nOffset: tz.utcOffset()
      }
    })
    return timezoneMap
  }])

  // Timezone name to country codemap
  .factory('zoneToCC', ['_', function (_) {
    // Note: zones is populated with the data from 'data/zone.csv' when this file is built
    var zones = []
    var zoneMap = {}
    _.forEach(zones, function (zone) {
      zoneMap[zone.name] = zone.cca2
    })
    return zoneMap

  }])

  // Country code to country name map
  .factory('CCToCountryName', ['_', function (_) {
    // Note: codes is populated with the data from 'data/cca2_to_country_name.csv' when this file is built
    var codes = []
    var codeMap = {}
    _.forEach(codes, function (code) {
      codeMap[code.cca2] = code.name
    })
    return codeMap
  }])

  .directive('timezoneSelector', ['_', 'timezones', 'zoneToCC', 'CCToCountryName', function (_, timezones, zoneToCC, CCToCountryName) {
    return {
      restrict: 'E',
      replace: true,
      template: '<select style="min-width:300px;"></select>',
      scope: {
        ngModel: '='
      },
      link: function ($scope, elem, attrs) {
        var data = []

        // Group the timezones by their country code
        var timezonesGroupedByCC = {}
        _.forEach(timezones, function (timezone) {
          if (_.has(zoneToCC, timezone.id)) {
            var CC = zoneToCC[timezone.id]
            timezonesGroupedByCC[CC] = !timezonesGroupedByCC[CC] ? [] : timezonesGroupedByCC[CC]
            timezonesGroupedByCC[CC].push(timezone)
          }
        })

        // Add the grouped countries to the data array with their country name as the group option
        _.forEach(timezonesGroupedByCC, function (zonesByCountry, CC) {
          var zonesForCountry = {
            text: CCToCountryName[CC] + ': ',
            children: zonesByCountry
            firstNOffset: zonesByCountry[0].nOffset,
          }

          data.push(zonesForCountry)
        })

        // Sort by UTC or country name
        if (attrs.sortBy=="offset"){
            data = _.sortBy(data, 'firstNOffset');
            _.forEach(data,function(zonesForCountry,key){
                zonesForCountry.children=_.sortBy(zonesForCountry.children, 'nOffset');
            });
        } else {
            data = _.sortBy(data, 'text')
        }

        // add initial options forlocal
        if (attrs.showLocal!=undefined){
            if (jstz!=undefined){
                var extraTZs = _.where(timezones,{'name':jstz.determine().name() });
            } else {
                var localUTC = 'UTC'+moment().format('Z');
                var extraTZs = _.where(timezones,{'offset':localUTC});
            }
            data.splice(0,0,{
              text: 'Local' + ': ',
              children: extraTZs,
              firstNOffset: extraTZs[0].nOffset,
              firstOffset: extraTZs[0].offset
          })
        }

        // add initial options
        if (attrs.primaryChoices!=undefined){
            // var primaryChoices=['UTC','GB','WET','GMT','Asia/Macau']
            var primaryChoices = attrs.primaryChoices.split(' ');
            var extraTZs = _.filter(timezones,function(tz){return _.contains(primaryChoices,tz.name)});
            data.splice(0,0,{
              text: 'Primary' + ': ',
              children: extraTZs,
              firstNOffset: extraTZs[0].nOffset,
              firstOffset: extraTZs[0].offset
            })
        }

        // Construct a select box with the timezones grouped by country
        _.forEach(data, function (group) {
          var $optgroup = $('<optgroup label="' + group.text + '">')
          group.children.forEach(function (option) {

            if (attrs.displayUtc=="true" && !option.name.includes('(UTC')){
                option.name = option.name + ' (' + option.offset+')';
            }

            $optgroup.append('<option value="' + option.id + '">' +
              option.name + '</option>')
          })
          elem.append($optgroup)
        })

        // Initialise the chosen box
        elem.chosen({
          width: '300px',
          include_group_label_in_selected: true,
          search_contains: true,
          no_results_text: 'No results, try searching for the name of your country or nearest major city.',
          placeholder_text_single: 'Choose a timezone'
        })

        // Update the box if ngModel changes
        $scope.$watch('ngModel', function () {
          elem.val($scope.ngModel)
          elem.trigger('chosen:updated')
        })
      }
    }
  }])
<|endoftext|>


<commit_before>const { computed, createTransformer, observable, toJS } = require("mobx");

import { Player, Box, Wall, Target } from './classes';

const createDirectionCheck = (axis, dir) => {
  return computed(() => {
    const playerX = this.player.x;
    const playerY = this.player.y;
    const rightEntity = this.positionMap[playerY][playerX + 1];
    if (rightEntity instanceof Wall) {
      return false;
    } else if (rightEntity instanceof Box) {
      const righterEntity = this.positionMap[playerY][playerX + 2];
      if (righterEntity instanceof Wall || righterEntity instanceof Box) {
        return false;
      } else {
        return true;
      }
    }
  });
};

class LevelStore {
  constructor(entities) {
    this.entities = observable(entities);

    const createDirectionCheck = (axis, dir = 1) => {
      return computed(() => {
        const moveOnY = axis === "y";
        const nearEntity = this.positionMap[playerY + (moveOnY ? dir : 0)][
          playerX + (moveOnY ? 0 : dir)
        ];
        if (nearEntity instanceof Wall) {
          return false;
        } else if (nearEntity instanceof Box) {
          const nextEntityOver = this.positionMap[
            playerY + (moveOnY ? dir * 2 : 0)
          ][playerX + (moveOnY ? 0 : dir * 2)];
          if (nextEntityOver instanceof Wall || nextEntityOver instanceof Box) {
            return false;
          } else {
            return true;
          }
        }
      });
    };

    this.actions = {
      movePlayer(axis, dir) {
      }
    };
  }

  get player() {
    for (const entity of this.entities) {
      if (entity instanceof Player) {
        return entity;
      }
    }
  }

  tryMove(axis, step) {
    const player = this.player;
    const positionToTry = Object.assign({}, player, {
      [axis]: player[axis] + step
    });

    const entities = this.entities;
    const entityThere = entities.find(
      ent => ent.x === positionToTry.x && ent.y === positionToTry.y
    );
    if (entityThere) {
      if (entityThere instanceof Wall) {
        return;
      }
      if (entityThere instanceof Box) {
        const nextPositionOver = Object.assign({}, player, {
          [axis]: player[axis] + step * 2
        });
        const nextEntityOver = entities.find(
          ent => ent.x === nextPositionOver.x && ent.y === nextPositionOver.y
        );
        if (nextEntityOver instanceof Wall || nextEntityOver instanceof Box) {
          return;
        }
      }
    }
    this.player[axis] += step;
  }
}

const loadLevelMap = levelMap => {
  let entities = [];
  levelMap.forEach((row, y) => {
    for (let x in row) {
      x = Number(x);
      switch (row[x]) {
        case " ":
          break;
        case "p":
          entities.push(new Player({ x, y }));
          break;
        case "t":
          entities.push(new Target({ x, y }));
          break;
        case "b":
          entities.push(new Box({ x, y }));
          break;
        case "x":
          entities.push(new Wall({ x, y }));
          break;
        case "*":
          entities.push(new Target({ x, y }));
          entities.push(new Box({ x, y }));
          break;
        case "@":
          entities.push(new Player({ x, y }));
          entities.push(new Target({ x, y }));
          break;
      }
    }
  });
  return new LevelStore(entities);
};

export default loadLevelMap;

/*
const test = loadLevelMap(exampleLevelMap);
console.log(toJS(test.player));
test.tryMove("y", 1);
console.log(toJS(test.player));
*/<commit_msg>refactor: es6 import<commit_after>import { computed, createTransformer, observable, toJS } from 'mobx'

import { Player, Box, Wall, Target } from './classes';

const createDirectionCheck = (axis, dir) => {
  return computed(() => {
    const playerX = this.player.x;
    const playerY = this.player.y;
    const rightEntity = this.positionMap[playerY][playerX + 1];
    if (rightEntity instanceof Wall) {
      return false;
    } else if (rightEntity instanceof Box) {
      const righterEntity = this.positionMap[playerY][playerX + 2];
      if (righterEntity instanceof Wall || righterEntity instanceof Box) {
        return false;
      } else {
        return true;
      }
    }
  });
};

class LevelStore {
  constructor(entities) {
    this.entities = observable(entities);

    const createDirectionCheck = (axis, dir = 1) => {
      return computed(() => {
        const moveOnY = axis === "y";
        const nearEntity = this.positionMap[playerY + (moveOnY ? dir : 0)][
          playerX + (moveOnY ? 0 : dir)
        ];
        if (nearEntity instanceof Wall) {
          return false;
        } else if (nearEntity instanceof Box) {
          const nextEntityOver = this.positionMap[
            playerY + (moveOnY ? dir * 2 : 0)
          ][playerX + (moveOnY ? 0 : dir * 2)];
          if (nextEntityOver instanceof Wall || nextEntityOver instanceof Box) {
            return false;
          } else {
            return true;
          }
        }
      });
    };

    this.actions = {
      movePlayer(axis, dir) {
      }
    };
  }

  get player() {
    for (const entity of this.entities) {
      if (entity instanceof Player) {
        return entity;
      }
    }
  }

  tryMove(axis, step) {
    const player = this.player;
    const positionToTry = Object.assign({}, player, {
      [axis]: player[axis] + step
    });

    const entities = this.entities;
    const entityThere = entities.find(
      ent => ent.x === positionToTry.x && ent.y === positionToTry.y
    );
    if (entityThere) {
      if (entityThere instanceof Wall) {
        return;
      }
      if (entityThere instanceof Box) {
        const nextPositionOver = Object.assign({}, player, {
          [axis]: player[axis] + step * 2
        });
        const nextEntityOver = entities.find(
          ent => ent.x === nextPositionOver.x && ent.y === nextPositionOver.y
        );
        if (nextEntityOver instanceof Wall || nextEntityOver instanceof Box) {
          return;
        }
      }
    }
    this.player[axis] += step;
  }
}

const loadLevelMap = levelMap => {
  let entities = [];
  levelMap.forEach((row, y) => {
    for (let x in row) {
      x = Number(x);
      switch (row[x]) {
        case " ":
          break;
        case "p":
          entities.push(new Player({ x, y }));
          break;
        case "t":
          entities.push(new Target({ x, y }));
          break;
        case "b":
          entities.push(new Box({ x, y }));
          break;
        case "x":
          entities.push(new Wall({ x, y }));
          break;
        case "*":
          entities.push(new Target({ x, y }));
          entities.push(new Box({ x, y }));
          break;
        case "@":
          entities.push(new Player({ x, y }));
          entities.push(new Target({ x, y }));
          break;
      }
    }
  });
  return new LevelStore(entities);
};

export default loadLevelMap;

/*
const test = loadLevelMap(exampleLevelMap);
console.log(toJS(test.player));
test.tryMove("y", 1);
console.log(toJS(test.player));
*/<|endoftext|>