<commit_before>currentAction = "none";

var unFocus = function () {
  if (document.selection) {
    document.selection.empty()
  } else {
    window.getSelection().removeAllRanges()
  }
}

Template.post.onRendered(function () {
    var instance = Template.instance();

    var postLink = Template.instance().$('.titleBar a');
    postLink.attr('title', postLink.text());

    var usernameLink = Template.instance().$('.username');
    usernameLink.attr('title', usernameLink.text());

    /*instance.$('.postContent').dotdotdot({
        after: 'a.readMoreLink'
    });*/

    Link.find({ $or: [ { sourceId: this.data._id}, { targetId: this.data._id} ] })
    .forEach(function(link) {
        tree.addLink(link);
    });

    Link.find({sourceId: this.data._id}).forEach(function(link) {
        handlers.addHandler(link.targetId);
    });
    Link.find({targetId: this.data._id}).forEach(function(link) {
        handlers.addHandler(link.sourceId);
    });
    tree.runGraph();
    tree.render();
});

Template.post.helpers({
    avatarURL: function() {
        return 'https://avatars3.githubusercontent.com/u/6981448';
    },
    replyCount: function() {
        return Link.find({ $or: [ { sourceId: this._id}, { targetId: this._id} ] }).count();
    },
    user: function() {
        return Meteor.users.findOne(this.ownerId);
    },
    hasContent: function() {
        return (this.content && this.content.length > 0);
    }
});

Template.post.events({
    'click': function(event) {
        switch (currentAction) {
            case "deleting":
                event.stopImmediatePropagation();
                if ((this.ownerId === Meteor.userId() ||
                    Roles.userIsInRole(Meteor.userId(), ['moderator'])) &&
                    confirm("Are you sure you want to permanently delete this post?")) {

                    tree.removeNode(this);
                    handlers.stop(this._id);
                    Meteor.call('removeWithLinks', this._id);
                }
                break;

        }

    },
    'mousedown .unDraggable, touchstart .unDraggable': function(event) {
        event.stopImmediatePropagation();
    },
    'mousedown .draggable, touchstart .draggable': function(event) {
        event.stopImmediatePropagation();
        this.dragging = true;
        this.counter = 0;
        this.mousePos = {x: event.screenX, y: event.screenY};
    },
    'mouseup, touchend': function(event) {
        unFocus();
        this.dragging = false;
        tree.render();
    },
    'mousemove, touchmove': function(event) {
        if (this.dragging) {
            unFocus();
            let node = tree.findNode(this);
            node.x += (event.screenX - this.mousePos.x);
            node.y += (event.screenY - this.mousePos.y);
            this.mousePos = {x: event.screenX, y: event.screenY};
        }
        if (this.counter <= 0) {
            tree.render();
            this.counter = 2;
        } else this.counter--;
    },
    'click .showRepliesButton': function (event) {
        Link.find({sourceId: this._id})
        .forEach(function(link) {
            var postToAdd = Post.findOne({_id: link.targetId});
            if (postToAdd && !nodesInGraph.findOne({_id: postToAdd._id})) {
                postToAdd.type = "post";
                handlers.addHandler(postToAdd._id);
                tree.addNode(postToAdd);
            }
        });
        Link.find({targetId: this._id})
        .forEach(function(link) {
            var postToAdd = Post.findOne({_id: link.sourceId});
            if (postToAdd && !nodesInGraph.findOne({_id: postToAdd._id})) {
                postToAdd.type = "post";
                tree.addNode(postToAdd);
                handlers.addHandler(postToAdd._id);
            }
        });
    },
    'click .replyButton': function(event) {
        if (!Meteor.userId()) return;
        if (!nodesInGraph.findOne({type: "reply"})) {
            let _id = tree.addNode({type: "reply", links: [this._id]})._id;
            tree.addLink({sourceId: _id, targetId: this._id});
        } else {
            let reply = nodesInGraph.findOne({type: "reply"});
            let self = this;
            if (!reply.links.find(function(link) {
                return (link == self._id);
            })) {
                nodesInGraph.update({_id: reply._id}, { $push: { links: this._id}});
                tree.addLink({sourceId: reply._id, targetId: this._id});
            } else {
                nodesInGraph.update({_id: reply._id}, { $pull: { links: this._id}});
                tree.removeLink({sourceId: reply._id, targetId: this._id});
            }
        }
    },
    'click .closeButton': function(event) {
        let reply = nodesInGraph.findOne({type: "reply"});
        let self = this;
        if (reply) {
            nodesInGraph.update({_id: reply._id}, { $pull: { links: this._id}});
            tree.removeLink({sourceId: reply._id, targetId: this._id});
        }
        tree.removeNode(this);
    }

});

Template.reply.onRendered(function () {
    var instance = Template.instance();

    tree.runGraph();
    tree.render();
});

Template.reply.events({
    'mousedown .unDraggable, touchstart .unDraggable': function(event) {
        event.stopImmediatePropagation();
    },
    'mousedown draggable, touchstart .draggable': function(event) {
        event.stopImmediatePropagation();
        this.dragging = true;
        this.counter = 0;
        this.mousePos = {x: event.screenX, y: event.screenY};
    },
    'mouseup, touchend': function(event) {
        unFocus();
        this.dragging = false;
        tree.render();
    },
    'mousemove, touchmove': function(event) {
        if (this.dragging) {
            unFocus();
            let node = tree.findNode(this);
            node.x += (event.screenX - this.mousePos.x);
            node.y += (event.screenY - this.mousePos.y);
            this.mousePos = {x: event.screenX, y: event.screenY};
        }
        if (this.counter <= 0) {
            tree.render();
            this.counter = 2;
        } else this.counter--;
    },
    'click .closeButton': function(event) {
        tree.removeNode(this);
    },
    'click .submitButton': function(event) {
        if (!Meteor.userId() || this.links.length < 1) return;
        let title = $('#titleInput-' + this._id).val();
        let content = $('#contentInput-' + this._id).val();
        let newReplyPost = {
            links: this.links,
            title: title,
            content: content

        };
        let postId = Post.insert(newReplyPost);
        handlers.addHandler(postId);
        setTimeout(function() {
            let doc = Post.findOne({_id: postId});
            doc.type = "post";
            tree.addNode(doc);
        }, 1000);
        tree.removeNode(this);
    }
});

Template.forumIndex.onRendered(function () {
    var instance = Template.instance();
});

Template.forumIndex.events({
    'mousedown, touchstart': function(event, template) {
        template.dragging = true;
        template.counter = 0;
        template.mousePos = {x: event.screenX, y: event.screenY};
    },
    'mouseup, touchend, mouseleave': function(event, template) {
        template.dragging = false;
        tree.render();
    },
    'mousemove, touchmove': function(event, template) {
        if (template.dragging) {
            unFocus();
            for (let i = 0; i < tree.nodes.length; i++) {
                tree.nodes[i].x += (event.screenX - template.mousePos.x);
                tree.nodes[i].y += (event.screenY - template.mousePos.y);
            }
            template.mousePos = {x: event.screenX, y: event.screenY};

            if (template.counter <= 0) {
                tree.render();
                template.counter = 2;
            } else template.counter--;
        }
    },
    'click .button-delete': function(event) {
        event.preventDefault();
        if (currentAction != "deleting") currentAction = "deleting";
        else currentAction = "none";
    },
});

Template.forumIndex.helpers({
    posts() {
        return nodesInGraph.find({type: "post"});
    },
    replies() {
        return nodesInGraph.find({type: "reply"});
    }
});

Template.forumIndex.rendered = function() {
    var init = true;

    var nodesCursor = Post.find({}), linksCursor = Link.find({});

    tree = new ForumTree(this, nodesCursor, linksCursor);

    nodesCursor.observe({
        added: function(doc) {
            if (init) return;
            if (doc.isRoot) {
                doc.type = "post";
                tree.addNode(doc);
            }
        },
        removed: function(doc) {
            if (init) return;
            tree.removeNode(doc);
        }
    });

    linksCursor.observe({
        added: function(doc) {
            if (init) return;
            if (nodesInGraph.findOne({_id: doc.sourceId})) {
                handlers.addHandler(doc.targetId);
            } else if (nodesInGraph.findOne({_id: doc.targetId})) {
                handlers.addHandler(doc.sourceId);
            }
            tree.addLink(doc);
        },
        removed: function(doc) {
            if (init) return;
            tree.removeLink(doc);
        }
    });

    tree.runGraph();
    tree.render();
    init = false;
};
<commit_msg>Made counter for connecting posts update properly.<commit_after>currentAction = "none";
templates = {};
var unFocus = function () {
  if (document.selection) {
    document.selection.empty()
  } else {
    window.getSelection().removeAllRanges()
  }
}

Template.post.onCreated(function () {
    templates[this.data._id] = this;
    this.linkCount = new ReactiveVar(0);

    let linksCursor = Link.find({ $or: [ { sourceId: this.data._id}, { targetId: this.data._id} ] });

    let self = this;

    linksCursor.observe({
        added: function(doc) {
            let _id;
            if (self.data._id == doc.sourceId)
                _id = doc.targetId;
            if (self.data._id == doc.targetId)
                _id = doc.sourceId;

            if (!templates[_id])
                self.linkCount.set(self.linkCount.get() + 1);
        },
        removed: function(doc) {
            if (!templates[doc._id])
                self.linkCount.set(self.linkCount.get() - 1);
        }
    });
});

Template.post.onRendered(function () {
    var instance = Template.instance();

    var postLink = Template.instance().$('.titleBar a');
    postLink.attr('title', postLink.text());

    var usernameLink = Template.instance().$('.username');
    usernameLink.attr('title', usernameLink.text());

    /*instance.$('.postContent').dotdotdot({
        after: 'a.readMoreLink'
    });*/

    Link.find({ $or: [ { sourceId: this.data._id}, { targetId: this.data._id} ] })
    .forEach(function(link) {
        tree.addLink(link);
    });

    Link.find({sourceId: this.data._id}).forEach(function(link) {
        handlers.addHandler(link.targetId);
        var temp = templates[link.targetId];
        if (temp) temp.linkCount.set(temp.linkCount.get() - 1);
    });
    Link.find({targetId: this.data._id}).forEach(function(link) {
        handlers.addHandler(link.sourceId);
        var temp = templates[link.sourceId];
        if (temp) temp.linkCount.set(temp.linkCount.get() - 1);
    });
    tree.runGraph();
    tree.render();
});

Template.post.onDestroyed(function () {
    var self = this;
    Link.find({sourceId: this.data._id}).forEach(function(link) {
        var temp = templates[link.targetId];
        if (temp) temp.linkCount.set(temp.linkCount.get() + 1);
    });
    Link.find({targetId: this.data._id}).forEach(function(link) {
        var temp = templates[link.sourceId];
        if (temp) temp.linkCount.set(temp.linkCount.get() + 1);
    });

    delete templates[this.data._id];
});

Template.post.helpers({
    avatarURL: function() {
        return 'https://avatars3.githubusercontent.com/u/6981448';
    },
    replyCount: function() {
        console.log(Template.instance().linkCount);
        return Template.instance().linkCount.get();
    },
    user: function() {
        return Meteor.users.findOne(this.ownerId);
    },
    hasContent: function() {
        return (this.content && this.content.length > 0);
    }
});

Template.post.events({
    'click': function(event) {
        switch (currentAction) {
            case "deleting":
                event.stopImmediatePropagation();
                if ((this.ownerId === Meteor.userId() ||
                    Roles.userIsInRole(Meteor.userId(), ['moderator'])) &&
                    confirm("Are you sure you want to permanently delete this post?")) {

                    tree.removeNode(this);
                    handlers.stop(this._id);
                    Meteor.call('removeWithLinks', this._id);
                }
                break;

        }

    },
    'mousedown .unDraggable, touchstart .unDraggable': function(event) {
        event.stopImmediatePropagation();
    },
    'mousedown .draggable, touchstart .draggable': function(event) {
        event.stopImmediatePropagation();
        this.dragging = true;
        this.counter = 0;
        this.mousePos = {x: event.screenX, y: event.screenY};
    },
    'mouseup, touchend': function(event) {
        unFocus();
        this.dragging = false;
        tree.render();
    },
    'mousemove, touchmove': function(event) {
        if (this.dragging) {
            unFocus();
            let node = tree.findNode(this);
            node.x += (event.screenX - this.mousePos.x);
            node.y += (event.screenY - this.mousePos.y);
            this.mousePos = {x: event.screenX, y: event.screenY};
        }
        if (this.counter <= 0) {
            tree.render();
            this.counter = 2;
        } else this.counter--;
    },
    'click .showRepliesButton': function (event) {
        Link.find({sourceId: this._id})
        .forEach(function(link) {
            var postToAdd = Post.findOne({_id: link.targetId});
            if (postToAdd && !nodesInGraph.findOne({_id: postToAdd._id})) {
                postToAdd.type = "post";
                handlers.addHandler(postToAdd._id);
                tree.addNode(postToAdd);
            }
        });
        Link.find({targetId: this._id})
        .forEach(function(link) {
            var postToAdd = Post.findOne({_id: link.sourceId});
            if (postToAdd && !nodesInGraph.findOne({_id: postToAdd._id})) {
                postToAdd.type = "post";
                tree.addNode(postToAdd);
                handlers.addHandler(postToAdd._id);
            }
        });
    },
    'click .replyButton': function(event) {
        if (!Meteor.userId()) return;
        if (!nodesInGraph.findOne({type: "reply"})) {
            let _id = tree.addNode({type: "reply", links: [this._id]})._id;
            tree.addLink({sourceId: _id, targetId: this._id});
        } else {
            let reply = nodesInGraph.findOne({type: "reply"});
            let self = this;
            if (!reply.links.find(function(link) {
                return (link == self._id);
            })) {
                nodesInGraph.update({_id: reply._id}, { $push: { links: this._id}});
                tree.addLink({sourceId: reply._id, targetId: this._id});
            } else {
                nodesInGraph.update({_id: reply._id}, { $pull: { links: this._id}});
                tree.removeLink({sourceId: reply._id, targetId: this._id});
            }
        }
    },
    'click .closeButton': function(event) {
        let reply = nodesInGraph.findOne({type: "reply"});
        let self = this;
        if (reply) {
            nodesInGraph.update({_id: reply._id}, { $pull: { links: this._id}});
            tree.removeLink({sourceId: reply._id, targetId: this._id});
        }
        tree.removeNode(this);
    }

});

Template.reply.onRendered(function () {
    var instance = Template.instance();

    tree.runGraph();
    tree.render();
});

Template.reply.events({
    'mousedown .unDraggable, touchstart .unDraggable': function(event) {
        event.stopImmediatePropagation();
    },
    'mousedown draggable, touchstart .draggable': function(event) {
        event.stopImmediatePropagation();
        this.dragging = true;
        this.counter = 0;
        this.mousePos = {x: event.screenX, y: event.screenY};
    },
    'mouseup, touchend': function(event) {
        unFocus();
        this.dragging = false;
        tree.render();
    },
    'mousemove, touchmove': function(event) {
        if (this.dragging) {
            unFocus();
            let node = tree.findNode(this);
            node.x += (event.screenX - this.mousePos.x);
            node.y += (event.screenY - this.mousePos.y);
            this.mousePos = {x: event.screenX, y: event.screenY};
        }
        if (this.counter <= 0) {
            tree.render();
            this.counter = 2;
        } else this.counter--;
    },
    'click .closeButton': function(event) {
        tree.removeNode(this);
    },
    'click .submitButton': function(event) {
        if (!Meteor.userId() || this.links.length < 1) return;
        let title = $('#titleInput-' + this._id).val();
        let content = $('#contentInput-' + this._id).val();
        let newReplyPost = {
            links: this.links,
            title: title,
            content: content

        };
        let postId = Post.insert(newReplyPost);
        handlers.addHandler(postId);
        setTimeout(function() {
            let doc = Post.findOne({_id: postId});
            doc.type = "post";
            tree.addNode(doc);
        }, 1000);
        tree.removeNode(this);
    }
});

Template.forumIndex.onRendered(function () {
    var instance = Template.instance();
});

Template.forumIndex.events({
    'mousedown, touchstart': function(event, template) {
        template.dragging = true;
        template.counter = 0;
        template.mousePos = {x: event.screenX, y: event.screenY};
    },
    'mouseup, touchend, mouseleave': function(event, template) {
        template.dragging = false;
        tree.render();
    },
    'mousemove, touchmove': function(event, template) {
        if (template.dragging) {
            unFocus();
            for (let i = 0; i < tree.nodes.length; i++) {
                tree.nodes[i].x += (event.screenX - template.mousePos.x);
                tree.nodes[i].y += (event.screenY - template.mousePos.y);
            }
            template.mousePos = {x: event.screenX, y: event.screenY};

            if (template.counter <= 0) {
                tree.render();
                template.counter = 2;
            } else template.counter--;
        }
    },
    'click .button-delete': function(event) {
        event.preventDefault();
        if (currentAction != "deleting") currentAction = "deleting";
        else currentAction = "none";
    },
});

Template.forumIndex.helpers({
    posts() {
        return nodesInGraph.find({type: "post"});
    },
    replies() {
        return nodesInGraph.find({type: "reply"});
    }
});

Template.forumIndex.rendered = function() {
    var init = true;

    var nodesCursor = Post.find({}), linksCursor = Link.find({});

    tree = new ForumTree(this, nodesCursor, linksCursor);

    nodesCursor.observe({
        added: function(doc) {
            if (init) return;
            if (doc.isRoot) {
                doc.type = "post";
                tree.addNode(doc);
            }
        },
        removed: function(doc) {
            if (init) return;
            tree.removeNode(doc);
        }
    });

    linksCursor.observe({
        added: function(doc) {
            if (init) return;
            if (nodesInGraph.findOne({_id: doc.sourceId})) {
                handlers.addHandler(doc.targetId);
            } else if (nodesInGraph.findOne({_id: doc.targetId})) {
                handlers.addHandler(doc.sourceId);
            }
            tree.addLink(doc);
        },
        removed: function(doc) {
            if (init) return;
            tree.removeLink(doc);
        }
    });

    tree.runGraph();
    tree.render();
    init = false;
};
<|endoftext|>


<commit_before>// wallet_plans.js
App.Views.Parts.WalletPlans = Backbone.View.extend({

	templateName: 'parts/wallet_plans',
	events: {},
	areStatsReady: false,
	initialize: function() {
		console.log('views/parts/wallet_plans.js | Initializing Wallet Plans view');
		if (!this.model || !this.id)
			console.error('views/parts/wallet_plans.js | model and dom id should be provided for this view');

		this.areStatsReady = false;
		var that = this;

		App.exchange.loadRates(function() {
			that.listenToOnce(this.model, 'plansloaded', function() {
				that.invokeStatsLoading();
			});
			that.listenTo(that.model, 'plansloaded', that.render);
			that.model.getPlans();
		});
	},
	wakeUp: function() {
		console.error('views/parts/wallet_plans.js | Waking up');
	},
	invokeStatsLoading: function() {
		var that = this;
		var complete = _.invoke(this.model.plans.models, 'getStats');
		$.when.apply($, complete).done(function() {
			that.areStatsReady = true;
			that.render();
		});
	},
	render: function() {
		console.log('views/parts/wallet_plans.js | Rendering');
		this.setElement($('#' + this.id));

		var plans = [];
		for (var i = 0; i < this.model.plans.length; i++) {
			var allowedToSpend = null;
			if (this.areStatsReady)
				allowedToSpend = this.model.plans.at(i).getPlanForToday();
			plans.push({
				plan: this.model.plans.at(i).toJSON(),
				allowedToSpend: allowedToSpend
			});
		}

		var data = {
			wallet: this.model.toJSON(),
			plans: plans,
			areStatsReady: this.areStatsReady
		};
		var that = this;
		App.templateManager.fetch(this.templateName, data, function(html) {
			that.$el.html(html);
			that.trigger('render');
			that.trigger('loaded');
		});
	}
});<commit_msg>wallet plan thatthis<commit_after>// wallet_plans.js
App.Views.Parts.WalletPlans = Backbone.View.extend({

	templateName: 'parts/wallet_plans',
	events: {},
	areStatsReady: false,
	initialize: function() {
		console.log('views/parts/wallet_plans.js | Initializing Wallet Plans view');
		if (!this.model || !this.id)
			console.error('views/parts/wallet_plans.js | model and dom id should be provided for this view');

		this.areStatsReady = false;
		var that = this;

		App.exchange.loadRates(function() {
			that.listenToOnce(that.model, 'plansloaded', function() {
				that.invokeStatsLoading();
			});
			that.listenTo(that.model, 'plansloaded', that.render);
			that.model.getPlans();
		});
	},
	wakeUp: function() {
		console.error('views/parts/wallet_plans.js | Waking up');
	},
	invokeStatsLoading: function() {
		var that = this;
		var complete = _.invoke(this.model.plans.models, 'getStats');
		$.when.apply($, complete).done(function() {
			that.areStatsReady = true;
			that.render();
		});
	},
	render: function() {
		console.log('views/parts/wallet_plans.js | Rendering');
		this.setElement($('#' + this.id));

		var plans = [];
		if (this.model.plans)
			for (var i = 0; i < this.model.plans.length; i++) {
				var allowedToSpend = null;
				if (this.areStatsReady)
					allowedToSpend = this.model.plans.at(i).getPlanForToday();
				plans.push({
					plan: this.model.plans.at(i).toJSON(),
					allowedToSpend: allowedToSpend
				});
			}

		var data = {
			wallet: this.model.toJSON(),
			plans: plans,
			areStatsReady: this.areStatsReady
		};
		var that = this;
		App.templateManager.fetch(this.templateName, data, function(html) {
			that.$el.html(html);
			that.trigger('render');
			that.trigger('loaded');
		});
	}
});<|endoftext|>


<commit_before>const electron = require('electron')
// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow

const path = require('path')
const url = require('url')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 450,
    height: 350,
    minWidth: 450,
    minHeight: 350,
    icon: path.join(__dirname, 'assets/icons/png/64x64.png')
  })

  // and load the index.html of the app.
  mainWindow.loadURL(url.format({
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
  }))

  // Open the DevTools.
  //mainWindow.webContents.openDevTools()

  // Emitted when the window is closed.
  mainWindow.on('closed', function () {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null
  })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow()
  }
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
<commit_msg><commit_after>const electron = require('electron')
// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow

const path = require('path')
const url = require('url')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 450,
    height: 350,
    minWidth: 450,
    minHeight: 350,
    icon: path.join(__dirname, 'assets/icons/png/64x64.png')
  })

  // and load the index.html of the app.
  mainWindow.loadURL(url.format({
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
  }))

  // Open the DevTools.
  //mainWindow.webContents.openDevTools()

  mainWindow.setMenu(null);

  // Emitted when the window is closed.
  mainWindow.on('closed', function () {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null
  })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow()
  }
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
<|endoftext|>


<commit_before>app.controller('itemCtrl',function($scope, $http) {
    $.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
    options.async = true;
});

	$scope.master = {};
	$scope.editItem = {};
	$scope.showMe = {};

        $scope.add = function () {
          $scope.addInput.push({
          });
        };

	$scope.showAllItems=function(){
		 console.log("request all items");
		$http.get('/admin/showAllItems')
						.success(function(data){
							$scope.items = data;
							console.log("Succeed loading");
							for (var i = 0, length = $scope.items.length; i < length; i++) {
							$scope.showMe[$scope.items[i]._id] = true;
							}
						})
						.error(function(data){
							console.log("Error: "+data);
			 });
	}
$scope.addItem=function(item){
// use $.param jQuery function to serialize data from JSON
            var data = $.param({
                name : item.name,
                category : item.category,
                subCategory : item.subCategory,
                description : item.description,
				price : item.price,
                location : item.location,
				//colors.name[0]: item.colors.name[0],
				//colors.quantity[0]: item.colors.quantity[0],
            });

            var config = {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }
            }

            $http.post('/admin/addItem', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed post addItem");
                $scope.items.push(data);
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });

     console.log("addItem function"+ item.name+item.location);
     $scope.master = angular.copy(item);

$scope.reset();
};

$scope.changeItem=function(item){
    console.log("in change item in the client side");
    for (var i = 0, length = $scope.items.length; i < length; i++) {
              $scope.editItem[$scope.items[i]._id] = false;
            }
            var data = $.param({
				_id : item._id,
                name : item.name,
                category : item.category,
                subCategory : item.subCategory,
                description : item.description,
				price : item.price,
                location : item.location,
            });

            var config = {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }
            }

            $http.post('/admin/changeItem', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed changeItem Item");
                //$scope.items.push(data);
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });

     console.log("finish to change item"+ item.name+item.location);

$scope.update(item);
$scope.reset();
};

            $scope.showAndHide = function(item){
                console.log( "showMe[item.id] before: "+$scope.showMe[item._id]);
                $scope.showMe[item._id] = !$scope.showMe[item._id];
                console.log( "showMe[item.id] after: "+ $scope.showMe[item._id]);

            };
            $scope.modify = function(item){
                $scope.editItem[item._id] = true;

            };

            $scope.update = function(item){
                $scope.editItem[item._id] = false;
                $scope.showAllItems();
            };

$scope.deleteItem = function(item){
            var data = $.param({
                name : item.name,
                category : item.category,
            });
    var config = {
    headers : {
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
        }
    }
            $http.post('/admin/deleteItem', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed");
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });
            $scope.showAllItems();
};
$scope.deleteItemById = function(_id){
            var data = _id

    var config = {
    headers : {
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
        }
    }
            $http.post('/admin/deleteItemById', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed");
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });
$scope.showAllItems();
};
$scope.checkQuantity = function() {
	 console.log("checkQuantity");
	$http.get('/admin/checkQuantity')
					.success(function(data){
						$scope.quantity = data;
						console.log("Succeed loading");
					})
					.error(function(data){
						console.log("Error: "+data);
		 });
}
$scope.countItem = function(item){
    alert("count");
            var data = $.param({
                name : item.name,
                category : item.category,
            });
    var config = {
    headers : {
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
        }
    }
            $http.post('/admin/countItem', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed post countItem");
                $scope.items.push(data);
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });
};

/*$scope.checkIfItemExistsInStock = function(item){
  console.log("in checkIfItemExistsInStock in the client side");
            var data = $.param({
				_id : item._id,
                //colors.quantity: item.colors.quantity;
            });

            var config = {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }
            }
            $http.post('/checkIfItemExistsInStock', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed checkIfItemExistsInStock");
                //$scope.items.push(data);
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });
	};*/

$scope.reset = function(form) {
    if (form) {
      form.$setPristine();
      form.$setUntouched();
    }
    $scope.item = angular.copy($scope.master);
  };

});

<commit_msg>item controller<commit_after>app.controller('itemCtrl',function($scope, $http) {
    $.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
    options.async = true;
});

	$scope.master = {};
	$scope.editItem = {};
	$scope.showMe = {};

$scope.addInput = [];

        $scope.add = function () {
          $scope.addInput.push({
          });
        };

	$scope.showAllItems=function(){
		 console.log("request all items");
		$http.get('/admin/showAllItems')
						.success(function(data){
							$scope.items = data;
							console.log("Succeed loading");
							for (var i = 0, length = $scope.items.length; i < length; i++) {
							$scope.showMe[$scope.items[i]._id] = true;
							}
						})
						.error(function(data){
							console.log("Error: "+data);
			 });
	}
$scope.addItem=function(item){
// use $.param jQuery function to serialize data from JSON
            var data = $.param({
                name : item.name,
                category : item.category,
                subCategory : item.subCategory,
                description : item.description,
				price : item.price,
                location : item.location,
				//colors.name[0]: item.colors.name[0],
				//colors.quantity[0]: item.colors.quantity[0],
            });

            var config = {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }
            }

            $http.post('/admin/addItem', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed post addItem");
                $scope.items.push(data);
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });

     console.log("addItem function"+ item.name+item.location);
     $scope.master = angular.copy(item);

$scope.reset();
};

$scope.changeItem=function(item){
    console.log("in change item in the client side");
    for (var i = 0, length = $scope.items.length; i < length; i++) {
              $scope.editItem[$scope.items[i]._id] = false;
            }
            var data = $.param({
				_id : item._id,
                name : item.name,
                category : item.category,
                subCategory : item.subCategory,
                description : item.description,
				price : item.price,
                location : item.location,
            });

            var config = {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }
            }

            $http.post('/admin/changeItem', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed changeItem Item");
                //$scope.items.push(data);
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });

     console.log("finish to change item"+ item.name+item.location);

$scope.update(item);
$scope.reset();
};

            $scope.showAndHide = function(item){
                console.log( "showMe[item.id] before: "+$scope.showMe[item._id]);
                $scope.showMe[item._id] = !$scope.showMe[item._id];
                console.log( "showMe[item.id] after: "+ $scope.showMe[item._id]);

            };
            $scope.modify = function(item){
                $scope.editItem[item._id] = true;

            };

            $scope.update = function(item){
                $scope.editItem[item._id] = false;
                $scope.showAllItems();
            };

$scope.deleteItem = function(item){
            var data = $.param({
                name : item.name,
                category : item.category,
            });
    var config = {
    headers : {
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
        }
    }
            $http.post('/admin/deleteItem', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed");
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });
            $scope.showAllItems();
};
$scope.deleteItemById = function(_id){
            var data = _id

    var config = {
    headers : {
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
        }
    }
            $http.post('/admin/deleteItemById', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed");
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });
$scope.showAllItems();
};
$scope.checkQuantity = function() {
	 console.log("checkQuantity");
	$http.get('/admin/checkQuantity')
					.success(function(data){
						$scope.quantity = data;
						console.log("Succeed loading");
					})
					.error(function(data){
						console.log("Error: "+data);
		 });
}
$scope.countItem = function(item){
    alert("count");
            var data = $.param({
                name : item.name,
                category : item.category,
            });
    var config = {
    headers : {
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
        }
    }
            $http.post('/admin/countItem', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed post countItem");
                $scope.items.push(data);
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });
};

/*$scope.checkIfItemExistsInStock = function(item){
  console.log("in checkIfItemExistsInStock in the client side");
            var data = $.param({
				_id : item._id,
                //colors.quantity: item.colors.quantity;
            });

            var config = {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }
            }
            $http.post('/checkIfItemExistsInStock', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
                console.log("Succeed checkIfItemExistsInStock");
                //$scope.items.push(data);
            })
            .error(function (data, status, header, config) {
                console.log("Error: "+data);
                $scope.ResponseDetails = "Data: " + data +
                    "
status: " + status +
                    "
headers: " + header +
                    "
config: " + config;
            });
	};*/

$scope.reset = function(form) {
    if (form) {
      form.$setPristine();
      form.$setUntouched();
    }
    $scope.item = angular.copy($scope.master);
  };

});

<|endoftext|>


<commit_before>import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { css, select } from '../../styles/jss'
import * as s from '../../styles/jso'

const categoryPostSelectorStyle = css(
  s.inline,
  s.relative,
  s.mr10,
  s.ml10,
)

const categoriesListStyle = css(
  s.absolute,
  {
    top: 30,
    left: 0,
  },
  select('ul',
    s.resetList,
  ),
)

function filterSearch(categories, searchText) {
  if (searchText === '') { return categories }
  return categories.filter(c => c.get('name').toLowerCase().includes(searchText.toLowerCase()))
}

function CategoryItem({ category, index, selectedIndex, onSelect }) {
  const isSelected = selectedIndex === index
  return (

      <button onClick={() => onSelect(category)}>
        {category.get('name')}
      </button>

  )
}

CategoryItem.propTypes = {
  category: PropTypes.object.isRequired,
  index: PropTypes.number.isRequired,
  selectedIndex: PropTypes.number,
  onSelect: PropTypes.func.isRequired,
}

CategoryItem.defaultProps = {
  selectedIndex: null,
}

export default class CategoryPostSelector extends PureComponent {
  static propTypes = {
    onSelect: PropTypes.func.isRequired,
    onClear: PropTypes.func.isRequired,
    subscribedCategories: PropTypes.array.isRequired,
    featuredInCategories: PropTypes.array.isRequired,
    unsubscribedCategories: PropTypes.array.isRequired,
    selectedCategories: PropTypes.array.isRequired,
  }

  constructor(props) {
    super(props)
    const { subscribedCategories, unsubscribedCategories } = props
    this.state = {
      subscribedCategories,
      unsubscribedCategories,
      searchText: '',
      selectedIndex: null,
    }
  }

  componentDidMount() {
    const { onSelect, featuredInCategories } = this.props
    if (featuredInCategories.length > 0) {
      onSelect(featuredInCategories[0])
    }
  }

  componentWillReceiveProps(nextProps) {
    const { subscribedCategories, unsubscribedCategories } = nextProps
    const { searchText } = this.state
    this.setState({
      subscribedCategories: filterSearch(subscribedCategories, searchText),
      unsubscribedCategories: filterSearch(unsubscribedCategories, searchText),
    })
  }

  handleSearch = (event) => {
    const searchText = event.target.value
    const { subscribedCategories, unsubscribedCategories } = this.props
    this.setState({
      selectedIndex: 0,
      searchText,
      subscribedCategories: filterSearch(subscribedCategories, searchText),
      unsubscribedCategories: filterSearch(unsubscribedCategories, searchText),
    })
  }

  handleKeyDown = (event) => {
    const { subscribedCategories, unsubscribedCategories, selectedIndex } = this.state
    const { onSelect } = this.props
    const categories = subscribedCategories.concat(unsubscribedCategories)
    const max = categories.length
    if (event.key === 'ArrowDown' && isNaN(selectedIndex)) {
      this.setState({ selectedIndex: 0 })
    } else if (event.key === 'ArrowDown' && selectedIndex < max) {
      this.setState({ selectedIndex: selectedIndex + 1 })
    } else if (event.key === 'ArrowUp' && !isNaN(selectedIndex) && selectedIndex > 0) {
      this.setState({ selectedIndex: selectedIndex - 1 })
    } else if (event.key === 'Enter' && !isNaN(selectedIndex)) {
      onSelect(categories[selectedIndex])
    }
  }

  render() {
    const { selectedCategories, onClear, onSelect } = this.props
    const { subscribedCategories, unsubscribedCategories, searchText, selectedIndex } = this.state
    // Everything except this component could support multiple categories, but for now
    // we can assume there is only one selected category per post.
    const selectedCategory = selectedCategories[0]
    const offset = subscribedCategories.length
    return (

        {!selectedCategory &&
          <input
            type="search"
            value={searchText}
            onChange={this.handleSearch}
            onKeyDown={this.handleKeyDown}
          />
        }
        {selectedCategory &&

            {selectedCategory.get('name')}
            <button onClick={onClear}>X</button>

        }

          {subscribedCategories.length > 0 &&

              Your Categories

                {subscribedCategories.map((category, index) =>
                  (<CategoryItem
                    key={`categorySelect:${category.get('id')}`}
                    category={category}
                    index={index}
                    selectedIndex={selectedIndex}
                    onSelect={onSelect}
                  />),
                )}

          }

            All Categories

              {unsubscribedCategories.map((category, index) =>
                (<CategoryItem
                  key={`categorySelect:${category.get('id')}`}
                  category={category}
                  index={index + offset}
                  selectedIndex={selectedIndex}
                  onSelect={onSelect}
                />),
              )}

    )
  }
}
<commit_msg>editor - category selector - initial styling<commit_after>import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { css, hover, select } from '../../styles/jss'
import * as s from '../../styles/jso'

const categoryPostSelectorStyle = css(
  s.inlineBlock,
  s.relative,
  s.mr10,
  s.ml10,
  {
    width: 300,
  },
)

const categoriesSelectionsStyle = css(
  select('& .selector, & .selected',
    s.fullWidth,
  ),
  select('& .selector',
    {
      border: '1px solid #aaa',
      borderRadius: 0,
      borderTopRightRadius: 5,
      borderTopLeftRadius: 5,
    },
  ),
)

const categoriesListStyle = css(
  s.absolute,
  s.fullWidth,
  s.p10,
  s.overflowHidden,
  s.overflowScrollWebY,
  s.bgcWhite,
  s.zTools,
  {
    top: 40,
    left: 0,
    maxHeight: 260,
    border: '1px solid #aaa',
    borderRadius: 0,
    borderBottomRightRadius: 5,
    borderBottomLeftRadius: 5,
  },
  select('& .divider',
    s.p0,
    s.m10,
    s.bgcA,
    {
      height: 1,
      border: 0,
    },
  ),
  // list items
  select('& b',
    s.block,
    s.m0,
    s.p5,
    s.pr10,
    s.pl10,
    s.colorA,
    s.sansRegular,
    {
      lineHeight: 20,
    },
  ),
  select('& ul',
    s.resetList,
    select('& li',
      s.m0,
      s.p0,
      select('& button',
        s.block,
        s.p5,
        s.pr10,
        s.pl10,
        s.fullWidth,
        {
          height: 'auto',
          textAlign: 'left',
          lineHeight: 20,
        },
        hover(
          s.colorWhite,
          s.bgcBlack,
          { borderRadius: 3 },
        ),
      ),
      select('& button:active',
        s.colorBlack,
        s.bgcWhite,
      ),
    ),
  ),
)

function filterSearch(categories, searchText) {
  if (searchText === '') { return categories }
  return categories.filter(c => c.get('name').toLowerCase().includes(searchText.toLowerCase()))
}

function CategoryItem({ category, index, selectedIndex, onSelect }) {
  const isSelected = selectedIndex === index
  return (

      <button onClick={() => onSelect(category)}>
        {category.get('name')}
      </button>

  )
}

CategoryItem.propTypes = {
  category: PropTypes.object.isRequired,
  index: PropTypes.number.isRequired,
  selectedIndex: PropTypes.number,
  onSelect: PropTypes.func.isRequired,
}

CategoryItem.defaultProps = {
  selectedIndex: null,
}

export default class CategoryPostSelector extends PureComponent {
  static propTypes = {
    onSelect: PropTypes.func.isRequired,
    onClear: PropTypes.func.isRequired,
    subscribedCategories: PropTypes.array.isRequired,
    featuredInCategories: PropTypes.array.isRequired,
    unsubscribedCategories: PropTypes.array.isRequired,
    selectedCategories: PropTypes.array.isRequired,
  }

  constructor(props) {
    super(props)
    const { subscribedCategories, unsubscribedCategories } = props
    this.state = {
      subscribedCategories,
      unsubscribedCategories,
      searchText: '',
      selectedIndex: null,
    }
  }

  componentDidMount() {
    const { onSelect, featuredInCategories } = this.props
    if (featuredInCategories.length > 0) {
      onSelect(featuredInCategories[0])
    }
  }

  componentWillReceiveProps(nextProps) {
    const { subscribedCategories, unsubscribedCategories } = nextProps
    const { searchText } = this.state
    this.setState({
      subscribedCategories: filterSearch(subscribedCategories, searchText),
      unsubscribedCategories: filterSearch(unsubscribedCategories, searchText),
    })
  }

  handleSearch = (event) => {
    const searchText = event.target.value
    const { subscribedCategories, unsubscribedCategories } = this.props
    this.setState({
      selectedIndex: 0,
      searchText,
      subscribedCategories: filterSearch(subscribedCategories, searchText),
      unsubscribedCategories: filterSearch(unsubscribedCategories, searchText),
    })
  }

  handleKeyDown = (event) => {
    const { subscribedCategories, unsubscribedCategories, selectedIndex } = this.state
    const { onSelect } = this.props
    const categories = subscribedCategories.concat(unsubscribedCategories)
    const max = categories.length
    if (event.key === 'ArrowDown' && isNaN(selectedIndex)) {
      this.setState({ selectedIndex: 0 })
    } else if (event.key === 'ArrowDown' && selectedIndex < max) {
      this.setState({ selectedIndex: selectedIndex + 1 })
    } else if (event.key === 'ArrowUp' && !isNaN(selectedIndex) && selectedIndex > 0) {
      this.setState({ selectedIndex: selectedIndex - 1 })
    } else if (event.key === 'Enter' && !isNaN(selectedIndex)) {
      onSelect(categories[selectedIndex])
    }
  }

  render() {
    const { selectedCategories, onClear, onSelect } = this.props
    const { subscribedCategories, unsubscribedCategories, searchText, selectedIndex } = this.state
    // Everything except this component could support multiple categories, but for now
    // we can assume there is only one selected category per post.
    const selectedCategory = selectedCategories[0]
    const offset = subscribedCategories.length
    return (

          {!selectedCategory &&
            <input
              className="selector"
              type="search"
              value={searchText}
              onChange={this.handleSearch}
              onKeyDown={this.handleKeyDown}
            />
          }
          {selectedCategory &&

              {selectedCategory.get('name')}
              <button onClick={onClear}>X</button>

          }

          {subscribedCategories.length > 0 &&

              Your Categories

                {subscribedCategories.map((category, index) =>
                  (<CategoryItem
                    key={`categorySelect:${category.get('id')}`}
                    category={category}
                    index={index}
                    selectedIndex={selectedIndex}
                    onSelect={onSelect}
                  />),
                )}

          }

            All Categories

              {unsubscribedCategories.map((category, index) =>
                (<CategoryItem
                  key={`categorySelect:${category.get('id')}`}
                  category={category}
                  index={index + offset}
                  selectedIndex={selectedIndex}
                  onSelect={onSelect}
                />),
              )}

    )
  }
}
<|endoftext|>


<commit_before>import React from "react";
import ImageGallery from "react-image-gallery";

// This component knows how to process a "thing" (case, method, etc) and extract the images
// and other data that the ImageGallery component needs.

function getPics(thing) {
  let awsUrl = process.env.REACT_APP_ASSETS_URL;
  let theLength = "";
  let pics = [];
  console.log(thing, thing.lead_image);
  if (thing && thing.lead_image) {
    pics.push(awsUrl + encodeURIComponent(thing.lead_image.url));
  }
  if (thing && thing.other_images.length) {
    theLength = thing.other_images;
    Object.keys(theLength).forEach(function(key) {
      let obj = theLength[key];
      pics.push(awsUrl + encodeURIComponent(obj.url));
    });
  }
  return pics;
}

class Gallery extends React.Component {
  constructor(props) {
    super(props);
    this.defineImage = this.defineImage.bind(this);
    this.getWidth = this.getWidth.bind(this);
    this.renderItem = this.renderItem.bind(this);
    this.state = { pics: getPics(props.thing) };
  }

  componentWillReceiveProps(nextProps) {
    this.setState({ pics: getPics(nextProps.thing) });
  }

  defineImage(url) {
    if (url) {
      let width = this.getWidth(url);
      if (width < 500) {
        return "portrait";
      } else {
        return "landscape";
      }
    } else {
      return;
    }
  }

  getWidth(url) {
    let img = new Image();
    img.src = url;
    return img.naturalWidth;
  }

  renderItem(item) {
    const imageClass = this.defineImage(item.original);
    return (

    );
  }

  render() {
    const images = this.state.pics.map(photo => {
      const src = photo;
      return {
        original: src,
        thumbnail: src
      };
    });

    if (images.length === 0) {
      return
;
    } else if (images.length > 1) {
      return (
        <ImageGallery
          items={images}
          showFullscreenButton={false}
          renderItem={this.renderItem}
          slideInterval={2000}
        />
      );
    } else {
      return this.renderItem(images[0]);
    }
  }
}

export default Gallery;
<commit_msg>remove console.log<commit_after>import React from "react";
import ImageGallery from "react-image-gallery";

// This component knows how to process a "thing" (case, method, etc) and extract the images
// and other data that the ImageGallery component needs.

function getPics(thing) {
  let awsUrl = process.env.REACT_APP_ASSETS_URL;
  let theLength = "";
  let pics = [];
  if (thing && thing.lead_image) {
    pics.push(awsUrl + encodeURIComponent(thing.lead_image.url));
  }
  if (thing && thing.other_images.length) {
    theLength = thing.other_images;
    Object.keys(theLength).forEach(function(key) {
      let obj = theLength[key];
      pics.push(awsUrl + encodeURIComponent(obj.url));
    });
  }
  return pics;
}

class Gallery extends React.Component {
  constructor(props) {
    super(props);
    this.defineImage = this.defineImage.bind(this);
    this.getWidth = this.getWidth.bind(this);
    this.renderItem = this.renderItem.bind(this);
    this.state = { pics: getPics(props.thing) };
  }

  componentWillReceiveProps(nextProps) {
    this.setState({ pics: getPics(nextProps.thing) });
  }

  defineImage(url) {
    if (url) {
      let width = this.getWidth(url);
      if (width < 500) {
        return "portrait";
      } else {
        return "landscape";
      }
    } else {
      return;
    }
  }

  getWidth(url) {
    let img = new Image();
    img.src = url;
    return img.naturalWidth;
  }

  renderItem(item) {
    const imageClass = this.defineImage(item.original);
    return (

    );
  }

  render() {
    const images = this.state.pics.map(photo => {
      const src = photo;
      return {
        original: src,
        thumbnail: src
      };
    });

    if (images.length === 0) {
      return
;
    } else if (images.length > 1) {
      return (
        <ImageGallery
          items={images}
          showFullscreenButton={false}
          renderItem={this.renderItem}
          slideInterval={2000}
        />
      );
    } else {
      return this.renderItem(images[0]);
    }
  }
}

export default Gallery;
<|endoftext|>


<commit_before>/*globals jQuery, define, module, exports, require, window, document, postMessage */
(function (factory) {
  'use strict';
  if (typeof define === 'function' && define.amd) {
    define(['jquery'], factory);
  }
  else if(typeof module !== 'undefined' && module.exports) {
    module.exports = factory(require('jquery'));
  }
  else {
    factory(jQuery);
  }
}(function ($, undefined) {
  'use strict';

  if($.sidebar) {
    return;
  }

  $.fn.sidebar = function(arg) {
    return $.sidebar.create(this, arg);
  };

	var _templateWindowNode = document.createElement('li');
	_templateWindowNode.className = 'sidebar-window-node';
	var windowHighlightEl = document.createElement('div');
	windowHighlightEl.className = 'sidebar-window-row';
	windowHighlightEl.textContent = ' ';
	_templateWindowNode.appendChild(windowHighlightEl);
	var windowPrefixEl = document.createElement('span');
	windowPrefixEl.className = 'sidebar-window-prefix';
	_templateWindowNode.appendChild(windowPrefixEl);
	var windowAnchorEl = document.createElement('a');
	windowAnchorEl.className = 'sidebar-window-anchor';
	windowAnchorEl.setAttribute('href', '#');
	windowAnchorEl.setAttribute('tabIndex', '-1');
	_templateWindowNode.appendChild(windowAnchorEl);
	var windowSuffixEl = document.createElement('span');
	_templateWindowNode.appendChild(windowSuffixEl);
	var windowUl = document.createElement('ul');
    windowUl.className = 'sidebar-tabs-list';
	_templateWindowNode.appendChild(windowUl);
	var _windowUlPos = 4;

	var _templateTabNode = document.createElement('li');
	_templateTabNode.className = 'sidebar-tab-node';
	var tabHighlightEl = document.createElement('div');
	tabHighlightEl.className = 'sidebar-tab-row';
	tabHighlightEl.textContent = ' ';
	_templateTabNode.appendChild(tabHighlightEl);
	var tabPrefixEl = document.createElement('span');
	tabPrefixEl.className = 'sidebar-tab-favicon';
	_templateTabNode.appendChild(tabPrefixEl);
	var tabAnchorEl = document.createElement('a');
	tabAnchorEl.className = 'sidebar-tab-anchor';
	tabAnchorEl.setAttribute('href', '#');
	tabAnchorEl.setAttribute('tabIndex', '-1');
	_templateTabNode.appendChild(tabAnchorEl);
	var tabSuffixEl = document.createElement('span');
	tabSuffixEl.className = 'sidebar-tab-icon sidebar-tab-icon-close';
	_templateTabNode.appendChild(tabSuffixEl);

  $.sidebar = {};

  $.sidebar.create = function(el) {
    var result = new $.sidebar.core(el);
    result.init(el);
    return result;
  };

  $.sidebar.core = function(el) {
  };

  $.sidebar.core.prototype = {
    init: function(el) {
      this._model = {};
      this._model.windows = new Map();
      this._model.tabs = new Map();
      this._element = $(el).addClass('tabs-lorg-nav-root');
      this._root = $('<ul>').addClass('sidebar-nodes-container-list').appendTo(this._element)[0];
      this.bind();
    },

    bind: function() {
      this._element.on('click.sidebar', '.sidebar-tab-node', $.proxy(function (e) {
      	log('Clicked!', e);
      	this._tabNodeClicked(e);
      }, this));
    },

    _getTabElement: function(tabId) {
      return document.getElementById('sidebar-tab-' + tabId);
    },

    _getWindowElement: function(windowId) {
      return document.getElementById('sidebar-win-' + windowId);
    },

    _getTabIdsForWindow: function(windowId) {
      var result = [];
      this._model.tabs.forEach(tabModel => {
      	if (tabModel.windowId === windowId) {
      	  result.push(tabModel.tabId);
      	}
      });
      return result;
    },

    _tabNodeClicked: function(e) {
      var tabNode = e.currentTarget;
      var tabId = parseInt(tabNode.id.substring(12));
      log('Tab node clicked', tabId, tabNode);
      chrome.tabs.get(tabId, function(tab) {
        chrome.windows.get(tab.windowId, {}, function(window) {
          if (!tab.active) {
            log('Activating tab because node was selected', tab);
            chrome.tabs.update(tab.id, {active: true});
          }
          if (!window.focused) {
            chrome.windows.update(tab.windowId, {focused: true});
          }
        });
      });
    },

    _updateViewTimer: null,
    _updateView: function() {
	    if (this._updateViewTimer) {
	      clearTimeout(this._updateViewTimer);
	    }
	    this._updateViewTimer = setTimeout(() => {
	      log('Updating view...', this._model.tabs);
	      var tabsGroupedByUrl = new Map();
	      var tabsGroupedByWindow = new Map();
	      this._model.tabs.forEach((tabModel, tabId) => {
	      	var url = tabModel.url;
	      	if (url) {
		      var pos = url.indexOf('chrome-extension://klbibkeccnjlkjkiokjodocebajanakg/suspended.html#uri=');
		      if (pos === 0) {
		        url = url.substring(71);
		      }
		      pos = url.indexOf('#');
		      if (pos >= 0) {
		        url = url.substring(0, pos);
		      }
		      pos = url.indexOf('http://');
		      if (pos === 0) {
		        url = url.substring(7);
		      }
		      pos = url.indexOf('https://');
		      if (pos === 0) {
		        url = url.substring(8);
		      }
		    }
	      	var tabIdsByUrl = tabsGroupedByUrl.get(url) || [];
	      	tabIdsByUrl.push(tabId);
	      	tabsGroupedByUrl.set(url, tabIdsByUrl);

	      	var tabIdsByWindow = tabsGroupedByWindow.get(tabModel.windowId) || [];
	      	tabIdsByWindow.push(tabId);
	      	tabsGroupedByWindow.set(tabModel.windowId, tabIdsByWindow);

	      	if (tabModel.url && tabModel.url.indexOf('chrome-extension://klbibkeccnjlkjkiokjodocebajanakg') === 0) {
              log('Hibernated tab found', tabModel);
              this._getTabElement(tabId).classList.add('sidebar-tab-hibernated');
            }
            else {
              this._getTabElement(tabId).classList.remove('sidebar-tab-hibernated');
            }
	      });
	      log('Duplicates analysis result', tabsGroupedByUrl);
	      tabsGroupedByUrl.forEach((tabIds, url) => {
	        tabIds.forEach(tabId => {
	          if (tabIds.length > 1) {
	            log('Duplicate URL found', url, tabId);
	          	this._getTabElement(tabId).children[2].classList.add('sidebar-tab-duplicate');
	          }
	          else {
	          	this._getTabElement(tabId).children[2].classList.remove('sidebar-tab-duplicate');
	          }
	        });
	      });
	      tabsGroupedByWindow.forEach((tabIds, windowId) => {
	        var windowElement = this._getWindowElement(windowId);
	        var windowModel = this._model.windows.get(windowId);
	        windowElement.children[2].textContent = windowModel.text + ' (' + tabIds.length + ')';
	      });
	    }, 500);
    },

    addWindow: function(windowId, text) {
      if (!this._model.windows.has(windowId)) {
        var windowEl = _templateWindowNode.cloneNode(true);
        windowEl.id = 'sidebar-win-' + windowId;
        windowEl.children[2].textContent = text + '(1)';
        this._root.appendChild(windowEl);
        this._model.windows.set(windowId, {windowId: windowId, text: text});
        this._updateView();
      }
    },

    removeWindow: function(windowId) {
      var windowElement = this._getWindowElement(windowId);
      if (windowElement) {
        windowElement.remove();
      }
      var tabIdsToDelete = this._getTabIdsForWindow(windowId);
      tabIdsToDelete.forEach(tabId => {
        this._model.tabs.delete(tabId);
      });
      this._model.windows.delete(windowId);
    },

    addTab: function(windowId, tabId, pos, text, icon, url) {
      if (this._model.windows.has(windowId)) {
        var windowElement = this._getWindowElement(windowId);
        var tabElement = _templateTabNode.cloneNode(true);
        tabElement.id = 'sidebar-tab-' + tabId;
        tabElement.children[2].appendChild(document.createTextNode(text));
        tabElement.children[1].style.backgroundImage = 'url(' + icon + ')';
        windowElement.children[4].appendChild(tabElement);
        // Model update
        var tabModel = {windowId: windowId, tabId: tabId, text: text, icon: icon, url: url, selected: false};
        this._model.tabs.set(tabId, tabModel);
        this._updateView();
        return true;
      }
      return false;
    },

    removeTab: function(tabId) {
      var tabModel = this._model.tabs.get(tabId);
      if (tabModel) {
      	this._model.tabs.delete(tabId);
      	var tabElement = this._getTabElement(tabId);
      	tabElement.remove();
      }
      this._updateView();
    },

    setTabText: function(tabId, tabText) {
      log('Setting text for tab', tabId, tabText);
      var tabElement = this._getTabElement(tabId);
      if (tabElement) {
        tabElement.children[2].textContent = tabText;
      }
    },

    setTabIcon: function(tabId, icon) {
      log('Setting icon for tab', tabId, icon);
      var tabElement = this._getTabElement(tabId);
      if (tabElement) {
        tabElement.children[1].style.backgroundImage = 'url(' + icon + ')';
      }
    },

    setTabUrl: function(tabId, url) {
      log('Setting URL for tab', tabId, url);
      var tabModel = this._model.tabs.get(tabId);
      if (tabModel) {
        tabModel.url = url;
      }
      this._updateView();
    },

    selectTab: function(selectedTabId) {
      log('Selecting tab', selectedTabId);
      this._model.tabs.forEach((tabModel, tabId) => {
      	if (tabId !== selectedTabId && tabModel.selected) {
      	  log('Deselecting tab', tabId, tabModel);
          var tabElement = this._getTabElement(tabId);
          tabModel.selected = false;
          tabElement.children[0].classList.remove('sidebar-tab-selected');
      	}
      });
      var tabElement = this._getTabElement(selectedTabId);
      tabElement.children[0].classList.add('sidebar-tab-selected');
      this._model.tabs.get(selectedTabId).selected = true;
	  if (!$(tabElement).visible()) {
	    var offset = tabElement.offset();
	    if (offset) {
	      jQuery(document).scrollTop(tabElement.offset().top - 25);
	    }
	  }
    },

    moveTab: function(tabId, targetWindowId, pos) {
      var tabElement = this._getTabElement(tabId);
      var targetWindowElement = this._getWindowElement(targetWindowId);
      targetWindowElement.children[4].insertBefore(tabElement.parentNode.removeChild(tabElement), targetWindowElement.children[4].children[pos]);
      this._model.tabs.get(tabId).windowId = targetWindowId;
      this._updateView();
    },

    search: function(searchPattern) {
      this._model.tabs.forEach((tabModel, tabId) => {
      	var tabElement = this._getTabElement(tabId);
      	if (searchPattern.length === 0) {
          tabElement.classList.remove('sidebar-tab-hidden');
          tabElement.classList.remove('sidebar-tab-search-match');
      	}
      	else if (tabModel.text.toLowerCase().indexOf(searchPattern) === -1 && tabModel.url.toLowerCase().indexOf(searchPattern) === -1) {
          tabElement.classList.add('sidebar-tab-hidden');
          tabElement.classList.remove('sidebar-tab-search-match');
      	}
      	else {
          tabElement.classList.remove('sidebar-tab-hidden');
          tabElement.classList.add('sidebar-tab-search-match');
      	}
      });
    }
  };
}));<commit_msg>Fixed formatting<commit_after>/*globals jQuery, define, module, exports, require, window, document, postMessage */
(function (factory) {
  'use strict';
  if (typeof define === 'function' && define.amd) {
    define(['jquery'], factory);
  }
  else if(typeof module !== 'undefined' && module.exports) {
    module.exports = factory(require('jquery'));
  }
  else {
    factory(jQuery);
  }
}(function ($, undefined) {
  'use strict';

  if($.sidebar) {
    return;
  }

  $.fn.sidebar = function(arg) {
    return $.sidebar.create(this, arg);
  };

  var _templateWindowNode = document.createElement('li');
  _templateWindowNode.className = 'sidebar-window-node';
  var windowHighlightEl = document.createElement('div');
  windowHighlightEl.className = 'sidebar-window-row';
  windowHighlightEl.textContent = ' ';
  _templateWindowNode.appendChild(windowHighlightEl);
  var windowPrefixEl = document.createElement('span');
  windowPrefixEl.className = 'sidebar-window-prefix';
  _templateWindowNode.appendChild(windowPrefixEl);
  var windowAnchorEl = document.createElement('a');
  windowAnchorEl.className = 'sidebar-window-anchor';
  windowAnchorEl.setAttribute('href', '#');
  windowAnchorEl.setAttribute('tabIndex', '-1');
  _templateWindowNode.appendChild(windowAnchorEl);
  var windowSuffixEl = document.createElement('span');
  _templateWindowNode.appendChild(windowSuffixEl);
  var windowUl = document.createElement('ul');
  windowUl.className = 'sidebar-tabs-list';
  _templateWindowNode.appendChild(windowUl);

  var _templateTabNode = document.createElement('li');
  _templateTabNode.className = 'sidebar-tab-node';
  var tabHighlightEl = document.createElement('div');
  tabHighlightEl.className = 'sidebar-tab-row';
  tabHighlightEl.textContent = ' ';
  _templateTabNode.appendChild(tabHighlightEl);
  var tabPrefixEl = document.createElement('span');
  tabPrefixEl.className = 'sidebar-tab-favicon';
  _templateTabNode.appendChild(tabPrefixEl);
  var tabAnchorEl = document.createElement('a');
  tabAnchorEl.className = 'sidebar-tab-anchor';
  tabAnchorEl.setAttribute('href', '#');
  tabAnchorEl.setAttribute('tabIndex', '-1');
  _templateTabNode.appendChild(tabAnchorEl);
  var tabSuffixEl = document.createElement('span');
  tabSuffixEl.className = 'sidebar-tab-icon sidebar-tab-icon-close';
  _templateTabNode.appendChild(tabSuffixEl);

  $.sidebar = {};

  $.sidebar.create = function(el) {
    var result = new $.sidebar.core(el);
    result.init(el);
    return result;
  };

  $.sidebar.core = function(el) {
  };

  $.sidebar.core.prototype = {
    init: function(el) {
      this._model = {};
      this._model.windows = new Map();
      this._model.tabs = new Map();
      this._element = $(el).addClass('tabs-lorg-nav-root');
      this._root = $('<ul>').addClass('sidebar-nodes-container-list').appendTo(this._element)[0];
      this.bind();
    },

    bind: function() {
      this._element
      .on('click.sidebar', '.sidebar-tab-icon-close', $.proxy(function (e) {
        log('Close icon clicked!', e);
        e.stopImmediatePropagation();
        this._closeTabClicked(e);
      }, this))
      .on('click.sidebar', '.sidebar-tab-node', $.proxy(function (e) {
        log('Clicked!', e);
        this._tabNodeClicked(e);
      }, this));
    },

    _getTabElement: function(tabId) {
      return document.getElementById('sidebar-tab-' + tabId);
    },

    _getWindowElement: function(windowId) {
      return document.getElementById('sidebar-win-' + windowId);
    },

    _getTabIdsForWindow: function(windowId) {
      var result = [];
      this._model.tabs.forEach(tabModel => {
        if (tabModel.windowId === windowId) {
          result.push(tabModel.tabId);
        }
      });
      return result;
    },

    _closeTabClicked: function(e) {
      var tabNode = e.currentTarget.parentNode;
      var tabId = parseInt(tabNode.id.substring(12));
      log('Closed tab icon node clicked', tabId, tabNode);
      chrome.tabs.remove(tabId, () => {
        this._updateView();
      });
    },

    _tabNodeClicked: function(e) {
      var tabNode = e.currentTarget;
      var tabId = parseInt(tabNode.id.substring(12));
      log('Tab node clicked', tabId, tabNode);
      chrome.tabs.get(tabId, function(tab) {
        chrome.windows.get(tab.windowId, {}, window => {
          if (!tab.active) {
            log('Activating tab because node was selected', tab);
            chrome.tabs.update(tab.id, {active: true});
          }
          if (!window.focused) {
            chrome.windows.update(tab.windowId, {focused: true});
          }
        });
      });
    },

    _updateViewTimer: null,
    _updateView: function() {
      if (this._updateViewTimer) {
        clearTimeout(this._updateViewTimer);
      }
      this._updateViewTimer = setTimeout(() => {
        log('Updating view...', this._model.tabs);
        var tabsGroupedByUrl = new Map();
        var tabsGroupedByWindow = new Map();
        this._model.tabs.forEach((tabModel, tabId) => {
          var url = tabModel.url;
          if (url) {
            var pos = url.indexOf('chrome-extension://klbibkeccnjlkjkiokjodocebajanakg/suspended.html#uri=');
            if (pos === 0) {
              url = url.substring(71);
            }
            pos = url.indexOf('#');
            if (pos >= 0) {
              url = url.substring(0, pos);
            }
            pos = url.indexOf('http://');
            if (pos === 0) {
              url = url.substring(7);
            }
            pos = url.indexOf('https://');
            if (pos === 0) {
              url = url.substring(8);
            }
          }
          var tabIdsByUrl = tabsGroupedByUrl.get(url) || [];
          tabIdsByUrl.push(tabId);
          tabsGroupedByUrl.set(url, tabIdsByUrl);

          var tabIdsByWindow = tabsGroupedByWindow.get(tabModel.windowId) || [];
          tabIdsByWindow.push(tabId);
          tabsGroupedByWindow.set(tabModel.windowId, tabIdsByWindow);

          if (tabModel.url && tabModel.url.indexOf('chrome-extension://klbibkeccnjlkjkiokjodocebajanakg') === 0) {
            log('Hibernated tab found', tabModel);
            this._getTabElement(tabId).classList.add('sidebar-tab-hibernated');
          }
          else {
            this._getTabElement(tabId).classList.remove('sidebar-tab-hibernated');
          }
        });
        log('Duplicates analysis result', tabsGroupedByUrl);
        tabsGroupedByUrl.forEach((tabIds, url) => {
          tabIds.forEach(tabId => {
            if (tabIds.length > 1) {
              log('Duplicate URL found', url, tabId);
              this._getTabElement(tabId).children[2].classList.add('sidebar-tab-duplicate');
            }
            else {
              this._getTabElement(tabId).children[2].classList.remove('sidebar-tab-duplicate');
            }
          });
        });
        tabsGroupedByWindow.forEach((tabIds, windowId) => {
          var windowElement = this._getWindowElement(windowId);
          var windowModel = this._model.windows.get(windowId);
          windowElement.children[2].textContent = windowModel.text + ' (' + tabIds.length + ')';
        });
      }, 500);
    },

    addWindow: function(windowId, text) {
      if (!this._model.windows.has(windowId)) {
        var windowEl = _templateWindowNode.cloneNode(true);
        windowEl.id = 'sidebar-win-' + windowId;
        windowEl.children[2].textContent = text + '(1)';
        this._root.appendChild(windowEl);
        this._model.windows.set(windowId, {windowId: windowId, text: text});
        this._updateView();
      }
    },

    removeWindow: function(windowId) {
      var windowElement = this._getWindowElement(windowId);
      if (windowElement) {
        windowElement.remove();
      }
      var tabIdsToDelete = this._getTabIdsForWindow(windowId);
      tabIdsToDelete.forEach(tabId => {
        this._model.tabs.delete(tabId);
      });
      this._model.windows.delete(windowId);
    },

    addTab: function(windowId, tabId, pos, text, icon, url) {
      if (this._model.windows.has(windowId)) {
        var windowElement = this._getWindowElement(windowId);
        var tabElement = _templateTabNode.cloneNode(true);
        tabElement.id = 'sidebar-tab-' + tabId;
        tabElement.children[2].appendChild(document.createTextNode(text));
        tabElement.children[1].style.backgroundImage = 'url(' + icon + ')';
        windowElement.children[4].appendChild(tabElement);
        // Model update
        var tabModel = {windowId: windowId, tabId: tabId, text: text, icon: icon, url: url, selected: false};
        this._model.tabs.set(tabId, tabModel);
        this._updateView();
        return true;
      }
      return false;
    },

    removeTab: function(tabId) {
      var tabModel = this._model.tabs.get(tabId);
      if (tabModel) {
        this._model.tabs.delete(tabId);
        var tabElement = this._getTabElement(tabId);
        tabElement.remove();
      }
      this._updateView();
    },

    setTabText: function(tabId, tabText) {
      log('Setting text for tab', tabId, tabText);
      var tabElement = this._getTabElement(tabId);
      if (tabElement) {
        tabElement.children[2].textContent = tabText;
      }
    },

    setTabIcon: function(tabId, icon) {
      log('Setting icon for tab', tabId, icon);
      var tabElement = this._getTabElement(tabId);
      if (tabElement) {
        tabElement.children[1].style.backgroundImage = 'url(' + icon + ')';
      }
    },

    setTabUrl: function(tabId, url) {
      log('Setting URL for tab', tabId, url);
      var tabModel = this._model.tabs.get(tabId);
      if (tabModel) {
        tabModel.url = url;
      }
      this._updateView();
    },

    selectTab: function(selectedTabId) {
      log('Selecting tab', selectedTabId);
      this._model.tabs.forEach((tabModel, tabId) => {
        if (tabId !== selectedTabId && tabModel.selected) {
          log('Deselecting tab', tabId, tabModel);
          var tabElement = this._getTabElement(tabId);
          tabModel.selected = false;
          tabElement.children[0].classList.remove('sidebar-tab-selected');
        }
      });
      var tabElement = this._getTabElement(selectedTabId);
      tabElement.children[0].classList.add('sidebar-tab-selected');
      this._model.tabs.get(selectedTabId).selected = true;
      if (!$(tabElement).visible()) {
        var offset = tabElement.offset();
        if (offset) {
          jQuery(document).scrollTop(tabElement.offset().top - 25);
        }
      }
    },

    moveTab: function(tabId, targetWindowId, pos) {
      var tabElement = this._getTabElement(tabId);
      var targetWindowElement = this._getWindowElement(targetWindowId);
      targetWindowElement.children[4].insertBefore(tabElement.parentNode.removeChild(tabElement), targetWindowElement.children[4].children[pos]);
      this._model.tabs.get(tabId).windowId = targetWindowId;
      this._updateView();
    },

    search: function(searchPattern) {
      this._model.tabs.forEach((tabModel, tabId) => {
        var tabElement = this._getTabElement(tabId);
        if (searchPattern.length === 0) {
          tabElement.classList.remove('sidebar-tab-hidden');
          tabElement.classList.remove('sidebar-tab-search-match');
        }
        else if (tabModel.text.toLowerCase().indexOf(searchPattern) === -1 && tabModel.url.toLowerCase().indexOf(searchPattern) === -1) {
          tabElement.classList.add('sidebar-tab-hidden');
          tabElement.classList.remove('sidebar-tab-search-match');
        }
        else {
          tabElement.classList.remove('sidebar-tab-hidden');
          tabElement.classList.add('sidebar-tab-search-match');
        }
      });
    }
  };
}));<|endoftext|>